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