1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "interpreter_common.h" 18 19 namespace art { 20 namespace interpreter { 21 22 // In the following macros, we expect the following local variables exist: 23 // - "self": the current Thread*. 24 // - "inst" : the current Instruction*. 25 // - "inst_data" : the current instruction's first 16 bits. 26 // - "dex_pc": the current pc. 27 // - "shadow_frame": the current shadow frame. 28 // - "mh": the current MethodHelper. 29 // - "currentHandlersTable": the current table of pointer to each instruction handler. 30 31 // Advance to the next instruction and updates interpreter state. 32 #define ADVANCE(_offset) \ 33 do { \ 34 int32_t disp = static_cast<int32_t>(_offset); \ 35 inst = inst->RelativeAt(disp); \ 36 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \ 37 shadow_frame.SetDexPC(dex_pc); \ 38 TraceExecution(shadow_frame, inst, dex_pc, mh); \ 39 inst_data = inst->Fetch16(0); \ 40 goto *currentHandlersTable[inst->Opcode(inst_data)]; \ 41 } while (false) 42 43 #define HANDLE_PENDING_EXCEPTION() goto exception_pending_label 44 45 #define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \ 46 do { \ 47 if (UNLIKELY(_is_exception_pending)) { \ 48 HANDLE_PENDING_EXCEPTION(); \ 49 } else { \ 50 ADVANCE(_offset); \ 51 } \ 52 } while (false) 53 54 #define UPDATE_HANDLER_TABLE() \ 55 currentHandlersTable = handlersTable[Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()] 56 57 #define UNREACHABLE_CODE_CHECK() \ 58 do { \ 59 if (kIsDebugBuild) { \ 60 LOG(FATAL) << "We should not be here !"; \ 61 } \ 62 } while (false) 63 64 #define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels) 65 #define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK() 66 67 /** 68 * Interpreter based on computed goto tables. 69 * 70 * Each instruction is associated to a handler. This handler is responsible for executing the 71 * instruction and jump to the next instruction's handler. 72 * In order to limit the cost of instrumentation, we have two handler tables: 73 * - the "main" handler table: it contains handlers for normal execution of each instruction without 74 * handling of instrumentation. 75 * - the "alternative" handler table: it contains alternative handlers which first handle 76 * instrumentation before jumping to the corresponding "normal" instruction's handler. 77 * 78 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise 79 * it uses the "main" handler table. 80 * 81 * The current handler table is the handler table being used by the interpreter. It is updated: 82 * - on backward branch (goto, if and switch instructions) 83 * - after invoke 84 * - when an exception is thrown. 85 * This allows to support an attaching debugger to an already running application for instance. 86 * 87 * For a fast handler table update, handler tables are stored in an array of handler tables. Each 88 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it 89 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable). 90 * 91 * Here's the current layout of this array of handler tables: 92 * 93 * ---------------------+---------------+ 94 * | NOP | (handler for NOP instruction) 95 * +---------------+ 96 * "main" | MOVE | (handler for MOVE instruction) 97 * handler table +---------------+ 98 * | ... | 99 * +---------------+ 100 * | UNUSED_FF | (handler for UNUSED_FF instruction) 101 * ---------------------+---------------+ 102 * | NOP | (alternative handler for NOP instruction) 103 * +---------------+ 104 * "alternative" | MOVE | (alternative handler for MOVE instruction) 105 * handler table +---------------+ 106 * | ... | 107 * +---------------+ 108 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction) 109 * ---------------------+---------------+ 110 * 111 */ 112 template<bool do_access_check, bool transaction_active> 113 JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 114 ShadowFrame& shadow_frame, JValue result_register) { 115 // Define handler tables: 116 // - The main handler table contains execution handlers for each instruction. 117 // - The alternative handler table contains prelude handlers which check for thread suspend and 118 // manage instrumentation before jumping to the execution handler. 119 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = { 120 { 121 // Main handler table. 122 #define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code, 123 #include "dex_instruction_list.h" 124 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER) 125 #undef DEX_INSTRUCTION_LIST 126 #undef INSTRUCTION_HANDLER 127 }, { 128 // Alternative handler table. 129 #define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code, 130 #include "dex_instruction_list.h" 131 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER) 132 #undef DEX_INSTRUCTION_LIST 133 #undef INSTRUCTION_HANDLER 134 } 135 }; 136 137 const bool do_assignability_check = do_access_check; 138 if (UNLIKELY(!shadow_frame.HasReferenceArray())) { 139 LOG(FATAL) << "Invalid shadow frame for interpreter use"; 140 return JValue(); 141 } 142 self->VerifyStack(); 143 144 uint32_t dex_pc = shadow_frame.GetDexPC(); 145 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc); 146 uint16_t inst_data; 147 const void* const* currentHandlersTable; 148 bool notified_method_entry_event = false; 149 UPDATE_HANDLER_TABLE(); 150 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.. 151 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 152 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) { 153 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 154 shadow_frame.GetMethod(), 0); 155 notified_method_entry_event = true; 156 } 157 } 158 159 // Jump to first instruction. 160 ADVANCE(0); 161 UNREACHABLE_CODE_CHECK(); 162 163 HANDLE_INSTRUCTION_START(NOP) 164 ADVANCE(1); 165 HANDLE_INSTRUCTION_END(); 166 167 HANDLE_INSTRUCTION_START(MOVE) 168 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), 169 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 170 ADVANCE(1); 171 HANDLE_INSTRUCTION_END(); 172 173 HANDLE_INSTRUCTION_START(MOVE_FROM16) 174 shadow_frame.SetVReg(inst->VRegA_22x(inst_data), 175 shadow_frame.GetVReg(inst->VRegB_22x())); 176 ADVANCE(2); 177 HANDLE_INSTRUCTION_END(); 178 179 HANDLE_INSTRUCTION_START(MOVE_16) 180 shadow_frame.SetVReg(inst->VRegA_32x(), 181 shadow_frame.GetVReg(inst->VRegB_32x())); 182 ADVANCE(3); 183 HANDLE_INSTRUCTION_END(); 184 185 HANDLE_INSTRUCTION_START(MOVE_WIDE) 186 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), 187 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 188 ADVANCE(1); 189 HANDLE_INSTRUCTION_END(); 190 191 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16) 192 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data), 193 shadow_frame.GetVRegLong(inst->VRegB_22x())); 194 ADVANCE(2); 195 HANDLE_INSTRUCTION_END(); 196 197 HANDLE_INSTRUCTION_START(MOVE_WIDE_16) 198 shadow_frame.SetVRegLong(inst->VRegA_32x(), 199 shadow_frame.GetVRegLong(inst->VRegB_32x())); 200 ADVANCE(3); 201 HANDLE_INSTRUCTION_END(); 202 203 HANDLE_INSTRUCTION_START(MOVE_OBJECT) 204 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data), 205 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data))); 206 ADVANCE(1); 207 HANDLE_INSTRUCTION_END(); 208 209 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16) 210 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data), 211 shadow_frame.GetVRegReference(inst->VRegB_22x())); 212 ADVANCE(2); 213 HANDLE_INSTRUCTION_END(); 214 215 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16) 216 shadow_frame.SetVRegReference(inst->VRegA_32x(), 217 shadow_frame.GetVRegReference(inst->VRegB_32x())); 218 ADVANCE(3); 219 HANDLE_INSTRUCTION_END(); 220 221 HANDLE_INSTRUCTION_START(MOVE_RESULT) 222 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI()); 223 ADVANCE(1); 224 HANDLE_INSTRUCTION_END(); 225 226 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE) 227 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ()); 228 ADVANCE(1); 229 HANDLE_INSTRUCTION_END(); 230 231 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT) 232 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL()); 233 ADVANCE(1); 234 HANDLE_INSTRUCTION_END(); 235 236 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) { 237 Throwable* exception = self->GetException(nullptr); 238 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception); 239 self->ClearException(); 240 ADVANCE(1); 241 } 242 HANDLE_INSTRUCTION_END(); 243 244 HANDLE_INSTRUCTION_START(RETURN_VOID) { 245 JValue result; 246 if (do_access_check) { 247 // If access checks are required then the dex-to-dex compiler and analysis of 248 // whether the class has final fields hasn't been performed. Conservatively 249 // perform the memory barrier now. 250 QuasiAtomic::ThreadFenceForConstructor(); 251 } 252 if (UNLIKELY(self->TestAllFlags())) { 253 CheckSuspend(self); 254 } 255 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 256 if (UNLIKELY(instrumentation->HasMethodExitListeners())) { 257 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 258 shadow_frame.GetMethod(), dex_pc, 259 result); 260 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { 261 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 262 shadow_frame.GetMethod(), dex_pc); 263 } 264 return result; 265 } 266 HANDLE_INSTRUCTION_END(); 267 268 HANDLE_INSTRUCTION_START(RETURN_VOID_BARRIER) { 269 QuasiAtomic::ThreadFenceForConstructor(); 270 JValue result; 271 if (UNLIKELY(self->TestAllFlags())) { 272 CheckSuspend(self); 273 } 274 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 275 if (UNLIKELY(instrumentation->HasMethodExitListeners())) { 276 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 277 shadow_frame.GetMethod(), dex_pc, 278 result); 279 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { 280 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 281 shadow_frame.GetMethod(), dex_pc); 282 } 283 return result; 284 } 285 HANDLE_INSTRUCTION_END(); 286 287 HANDLE_INSTRUCTION_START(RETURN) { 288 JValue result; 289 result.SetJ(0); 290 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data))); 291 if (UNLIKELY(self->TestAllFlags())) { 292 CheckSuspend(self); 293 } 294 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 295 if (UNLIKELY(instrumentation->HasMethodExitListeners())) { 296 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 297 shadow_frame.GetMethod(), dex_pc, 298 result); 299 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { 300 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 301 shadow_frame.GetMethod(), dex_pc); 302 } 303 return result; 304 } 305 HANDLE_INSTRUCTION_END(); 306 307 HANDLE_INSTRUCTION_START(RETURN_WIDE) { 308 JValue result; 309 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data))); 310 if (UNLIKELY(self->TestAllFlags())) { 311 CheckSuspend(self); 312 } 313 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 314 if (UNLIKELY(instrumentation->HasMethodExitListeners())) { 315 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 316 shadow_frame.GetMethod(), dex_pc, 317 result); 318 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { 319 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 320 shadow_frame.GetMethod(), dex_pc); 321 } 322 return result; 323 } 324 HANDLE_INSTRUCTION_END(); 325 326 HANDLE_INSTRUCTION_START(RETURN_OBJECT) { 327 JValue result; 328 if (UNLIKELY(self->TestAllFlags())) { 329 CheckSuspend(self); 330 } 331 const uint8_t vreg_index = inst->VRegA_11x(inst_data); 332 Object* obj_result = shadow_frame.GetVRegReference(vreg_index); 333 if (do_assignability_check && obj_result != NULL) { 334 StackHandleScope<1> hs(self); 335 MethodHelper mh(hs.NewHandle(shadow_frame.GetMethod())); 336 Class* return_type = mh.GetReturnType(); 337 obj_result = shadow_frame.GetVRegReference(vreg_index); 338 if (return_type == NULL) { 339 // Return the pending exception. 340 HANDLE_PENDING_EXCEPTION(); 341 } 342 if (!obj_result->VerifierInstanceOf(return_type)) { 343 // This should never happen. 344 std::string temp1, temp2; 345 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(), 346 "Ljava/lang/VirtualMachineError;", 347 "Returning '%s' that is not instance of return type '%s'", 348 obj_result->GetClass()->GetDescriptor(&temp1), 349 return_type->GetDescriptor(&temp2)); 350 HANDLE_PENDING_EXCEPTION(); 351 } 352 } 353 result.SetL(obj_result); 354 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 355 if (UNLIKELY(instrumentation->HasMethodExitListeners())) { 356 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 357 shadow_frame.GetMethod(), dex_pc, 358 result); 359 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { 360 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 361 shadow_frame.GetMethod(), dex_pc); 362 } 363 return result; 364 } 365 HANDLE_INSTRUCTION_END(); 366 367 HANDLE_INSTRUCTION_START(CONST_4) { 368 uint32_t dst = inst->VRegA_11n(inst_data); 369 int32_t val = inst->VRegB_11n(inst_data); 370 shadow_frame.SetVReg(dst, val); 371 if (val == 0) { 372 shadow_frame.SetVRegReference(dst, NULL); 373 } 374 ADVANCE(1); 375 } 376 HANDLE_INSTRUCTION_END(); 377 378 HANDLE_INSTRUCTION_START(CONST_16) { 379 uint32_t dst = inst->VRegA_21s(inst_data); 380 int32_t val = inst->VRegB_21s(); 381 shadow_frame.SetVReg(dst, val); 382 if (val == 0) { 383 shadow_frame.SetVRegReference(dst, NULL); 384 } 385 ADVANCE(2); 386 } 387 HANDLE_INSTRUCTION_END(); 388 389 HANDLE_INSTRUCTION_START(CONST) { 390 uint32_t dst = inst->VRegA_31i(inst_data); 391 int32_t val = inst->VRegB_31i(); 392 shadow_frame.SetVReg(dst, val); 393 if (val == 0) { 394 shadow_frame.SetVRegReference(dst, NULL); 395 } 396 ADVANCE(3); 397 } 398 HANDLE_INSTRUCTION_END(); 399 400 HANDLE_INSTRUCTION_START(CONST_HIGH16) { 401 uint32_t dst = inst->VRegA_21h(inst_data); 402 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16); 403 shadow_frame.SetVReg(dst, val); 404 if (val == 0) { 405 shadow_frame.SetVRegReference(dst, NULL); 406 } 407 ADVANCE(2); 408 } 409 HANDLE_INSTRUCTION_END(); 410 411 HANDLE_INSTRUCTION_START(CONST_WIDE_16) 412 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s()); 413 ADVANCE(2); 414 HANDLE_INSTRUCTION_END(); 415 416 HANDLE_INSTRUCTION_START(CONST_WIDE_32) 417 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i()); 418 ADVANCE(3); 419 HANDLE_INSTRUCTION_END(); 420 421 HANDLE_INSTRUCTION_START(CONST_WIDE) 422 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l()); 423 ADVANCE(5); 424 HANDLE_INSTRUCTION_END(); 425 426 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16) 427 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data), 428 static_cast<uint64_t>(inst->VRegB_21h()) << 48); 429 ADVANCE(2); 430 HANDLE_INSTRUCTION_END(); 431 432 HANDLE_INSTRUCTION_START(CONST_STRING) { 433 String* s = ResolveString(self, mh, inst->VRegB_21c()); 434 if (UNLIKELY(s == NULL)) { 435 HANDLE_PENDING_EXCEPTION(); 436 } else { 437 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s); 438 ADVANCE(2); 439 } 440 } 441 HANDLE_INSTRUCTION_END(); 442 443 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) { 444 String* s = ResolveString(self, mh, inst->VRegB_31c()); 445 if (UNLIKELY(s == NULL)) { 446 HANDLE_PENDING_EXCEPTION(); 447 } else { 448 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s); 449 ADVANCE(3); 450 } 451 } 452 HANDLE_INSTRUCTION_END(); 453 454 HANDLE_INSTRUCTION_START(CONST_CLASS) { 455 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(), 456 self, false, do_access_check); 457 if (UNLIKELY(c == NULL)) { 458 HANDLE_PENDING_EXCEPTION(); 459 } else { 460 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c); 461 ADVANCE(2); 462 } 463 } 464 HANDLE_INSTRUCTION_END(); 465 466 HANDLE_INSTRUCTION_START(MONITOR_ENTER) { 467 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); 468 if (UNLIKELY(obj == NULL)) { 469 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 470 HANDLE_PENDING_EXCEPTION(); 471 } else { 472 DoMonitorEnter(self, obj); 473 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1); 474 } 475 } 476 HANDLE_INSTRUCTION_END(); 477 478 HANDLE_INSTRUCTION_START(MONITOR_EXIT) { 479 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); 480 if (UNLIKELY(obj == NULL)) { 481 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 482 HANDLE_PENDING_EXCEPTION(); 483 } else { 484 DoMonitorExit(self, obj); 485 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1); 486 } 487 } 488 HANDLE_INSTRUCTION_END(); 489 490 HANDLE_INSTRUCTION_START(CHECK_CAST) { 491 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(), 492 self, false, do_access_check); 493 if (UNLIKELY(c == NULL)) { 494 HANDLE_PENDING_EXCEPTION(); 495 } else { 496 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data)); 497 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) { 498 ThrowClassCastException(c, obj->GetClass()); 499 HANDLE_PENDING_EXCEPTION(); 500 } else { 501 ADVANCE(2); 502 } 503 } 504 } 505 HANDLE_INSTRUCTION_END(); 506 507 HANDLE_INSTRUCTION_START(INSTANCE_OF) { 508 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(), 509 self, false, do_access_check); 510 if (UNLIKELY(c == NULL)) { 511 HANDLE_PENDING_EXCEPTION(); 512 } else { 513 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); 514 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0); 515 ADVANCE(2); 516 } 517 } 518 HANDLE_INSTRUCTION_END(); 519 520 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) { 521 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)); 522 if (UNLIKELY(array == NULL)) { 523 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 524 HANDLE_PENDING_EXCEPTION(); 525 } else { 526 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength()); 527 ADVANCE(1); 528 } 529 } 530 HANDLE_INSTRUCTION_END(); 531 532 HANDLE_INSTRUCTION_START(NEW_INSTANCE) { 533 Runtime* runtime = Runtime::Current(); 534 Object* obj = AllocObjectFromCode<do_access_check, true>( 535 inst->VRegB_21c(), shadow_frame.GetMethod(), self, 536 runtime->GetHeap()->GetCurrentAllocator()); 537 if (UNLIKELY(obj == NULL)) { 538 HANDLE_PENDING_EXCEPTION(); 539 } else { 540 obj->GetClass()->AssertInitializedOrInitializingInThread(self); 541 // Don't allow finalizable objects to be allocated during a transaction since these can't be 542 // finalized without a started runtime. 543 if (transaction_active && obj->GetClass()->IsFinalizable()) { 544 AbortTransaction(self, "Allocating finalizable object in transaction: %s", 545 PrettyTypeOf(obj).c_str()); 546 HANDLE_PENDING_EXCEPTION(); 547 } 548 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj); 549 ADVANCE(2); 550 } 551 } 552 HANDLE_INSTRUCTION_END(); 553 554 HANDLE_INSTRUCTION_START(NEW_ARRAY) { 555 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data)); 556 Object* obj = AllocArrayFromCode<do_access_check, true>( 557 inst->VRegC_22c(), shadow_frame.GetMethod(), length, self, 558 Runtime::Current()->GetHeap()->GetCurrentAllocator()); 559 if (UNLIKELY(obj == NULL)) { 560 HANDLE_PENDING_EXCEPTION(); 561 } else { 562 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj); 563 ADVANCE(2); 564 } 565 } 566 HANDLE_INSTRUCTION_END(); 567 568 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) { 569 bool success = 570 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, 571 self, &result_register); 572 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 573 } 574 HANDLE_INSTRUCTION_END(); 575 576 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) { 577 bool success = 578 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame, 579 self, &result_register); 580 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 581 } 582 HANDLE_INSTRUCTION_END(); 583 584 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) { 585 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data)); 586 if (UNLIKELY(obj == NULL)) { 587 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA"); 588 HANDLE_PENDING_EXCEPTION(); 589 } else { 590 Array* array = obj->AsArray(); 591 DCHECK(array->IsArrayInstance() && !array->IsObjectArray()); 592 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t(); 593 const Instruction::ArrayDataPayload* payload = 594 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr); 595 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) { 596 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(), 597 "Ljava/lang/ArrayIndexOutOfBoundsException;", 598 "failed FILL_ARRAY_DATA; length=%d, index=%d", 599 array->GetLength(), payload->element_count); 600 HANDLE_PENDING_EXCEPTION(); 601 } else { 602 if (transaction_active) { 603 RecordArrayElementsInTransaction(array, payload->element_count); 604 } 605 uint32_t size_in_bytes = payload->element_count * payload->element_width; 606 memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes); 607 ADVANCE(3); 608 } 609 } 610 } 611 HANDLE_INSTRUCTION_END(); 612 613 HANDLE_INSTRUCTION_START(THROW) { 614 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); 615 if (UNLIKELY(exception == NULL)) { 616 ThrowNullPointerException(NULL, "throw with null exception"); 617 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) { 618 // This should never happen. 619 std::string temp; 620 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(), 621 "Ljava/lang/VirtualMachineError;", 622 "Throwing '%s' that is not instance of Throwable", 623 exception->GetClass()->GetDescriptor(&temp)); 624 } else { 625 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable()); 626 } 627 HANDLE_PENDING_EXCEPTION(); 628 } 629 HANDLE_INSTRUCTION_END(); 630 631 HANDLE_INSTRUCTION_START(GOTO) { 632 int8_t offset = inst->VRegA_10t(inst_data); 633 if (IsBackwardBranch(offset)) { 634 if (UNLIKELY(self->TestAllFlags())) { 635 CheckSuspend(self); 636 UPDATE_HANDLER_TABLE(); 637 } 638 } 639 ADVANCE(offset); 640 } 641 HANDLE_INSTRUCTION_END(); 642 643 HANDLE_INSTRUCTION_START(GOTO_16) { 644 int16_t offset = inst->VRegA_20t(); 645 if (IsBackwardBranch(offset)) { 646 if (UNLIKELY(self->TestAllFlags())) { 647 CheckSuspend(self); 648 UPDATE_HANDLER_TABLE(); 649 } 650 } 651 ADVANCE(offset); 652 } 653 HANDLE_INSTRUCTION_END(); 654 655 HANDLE_INSTRUCTION_START(GOTO_32) { 656 int32_t offset = inst->VRegA_30t(); 657 if (IsBackwardBranch(offset)) { 658 if (UNLIKELY(self->TestAllFlags())) { 659 CheckSuspend(self); 660 UPDATE_HANDLER_TABLE(); 661 } 662 } 663 ADVANCE(offset); 664 } 665 HANDLE_INSTRUCTION_END(); 666 667 HANDLE_INSTRUCTION_START(PACKED_SWITCH) { 668 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data); 669 if (IsBackwardBranch(offset)) { 670 if (UNLIKELY(self->TestAllFlags())) { 671 CheckSuspend(self); 672 UPDATE_HANDLER_TABLE(); 673 } 674 } 675 ADVANCE(offset); 676 } 677 HANDLE_INSTRUCTION_END(); 678 679 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) { 680 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data); 681 if (IsBackwardBranch(offset)) { 682 if (UNLIKELY(self->TestAllFlags())) { 683 CheckSuspend(self); 684 UPDATE_HANDLER_TABLE(); 685 } 686 } 687 ADVANCE(offset); 688 } 689 HANDLE_INSTRUCTION_END(); 690 691 HANDLE_INSTRUCTION_START(CMPL_FLOAT) { 692 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x()); 693 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x()); 694 int32_t result; 695 if (val1 > val2) { 696 result = 1; 697 } else if (val1 == val2) { 698 result = 0; 699 } else { 700 result = -1; 701 } 702 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result); 703 ADVANCE(2); 704 } 705 HANDLE_INSTRUCTION_END(); 706 707 HANDLE_INSTRUCTION_START(CMPG_FLOAT) { 708 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x()); 709 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x()); 710 int32_t result; 711 if (val1 < val2) { 712 result = -1; 713 } else if (val1 == val2) { 714 result = 0; 715 } else { 716 result = 1; 717 } 718 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result); 719 ADVANCE(2); 720 } 721 HANDLE_INSTRUCTION_END(); 722 723 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) { 724 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x()); 725 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x()); 726 int32_t result; 727 if (val1 > val2) { 728 result = 1; 729 } else if (val1 == val2) { 730 result = 0; 731 } else { 732 result = -1; 733 } 734 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result); 735 ADVANCE(2); 736 } 737 HANDLE_INSTRUCTION_END(); 738 739 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) { 740 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x()); 741 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x()); 742 int32_t result; 743 if (val1 < val2) { 744 result = -1; 745 } else if (val1 == val2) { 746 result = 0; 747 } else { 748 result = 1; 749 } 750 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result); 751 ADVANCE(2); 752 } 753 HANDLE_INSTRUCTION_END(); 754 755 HANDLE_INSTRUCTION_START(CMP_LONG) { 756 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x()); 757 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x()); 758 int32_t result; 759 if (val1 > val2) { 760 result = 1; 761 } else if (val1 == val2) { 762 result = 0; 763 } else { 764 result = -1; 765 } 766 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result); 767 ADVANCE(2); 768 } 769 HANDLE_INSTRUCTION_END(); 770 771 HANDLE_INSTRUCTION_START(IF_EQ) { 772 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) { 773 int16_t offset = inst->VRegC_22t(); 774 if (IsBackwardBranch(offset)) { 775 if (UNLIKELY(self->TestAllFlags())) { 776 CheckSuspend(self); 777 UPDATE_HANDLER_TABLE(); 778 } 779 } 780 ADVANCE(offset); 781 } else { 782 ADVANCE(2); 783 } 784 } 785 HANDLE_INSTRUCTION_END(); 786 787 HANDLE_INSTRUCTION_START(IF_NE) { 788 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) != shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) { 789 int16_t offset = inst->VRegC_22t(); 790 if (IsBackwardBranch(offset)) { 791 if (UNLIKELY(self->TestAllFlags())) { 792 CheckSuspend(self); 793 UPDATE_HANDLER_TABLE(); 794 } 795 } 796 ADVANCE(offset); 797 } else { 798 ADVANCE(2); 799 } 800 } 801 HANDLE_INSTRUCTION_END(); 802 803 HANDLE_INSTRUCTION_START(IF_LT) { 804 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) < shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) { 805 int16_t offset = inst->VRegC_22t(); 806 if (IsBackwardBranch(offset)) { 807 if (UNLIKELY(self->TestAllFlags())) { 808 CheckSuspend(self); 809 UPDATE_HANDLER_TABLE(); 810 } 811 } 812 ADVANCE(offset); 813 } else { 814 ADVANCE(2); 815 } 816 } 817 HANDLE_INSTRUCTION_END(); 818 819 HANDLE_INSTRUCTION_START(IF_GE) { 820 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) { 821 int16_t offset = inst->VRegC_22t(); 822 if (IsBackwardBranch(offset)) { 823 if (UNLIKELY(self->TestAllFlags())) { 824 CheckSuspend(self); 825 UPDATE_HANDLER_TABLE(); 826 } 827 } 828 ADVANCE(offset); 829 } else { 830 ADVANCE(2); 831 } 832 } 833 HANDLE_INSTRUCTION_END(); 834 835 HANDLE_INSTRUCTION_START(IF_GT) { 836 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) > shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) { 837 int16_t offset = inst->VRegC_22t(); 838 if (IsBackwardBranch(offset)) { 839 if (UNLIKELY(self->TestAllFlags())) { 840 CheckSuspend(self); 841 UPDATE_HANDLER_TABLE(); 842 } 843 } 844 ADVANCE(offset); 845 } else { 846 ADVANCE(2); 847 } 848 } 849 HANDLE_INSTRUCTION_END(); 850 851 HANDLE_INSTRUCTION_START(IF_LE) { 852 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) { 853 int16_t offset = inst->VRegC_22t(); 854 if (IsBackwardBranch(offset)) { 855 if (UNLIKELY(self->TestAllFlags())) { 856 CheckSuspend(self); 857 UPDATE_HANDLER_TABLE(); 858 } 859 } 860 ADVANCE(offset); 861 } else { 862 ADVANCE(2); 863 } 864 } 865 HANDLE_INSTRUCTION_END(); 866 867 HANDLE_INSTRUCTION_START(IF_EQZ) { 868 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) { 869 int16_t offset = inst->VRegB_21t(); 870 if (IsBackwardBranch(offset)) { 871 if (UNLIKELY(self->TestAllFlags())) { 872 CheckSuspend(self); 873 UPDATE_HANDLER_TABLE(); 874 } 875 } 876 ADVANCE(offset); 877 } else { 878 ADVANCE(2); 879 } 880 } 881 HANDLE_INSTRUCTION_END(); 882 883 HANDLE_INSTRUCTION_START(IF_NEZ) { 884 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) { 885 int16_t offset = inst->VRegB_21t(); 886 if (IsBackwardBranch(offset)) { 887 if (UNLIKELY(self->TestAllFlags())) { 888 CheckSuspend(self); 889 UPDATE_HANDLER_TABLE(); 890 } 891 } 892 ADVANCE(offset); 893 } else { 894 ADVANCE(2); 895 } 896 } 897 HANDLE_INSTRUCTION_END(); 898 899 HANDLE_INSTRUCTION_START(IF_LTZ) { 900 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) { 901 int16_t offset = inst->VRegB_21t(); 902 if (IsBackwardBranch(offset)) { 903 if (UNLIKELY(self->TestAllFlags())) { 904 CheckSuspend(self); 905 UPDATE_HANDLER_TABLE(); 906 } 907 } 908 ADVANCE(offset); 909 } else { 910 ADVANCE(2); 911 } 912 } 913 HANDLE_INSTRUCTION_END(); 914 915 HANDLE_INSTRUCTION_START(IF_GEZ) { 916 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) { 917 int16_t offset = inst->VRegB_21t(); 918 if (IsBackwardBranch(offset)) { 919 if (UNLIKELY(self->TestAllFlags())) { 920 CheckSuspend(self); 921 UPDATE_HANDLER_TABLE(); 922 } 923 } 924 ADVANCE(offset); 925 } else { 926 ADVANCE(2); 927 } 928 } 929 HANDLE_INSTRUCTION_END(); 930 931 HANDLE_INSTRUCTION_START(IF_GTZ) { 932 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) { 933 int16_t offset = inst->VRegB_21t(); 934 if (IsBackwardBranch(offset)) { 935 if (UNLIKELY(self->TestAllFlags())) { 936 CheckSuspend(self); 937 UPDATE_HANDLER_TABLE(); 938 } 939 } 940 ADVANCE(offset); 941 } else { 942 ADVANCE(2); 943 } 944 } 945 HANDLE_INSTRUCTION_END(); 946 947 HANDLE_INSTRUCTION_START(IF_LEZ) { 948 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) { 949 int16_t offset = inst->VRegB_21t(); 950 if (IsBackwardBranch(offset)) { 951 if (UNLIKELY(self->TestAllFlags())) { 952 CheckSuspend(self); 953 UPDATE_HANDLER_TABLE(); 954 } 955 } 956 ADVANCE(offset); 957 } else { 958 ADVANCE(2); 959 } 960 } 961 HANDLE_INSTRUCTION_END(); 962 963 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) { 964 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 965 if (UNLIKELY(a == NULL)) { 966 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 967 HANDLE_PENDING_EXCEPTION(); 968 } else { 969 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 970 BooleanArray* array = a->AsBooleanArray(); 971 if (LIKELY(array->CheckIsValidIndex(index))) { 972 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); 973 ADVANCE(2); 974 } else { 975 HANDLE_PENDING_EXCEPTION(); 976 } 977 } 978 } 979 HANDLE_INSTRUCTION_END(); 980 981 HANDLE_INSTRUCTION_START(AGET_BYTE) { 982 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 983 if (UNLIKELY(a == NULL)) { 984 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 985 HANDLE_PENDING_EXCEPTION(); 986 } else { 987 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 988 ByteArray* array = a->AsByteArray(); 989 if (LIKELY(array->CheckIsValidIndex(index))) { 990 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); 991 ADVANCE(2); 992 } else { 993 HANDLE_PENDING_EXCEPTION(); 994 } 995 } 996 } 997 HANDLE_INSTRUCTION_END(); 998 999 HANDLE_INSTRUCTION_START(AGET_CHAR) { 1000 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1001 if (UNLIKELY(a == NULL)) { 1002 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1003 HANDLE_PENDING_EXCEPTION(); 1004 } else { 1005 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1006 CharArray* array = a->AsCharArray(); 1007 if (LIKELY(array->CheckIsValidIndex(index))) { 1008 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); 1009 ADVANCE(2); 1010 } else { 1011 HANDLE_PENDING_EXCEPTION(); 1012 } 1013 } 1014 } 1015 HANDLE_INSTRUCTION_END(); 1016 1017 HANDLE_INSTRUCTION_START(AGET_SHORT) { 1018 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1019 if (UNLIKELY(a == NULL)) { 1020 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1021 HANDLE_PENDING_EXCEPTION(); 1022 } else { 1023 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1024 ShortArray* array = a->AsShortArray(); 1025 if (LIKELY(array->CheckIsValidIndex(index))) { 1026 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); 1027 ADVANCE(2); 1028 } else { 1029 HANDLE_PENDING_EXCEPTION(); 1030 } 1031 } 1032 } 1033 HANDLE_INSTRUCTION_END(); 1034 1035 HANDLE_INSTRUCTION_START(AGET) { 1036 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1037 if (UNLIKELY(a == NULL)) { 1038 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1039 HANDLE_PENDING_EXCEPTION(); 1040 } else { 1041 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1042 IntArray* array = a->AsIntArray(); 1043 if (LIKELY(array->CheckIsValidIndex(index))) { 1044 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); 1045 ADVANCE(2); 1046 } else { 1047 HANDLE_PENDING_EXCEPTION(); 1048 } 1049 } 1050 } 1051 HANDLE_INSTRUCTION_END(); 1052 1053 HANDLE_INSTRUCTION_START(AGET_WIDE) { 1054 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1055 if (UNLIKELY(a == NULL)) { 1056 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1057 HANDLE_PENDING_EXCEPTION(); 1058 } else { 1059 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1060 LongArray* array = a->AsLongArray(); 1061 if (LIKELY(array->CheckIsValidIndex(index))) { 1062 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); 1063 ADVANCE(2); 1064 } else { 1065 HANDLE_PENDING_EXCEPTION(); 1066 } 1067 } 1068 } 1069 HANDLE_INSTRUCTION_END(); 1070 1071 HANDLE_INSTRUCTION_START(AGET_OBJECT) { 1072 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1073 if (UNLIKELY(a == NULL)) { 1074 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1075 HANDLE_PENDING_EXCEPTION(); 1076 } else { 1077 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1078 ObjectArray<Object>* array = a->AsObjectArray<Object>(); 1079 if (LIKELY(array->CheckIsValidIndex(index))) { 1080 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); 1081 ADVANCE(2); 1082 } else { 1083 HANDLE_PENDING_EXCEPTION(); 1084 } 1085 } 1086 } 1087 HANDLE_INSTRUCTION_END(); 1088 1089 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) { 1090 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1091 if (UNLIKELY(a == NULL)) { 1092 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1093 HANDLE_PENDING_EXCEPTION(); 1094 } else { 1095 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data)); 1096 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1097 BooleanArray* array = a->AsBooleanArray(); 1098 if (LIKELY(array->CheckIsValidIndex(index))) { 1099 array->SetWithoutChecks<transaction_active>(index, val); 1100 ADVANCE(2); 1101 } else { 1102 HANDLE_PENDING_EXCEPTION(); 1103 } 1104 } 1105 } 1106 HANDLE_INSTRUCTION_END(); 1107 1108 HANDLE_INSTRUCTION_START(APUT_BYTE) { 1109 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1110 if (UNLIKELY(a == NULL)) { 1111 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1112 HANDLE_PENDING_EXCEPTION(); 1113 } else { 1114 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data)); 1115 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1116 ByteArray* array = a->AsByteArray(); 1117 if (LIKELY(array->CheckIsValidIndex(index))) { 1118 array->SetWithoutChecks<transaction_active>(index, val); 1119 ADVANCE(2); 1120 } else { 1121 HANDLE_PENDING_EXCEPTION(); 1122 } 1123 } 1124 } 1125 HANDLE_INSTRUCTION_END(); 1126 1127 HANDLE_INSTRUCTION_START(APUT_CHAR) { 1128 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1129 if (UNLIKELY(a == NULL)) { 1130 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1131 HANDLE_PENDING_EXCEPTION(); 1132 } else { 1133 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data)); 1134 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1135 CharArray* array = a->AsCharArray(); 1136 if (LIKELY(array->CheckIsValidIndex(index))) { 1137 array->SetWithoutChecks<transaction_active>(index, val); 1138 ADVANCE(2); 1139 } else { 1140 HANDLE_PENDING_EXCEPTION(); 1141 } 1142 } 1143 } 1144 HANDLE_INSTRUCTION_END(); 1145 1146 HANDLE_INSTRUCTION_START(APUT_SHORT) { 1147 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1148 if (UNLIKELY(a == NULL)) { 1149 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1150 HANDLE_PENDING_EXCEPTION(); 1151 } else { 1152 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data)); 1153 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1154 ShortArray* array = a->AsShortArray(); 1155 if (LIKELY(array->CheckIsValidIndex(index))) { 1156 array->SetWithoutChecks<transaction_active>(index, val); 1157 ADVANCE(2); 1158 } else { 1159 HANDLE_PENDING_EXCEPTION(); 1160 } 1161 } 1162 } 1163 HANDLE_INSTRUCTION_END(); 1164 1165 HANDLE_INSTRUCTION_START(APUT) { 1166 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1167 if (UNLIKELY(a == NULL)) { 1168 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1169 HANDLE_PENDING_EXCEPTION(); 1170 } else { 1171 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data)); 1172 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1173 IntArray* array = a->AsIntArray(); 1174 if (LIKELY(array->CheckIsValidIndex(index))) { 1175 array->SetWithoutChecks<transaction_active>(index, val); 1176 ADVANCE(2); 1177 } else { 1178 HANDLE_PENDING_EXCEPTION(); 1179 } 1180 } 1181 } 1182 HANDLE_INSTRUCTION_END(); 1183 1184 HANDLE_INSTRUCTION_START(APUT_WIDE) { 1185 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1186 if (UNLIKELY(a == NULL)) { 1187 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1188 HANDLE_PENDING_EXCEPTION(); 1189 } else { 1190 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data)); 1191 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1192 LongArray* array = a->AsLongArray(); 1193 if (LIKELY(array->CheckIsValidIndex(index))) { 1194 array->SetWithoutChecks<transaction_active>(index, val); 1195 ADVANCE(2); 1196 } else { 1197 HANDLE_PENDING_EXCEPTION(); 1198 } 1199 } 1200 } 1201 HANDLE_INSTRUCTION_END(); 1202 1203 HANDLE_INSTRUCTION_START(APUT_OBJECT) { 1204 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1205 if (UNLIKELY(a == NULL)) { 1206 ThrowNullPointerExceptionFromInterpreter(shadow_frame); 1207 HANDLE_PENDING_EXCEPTION(); 1208 } else { 1209 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1210 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data)); 1211 ObjectArray<Object>* array = a->AsObjectArray<Object>(); 1212 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) { 1213 array->SetWithoutChecks<transaction_active>(index, val); 1214 ADVANCE(2); 1215 } else { 1216 HANDLE_PENDING_EXCEPTION(); 1217 } 1218 } 1219 } 1220 HANDLE_INSTRUCTION_END(); 1221 1222 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) { 1223 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data); 1224 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1225 } 1226 HANDLE_INSTRUCTION_END(); 1227 1228 HANDLE_INSTRUCTION_START(IGET_BYTE) { 1229 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data); 1230 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1231 } 1232 HANDLE_INSTRUCTION_END(); 1233 1234 HANDLE_INSTRUCTION_START(IGET_CHAR) { 1235 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data); 1236 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1237 } 1238 HANDLE_INSTRUCTION_END(); 1239 1240 HANDLE_INSTRUCTION_START(IGET_SHORT) { 1241 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data); 1242 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1243 } 1244 HANDLE_INSTRUCTION_END(); 1245 1246 HANDLE_INSTRUCTION_START(IGET) { 1247 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data); 1248 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1249 } 1250 HANDLE_INSTRUCTION_END(); 1251 1252 HANDLE_INSTRUCTION_START(IGET_WIDE) { 1253 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data); 1254 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1255 } 1256 HANDLE_INSTRUCTION_END(); 1257 1258 HANDLE_INSTRUCTION_START(IGET_OBJECT) { 1259 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data); 1260 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1261 } 1262 HANDLE_INSTRUCTION_END(); 1263 1264 HANDLE_INSTRUCTION_START(IGET_QUICK) { 1265 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data); 1266 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1267 } 1268 HANDLE_INSTRUCTION_END(); 1269 1270 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) { 1271 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data); 1272 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1273 } 1274 HANDLE_INSTRUCTION_END(); 1275 1276 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) { 1277 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data); 1278 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1279 } 1280 HANDLE_INSTRUCTION_END(); 1281 1282 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) { 1283 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data); 1284 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1285 } 1286 HANDLE_INSTRUCTION_END(); 1287 1288 HANDLE_INSTRUCTION_START(SGET_BYTE) { 1289 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data); 1290 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1291 } 1292 HANDLE_INSTRUCTION_END(); 1293 1294 HANDLE_INSTRUCTION_START(SGET_CHAR) { 1295 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data); 1296 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1297 } 1298 HANDLE_INSTRUCTION_END(); 1299 1300 HANDLE_INSTRUCTION_START(SGET_SHORT) { 1301 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data); 1302 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1303 } 1304 HANDLE_INSTRUCTION_END(); 1305 1306 HANDLE_INSTRUCTION_START(SGET) { 1307 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data); 1308 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1309 } 1310 HANDLE_INSTRUCTION_END(); 1311 1312 HANDLE_INSTRUCTION_START(SGET_WIDE) { 1313 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data); 1314 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1315 } 1316 HANDLE_INSTRUCTION_END(); 1317 1318 HANDLE_INSTRUCTION_START(SGET_OBJECT) { 1319 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data); 1320 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1321 } 1322 HANDLE_INSTRUCTION_END(); 1323 1324 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) { 1325 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1326 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1327 } 1328 HANDLE_INSTRUCTION_END(); 1329 1330 HANDLE_INSTRUCTION_START(IPUT_BYTE) { 1331 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1332 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1333 } 1334 HANDLE_INSTRUCTION_END(); 1335 1336 HANDLE_INSTRUCTION_START(IPUT_CHAR) { 1337 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1338 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1339 } 1340 HANDLE_INSTRUCTION_END(); 1341 1342 HANDLE_INSTRUCTION_START(IPUT_SHORT) { 1343 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1344 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1345 } 1346 HANDLE_INSTRUCTION_END(); 1347 1348 HANDLE_INSTRUCTION_START(IPUT) { 1349 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1350 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1351 } 1352 HANDLE_INSTRUCTION_END(); 1353 1354 HANDLE_INSTRUCTION_START(IPUT_WIDE) { 1355 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1356 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1357 } 1358 HANDLE_INSTRUCTION_END(); 1359 1360 HANDLE_INSTRUCTION_START(IPUT_OBJECT) { 1361 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1362 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1363 } 1364 HANDLE_INSTRUCTION_END(); 1365 1366 HANDLE_INSTRUCTION_START(IPUT_QUICK) { 1367 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(shadow_frame, inst, inst_data); 1368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1369 } 1370 HANDLE_INSTRUCTION_END(); 1371 1372 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) { 1373 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(shadow_frame, inst, inst_data); 1374 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1375 } 1376 HANDLE_INSTRUCTION_END(); 1377 1378 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) { 1379 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(shadow_frame, inst, inst_data); 1380 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1381 } 1382 HANDLE_INSTRUCTION_END(); 1383 1384 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) { 1385 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1386 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1387 } 1388 HANDLE_INSTRUCTION_END(); 1389 1390 HANDLE_INSTRUCTION_START(SPUT_BYTE) { 1391 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1392 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1393 } 1394 HANDLE_INSTRUCTION_END(); 1395 1396 HANDLE_INSTRUCTION_START(SPUT_CHAR) { 1397 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1399 } 1400 HANDLE_INSTRUCTION_END(); 1401 1402 HANDLE_INSTRUCTION_START(SPUT_SHORT) { 1403 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1404 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1405 } 1406 HANDLE_INSTRUCTION_END(); 1407 1408 HANDLE_INSTRUCTION_START(SPUT) { 1409 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1410 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1411 } 1412 HANDLE_INSTRUCTION_END(); 1413 1414 HANDLE_INSTRUCTION_START(SPUT_WIDE) { 1415 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1416 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1417 } 1418 HANDLE_INSTRUCTION_END(); 1419 1420 HANDLE_INSTRUCTION_START(SPUT_OBJECT) { 1421 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data); 1422 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1423 } 1424 HANDLE_INSTRUCTION_END(); 1425 1426 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) { 1427 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); 1428 UPDATE_HANDLER_TABLE(); 1429 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1430 } 1431 HANDLE_INSTRUCTION_END(); 1432 1433 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) { 1434 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); 1435 UPDATE_HANDLER_TABLE(); 1436 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1437 } 1438 HANDLE_INSTRUCTION_END(); 1439 1440 HANDLE_INSTRUCTION_START(INVOKE_SUPER) { 1441 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); 1442 UPDATE_HANDLER_TABLE(); 1443 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1444 } 1445 HANDLE_INSTRUCTION_END(); 1446 1447 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) { 1448 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); 1449 UPDATE_HANDLER_TABLE(); 1450 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1451 } 1452 HANDLE_INSTRUCTION_END(); 1453 1454 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) { 1455 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); 1456 UPDATE_HANDLER_TABLE(); 1457 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1458 } 1459 HANDLE_INSTRUCTION_END(); 1460 1461 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) { 1462 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); 1463 UPDATE_HANDLER_TABLE(); 1464 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1465 } 1466 HANDLE_INSTRUCTION_END(); 1467 1468 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) { 1469 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); 1470 UPDATE_HANDLER_TABLE(); 1471 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1472 } 1473 HANDLE_INSTRUCTION_END(); 1474 1475 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) { 1476 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); 1477 UPDATE_HANDLER_TABLE(); 1478 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1479 } 1480 HANDLE_INSTRUCTION_END(); 1481 1482 HANDLE_INSTRUCTION_START(INVOKE_STATIC) { 1483 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); 1484 UPDATE_HANDLER_TABLE(); 1485 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1486 } 1487 HANDLE_INSTRUCTION_END(); 1488 1489 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) { 1490 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); 1491 UPDATE_HANDLER_TABLE(); 1492 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1493 } 1494 HANDLE_INSTRUCTION_END(); 1495 1496 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) { 1497 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register); 1498 UPDATE_HANDLER_TABLE(); 1499 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1500 } 1501 HANDLE_INSTRUCTION_END(); 1502 1503 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) { 1504 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register); 1505 UPDATE_HANDLER_TABLE(); 1506 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); 1507 } 1508 HANDLE_INSTRUCTION_END(); 1509 1510 HANDLE_INSTRUCTION_START(NEG_INT) 1511 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1512 ADVANCE(1); 1513 HANDLE_INSTRUCTION_END(); 1514 1515 HANDLE_INSTRUCTION_START(NOT_INT) 1516 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1517 ADVANCE(1); 1518 HANDLE_INSTRUCTION_END(); 1519 1520 HANDLE_INSTRUCTION_START(NEG_LONG) 1521 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 1522 ADVANCE(1); 1523 HANDLE_INSTRUCTION_END(); 1524 1525 HANDLE_INSTRUCTION_START(NOT_LONG) 1526 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 1527 ADVANCE(1); 1528 HANDLE_INSTRUCTION_END(); 1529 1530 HANDLE_INSTRUCTION_START(NEG_FLOAT) 1531 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))); 1532 ADVANCE(1); 1533 HANDLE_INSTRUCTION_END(); 1534 1535 HANDLE_INSTRUCTION_START(NEG_DOUBLE) 1536 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))); 1537 ADVANCE(1); 1538 HANDLE_INSTRUCTION_END(); 1539 1540 HANDLE_INSTRUCTION_START(INT_TO_LONG) 1541 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1542 ADVANCE(1); 1543 HANDLE_INSTRUCTION_END(); 1544 1545 HANDLE_INSTRUCTION_START(INT_TO_FLOAT) 1546 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1547 ADVANCE(1); 1548 HANDLE_INSTRUCTION_END(); 1549 1550 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE) 1551 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1552 ADVANCE(1); 1553 HANDLE_INSTRUCTION_END(); 1554 1555 HANDLE_INSTRUCTION_START(LONG_TO_INT) 1556 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 1557 ADVANCE(1); 1558 HANDLE_INSTRUCTION_END(); 1559 1560 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT) 1561 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 1562 ADVANCE(1); 1563 HANDLE_INSTRUCTION_END(); 1564 1565 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE) 1566 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 1567 ADVANCE(1); 1568 HANDLE_INSTRUCTION_END(); 1569 1570 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) { 1571 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)); 1572 int32_t result = art_float_to_integral<int32_t, float>(val); 1573 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result); 1574 ADVANCE(1); 1575 } 1576 HANDLE_INSTRUCTION_END(); 1577 1578 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) { 1579 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)); 1580 int64_t result = art_float_to_integral<int64_t, float>(val); 1581 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result); 1582 ADVANCE(1); 1583 } 1584 HANDLE_INSTRUCTION_END(); 1585 1586 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE) 1587 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))); 1588 ADVANCE(1); 1589 HANDLE_INSTRUCTION_END(); 1590 1591 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) { 1592 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)); 1593 int32_t result = art_float_to_integral<int32_t, double>(val); 1594 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result); 1595 ADVANCE(1); 1596 } 1597 HANDLE_INSTRUCTION_END(); 1598 1599 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) { 1600 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)); 1601 int64_t result = art_float_to_integral<int64_t, double>(val); 1602 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result); 1603 ADVANCE(1); 1604 } 1605 HANDLE_INSTRUCTION_END(); 1606 1607 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT) 1608 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))); 1609 ADVANCE(1); 1610 HANDLE_INSTRUCTION_END(); 1611 1612 HANDLE_INSTRUCTION_START(INT_TO_BYTE) 1613 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), 1614 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data)))); 1615 ADVANCE(1); 1616 HANDLE_INSTRUCTION_END(); 1617 1618 HANDLE_INSTRUCTION_START(INT_TO_CHAR) 1619 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), 1620 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data)))); 1621 ADVANCE(1); 1622 HANDLE_INSTRUCTION_END(); 1623 1624 HANDLE_INSTRUCTION_START(INT_TO_SHORT) 1625 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), 1626 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data)))); 1627 ADVANCE(1); 1628 HANDLE_INSTRUCTION_END(); 1629 1630 HANDLE_INSTRUCTION_START(ADD_INT) 1631 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), 1632 shadow_frame.GetVReg(inst->VRegB_23x()) + 1633 shadow_frame.GetVReg(inst->VRegC_23x())); 1634 ADVANCE(2); 1635 HANDLE_INSTRUCTION_END(); 1636 1637 HANDLE_INSTRUCTION_START(SUB_INT) 1638 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), 1639 shadow_frame.GetVReg(inst->VRegB_23x()) - 1640 shadow_frame.GetVReg(inst->VRegC_23x())); 1641 ADVANCE(2); 1642 HANDLE_INSTRUCTION_END(); 1643 1644 HANDLE_INSTRUCTION_START(MUL_INT) 1645 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), 1646 shadow_frame.GetVReg(inst->VRegB_23x()) * 1647 shadow_frame.GetVReg(inst->VRegC_23x())); 1648 ADVANCE(2); 1649 HANDLE_INSTRUCTION_END(); 1650 1651 HANDLE_INSTRUCTION_START(DIV_INT) { 1652 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data), 1653 shadow_frame.GetVReg(inst->VRegB_23x()), 1654 shadow_frame.GetVReg(inst->VRegC_23x())); 1655 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1656 } 1657 HANDLE_INSTRUCTION_END(); 1658 1659 HANDLE_INSTRUCTION_START(REM_INT) { 1660 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data), 1661 shadow_frame.GetVReg(inst->VRegB_23x()), 1662 shadow_frame.GetVReg(inst->VRegC_23x())); 1663 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1664 } 1665 HANDLE_INSTRUCTION_END(); 1666 1667 HANDLE_INSTRUCTION_START(SHL_INT) 1668 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), 1669 shadow_frame.GetVReg(inst->VRegB_23x()) << 1670 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f)); 1671 ADVANCE(2); 1672 HANDLE_INSTRUCTION_END(); 1673 1674 HANDLE_INSTRUCTION_START(SHR_INT) 1675 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), 1676 shadow_frame.GetVReg(inst->VRegB_23x()) >> 1677 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f)); 1678 ADVANCE(2); 1679 HANDLE_INSTRUCTION_END(); 1680 1681 HANDLE_INSTRUCTION_START(USHR_INT) 1682 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), 1683 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >> 1684 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f)); 1685 ADVANCE(2); 1686 HANDLE_INSTRUCTION_END(); 1687 1688 HANDLE_INSTRUCTION_START(AND_INT) 1689 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), 1690 shadow_frame.GetVReg(inst->VRegB_23x()) & 1691 shadow_frame.GetVReg(inst->VRegC_23x())); 1692 ADVANCE(2); 1693 HANDLE_INSTRUCTION_END(); 1694 1695 HANDLE_INSTRUCTION_START(OR_INT) 1696 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), 1697 shadow_frame.GetVReg(inst->VRegB_23x()) | 1698 shadow_frame.GetVReg(inst->VRegC_23x())); 1699 ADVANCE(2); 1700 HANDLE_INSTRUCTION_END(); 1701 1702 HANDLE_INSTRUCTION_START(XOR_INT) 1703 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), 1704 shadow_frame.GetVReg(inst->VRegB_23x()) ^ 1705 shadow_frame.GetVReg(inst->VRegC_23x())); 1706 ADVANCE(2); 1707 HANDLE_INSTRUCTION_END(); 1708 1709 HANDLE_INSTRUCTION_START(ADD_LONG) 1710 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), 1711 shadow_frame.GetVRegLong(inst->VRegB_23x()) + 1712 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1713 ADVANCE(2); 1714 HANDLE_INSTRUCTION_END(); 1715 1716 HANDLE_INSTRUCTION_START(SUB_LONG) 1717 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), 1718 shadow_frame.GetVRegLong(inst->VRegB_23x()) - 1719 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1720 ADVANCE(2); 1721 HANDLE_INSTRUCTION_END(); 1722 1723 HANDLE_INSTRUCTION_START(MUL_LONG) 1724 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), 1725 shadow_frame.GetVRegLong(inst->VRegB_23x()) * 1726 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1727 ADVANCE(2); 1728 HANDLE_INSTRUCTION_END(); 1729 1730 HANDLE_INSTRUCTION_START(DIV_LONG) { 1731 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data), 1732 shadow_frame.GetVRegLong(inst->VRegB_23x()), 1733 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1734 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1735 } 1736 HANDLE_INSTRUCTION_END(); 1737 1738 HANDLE_INSTRUCTION_START(REM_LONG) { 1739 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data), 1740 shadow_frame.GetVRegLong(inst->VRegB_23x()), 1741 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1742 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 1743 } 1744 HANDLE_INSTRUCTION_END(); 1745 1746 HANDLE_INSTRUCTION_START(AND_LONG) 1747 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), 1748 shadow_frame.GetVRegLong(inst->VRegB_23x()) & 1749 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1750 ADVANCE(2); 1751 HANDLE_INSTRUCTION_END(); 1752 1753 HANDLE_INSTRUCTION_START(OR_LONG) 1754 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), 1755 shadow_frame.GetVRegLong(inst->VRegB_23x()) | 1756 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1757 ADVANCE(2); 1758 HANDLE_INSTRUCTION_END(); 1759 1760 HANDLE_INSTRUCTION_START(XOR_LONG) 1761 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), 1762 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^ 1763 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1764 ADVANCE(2); 1765 HANDLE_INSTRUCTION_END(); 1766 1767 HANDLE_INSTRUCTION_START(SHL_LONG) 1768 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), 1769 shadow_frame.GetVRegLong(inst->VRegB_23x()) << 1770 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f)); 1771 ADVANCE(2); 1772 HANDLE_INSTRUCTION_END(); 1773 1774 HANDLE_INSTRUCTION_START(SHR_LONG) 1775 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), 1776 shadow_frame.GetVRegLong(inst->VRegB_23x()) >> 1777 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f)); 1778 ADVANCE(2); 1779 HANDLE_INSTRUCTION_END(); 1780 1781 HANDLE_INSTRUCTION_START(USHR_LONG) 1782 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), 1783 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >> 1784 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f)); 1785 ADVANCE(2); 1786 HANDLE_INSTRUCTION_END(); 1787 1788 HANDLE_INSTRUCTION_START(ADD_FLOAT) 1789 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data), 1790 shadow_frame.GetVRegFloat(inst->VRegB_23x()) + 1791 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 1792 ADVANCE(2); 1793 HANDLE_INSTRUCTION_END(); 1794 1795 HANDLE_INSTRUCTION_START(SUB_FLOAT) 1796 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data), 1797 shadow_frame.GetVRegFloat(inst->VRegB_23x()) - 1798 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 1799 ADVANCE(2); 1800 HANDLE_INSTRUCTION_END(); 1801 1802 HANDLE_INSTRUCTION_START(MUL_FLOAT) 1803 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data), 1804 shadow_frame.GetVRegFloat(inst->VRegB_23x()) * 1805 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 1806 ADVANCE(2); 1807 HANDLE_INSTRUCTION_END(); 1808 1809 HANDLE_INSTRUCTION_START(DIV_FLOAT) 1810 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data), 1811 shadow_frame.GetVRegFloat(inst->VRegB_23x()) / 1812 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 1813 ADVANCE(2); 1814 HANDLE_INSTRUCTION_END(); 1815 1816 HANDLE_INSTRUCTION_START(REM_FLOAT) 1817 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data), 1818 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()), 1819 shadow_frame.GetVRegFloat(inst->VRegC_23x()))); 1820 ADVANCE(2); 1821 HANDLE_INSTRUCTION_END(); 1822 1823 HANDLE_INSTRUCTION_START(ADD_DOUBLE) 1824 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data), 1825 shadow_frame.GetVRegDouble(inst->VRegB_23x()) + 1826 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 1827 ADVANCE(2); 1828 HANDLE_INSTRUCTION_END(); 1829 1830 HANDLE_INSTRUCTION_START(SUB_DOUBLE) 1831 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data), 1832 shadow_frame.GetVRegDouble(inst->VRegB_23x()) - 1833 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 1834 ADVANCE(2); 1835 HANDLE_INSTRUCTION_END(); 1836 1837 HANDLE_INSTRUCTION_START(MUL_DOUBLE) 1838 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data), 1839 shadow_frame.GetVRegDouble(inst->VRegB_23x()) * 1840 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 1841 ADVANCE(2); 1842 HANDLE_INSTRUCTION_END(); 1843 1844 HANDLE_INSTRUCTION_START(DIV_DOUBLE) 1845 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data), 1846 shadow_frame.GetVRegDouble(inst->VRegB_23x()) / 1847 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 1848 ADVANCE(2); 1849 HANDLE_INSTRUCTION_END(); 1850 1851 HANDLE_INSTRUCTION_START(REM_DOUBLE) 1852 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data), 1853 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()), 1854 shadow_frame.GetVRegDouble(inst->VRegC_23x()))); 1855 ADVANCE(2); 1856 HANDLE_INSTRUCTION_END(); 1857 1858 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) { 1859 uint32_t vregA = inst->VRegA_12x(inst_data); 1860 shadow_frame.SetVReg(vregA, 1861 shadow_frame.GetVReg(vregA) + 1862 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1863 ADVANCE(1); 1864 } 1865 HANDLE_INSTRUCTION_END(); 1866 1867 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) { 1868 uint32_t vregA = inst->VRegA_12x(inst_data); 1869 shadow_frame.SetVReg(vregA, 1870 shadow_frame.GetVReg(vregA) - 1871 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1872 ADVANCE(1); 1873 } 1874 HANDLE_INSTRUCTION_END(); 1875 1876 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) { 1877 uint32_t vregA = inst->VRegA_12x(inst_data); 1878 shadow_frame.SetVReg(vregA, 1879 shadow_frame.GetVReg(vregA) * 1880 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1881 ADVANCE(1); 1882 } 1883 HANDLE_INSTRUCTION_END(); 1884 1885 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) { 1886 uint32_t vregA = inst->VRegA_12x(inst_data); 1887 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA), 1888 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1889 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1); 1890 } 1891 HANDLE_INSTRUCTION_END(); 1892 1893 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) { 1894 uint32_t vregA = inst->VRegA_12x(inst_data); 1895 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA), 1896 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1897 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1); 1898 } 1899 HANDLE_INSTRUCTION_END(); 1900 1901 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) { 1902 uint32_t vregA = inst->VRegA_12x(inst_data); 1903 shadow_frame.SetVReg(vregA, 1904 shadow_frame.GetVReg(vregA) << 1905 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f)); 1906 ADVANCE(1); 1907 } 1908 HANDLE_INSTRUCTION_END(); 1909 1910 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) { 1911 uint32_t vregA = inst->VRegA_12x(inst_data); 1912 shadow_frame.SetVReg(vregA, 1913 shadow_frame.GetVReg(vregA) >> 1914 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f)); 1915 ADVANCE(1); 1916 } 1917 HANDLE_INSTRUCTION_END(); 1918 1919 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) { 1920 uint32_t vregA = inst->VRegA_12x(inst_data); 1921 shadow_frame.SetVReg(vregA, 1922 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >> 1923 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f)); 1924 ADVANCE(1); 1925 } 1926 HANDLE_INSTRUCTION_END(); 1927 1928 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) { 1929 uint32_t vregA = inst->VRegA_12x(inst_data); 1930 shadow_frame.SetVReg(vregA, 1931 shadow_frame.GetVReg(vregA) & 1932 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1933 ADVANCE(1); 1934 } 1935 HANDLE_INSTRUCTION_END(); 1936 1937 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) { 1938 uint32_t vregA = inst->VRegA_12x(inst_data); 1939 shadow_frame.SetVReg(vregA, 1940 shadow_frame.GetVReg(vregA) | 1941 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1942 ADVANCE(1); 1943 } 1944 HANDLE_INSTRUCTION_END(); 1945 1946 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) { 1947 uint32_t vregA = inst->VRegA_12x(inst_data); 1948 shadow_frame.SetVReg(vregA, 1949 shadow_frame.GetVReg(vregA) ^ 1950 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))); 1951 ADVANCE(1); 1952 } 1953 HANDLE_INSTRUCTION_END(); 1954 1955 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) { 1956 uint32_t vregA = inst->VRegA_12x(inst_data); 1957 shadow_frame.SetVRegLong(vregA, 1958 shadow_frame.GetVRegLong(vregA) + 1959 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 1960 ADVANCE(1); 1961 } 1962 HANDLE_INSTRUCTION_END(); 1963 1964 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) { 1965 uint32_t vregA = inst->VRegA_12x(inst_data); 1966 shadow_frame.SetVRegLong(vregA, 1967 shadow_frame.GetVRegLong(vregA) - 1968 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 1969 ADVANCE(1); 1970 } 1971 HANDLE_INSTRUCTION_END(); 1972 1973 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) { 1974 uint32_t vregA = inst->VRegA_12x(inst_data); 1975 shadow_frame.SetVRegLong(vregA, 1976 shadow_frame.GetVRegLong(vregA) * 1977 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 1978 ADVANCE(1); 1979 } 1980 HANDLE_INSTRUCTION_END(); 1981 1982 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) { 1983 uint32_t vregA = inst->VRegA_12x(inst_data); 1984 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA), 1985 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 1986 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1); 1987 } 1988 HANDLE_INSTRUCTION_END(); 1989 1990 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) { 1991 uint32_t vregA = inst->VRegA_12x(inst_data); 1992 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA), 1993 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 1994 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1); 1995 } 1996 HANDLE_INSTRUCTION_END(); 1997 1998 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) { 1999 uint32_t vregA = inst->VRegA_12x(inst_data); 2000 shadow_frame.SetVRegLong(vregA, 2001 shadow_frame.GetVRegLong(vregA) & 2002 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 2003 ADVANCE(1); 2004 } 2005 HANDLE_INSTRUCTION_END(); 2006 2007 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) { 2008 uint32_t vregA = inst->VRegA_12x(inst_data); 2009 shadow_frame.SetVRegLong(vregA, 2010 shadow_frame.GetVRegLong(vregA) | 2011 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 2012 ADVANCE(1); 2013 } 2014 HANDLE_INSTRUCTION_END(); 2015 2016 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) { 2017 uint32_t vregA = inst->VRegA_12x(inst_data); 2018 shadow_frame.SetVRegLong(vregA, 2019 shadow_frame.GetVRegLong(vregA) ^ 2020 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))); 2021 ADVANCE(1); 2022 } 2023 HANDLE_INSTRUCTION_END(); 2024 2025 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) { 2026 uint32_t vregA = inst->VRegA_12x(inst_data); 2027 shadow_frame.SetVRegLong(vregA, 2028 shadow_frame.GetVRegLong(vregA) << 2029 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f)); 2030 ADVANCE(1); 2031 } 2032 HANDLE_INSTRUCTION_END(); 2033 2034 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) { 2035 uint32_t vregA = inst->VRegA_12x(inst_data); 2036 shadow_frame.SetVRegLong(vregA, 2037 shadow_frame.GetVRegLong(vregA) >> 2038 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f)); 2039 ADVANCE(1); 2040 } 2041 HANDLE_INSTRUCTION_END(); 2042 2043 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) { 2044 uint32_t vregA = inst->VRegA_12x(inst_data); 2045 shadow_frame.SetVRegLong(vregA, 2046 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >> 2047 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f)); 2048 ADVANCE(1); 2049 } 2050 HANDLE_INSTRUCTION_END(); 2051 2052 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) { 2053 uint32_t vregA = inst->VRegA_12x(inst_data); 2054 shadow_frame.SetVRegFloat(vregA, 2055 shadow_frame.GetVRegFloat(vregA) + 2056 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))); 2057 ADVANCE(1); 2058 } 2059 HANDLE_INSTRUCTION_END(); 2060 2061 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) { 2062 uint32_t vregA = inst->VRegA_12x(inst_data); 2063 shadow_frame.SetVRegFloat(vregA, 2064 shadow_frame.GetVRegFloat(vregA) - 2065 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))); 2066 ADVANCE(1); 2067 } 2068 HANDLE_INSTRUCTION_END(); 2069 2070 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) { 2071 uint32_t vregA = inst->VRegA_12x(inst_data); 2072 shadow_frame.SetVRegFloat(vregA, 2073 shadow_frame.GetVRegFloat(vregA) * 2074 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))); 2075 ADVANCE(1); 2076 } 2077 HANDLE_INSTRUCTION_END(); 2078 2079 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) { 2080 uint32_t vregA = inst->VRegA_12x(inst_data); 2081 shadow_frame.SetVRegFloat(vregA, 2082 shadow_frame.GetVRegFloat(vregA) / 2083 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))); 2084 ADVANCE(1); 2085 } 2086 HANDLE_INSTRUCTION_END(); 2087 2088 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) { 2089 uint32_t vregA = inst->VRegA_12x(inst_data); 2090 shadow_frame.SetVRegFloat(vregA, 2091 fmodf(shadow_frame.GetVRegFloat(vregA), 2092 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)))); 2093 ADVANCE(1); 2094 } 2095 HANDLE_INSTRUCTION_END(); 2096 2097 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) { 2098 uint32_t vregA = inst->VRegA_12x(inst_data); 2099 shadow_frame.SetVRegDouble(vregA, 2100 shadow_frame.GetVRegDouble(vregA) + 2101 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))); 2102 ADVANCE(1); 2103 } 2104 HANDLE_INSTRUCTION_END(); 2105 2106 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) { 2107 uint32_t vregA = inst->VRegA_12x(inst_data); 2108 shadow_frame.SetVRegDouble(vregA, 2109 shadow_frame.GetVRegDouble(vregA) - 2110 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))); 2111 ADVANCE(1); 2112 } 2113 HANDLE_INSTRUCTION_END(); 2114 2115 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) { 2116 uint32_t vregA = inst->VRegA_12x(inst_data); 2117 shadow_frame.SetVRegDouble(vregA, 2118 shadow_frame.GetVRegDouble(vregA) * 2119 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))); 2120 ADVANCE(1); 2121 } 2122 HANDLE_INSTRUCTION_END(); 2123 2124 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) { 2125 uint32_t vregA = inst->VRegA_12x(inst_data); 2126 shadow_frame.SetVRegDouble(vregA, 2127 shadow_frame.GetVRegDouble(vregA) / 2128 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))); 2129 ADVANCE(1); 2130 } 2131 HANDLE_INSTRUCTION_END(); 2132 2133 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) { 2134 uint32_t vregA = inst->VRegA_12x(inst_data); 2135 shadow_frame.SetVRegDouble(vregA, 2136 fmod(shadow_frame.GetVRegDouble(vregA), 2137 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)))); 2138 ADVANCE(1); 2139 } 2140 HANDLE_INSTRUCTION_END(); 2141 2142 HANDLE_INSTRUCTION_START(ADD_INT_LIT16) 2143 shadow_frame.SetVReg(inst->VRegA_22s(inst_data), 2144 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) + 2145 inst->VRegC_22s()); 2146 ADVANCE(2); 2147 HANDLE_INSTRUCTION_END(); 2148 2149 HANDLE_INSTRUCTION_START(RSUB_INT) 2150 shadow_frame.SetVReg(inst->VRegA_22s(inst_data), 2151 inst->VRegC_22s() - 2152 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))); 2153 ADVANCE(2); 2154 HANDLE_INSTRUCTION_END(); 2155 2156 HANDLE_INSTRUCTION_START(MUL_INT_LIT16) 2157 shadow_frame.SetVReg(inst->VRegA_22s(inst_data), 2158 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) * 2159 inst->VRegC_22s()); 2160 ADVANCE(2); 2161 HANDLE_INSTRUCTION_END(); 2162 2163 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) { 2164 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data), 2165 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s()); 2166 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 2167 } 2168 HANDLE_INSTRUCTION_END(); 2169 2170 HANDLE_INSTRUCTION_START(REM_INT_LIT16) { 2171 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data), 2172 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s()); 2173 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 2174 } 2175 HANDLE_INSTRUCTION_END(); 2176 2177 HANDLE_INSTRUCTION_START(AND_INT_LIT16) 2178 shadow_frame.SetVReg(inst->VRegA_22s(inst_data), 2179 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) & 2180 inst->VRegC_22s()); 2181 ADVANCE(2); 2182 HANDLE_INSTRUCTION_END(); 2183 2184 HANDLE_INSTRUCTION_START(OR_INT_LIT16) 2185 shadow_frame.SetVReg(inst->VRegA_22s(inst_data), 2186 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) | 2187 inst->VRegC_22s()); 2188 ADVANCE(2); 2189 HANDLE_INSTRUCTION_END(); 2190 2191 HANDLE_INSTRUCTION_START(XOR_INT_LIT16) 2192 shadow_frame.SetVReg(inst->VRegA_22s(inst_data), 2193 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^ 2194 inst->VRegC_22s()); 2195 ADVANCE(2); 2196 HANDLE_INSTRUCTION_END(); 2197 2198 HANDLE_INSTRUCTION_START(ADD_INT_LIT8) 2199 shadow_frame.SetVReg(inst->VRegA_22b(inst_data), 2200 shadow_frame.GetVReg(inst->VRegB_22b()) + 2201 inst->VRegC_22b()); 2202 ADVANCE(2); 2203 HANDLE_INSTRUCTION_END(); 2204 2205 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8) 2206 shadow_frame.SetVReg(inst->VRegA_22b(inst_data), 2207 inst->VRegC_22b() - 2208 shadow_frame.GetVReg(inst->VRegB_22b())); 2209 ADVANCE(2); 2210 HANDLE_INSTRUCTION_END(); 2211 2212 HANDLE_INSTRUCTION_START(MUL_INT_LIT8) 2213 shadow_frame.SetVReg(inst->VRegA_22b(inst_data), 2214 shadow_frame.GetVReg(inst->VRegB_22b()) * 2215 inst->VRegC_22b()); 2216 ADVANCE(2); 2217 HANDLE_INSTRUCTION_END(); 2218 2219 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) { 2220 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data), 2221 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()); 2222 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 2223 } 2224 HANDLE_INSTRUCTION_END(); 2225 2226 HANDLE_INSTRUCTION_START(REM_INT_LIT8) { 2227 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data), 2228 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()); 2229 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); 2230 } 2231 HANDLE_INSTRUCTION_END(); 2232 2233 HANDLE_INSTRUCTION_START(AND_INT_LIT8) 2234 shadow_frame.SetVReg(inst->VRegA_22b(inst_data), 2235 shadow_frame.GetVReg(inst->VRegB_22b()) & 2236 inst->VRegC_22b()); 2237 ADVANCE(2); 2238 HANDLE_INSTRUCTION_END(); 2239 2240 HANDLE_INSTRUCTION_START(OR_INT_LIT8) 2241 shadow_frame.SetVReg(inst->VRegA_22b(inst_data), 2242 shadow_frame.GetVReg(inst->VRegB_22b()) | 2243 inst->VRegC_22b()); 2244 ADVANCE(2); 2245 HANDLE_INSTRUCTION_END(); 2246 2247 HANDLE_INSTRUCTION_START(XOR_INT_LIT8) 2248 shadow_frame.SetVReg(inst->VRegA_22b(inst_data), 2249 shadow_frame.GetVReg(inst->VRegB_22b()) ^ 2250 inst->VRegC_22b()); 2251 ADVANCE(2); 2252 HANDLE_INSTRUCTION_END(); 2253 2254 HANDLE_INSTRUCTION_START(SHL_INT_LIT8) 2255 shadow_frame.SetVReg(inst->VRegA_22b(inst_data), 2256 shadow_frame.GetVReg(inst->VRegB_22b()) << 2257 (inst->VRegC_22b() & 0x1f)); 2258 ADVANCE(2); 2259 HANDLE_INSTRUCTION_END(); 2260 2261 HANDLE_INSTRUCTION_START(SHR_INT_LIT8) 2262 shadow_frame.SetVReg(inst->VRegA_22b(inst_data), 2263 shadow_frame.GetVReg(inst->VRegB_22b()) >> 2264 (inst->VRegC_22b() & 0x1f)); 2265 ADVANCE(2); 2266 HANDLE_INSTRUCTION_END(); 2267 2268 HANDLE_INSTRUCTION_START(USHR_INT_LIT8) 2269 shadow_frame.SetVReg(inst->VRegA_22b(inst_data), 2270 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >> 2271 (inst->VRegC_22b() & 0x1f)); 2272 ADVANCE(2); 2273 HANDLE_INSTRUCTION_END(); 2274 2275 HANDLE_INSTRUCTION_START(UNUSED_3E) 2276 UnexpectedOpcode(inst, mh); 2277 HANDLE_INSTRUCTION_END(); 2278 2279 HANDLE_INSTRUCTION_START(UNUSED_3F) 2280 UnexpectedOpcode(inst, mh); 2281 HANDLE_INSTRUCTION_END(); 2282 2283 HANDLE_INSTRUCTION_START(UNUSED_40) 2284 UnexpectedOpcode(inst, mh); 2285 HANDLE_INSTRUCTION_END(); 2286 2287 HANDLE_INSTRUCTION_START(UNUSED_41) 2288 UnexpectedOpcode(inst, mh); 2289 HANDLE_INSTRUCTION_END(); 2290 2291 HANDLE_INSTRUCTION_START(UNUSED_42) 2292 UnexpectedOpcode(inst, mh); 2293 HANDLE_INSTRUCTION_END(); 2294 2295 HANDLE_INSTRUCTION_START(UNUSED_43) 2296 UnexpectedOpcode(inst, mh); 2297 HANDLE_INSTRUCTION_END(); 2298 2299 HANDLE_INSTRUCTION_START(UNUSED_79) 2300 UnexpectedOpcode(inst, mh); 2301 HANDLE_INSTRUCTION_END(); 2302 2303 HANDLE_INSTRUCTION_START(UNUSED_7A) 2304 UnexpectedOpcode(inst, mh); 2305 HANDLE_INSTRUCTION_END(); 2306 2307 HANDLE_INSTRUCTION_START(UNUSED_EB) 2308 UnexpectedOpcode(inst, mh); 2309 HANDLE_INSTRUCTION_END(); 2310 2311 HANDLE_INSTRUCTION_START(UNUSED_EC) 2312 UnexpectedOpcode(inst, mh); 2313 HANDLE_INSTRUCTION_END(); 2314 2315 HANDLE_INSTRUCTION_START(UNUSED_ED) 2316 UnexpectedOpcode(inst, mh); 2317 HANDLE_INSTRUCTION_END(); 2318 2319 HANDLE_INSTRUCTION_START(UNUSED_EE) 2320 UnexpectedOpcode(inst, mh); 2321 HANDLE_INSTRUCTION_END(); 2322 2323 HANDLE_INSTRUCTION_START(UNUSED_EF) 2324 UnexpectedOpcode(inst, mh); 2325 HANDLE_INSTRUCTION_END(); 2326 2327 HANDLE_INSTRUCTION_START(UNUSED_F0) 2328 UnexpectedOpcode(inst, mh); 2329 HANDLE_INSTRUCTION_END(); 2330 2331 HANDLE_INSTRUCTION_START(UNUSED_F1) 2332 UnexpectedOpcode(inst, mh); 2333 HANDLE_INSTRUCTION_END(); 2334 2335 HANDLE_INSTRUCTION_START(UNUSED_F2) 2336 UnexpectedOpcode(inst, mh); 2337 HANDLE_INSTRUCTION_END(); 2338 2339 HANDLE_INSTRUCTION_START(UNUSED_F3) 2340 UnexpectedOpcode(inst, mh); 2341 HANDLE_INSTRUCTION_END(); 2342 2343 HANDLE_INSTRUCTION_START(UNUSED_F4) 2344 UnexpectedOpcode(inst, mh); 2345 HANDLE_INSTRUCTION_END(); 2346 2347 HANDLE_INSTRUCTION_START(UNUSED_F5) 2348 UnexpectedOpcode(inst, mh); 2349 HANDLE_INSTRUCTION_END(); 2350 2351 HANDLE_INSTRUCTION_START(UNUSED_F6) 2352 UnexpectedOpcode(inst, mh); 2353 HANDLE_INSTRUCTION_END(); 2354 2355 HANDLE_INSTRUCTION_START(UNUSED_F7) 2356 UnexpectedOpcode(inst, mh); 2357 HANDLE_INSTRUCTION_END(); 2358 2359 HANDLE_INSTRUCTION_START(UNUSED_F8) 2360 UnexpectedOpcode(inst, mh); 2361 HANDLE_INSTRUCTION_END(); 2362 2363 HANDLE_INSTRUCTION_START(UNUSED_F9) 2364 UnexpectedOpcode(inst, mh); 2365 HANDLE_INSTRUCTION_END(); 2366 2367 HANDLE_INSTRUCTION_START(UNUSED_FA) 2368 UnexpectedOpcode(inst, mh); 2369 HANDLE_INSTRUCTION_END(); 2370 2371 HANDLE_INSTRUCTION_START(UNUSED_FB) 2372 UnexpectedOpcode(inst, mh); 2373 HANDLE_INSTRUCTION_END(); 2374 2375 HANDLE_INSTRUCTION_START(UNUSED_FC) 2376 UnexpectedOpcode(inst, mh); 2377 HANDLE_INSTRUCTION_END(); 2378 2379 HANDLE_INSTRUCTION_START(UNUSED_FD) 2380 UnexpectedOpcode(inst, mh); 2381 HANDLE_INSTRUCTION_END(); 2382 2383 HANDLE_INSTRUCTION_START(UNUSED_FE) 2384 UnexpectedOpcode(inst, mh); 2385 HANDLE_INSTRUCTION_END(); 2386 2387 HANDLE_INSTRUCTION_START(UNUSED_FF) 2388 UnexpectedOpcode(inst, mh); 2389 HANDLE_INSTRUCTION_END(); 2390 2391 exception_pending_label: { 2392 CHECK(self->IsExceptionPending()); 2393 if (UNLIKELY(self->TestAllFlags())) { 2394 CheckSuspend(self); 2395 UPDATE_HANDLER_TABLE(); 2396 } 2397 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 2398 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc, 2399 instrumentation); 2400 if (found_dex_pc == DexFile::kDexNoIndex) { 2401 return JValue(); /* Handled in caller. */ 2402 } else { 2403 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); 2404 ADVANCE(displacement); 2405 } 2406 } 2407 2408 // Create alternative instruction handlers dedicated to instrumentation. 2409 // Return instructions must not call Instrumentation::DexPcMovedEvent since they already call 2410 // Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location. 2411 // Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The 2412 // compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to 2413 // a constant condition that would remove the "if" statement so the test is free. 2414 #define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \ 2415 alt_op_##code: { \ 2416 if (Instruction::code != Instruction::RETURN_VOID && \ 2417 Instruction::code != Instruction::RETURN_VOID_BARRIER && \ 2418 Instruction::code != Instruction::RETURN && \ 2419 Instruction::code != Instruction::RETURN_WIDE && \ 2420 Instruction::code != Instruction::RETURN_OBJECT) { \ 2421 if (LIKELY(!notified_method_entry_event)) { \ 2422 Runtime* runtime = Runtime::Current(); \ 2423 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \ 2424 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \ 2425 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \ 2426 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \ 2427 } \ 2428 } else { \ 2429 notified_method_entry_event = false; \ 2430 } \ 2431 } \ 2432 UPDATE_HANDLER_TABLE(); \ 2433 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \ 2434 } 2435 #include "dex_instruction_list.h" 2436 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER) 2437 #undef DEX_INSTRUCTION_LIST 2438 #undef INSTRUMENTATION_INSTRUCTION_HANDLER 2439 } // NOLINT(readability/fn_size) 2440 2441 // Explicit definitions of ExecuteGotoImpl. 2442 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR 2443 JValue ExecuteGotoImpl<true, false>(Thread* self, MethodHelper& mh, 2444 const DexFile::CodeItem* code_item, 2445 ShadowFrame& shadow_frame, JValue result_register); 2446 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR 2447 JValue ExecuteGotoImpl<false, false>(Thread* self, MethodHelper& mh, 2448 const DexFile::CodeItem* code_item, 2449 ShadowFrame& shadow_frame, JValue result_register); 2450 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 2451 JValue ExecuteGotoImpl<true, true>(Thread* self, MethodHelper& mh, 2452 const DexFile::CodeItem* code_item, 2453 ShadowFrame& shadow_frame, JValue result_register); 2454 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 2455 JValue ExecuteGotoImpl<false, true>(Thread* self, MethodHelper& mh, 2456 const DexFile::CodeItem* code_item, 2457 ShadowFrame& shadow_frame, JValue result_register); 2458 2459 } // namespace interpreter 2460 } // namespace art 2461