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