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