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