Snap for 4885240 from eee47141ce6cfa980e623c01c3d1d838c975d846 to qt-release

Change-Id: I0b3bc816dcae035f08346114c583c3485efe3c2f
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 26c9e9f..d1c83ce 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -5493,36 +5493,13 @@
   LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(
       instruction, LocationSummary::kCallOnMainOnly);
   InvokeRuntimeCallingConvention calling_convention;
-  if (instruction->IsStringAlloc()) {
-    locations->AddTemp(LocationFrom(kArtMethodRegister));
-  } else {
-    locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(0)));
-  }
+  locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(0)));
   locations->SetOut(calling_convention.GetReturnLocation(DataType::Type::kReference));
 }
 
 void InstructionCodeGeneratorARM64::VisitNewInstance(HNewInstance* instruction) {
-  // Note: if heap poisoning is enabled, the entry point takes cares
-  // of poisoning the reference.
-  if (instruction->IsStringAlloc()) {
-    // String is allocated through StringFactory. Call NewEmptyString entry point.
-    Location temp = instruction->GetLocations()->GetTemp(0);
-    MemberOffset code_offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kArm64PointerSize);
-    __ Ldr(XRegisterFrom(temp), MemOperand(tr, QUICK_ENTRY_POINT(pNewEmptyString)));
-    __ Ldr(lr, MemOperand(XRegisterFrom(temp), code_offset.Int32Value()));
-
-    {
-      // Ensure the pc position is recorded immediately after the `blr` instruction.
-      ExactAssemblyScope eas(GetVIXLAssembler(),
-                             kInstructionSize,
-                             CodeBufferCheckScope::kExactSize);
-      __ blr(lr);
-      codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
-    }
-  } else {
-    codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
-    CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
-  }
+  codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
+  CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
   codegen_->MaybeGenerateMarkingRegisterCheck(/* code */ __LINE__);
 }
 
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index 9e1ef40..deab239 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -5479,34 +5479,14 @@
 void LocationsBuilderARMVIXL::VisitNewInstance(HNewInstance* instruction) {
   LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(
       instruction, LocationSummary::kCallOnMainOnly);
-  if (instruction->IsStringAlloc()) {
-    locations->AddTemp(LocationFrom(kMethodRegister));
-  } else {
-    InvokeRuntimeCallingConventionARMVIXL calling_convention;
-    locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(0)));
-  }
+  InvokeRuntimeCallingConventionARMVIXL calling_convention;
+  locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(0)));
   locations->SetOut(LocationFrom(r0));
 }
 
 void InstructionCodeGeneratorARMVIXL::VisitNewInstance(HNewInstance* instruction) {
-  // Note: if heap poisoning is enabled, the entry point takes cares
-  // of poisoning the reference.
-  if (instruction->IsStringAlloc()) {
-    // String is allocated through StringFactory. Call NewEmptyString entry point.
-    vixl32::Register temp = RegisterFrom(instruction->GetLocations()->GetTemp(0));
-    MemberOffset code_offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kArmPointerSize);
-    GetAssembler()->LoadFromOffset(kLoadWord, temp, tr, QUICK_ENTRY_POINT(pNewEmptyString));
-    GetAssembler()->LoadFromOffset(kLoadWord, lr, temp, code_offset.Int32Value());
-    // blx in T32 has only 16bit encoding that's why a stricter check for the scope is used.
-    ExactAssemblyScope aas(GetVIXLAssembler(),
-                           vixl32::k16BitT32InstructionSizeInBytes,
-                           CodeBufferCheckScope::kExactSize);
-    __ blx(lr);
-    codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
-  } else {
-    codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
-    CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
-  }
+  codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
+  CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
   codegen_->MaybeGenerateMarkingRegisterCheck(/* code */ 11);
 }
 
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index f0ef30e..c7295e4 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -8701,30 +8701,13 @@
   LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(
       instruction, LocationSummary::kCallOnMainOnly);
   InvokeRuntimeCallingConvention calling_convention;
-  if (instruction->IsStringAlloc()) {
-    locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
-  } else {
-    locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
-  }
+  locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
   locations->SetOut(calling_convention.GetReturnLocation(DataType::Type::kReference));
 }
 
 void InstructionCodeGeneratorMIPS::VisitNewInstance(HNewInstance* instruction) {
-  // Note: if heap poisoning is enabled, the entry point takes care
-  // of poisoning the reference.
-  if (instruction->IsStringAlloc()) {
-    // String is allocated through StringFactory. Call NewEmptyString entry point.
-    Register temp = instruction->GetLocations()->GetTemp(0).AsRegister<Register>();
-    MemberOffset code_offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kMipsPointerSize);
-    __ LoadFromOffset(kLoadWord, temp, TR, QUICK_ENTRY_POINT(pNewEmptyString));
-    __ LoadFromOffset(kLoadWord, T9, temp, code_offset.Int32Value());
-    __ Jalr(T9);
-    __ NopIfNoReordering();
-    codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
-  } else {
-    codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
-    CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
-  }
+  codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
+  CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
 }
 
 void LocationsBuilderMIPS::VisitNot(HNot* instruction) {
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index 6e72727..ffde45e 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -6632,31 +6632,13 @@
   LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(
       instruction, LocationSummary::kCallOnMainOnly);
   InvokeRuntimeCallingConvention calling_convention;
-  if (instruction->IsStringAlloc()) {
-    locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
-  } else {
-    locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
-  }
+  locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
   locations->SetOut(calling_convention.GetReturnLocation(DataType::Type::kReference));
 }
 
 void InstructionCodeGeneratorMIPS64::VisitNewInstance(HNewInstance* instruction) {
-  // Note: if heap poisoning is enabled, the entry point takes care
-  // of poisoning the reference.
-  if (instruction->IsStringAlloc()) {
-    // String is allocated through StringFactory. Call NewEmptyString entry point.
-    GpuRegister temp = instruction->GetLocations()->GetTemp(0).AsRegister<GpuRegister>();
-    MemberOffset code_offset =
-        ArtMethod::EntryPointFromQuickCompiledCodeOffset(kMips64PointerSize);
-    __ LoadFromOffset(kLoadDoubleword, temp, TR, QUICK_ENTRY_POINT(pNewEmptyString));
-    __ LoadFromOffset(kLoadDoubleword, T9, temp, code_offset.Int32Value());
-    __ Jalr(T9);
-    __ Nop();
-    codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
-  } else {
-    codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
-    CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
-  }
+  codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
+  CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
 }
 
 void LocationsBuilderMIPS64::VisitNot(HNot* instruction) {
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index d189476..1c0d283 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -4496,29 +4496,14 @@
   LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(
       instruction, LocationSummary::kCallOnMainOnly);
   locations->SetOut(Location::RegisterLocation(EAX));
-  if (instruction->IsStringAlloc()) {
-    locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
-  } else {
-    InvokeRuntimeCallingConvention calling_convention;
-    locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
-  }
+  InvokeRuntimeCallingConvention calling_convention;
+  locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
 }
 
 void InstructionCodeGeneratorX86::VisitNewInstance(HNewInstance* instruction) {
-  // Note: if heap poisoning is enabled, the entry point takes cares
-  // of poisoning the reference.
-  if (instruction->IsStringAlloc()) {
-    // String is allocated through StringFactory. Call NewEmptyString entry point.
-    Register temp = instruction->GetLocations()->GetTemp(0).AsRegister<Register>();
-    MemberOffset code_offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kX86PointerSize);
-    __ fs()->movl(temp, Address::Absolute(QUICK_ENTRY_POINT(pNewEmptyString)));
-    __ call(Address(temp, code_offset.Int32Value()));
-    codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
-  } else {
-    codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
-    CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
-    DCHECK(!codegen_->IsLeafMethod());
-  }
+  codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
+  CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
+  DCHECK(!codegen_->IsLeafMethod());
 }
 
 void LocationsBuilderX86::VisitNewArray(HNewArray* instruction) {
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index bea3da0..3073be6 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -4343,29 +4343,14 @@
   LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(
       instruction, LocationSummary::kCallOnMainOnly);
   InvokeRuntimeCallingConvention calling_convention;
-  if (instruction->IsStringAlloc()) {
-    locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
-  } else {
-    locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
-  }
+  locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
   locations->SetOut(Location::RegisterLocation(RAX));
 }
 
 void InstructionCodeGeneratorX86_64::VisitNewInstance(HNewInstance* instruction) {
-  // Note: if heap poisoning is enabled, the entry point takes cares
-  // of poisoning the reference.
-  if (instruction->IsStringAlloc()) {
-    // String is allocated through StringFactory. Call NewEmptyString entry point.
-    CpuRegister temp = instruction->GetLocations()->GetTemp(0).AsRegister<CpuRegister>();
-    MemberOffset code_offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kX86_64PointerSize);
-    __ gs()->movq(temp, Address::Absolute(QUICK_ENTRY_POINT(pNewEmptyString), /* no_rip */ true));
-    __ call(Address(temp, code_offset.SizeValue()));
-    codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
-  } else {
-    codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
-    CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
-    DCHECK(!codegen_->IsLeafMethod());
-  }
+  codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
+  CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
+  DCHECK(!codegen_->IsLeafMethod());
 }
 
 void LocationsBuilderX86_64::VisitNewArray(HNewArray* instruction) {
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 731accd..ba160e5 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -1075,6 +1075,10 @@
   if (load_class->NeedsAccessCheck() || klass->IsFinalizable() || !klass->IsInstantiable()) {
     entrypoint = kQuickAllocObjectWithChecks;
   }
+  // We will always be able to resolve the string class since it is in the BCP.
+  if (!klass.IsNull() && klass->IsStringClass()) {
+    entrypoint = kQuickAllocStringObject;
+  }
 
   // Consider classes we haven't resolved as potentially finalizable.
   bool finalizable = (klass == nullptr) || klass->IsFinalizable();
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index d243331..50ce755 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -2892,8 +2892,7 @@
 }
 
 bool HNewInstance::IsStringAlloc() const {
-  ScopedObjectAccess soa(Thread::Current());
-  return GetReferenceTypeInfo().IsStringClass();
+  return GetEntrypoint() == kQuickAllocStringObject;
 }
 
 bool HInvoke::NeedsEnvironment() const {
diff --git a/compiler/utils/assembler_thumb_test_expected.cc.inc b/compiler/utils/assembler_thumb_test_expected.cc.inc
index e76e98a..85e4326 100644
--- a/compiler/utils/assembler_thumb_test_expected.cc.inc
+++ b/compiler/utils/assembler_thumb_test_expected.cc.inc
@@ -153,7 +153,7 @@
   " 21c:	f8d9 8034 	ldr.w	r8, [r9, #52]	; 0x34\n",
   " 220:	4770      	bx	lr\n",
   " 222:	4660      	mov	r0, ip\n",
-  " 224:	f8d9 c2d0 	ldr.w	ip, [r9, #720]	; 0x2d0\n",
+  " 224:	f8d9 c2d4 	ldr.w	ip, [r9, #724]	; 0x2d4\n",
   " 228:	47e0      	blx	ip\n",
   nullptr
 };
diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc
index 7aa1ebb..f837051 100644
--- a/dex2oat/linker/oat_writer_test.cc
+++ b/dex2oat/linker/oat_writer_test.cc
@@ -476,7 +476,7 @@
   EXPECT_EQ(76U, sizeof(OatHeader));
   EXPECT_EQ(4U, sizeof(OatMethodOffsets));
   EXPECT_EQ(24U, sizeof(OatQuickMethodHeader));
-  EXPECT_EQ(165 * static_cast<size_t>(GetInstructionSetPointerSize(kRuntimeISA)),
+  EXPECT_EQ(166 * static_cast<size_t>(GetInstructionSetPointerSize(kRuntimeISA)),
             sizeof(QuickEntryPoints));
 }
 
diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc
index dea92e0..24ee089 100644
--- a/imgdiag/imgdiag.cc
+++ b/imgdiag/imgdiag.cc
@@ -176,8 +176,11 @@
 
   uintptr_t remote = reinterpret_cast<uintptr_t>(remote_ptr);
 
-  CHECK_LE(boot_map.start, remote);
-  CHECK_GT(boot_map.end, remote);
+  // In the case the remote pointer is out of range, it probably belongs to another image.
+  // Just return null for this case.
+  if (remote < boot_map.start || remote >= boot_map.end) {
+    return nullptr;
+  }
 
   off_t boot_offset = remote - boot_map.start;
 
diff --git a/openjdkjvmti/deopt_manager.cc b/openjdkjvmti/deopt_manager.cc
index 2f24d7e..b444cc7 100644
--- a/openjdkjvmti/deopt_manager.cc
+++ b/openjdkjvmti/deopt_manager.cc
@@ -40,7 +40,9 @@
 #include "dex/dex_file_annotations.h"
 #include "dex/modifiers.h"
 #include "events-inl.h"
+#include "intrinsics_list.h"
 #include "jit/jit.h"
+#include "jit/jit_code_cache.h"
 #include "jni/jni_internal.h"
 #include "mirror/class-inl.h"
 #include "mirror/object_array-inl.h"
@@ -84,11 +86,13 @@
     deoptimization_condition_("JVMTI_DeoptimizationCondition", deoptimization_status_lock_),
     performing_deoptimization_(false),
     global_deopt_count_(0),
+    global_interpreter_deopt_count_(0),
     deopter_count_(0),
     breakpoint_status_lock_("JVMTI_BreakpointStatusLock",
                             static_cast<art::LockLevel>(art::LockLevel::kAbortLock + 1)),
     inspection_callback_(this),
-    set_local_variable_called_(false) { }
+    set_local_variable_called_(false),
+    already_disabled_intrinsics_(false) { }
 
 void DeoptManager::Setup() {
   art::ScopedThreadStateChange stsc(art::Thread::Current(),
@@ -159,18 +163,18 @@
   return elem != breakpoint_status_.end() && elem->second != 0;
 }
 
-void DeoptManager::RemoveDeoptimizeAllMethods() {
+void DeoptManager::RemoveDeoptimizeAllMethods(FullDeoptRequirement req) {
   art::Thread* self = art::Thread::Current();
   art::ScopedThreadSuspension sts(self, art::kSuspended);
   deoptimization_status_lock_.ExclusiveLock(self);
-  RemoveDeoptimizeAllMethodsLocked(self);
+  RemoveDeoptimizeAllMethodsLocked(self, req);
 }
 
-void DeoptManager::AddDeoptimizeAllMethods() {
+void DeoptManager::AddDeoptimizeAllMethods(FullDeoptRequirement req) {
   art::Thread* self = art::Thread::Current();
   art::ScopedThreadSuspension sts(self, art::kSuspended);
   deoptimization_status_lock_.ExclusiveLock(self);
-  AddDeoptimizeAllMethodsLocked(self);
+  AddDeoptimizeAllMethodsLocked(self, req);
 }
 
 void DeoptManager::AddMethodBreakpoint(art::ArtMethod* method) {
@@ -207,7 +211,7 @@
     deoptimization_status_lock_.ExclusiveUnlock(self);
     return;
   } else if (is_default) {
-    AddDeoptimizeAllMethodsLocked(self);
+    AddDeoptimizeAllMethodsLocked(self, FullDeoptRequirement::kInterpreter);
   } else {
     PerformLimitedDeoptimization(self, method);
   }
@@ -244,7 +248,7 @@
     return;
   } else if (is_last_breakpoint) {
     if (UNLIKELY(is_default)) {
-      RemoveDeoptimizeAllMethodsLocked(self);
+      RemoveDeoptimizeAllMethodsLocked(self, FullDeoptRequirement::kInterpreter);
     } else {
       PerformLimitedUndeoptimization(self, method);
     }
@@ -272,13 +276,22 @@
       RELEASE(deopt->deoptimization_status_lock_)
       ACQUIRE(art::Locks::mutator_lock_)
       ACQUIRE(art::Roles::uninterruptible_)
-      : self_(self), deopt_(deopt), uninterruptible_cause_(nullptr) {
+      : self_(self),
+        deopt_(deopt),
+        uninterruptible_cause_(nullptr),
+        jit_(art::Runtime::Current()->GetJit()) {
     deopt_->WaitForDeoptimizationToFinishLocked(self_);
     DCHECK(!deopt->performing_deoptimization_)
         << "Already performing deoptimization on another thread!";
     // Use performing_deoptimization_ to keep track of the lock.
     deopt_->performing_deoptimization_ = true;
     deopt_->deoptimization_status_lock_.Unlock(self_);
+    // Stop the jit. We might need to disable all intrinsics which needs the jit disabled and this
+    // is the only place we can do that. Since this isn't expected to be entered too often it should
+    // be fine to always stop it.
+    if (jit_ != nullptr) {
+      jit_->Stop();
+    }
     art::Runtime::Current()->GetThreadList()->SuspendAll("JMVTI Deoptimizing methods",
                                                          /*long_suspend*/ false);
     uninterruptible_cause_ = self_->StartAssertNoThreadSuspension("JVMTI deoptimizing methods");
@@ -291,6 +304,10 @@
     self_->EndAssertNoThreadSuspension(uninterruptible_cause_);
     // Release the mutator lock.
     art::Runtime::Current()->GetThreadList()->ResumeAll();
+    // Let the jit start again.
+    if (jit_ != nullptr) {
+      jit_->Start();
+    }
     // Let other threads know it's fine to proceed.
     art::MutexLock lk(self_, deopt_->deoptimization_status_lock_);
     deopt_->performing_deoptimization_ = false;
@@ -301,22 +318,44 @@
   art::Thread* self_;
   DeoptManager* deopt_;
   const char* uninterruptible_cause_;
+  art::jit::Jit* jit_;
 };
 
-void DeoptManager::AddDeoptimizeAllMethodsLocked(art::Thread* self) {
+void DeoptManager::AddDeoptimizeAllMethodsLocked(art::Thread* self, FullDeoptRequirement req) {
+  DCHECK_GE(global_deopt_count_, global_interpreter_deopt_count_);
   global_deopt_count_++;
+  if (req == FullDeoptRequirement::kInterpreter) {
+    global_interpreter_deopt_count_++;
+  }
   if (global_deopt_count_ == 1) {
-    PerformGlobalDeoptimization(self);
+    PerformGlobalDeoptimization(self,
+                                /*needs_interpreter*/ global_interpreter_deopt_count_ > 0,
+                                /*disable_intrinsics*/ global_interpreter_deopt_count_ == 0);
+  } else if (req == FullDeoptRequirement::kInterpreter && global_interpreter_deopt_count_ == 1) {
+    // First kInterpreter request.
+    PerformGlobalDeoptimization(self,
+                                /*needs_interpreter*/true,
+                                /*disable_intrinsics*/false);
   } else {
     WaitForDeoptimizationToFinish(self);
   }
 }
 
-void DeoptManager::RemoveDeoptimizeAllMethodsLocked(art::Thread* self) {
+void DeoptManager::RemoveDeoptimizeAllMethodsLocked(art::Thread* self, FullDeoptRequirement req) {
   DCHECK_GT(global_deopt_count_, 0u) << "Request to remove non-existent global deoptimization!";
+  DCHECK_GE(global_deopt_count_, global_interpreter_deopt_count_);
   global_deopt_count_--;
+  if (req == FullDeoptRequirement::kInterpreter) {
+    global_interpreter_deopt_count_--;
+  }
   if (global_deopt_count_ == 0) {
-    PerformGlobalUndeoptimization(self);
+    PerformGlobalUndeoptimization(self,
+                                  /*still_needs_stubs*/ false,
+                                  /*disable_intrinsics*/ false);
+  } else if (req == FullDeoptRequirement::kInterpreter && global_interpreter_deopt_count_ == 0) {
+    PerformGlobalUndeoptimization(self,
+                                  /*still_needs_stubs*/ global_deopt_count_ > 0,
+                                  /*disable_intrinsics*/ global_deopt_count_ > 0);
   } else {
     WaitForDeoptimizationToFinish(self);
   }
@@ -332,18 +371,85 @@
   art::Runtime::Current()->GetInstrumentation()->Undeoptimize(method);
 }
 
-void DeoptManager::PerformGlobalDeoptimization(art::Thread* self) {
+void DeoptManager::PerformGlobalDeoptimization(art::Thread* self,
+                                               bool needs_interpreter,
+                                               bool disable_intrinsics) {
   ScopedDeoptimizationContext sdc(self, this);
-  art::Runtime::Current()->GetInstrumentation()->DeoptimizeEverything(
-      kDeoptManagerInstrumentationKey);
+  art::Runtime::Current()->GetInstrumentation()->EnableMethodTracing(
+      kDeoptManagerInstrumentationKey, needs_interpreter);
+  MaybeDisableIntrinsics(disable_intrinsics);
 }
 
-void DeoptManager::PerformGlobalUndeoptimization(art::Thread* self) {
+void DeoptManager::PerformGlobalUndeoptimization(art::Thread* self,
+                                                 bool still_needs_stubs,
+                                                 bool disable_intrinsics) {
   ScopedDeoptimizationContext sdc(self, this);
-  art::Runtime::Current()->GetInstrumentation()->UndeoptimizeEverything(
-      kDeoptManagerInstrumentationKey);
+  if (still_needs_stubs) {
+    art::Runtime::Current()->GetInstrumentation()->EnableMethodTracing(
+        kDeoptManagerInstrumentationKey, /*needs_interpreter*/false);
+    MaybeDisableIntrinsics(disable_intrinsics);
+  } else {
+    art::Runtime::Current()->GetInstrumentation()->DisableMethodTracing(
+        kDeoptManagerInstrumentationKey);
+    // We shouldn't care about intrinsics if we don't need tracing anymore.
+    DCHECK(!disable_intrinsics);
+  }
 }
 
+static void DisableSingleIntrinsic(const char* class_name,
+                                   const char* method_name,
+                                   const char* signature)
+    REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
+  // Since these intrinsics are all loaded during runtime startup this cannot fail and will not
+  // suspend.
+  art::Thread* self = art::Thread::Current();
+  art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
+  art::ObjPtr<art::mirror::Class> cls = class_linker->FindSystemClass(self, class_name);
+
+  if (cls == nullptr) {
+    LOG(FATAL) << "Could not find class of intrinsic "
+               << class_name << "->" << method_name << signature;
+  }
+
+  art::ArtMethod* method = cls->FindClassMethod(method_name, signature, art::kRuntimePointerSize);
+  if (method == nullptr || method->GetDeclaringClass() != cls) {
+    LOG(FATAL) << "Could not find method of intrinsic "
+               << class_name << "->" << method_name << signature;
+  }
+
+  if (LIKELY(method->IsIntrinsic())) {
+    method->SetNotIntrinsic();
+  } else {
+    LOG(WARNING) << method->PrettyMethod() << " was already marked as non-intrinsic!";
+  }
+}
+
+void DeoptManager::MaybeDisableIntrinsics(bool do_disable) {
+  if (!do_disable || already_disabled_intrinsics_) {
+    // Don't toggle intrinsics on and off. It will lead to too much purging of the jit and would
+    // require us to keep around the intrinsics status of all methods.
+    return;
+  }
+  already_disabled_intrinsics_ = true;
+  // First just mark all intrinsic methods as no longer intrinsics.
+#define DISABLE_INTRINSIC(_1, _2, _3, _4, _5, decl_class_name, meth_name, meth_desc) \
+    DisableSingleIntrinsic(decl_class_name, meth_name, meth_desc);
+  INTRINSICS_LIST(DISABLE_INTRINSIC);
+#undef DISABLE_INTRINSIC
+  // Next tell the jit to throw away all of its code (since there might be intrinsic code in them.
+  // TODO it would be nice to be more selective.
+  art::jit::Jit* jit = art::Runtime::Current()->GetJit();
+  if (jit != nullptr) {
+    jit->GetCodeCache()->ClearAllCompiledDexCode();
+  }
+  art::MutexLock mu(art::Thread::Current(), *art::Locks::thread_list_lock_);
+  // Now make all threads go to interpreter.
+  art::Runtime::Current()->GetThreadList()->ForEach(
+      [](art::Thread* thr, void* ctx) REQUIRES(art::Locks::mutator_lock_) {
+        reinterpret_cast<DeoptManager*>(ctx)->DeoptimizeThread(thr);
+      },
+      this);
+}
 
 void DeoptManager::RemoveDeoptimizationRequester() {
   art::Thread* self = art::Thread::Current();
diff --git a/openjdkjvmti/deopt_manager.h b/openjdkjvmti/deopt_manager.h
index 6e991de..1a13c0f 100644
--- a/openjdkjvmti/deopt_manager.h
+++ b/openjdkjvmti/deopt_manager.h
@@ -51,6 +51,11 @@
 
 namespace openjdkjvmti {
 
+enum class FullDeoptRequirement {
+  kStubs,
+  kInterpreter,
+};
+
 class DeoptManager;
 
 struct JvmtiMethodInspectionCallback : public art::MethodInspectionCallback {
@@ -94,11 +99,11 @@
       REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_)
       REQUIRES_SHARED(art::Locks::mutator_lock_);
 
-  void AddDeoptimizeAllMethods()
+  void AddDeoptimizeAllMethods(FullDeoptRequirement requirement)
       REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_)
       REQUIRES_SHARED(art::Locks::mutator_lock_);
 
-  void RemoveDeoptimizeAllMethods()
+  void RemoveDeoptimizeAllMethods(FullDeoptRequirement requirement)
       REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_)
       REQUIRES_SHARED(art::Locks::mutator_lock_);
 
@@ -132,19 +137,23 @@
   void WaitForDeoptimizationToFinishLocked(art::Thread* self)
       REQUIRES(deoptimization_status_lock_, !art::Locks::mutator_lock_);
 
-  void AddDeoptimizeAllMethodsLocked(art::Thread* self)
+  void AddDeoptimizeAllMethodsLocked(art::Thread* self, FullDeoptRequirement req)
       RELEASE(deoptimization_status_lock_)
       REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);
 
-  void RemoveDeoptimizeAllMethodsLocked(art::Thread* self)
+  void RemoveDeoptimizeAllMethodsLocked(art::Thread* self, FullDeoptRequirement req)
       RELEASE(deoptimization_status_lock_)
       REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);
 
-  void PerformGlobalDeoptimization(art::Thread* self)
+  void PerformGlobalDeoptimization(art::Thread* self,
+                                   bool needs_interpreter,
+                                   bool disable_intrinsics)
       RELEASE(deoptimization_status_lock_)
       REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);
 
-  void PerformGlobalUndeoptimization(art::Thread* self)
+  void PerformGlobalUndeoptimization(art::Thread* self,
+                                     bool still_needs_stubs,
+                                     bool disable_intrinsics)
       RELEASE(deoptimization_status_lock_)
       REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);
 
@@ -156,15 +165,25 @@
       RELEASE(deoptimization_status_lock_)
       REQUIRES(!art::Roles::uninterruptible_, !art::Locks::mutator_lock_);
 
+  // Disables intrinsics and purges the jit code cache if needed.
+  void MaybeDisableIntrinsics(bool do_disable)
+      REQUIRES(art::Locks::mutator_lock_,
+               !deoptimization_status_lock_,
+               art::Roles::uninterruptible_);
+
   static constexpr const char* kDeoptManagerInstrumentationKey = "JVMTI_DeoptManager";
 
   art::Mutex deoptimization_status_lock_ ACQUIRED_BEFORE(art::Locks::classlinker_classes_lock_);
   art::ConditionVariable deoptimization_condition_ GUARDED_BY(deoptimization_status_lock_);
   bool performing_deoptimization_ GUARDED_BY(deoptimization_status_lock_);
 
-  // Number of times we have gotten requests to deopt everything.
+  // Number of times we have gotten requests to deopt everything both requiring and not requiring
+  // interpreter.
   uint32_t global_deopt_count_ GUARDED_BY(deoptimization_status_lock_);
 
+  // Number of deopt-everything requests that require interpreter.
+  uint32_t global_interpreter_deopt_count_ GUARDED_BY(deoptimization_status_lock_);
+
   // Number of users of deoptimization there currently are.
   uint32_t deopter_count_ GUARDED_BY(deoptimization_status_lock_);
 
@@ -182,6 +201,10 @@
   // OSR after this.
   std::atomic<bool> set_local_variable_called_;
 
+  // If we have already disabled intrinsics. Since doing this throws out all JIT code we really will
+  // only ever do it once and never undo it.
+  bool already_disabled_intrinsics_ GUARDED_BY(art::Locks::mutator_lock_);
+
   // Helper for setting up/tearing-down for deoptimization.
   friend class ScopedDeoptimizationContext;
 };
diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc
index 5cb4299..10a4923 100644
--- a/openjdkjvmti/events.cc
+++ b/openjdkjvmti/events.cc
@@ -504,8 +504,9 @@
       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
     if (!method->IsRuntimeMethod() &&
         event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
-      DCHECK_EQ(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot)
-          << method->PrettyMethod();
+      DCHECK_EQ(
+          method->GetInterfaceMethodIfProxy(art::kRuntimePointerSize)->GetReturnTypePrimitive(),
+          art::Primitive::kPrimNot) << method->PrettyMethod();
       DCHECK(!self->IsExceptionPending());
       jvalue val;
       art::JNIEnvExt* jnienv = self->GetJniEnv();
@@ -530,8 +531,9 @@
       REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE {
     if (!method->IsRuntimeMethod() &&
         event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) {
-      DCHECK_NE(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot)
-          << method->PrettyMethod();
+      DCHECK_NE(
+          method->GetInterfaceMethodIfProxy(art::kRuntimePointerSize)->GetReturnTypePrimitive(),
+          art::Primitive::kPrimNot) << method->PrettyMethod();
       DCHECK(!self->IsExceptionPending());
       jvalue val;
       art::JNIEnvExt* jnienv = self->GetJniEnv();
@@ -886,16 +888,29 @@
     case ArtJvmtiEvent::kBreakpoint:
     case ArtJvmtiEvent::kException:
       return false;
-    // TODO We should support more of these or at least do something to make them discriminate by
-    // thread.
+    default:
+      return true;
+  }
+}
+
+static FullDeoptRequirement GetFullDeoptRequirement(ArtJvmtiEvent event) {
+  switch (event) {
+    // TODO We should support more of these as Limited or at least do something to make them
+    // discriminate by thread.
     case ArtJvmtiEvent::kMethodEntry:
-    case ArtJvmtiEvent::kExceptionCatch:
     case ArtJvmtiEvent::kMethodExit:
+      // We only need MethodEntered and MethodExited for these so we can use Stubs. We will need to
+      // disable intrinsics.
+      // TODO Offer a version of this without disabling intrinsics.
+      return FullDeoptRequirement::kStubs;
+    case ArtJvmtiEvent::kExceptionCatch:
     case ArtJvmtiEvent::kFieldModification:
     case ArtJvmtiEvent::kFieldAccess:
     case ArtJvmtiEvent::kSingleStep:
+    // NB If we ever make this runnable using stubs or some other method we will need to be careful
+    // that it doesn't require disabling intrinsics.
     case ArtJvmtiEvent::kFramePop:
-      return true;
+      return FullDeoptRequirement::kInterpreter;
     default:
       LOG(FATAL) << "Unexpected event type!";
       UNREACHABLE();
@@ -905,19 +920,18 @@
 void EventHandler::SetupTraceListener(JvmtiMethodTraceListener* listener,
                                       ArtJvmtiEvent event,
                                       bool enable) {
-  bool needs_full_deopt = EventNeedsFullDeopt(event);
   // Make sure we can deopt.
   {
     art::ScopedObjectAccess soa(art::Thread::Current());
     DeoptManager* deopt_manager = DeoptManager::Get();
     if (enable) {
       deopt_manager->AddDeoptimizationRequester();
-      if (needs_full_deopt) {
-        deopt_manager->AddDeoptimizeAllMethods();
+      if (EventNeedsFullDeopt(event)) {
+        deopt_manager->AddDeoptimizeAllMethods(GetFullDeoptRequirement(event));
       }
     } else {
-      if (needs_full_deopt) {
-        deopt_manager->RemoveDeoptimizeAllMethods();
+      if (EventNeedsFullDeopt(event)) {
+        deopt_manager->RemoveDeoptimizeAllMethods(GetFullDeoptRequirement(event));
       }
       deopt_manager->RemoveDeoptimizationRequester();
     }
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 0345c2f..8411982 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -243,7 +243,6 @@
 
     arch: {
         arm: {
-            clang_asflags: ["-no-integrated-as"],
             srcs: [
                 "interpreter/mterp/mterp.cc",
                 "interpreter/mterp/out/mterp_arm.S",
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index ccff9f6..96d7c96 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -1152,6 +1152,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB)
@@ -1164,6 +1165,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB)
@@ -2515,7 +2517,6 @@
 
 .macro BRBMI_FIELD_SLOW_PATH ldr_offset, label_suffix
     .balign 16
-.Lmark_introspection_unmarked\label_suffix:
     // Note: Generates exactly 16 bytes of code.
     BRBMI_UNMARKED_FORWARDING_ADDRESS_CHECK \label_suffix
     BRBMI_LOAD_AND_EXTRACT_RETURN_REG \ldr_offset, \label_suffix
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 80d5fce..6b0de48 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1604,6 +1604,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB)
@@ -1616,6 +1617,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB)
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index 508a201..303333c 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -1724,6 +1724,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB)
@@ -1736,6 +1737,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB)
diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S
index 258acdd..f35cb16 100644
--- a/runtime/arch/mips64/quick_entrypoints_mips64.S
+++ b/runtime/arch/mips64/quick_entrypoints_mips64.S
@@ -1648,6 +1648,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB)
@@ -1660,6 +1661,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB)
diff --git a/runtime/arch/quick_alloc_entrypoints.S b/runtime/arch/quick_alloc_entrypoints.S
index c091b0e..32888ed 100644
--- a/runtime/arch/quick_alloc_entrypoints.S
+++ b/runtime/arch/quick_alloc_entrypoints.S
@@ -22,6 +22,8 @@
 // Called by managed code to allocate an object when the caller doesn't know whether it has access
 // to the created type.
 ONE_ARG_DOWNCALL art_quick_alloc_object_with_checks\c_suffix, artAllocObjectFromCodeWithChecks\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
+// Called by managed code to allocate a string if it could not be removed by any optimizations
+ONE_ARG_DOWNCALL art_quick_alloc_string_object\c_suffix, artAllocStringObject\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
 // Called by managed code to allocate an array of a resolve class.
 TWO_ARG_DOWNCALL art_quick_alloc_array_resolved\c_suffix, artAllocArrayFromCodeResolved\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
 // Called by managed code to allocate a string from bytes
@@ -61,6 +63,8 @@
   ONE_ARG_DOWNCALL art_quick_alloc_object_initialized ## c_suffix, artAllocObjectFromCodeInitialized ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
 #define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(c_suffix, cxx_suffix) \
   ONE_ARG_DOWNCALL art_quick_alloc_object_with_checks ## c_suffix, artAllocObjectFromCodeWithChecks ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
+#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(c_suffix, cxx_suffix) \
+  ONE_ARG_DOWNCALL art_quick_alloc_string_object ## c_suffix, artAllocStringObject ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
 #define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(c_suffix, cxx_suffix) \
   FOUR_ARG_DOWNCALL art_quick_alloc_string_from_bytes ## c_suffix, artAllocStringFromBytesFromCode ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
 #define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_CHARS(c_suffix, cxx_suffix) \
@@ -83,6 +87,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB)
@@ -98,6 +103,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB)
@@ -117,6 +123,7 @@
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_dlmalloc, DlMalloc)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_dlmalloc, DlMalloc)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_dlmalloc, DlMalloc)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_dlmalloc, DlMalloc)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_dlmalloc, DlMalloc)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_dlmalloc, DlMalloc)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_dlmalloc, DlMalloc)
@@ -129,6 +136,7 @@
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_dlmalloc_instrumented, DlMallocInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_dlmalloc_instrumented, DlMallocInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_dlmalloc_instrumented, DlMallocInstrumented)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_dlmalloc_instrumented, DlMallocInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_dlmalloc_instrumented, DlMallocInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_dlmalloc_instrumented, DlMallocInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_dlmalloc_instrumented, DlMallocInstrumented)
@@ -142,6 +150,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc, RosAlloc)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_rosalloc, RosAlloc)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_rosalloc, RosAlloc)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_rosalloc, RosAlloc)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_rosalloc, RosAlloc)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_rosalloc, RosAlloc)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_rosalloc, RosAlloc)
@@ -154,6 +163,7 @@
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc_instrumented, RosAllocInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_rosalloc_instrumented, RosAllocInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_rosalloc_instrumented, RosAllocInstrumented)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_rosalloc_instrumented, RosAllocInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_rosalloc_instrumented, RosAllocInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_rosalloc_instrumented, RosAllocInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_rosalloc_instrumented, RosAllocInstrumented)
@@ -166,6 +176,7 @@
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_bump_pointer, BumpPointer)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_bump_pointer, BumpPointer)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_bump_pointer, BumpPointer)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_bump_pointer, BumpPointer)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_bump_pointer, BumpPointer)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_bump_pointer, BumpPointer)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_bump_pointer, BumpPointer)
@@ -178,6 +189,7 @@
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_bump_pointer_instrumented, BumpPointerInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_bump_pointer_instrumented, BumpPointerInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_bump_pointer_instrumented, BumpPointerInstrumented)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_bump_pointer_instrumented, BumpPointerInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_bump_pointer_instrumented, BumpPointerInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_bump_pointer_instrumented, BumpPointerInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_bump_pointer_instrumented, BumpPointerInstrumented)
@@ -190,6 +202,7 @@
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab_instrumented, TLABInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab_instrumented, TLABInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab_instrumented, TLABInstrumented)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_tlab_instrumented, TLABInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab_instrumented, TLABInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab_instrumented, TLABInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab_instrumented, TLABInstrumented)
@@ -202,6 +215,7 @@
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region, Region)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region, Region)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region, Region)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region, Region)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region, Region)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region, Region)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region, Region)
@@ -214,6 +228,7 @@
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_instrumented, RegionInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_instrumented, RegionInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_instrumented, RegionInstrumented)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_instrumented, RegionInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_instrumented, RegionInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_instrumented, RegionInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_instrumented, RegionInstrumented)
@@ -226,6 +241,7 @@
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab_instrumented, RegionTLABInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab_instrumented, RegionTLABInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab_instrumented, RegionTLABInstrumented)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_tlab_instrumented, RegionTLABInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab_instrumented, RegionTLABInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab_instrumented, RegionTLABInstrumented)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab_instrumented, RegionTLABInstrumented)
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index e1b3df8..9fe41ca 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -987,6 +987,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB)
@@ -999,6 +1000,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB)
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 9980966..c41d3e4 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -1011,6 +1011,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB)
@@ -1023,6 +1024,7 @@
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB)
 GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB)
+GENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB)
 // GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB)
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index ffbff88..e65c194 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -73,7 +73,7 @@
 
 // Offset of field Thread::tlsPtr_.mterp_current_ibase.
 #define THREAD_CURRENT_IBASE_OFFSET \
-    (THREAD_LOCAL_OBJECTS_OFFSET + __SIZEOF_SIZE_T__ + (1 + 165) * __SIZEOF_POINTER__)
+    (THREAD_LOCAL_OBJECTS_OFFSET + __SIZEOF_SIZE_T__ + (1 + 166) * __SIZEOF_POINTER__)
 ADD_TEST_EQ(THREAD_CURRENT_IBASE_OFFSET,
             art::Thread::MterpCurrentIBaseOffset<POINTER_SIZE>().Int32Value())
 // Offset of field Thread::tlsPtr_.mterp_default_ibase.
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index ee47e7c..ced0cb1 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -65,10 +65,14 @@
   kAbortLock,
   kNativeDebugInterfaceLock,
   kSignalHandlingLock,
+  // A generic lock level for mutexs that should not allow any additional mutexes to be gained after
+  // acquiring it.
+  kGenericBottomLock,
   kJdwpAdbStateLock,
   kJdwpSocketLock,
   kRegionSpaceRegionLock,
   kMarkSweepMarkStackLock,
+  kJitCodeCacheLock,
   kRosAllocGlobalLock,
   kRosAllocBracketLock,
   kRosAllocBulkFreeLock,
@@ -94,7 +98,6 @@
   kOatFileManagerLock,
   kTracingUniqueMethodsLock,
   kTracingStreamingLock,
-  kDeoptimizedMethodsLock,
   kClassLoaderClassesLock,
   kDefaultMutexLevel,
   kDexLock,
@@ -105,7 +108,6 @@
   kMonitorPoolLock,
   kClassLinkerClassesLock,  // TODO rename.
   kDexToDexCompilerLock,
-  kJitCodeCacheLock,
   kCHALock,
   kSubtypeCheckLock,
   kBreakpointLock,
@@ -736,6 +738,12 @@
   // Guard accesses to the JNI function table override.
   static Mutex* jni_function_table_lock_ ACQUIRED_AFTER(jni_weak_globals_lock_);
 
+  // When declaring any Mutex add BOTTOM_MUTEX_ACQUIRED_AFTER to use annotalysis to check the code
+  // doesn't try to acquire a higher level Mutex. NB Due to the way the annotalysis works this
+  // actually only encodes the mutex being below jni_function_table_lock_ although having
+  // kGenericBottomLock level is lower than this.
+  #define BOTTOM_MUTEX_ACQUIRED_AFTER ACQUIRED_AFTER(art::Locks::jni_function_table_lock_)
+
   // Have an exclusive aborting thread.
   static Mutex* abort_lock_ ACQUIRED_AFTER(jni_function_table_lock_);
 
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 4a5da1f..966d636 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2811,6 +2811,7 @@
 }
 
 bool ClassLinker::ShouldUseInterpreterEntrypoint(ArtMethod* method, const void* quick_code) {
+  ScopedAssertNoThreadSuspension sants(__FUNCTION__);
   if (UNLIKELY(method->IsNative() || method->IsProxyMethod())) {
     return false;
   }
@@ -2840,6 +2841,12 @@
     return true;
   }
 
+  if (quick_code == GetQuickInstrumentationEntryPoint()) {
+    const void* instr_target = instr->GetCodeForInvoke(method);
+    DCHECK_NE(instr_target, GetQuickInstrumentationEntryPoint()) << method->PrettyMethod();
+    return ShouldUseInterpreterEntrypoint(method, instr_target);
+  }
+
   if (runtime->IsJavaDebuggable()) {
     // For simplicity, we ignore precompiled code and go to the interpreter
     // assuming we don't already have jitted code.
@@ -2864,6 +2871,7 @@
 }
 
 void ClassLinker::FixupStaticTrampolines(ObjPtr<mirror::Class> klass) {
+  ScopedAssertNoThreadSuspension sants(__FUNCTION__);
   DCHECK(klass->IsInitialized()) << klass->PrettyDescriptor();
   if (klass->NumDirectMethods() == 0) {
     return;  // No direct methods => no static methods.
@@ -2923,6 +2931,7 @@
                      ArtMethod* method,
                      const OatFile::OatClass* oat_class,
                      uint32_t class_def_method_index) REQUIRES_SHARED(Locks::mutator_lock_) {
+  ScopedAssertNoThreadSuspension sants(__FUNCTION__);
   Runtime* const runtime = Runtime::Current();
   if (runtime->IsAotCompiler()) {
     // The following code only applies to a non-compiler runtime.
diff --git a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
index 5f7594c..257cd41 100644
--- a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
@@ -84,6 +84,13 @@
     REQUIRES_SHARED(Locks::mutator_lock_) { \
   return artAllocObjectFromCode<true, false, instrumented_bool, allocator_type>(klass, self); \
 } \
+extern "C" mirror::String* artAllocStringObject##suffix##suffix2( \
+    mirror::Class* klass, Thread* self) \
+    REQUIRES_SHARED(Locks::mutator_lock_) { \
+  /* The klass arg is so it matches the ABI of the other object alloc callbacks. */ \
+  DCHECK(klass->IsStringClass()) << klass->PrettyClass(); \
+  return mirror::String::AllocEmptyString<instrumented_bool>(self, allocator_type); \
+} \
 extern "C" mirror::Array* artAllocArrayFromCodeResolved##suffix##suffix2( \
     mirror::Class* klass, int32_t component_count, Thread* self) \
     REQUIRES_SHARED(Locks::mutator_lock_) { \
@@ -138,6 +145,7 @@
 extern "C" void* art_quick_alloc_object_resolved##suffix(mirror::Class* klass); \
 extern "C" void* art_quick_alloc_object_initialized##suffix(mirror::Class* klass); \
 extern "C" void* art_quick_alloc_object_with_checks##suffix(mirror::Class* klass); \
+extern "C" void* art_quick_alloc_string_object##suffix(mirror::Class* klass); \
 extern "C" void* art_quick_alloc_string_from_bytes##suffix(void*, int32_t, int32_t, int32_t); \
 extern "C" void* art_quick_alloc_string_from_chars##suffix(int32_t, int32_t, void*); \
 extern "C" void* art_quick_alloc_string_from_string##suffix(void*); \
@@ -149,6 +157,7 @@
 extern "C" void* art_quick_alloc_object_resolved##suffix##_instrumented(mirror::Class* klass); \
 extern "C" void* art_quick_alloc_object_initialized##suffix##_instrumented(mirror::Class* klass); \
 extern "C" void* art_quick_alloc_object_with_checks##suffix##_instrumented(mirror::Class* klass); \
+extern "C" void* art_quick_alloc_string_object##suffix##_instrumented(mirror::Class* klass); \
 extern "C" void* art_quick_alloc_string_from_bytes##suffix##_instrumented(void*, int32_t, int32_t, int32_t); \
 extern "C" void* art_quick_alloc_string_from_chars##suffix##_instrumented(int32_t, int32_t, void*); \
 extern "C" void* art_quick_alloc_string_from_string##suffix##_instrumented(void*); \
@@ -162,6 +171,7 @@
     qpoints->pAllocObjectResolved = art_quick_alloc_object_resolved##suffix##_instrumented; \
     qpoints->pAllocObjectInitialized = art_quick_alloc_object_initialized##suffix##_instrumented; \
     qpoints->pAllocObjectWithChecks = art_quick_alloc_object_with_checks##suffix##_instrumented; \
+    qpoints->pAllocStringObject = art_quick_alloc_string_object##suffix##_instrumented; \
     qpoints->pAllocStringFromBytes = art_quick_alloc_string_from_bytes##suffix##_instrumented; \
     qpoints->pAllocStringFromChars = art_quick_alloc_string_from_chars##suffix##_instrumented; \
     qpoints->pAllocStringFromString = art_quick_alloc_string_from_string##suffix##_instrumented; \
@@ -174,6 +184,7 @@
     qpoints->pAllocObjectResolved = art_quick_alloc_object_resolved##suffix; \
     qpoints->pAllocObjectInitialized = art_quick_alloc_object_initialized##suffix; \
     qpoints->pAllocObjectWithChecks = art_quick_alloc_object_with_checks##suffix; \
+    qpoints->pAllocStringObject = art_quick_alloc_string_object##suffix; \
     qpoints->pAllocStringFromBytes = art_quick_alloc_string_from_bytes##suffix; \
     qpoints->pAllocStringFromChars = art_quick_alloc_string_from_chars##suffix; \
     qpoints->pAllocStringFromString = art_quick_alloc_string_from_string##suffix; \
diff --git a/runtime/entrypoints/quick/quick_entrypoints_list.h b/runtime/entrypoints/quick/quick_entrypoints_list.h
index 415a158..4ce954c 100644
--- a/runtime/entrypoints/quick/quick_entrypoints_list.h
+++ b/runtime/entrypoints/quick/quick_entrypoints_list.h
@@ -28,6 +28,9 @@
   V(AllocObjectResolved, void*, mirror::Class*) \
   V(AllocObjectInitialized, void*, mirror::Class*) \
   V(AllocObjectWithChecks, void*, mirror::Class*) \
+  /* NB Class argument is purely to match the ABI of the other object alloc entrypoints. It is */ \
+  /*    not actually used for anything. */ \
+  V(AllocStringObject, void*, mirror::Class*) \
   V(AllocStringFromBytes, void*, void*, int32_t, int32_t, int32_t) \
   V(AllocStringFromChars, void*, int32_t, int32_t, void*) \
   V(AllocStringFromString, void*, void*) \
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index c894406..379292d 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -38,6 +38,7 @@
 #include "interpreter/interpreter_common.h"
 #include "interpreter/shadow_frame-inl.h"
 #include "jit/jit.h"
+#include "jit/jit_code_cache.h"
 #include "linear_alloc.h"
 #include "method_handles.h"
 #include "mirror/class-inl.h"
@@ -947,8 +948,36 @@
   jobject interface_method_jobj = soa.AddLocalReference<jobject>(interface_reflect_method);
 
   // All naked Object*s should now be in jobjects, so its safe to go into the main invoke code
-  // that performs allocations.
+  // that performs allocations or instrumentation events.
+  instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
+  if (instr->HasMethodEntryListeners()) {
+    instr->MethodEnterEvent(soa.Self(),
+                            soa.Decode<mirror::Object>(rcvr_jobj).Ptr(),
+                            proxy_method,
+                            0);
+    if (soa.Self()->IsExceptionPending()) {
+      instr->MethodUnwindEvent(self,
+                               soa.Decode<mirror::Object>(rcvr_jobj).Ptr(),
+                               proxy_method,
+                               0);
+      return 0;
+    }
+  }
   JValue result = InvokeProxyInvocationHandler(soa, shorty, rcvr_jobj, interface_method_jobj, args);
+  if (soa.Self()->IsExceptionPending()) {
+    if (instr->HasMethodUnwindListeners()) {
+      instr->MethodUnwindEvent(self,
+                               soa.Decode<mirror::Object>(rcvr_jobj).Ptr(),
+                               proxy_method,
+                               0);
+    }
+  } else if (instr->HasMethodExitListeners()) {
+    instr->MethodExitEvent(self,
+                           soa.Decode<mirror::Object>(rcvr_jobj).Ptr(),
+                           proxy_method,
+                           0,
+                           result);
+  }
   return result.GetJ();
 }
 
@@ -1107,7 +1136,20 @@
   if (instrumentation->IsDeoptimized(method)) {
     result = GetQuickToInterpreterBridge();
   } else {
-    result = instrumentation->GetQuickCodeFor(method, kRuntimePointerSize);
+    // This will get the entry point either from the oat file, the JIT or the appropriate bridge
+    // method if none of those can be found.
+    result = instrumentation->GetCodeForInvoke(method);
+    jit::Jit* jit = Runtime::Current()->GetJit();
+    DCHECK_NE(result, GetQuickInstrumentationEntryPoint()) << method->PrettyMethod();
+    DCHECK(jit == nullptr ||
+           // Native methods come through here in Interpreter entrypoints. We might not have
+           // disabled jit-gc but that is fine since we won't return jit-code for native methods.
+           method->IsNative() ||
+           !jit->GetCodeCache()->GetGarbageCollectCode());
+    DCHECK(!method->IsNative() ||
+           jit == nullptr ||
+           !jit->GetCodeCache()->ContainsPc(result))
+        << method->PrettyMethod() << " code will jump to possibly cleaned up jit code!";
   }
 
   bool interpreter_entry = (result == GetQuickToInterpreterBridge());
diff --git a/runtime/entrypoints_order_test.cc b/runtime/entrypoints_order_test.cc
index dda3dde..c3cd793 100644
--- a/runtime/entrypoints_order_test.cc
+++ b/runtime/entrypoints_order_test.cc
@@ -168,7 +168,9 @@
                          sizeof(void*));
     EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pAllocObjectInitialized, pAllocObjectWithChecks,
                          sizeof(void*));
-    EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pAllocObjectWithChecks, pAllocStringFromBytes,
+    EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pAllocObjectWithChecks, pAllocStringObject,
+                         sizeof(void*));
+    EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pAllocStringObject, pAllocStringFromBytes,
                          sizeof(void*));
     EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pAllocStringFromBytes, pAllocStringFromChars,
                          sizeof(void*));
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index e5cdef7..4196e19 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -94,6 +94,56 @@
   Instrumentation* const instrumentation_;
 };
 
+InstrumentationStackPopper::InstrumentationStackPopper(Thread* self)
+      : self_(self),
+        instrumentation_(Runtime::Current()->GetInstrumentation()),
+        frames_to_remove_(0) {}
+
+InstrumentationStackPopper::~InstrumentationStackPopper() {
+  std::deque<instrumentation::InstrumentationStackFrame>* stack = self_->GetInstrumentationStack();
+  for (size_t i = 0; i < frames_to_remove_; i++) {
+    stack->pop_front();
+  }
+}
+
+bool InstrumentationStackPopper::PopFramesTo(uint32_t desired_pops,
+                                             MutableHandle<mirror::Throwable>& exception) {
+  std::deque<instrumentation::InstrumentationStackFrame>* stack = self_->GetInstrumentationStack();
+  DCHECK_LE(frames_to_remove_, desired_pops);
+  DCHECK_GE(stack->size(), desired_pops);
+  DCHECK(!self_->IsExceptionPending());
+  if (!instrumentation_->HasMethodUnwindListeners()) {
+    frames_to_remove_ = desired_pops;
+    return true;
+  }
+  if (kVerboseInstrumentation) {
+    LOG(INFO) << "Popping frames for exception " << exception->Dump();
+  }
+  // The instrumentation events expect the exception to be set.
+  self_->SetException(exception.Get());
+  bool new_exception_thrown = false;
+  for (; frames_to_remove_ < desired_pops && !new_exception_thrown; frames_to_remove_++) {
+    InstrumentationStackFrame frame = stack->at(frames_to_remove_);
+    ArtMethod* method = frame.method_;
+    // Notify listeners of method unwind.
+    // TODO: improve the dex_pc information here.
+    uint32_t dex_pc = dex::kDexNoIndex;
+    if (kVerboseInstrumentation) {
+      LOG(INFO) << "Popping for unwind " << method->PrettyMethod();
+    }
+    if (!method->IsRuntimeMethod() && !frame.interpreter_entry_) {
+      instrumentation_->MethodUnwindEvent(self_, frame.this_object_, method, dex_pc);
+      new_exception_thrown = self_->GetException() != exception.Get();
+    }
+  }
+  exception.Assign(self_->GetException());
+  self_->ClearException();
+  if (kVerboseInstrumentation && new_exception_thrown) {
+    LOG(INFO) << "Failed to pop " << (desired_pops - frames_to_remove_)
+              << " frames due to new exception";
+  }
+  return !new_exception_thrown;
+}
 
 Instrumentation::Instrumentation()
     : instrumentation_stubs_installed_(false),
@@ -112,7 +162,7 @@
       have_branch_listeners_(false),
       have_invoke_virtual_or_interface_listeners_(false),
       have_exception_handled_listeners_(false),
-      deoptimized_methods_lock_("deoptimized methods lock", kDeoptimizedMethodsLock),
+      deoptimized_methods_lock_("deoptimized methods lock", kGenericBottomLock),
       deoptimization_enabled_(false),
       interpreter_handler_table_(kMainHandlerTable),
       quick_alloc_entry_points_instrumentation_counter_(0),
@@ -175,11 +225,7 @@
     if ((forced_interpret_only_ || IsDeoptimized(method)) && !method->IsNative()) {
       new_quick_code = GetQuickToInterpreterBridge();
     } else if (is_class_initialized || !method->IsStatic() || method->IsConstructor()) {
-      if (NeedDebugVersionFor(method)) {
-        new_quick_code = GetQuickToInterpreterBridge();
-      } else {
-        new_quick_code = class_linker->GetQuickOatCodeFor(method);
-      }
+      new_quick_code = GetCodeForInvoke(method);
     } else {
       new_quick_code = GetQuickResolutionStub();
     }
@@ -192,12 +238,15 @@
       // class, all its static methods code will be set to the instrumentation entry point.
       // For more details, see ClassLinker::FixupStaticTrampolines.
       if (is_class_initialized || !method->IsStatic() || method->IsConstructor()) {
-        if (NeedDebugVersionFor(method)) {
-          // Oat code should not be used. Don't install instrumentation stub and
-          // use interpreter for instrumentation.
-          new_quick_code = GetQuickToInterpreterBridge();
-        } else if (entry_exit_stubs_installed_) {
+        if (entry_exit_stubs_installed_) {
+          // This needs to be checked first since the instrumentation entrypoint will be able to
+          // find the actual JIT compiled code that corresponds to this method.
           new_quick_code = GetQuickInstrumentationEntryPoint();
+        } else if (NeedDebugVersionFor(method)) {
+          // It would be great to search the JIT for its implementation here but we cannot due to
+          // the locks we hold. Instead just set to the interpreter bridge and that code will search
+          // the JIT when it gets called and replace the entrypoint then.
+          new_quick_code = GetQuickToInterpreterBridge();
         } else {
           new_quick_code = class_linker->GetQuickOatCodeFor(method);
         }
@@ -801,6 +850,16 @@
                  // Proxy.<init> correctly in all cases.
                  method != jni::DecodeArtMethod(WellKnownClasses::java_lang_reflect_Proxy_init)) {
         new_quick_code = GetQuickInstrumentationEntryPoint();
+        if (!method->IsNative() && Runtime::Current()->GetJit() != nullptr) {
+          // Native methods use trampoline entrypoints during interpreter tracing.
+          DCHECK(!Runtime::Current()->GetJit()->GetCodeCache()->GetGarbageCollectCode());
+          ProfilingInfo* profiling_info = method->GetProfilingInfo(kRuntimePointerSize);
+          // Tracing will look at the saved entry point in the profiling info to know the actual
+          // entrypoint, so we store it here.
+          if (profiling_info != nullptr) {
+            profiling_info->SetSavedEntryPoint(quick_code);
+          }
+        }
       } else {
         new_quick_code = quick_code;
       }
@@ -995,6 +1054,14 @@
     level = InstrumentationLevel::kInstrumentWithInterpreter;
   } else {
     level = InstrumentationLevel::kInstrumentWithInstrumentationStubs;
+    if (Runtime::Current()->GetJit() != nullptr) {
+      // TODO b/110263880 It would be better if we didn't need to do this.
+      // Since we need to hold the method entrypoint across a suspend to ensure instrumentation
+      // hooks are called correctly we have to disable jit-gc to ensure that the entrypoint doesn't
+      // go away. Furthermore we need to leave this off permanently since one could get the same
+      // effect by causing this to be toggled on and off.
+      Runtime::Current()->GetJit()->GetCodeCache()->SetGarbageCollectCode(false);
+    }
   }
   ConfigureStubs(key, level);
 }
@@ -1003,6 +1070,49 @@
   ConfigureStubs(key, InstrumentationLevel::kInstrumentNothing);
 }
 
+const void* Instrumentation::GetCodeForInvoke(ArtMethod* method) const {
+  // This is called by instrumentation entry only and that should never be getting proxy methods.
+  DCHECK(!method->IsProxyMethod()) << method->PrettyMethod();
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  if (LIKELY(!instrumentation_stubs_installed_ && !interpreter_stubs_installed_)) {
+    // In general we just return whatever the method thinks its entrypoint is here. The only
+    // exception is if it still has the instrumentation entrypoint. That means we are racing another
+    // thread getting rid of instrumentation which is unexpected but possible. In that case we want
+    // to wait and try to get it from the oat file or jit.
+    const void* code = method->GetEntryPointFromQuickCompiledCodePtrSize(kRuntimePointerSize);
+    DCHECK(code != nullptr);
+    if (code != GetQuickInstrumentationEntryPoint()) {
+      return code;
+    } else if (method->IsNative()) {
+      return class_linker->GetQuickOatCodeFor(method);
+    }
+    // We don't know what it is. Fallthough to try to find the code from the JIT or Oat file.
+  } else if (method->IsNative()) {
+    // TODO We could have JIT compiled native entrypoints. It might be worth it to find these.
+    return class_linker->GetQuickOatCodeFor(method);
+  } else if (UNLIKELY(interpreter_stubs_installed_)) {
+    return GetQuickToInterpreterBridge();
+  }
+  // Since the method cannot be native due to ifs above we can always fall back to interpreter
+  // bridge.
+  const void* result = GetQuickToInterpreterBridge();
+  if (!NeedDebugVersionFor(method)) {
+    // If we don't need a debug version we should see what the oat file/class linker has to say.
+    result = class_linker->GetQuickOatCodeFor(method);
+  }
+  // If both those fail try the jit.
+  if (result == GetQuickToInterpreterBridge()) {
+    jit::Jit* jit = Runtime::Current()->GetJit();
+    if (jit != nullptr) {
+      const void* res = jit->GetCodeCache()->FindCompiledCodeForInstrumentation(method);
+      if (res != nullptr) {
+        result = res;
+      }
+    }
+  }
+  return result;
+}
+
 const void* Instrumentation::GetQuickCodeFor(ArtMethod* method, PointerSize pointer_size) const {
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   if (LIKELY(!instrumentation_stubs_installed_)) {
@@ -1428,36 +1538,29 @@
   }
 }
 
-uintptr_t Instrumentation::PopMethodForUnwind(Thread* self, bool is_deoptimization) const {
-  // Do the pop.
+uintptr_t Instrumentation::PopFramesForDeoptimization(Thread* self, size_t nframes) const {
   std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
-  CHECK_GT(stack->size(), 0U);
-  size_t idx = stack->size();
-  InstrumentationStackFrame instrumentation_frame = stack->front();
-
-  ArtMethod* method = instrumentation_frame.method_;
-  if (is_deoptimization) {
-    if (kVerboseInstrumentation) {
-      LOG(INFO) << "Popping for deoptimization " << ArtMethod::PrettyMethod(method);
-    }
-  } else {
-    if (kVerboseInstrumentation) {
-      LOG(INFO) << "Popping for unwind " << ArtMethod::PrettyMethod(method);
-    }
-
-    // Notify listeners of method unwind.
-    // TODO: improve the dex pc information here, requires knowledge of current PC as opposed to
-    //       return_pc.
-    uint32_t dex_pc = dex::kDexNoIndex;
-    if (!method->IsRuntimeMethod()) {
-      MethodUnwindEvent(self, instrumentation_frame.this_object_, method, dex_pc);
+  CHECK_GE(stack->size(), nframes);
+  if (nframes == 0) {
+    return 0u;
+  }
+  // Only need to send instrumentation events if it's not for deopt (do give the log messages if we
+  // have verbose-instrumentation anyway though).
+  if (kVerboseInstrumentation) {
+    for (size_t i = 0; i < nframes; i++) {
+      LOG(INFO) << "Popping for deoptimization " << stack->at(i).method_->PrettyMethod();
     }
   }
-  // TODO: bring back CheckStackDepth(self, instrumentation_frame, 2);
-  CHECK_EQ(stack->size(), idx);
-  DCHECK(instrumentation_frame.method_ == stack->front().method_);
+  // Now that we've sent all the instrumentation events we can actually modify the
+  // instrumentation-stack. We cannot do this earlier since MethodUnwindEvent can re-enter java and
+  // do other things that require the instrumentation stack to be in a consistent state with the
+  // actual stack.
+  for (size_t i = 0; i < nframes - 1; i++) {
+    stack->pop_front();
+  }
+  uintptr_t return_pc = stack->front().return_pc_;
   stack->pop_front();
-  return instrumentation_frame.return_pc_;
+  return return_pc;
 }
 
 std::string InstrumentationStackFrame::Dump() const {
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index 8e7a638..e5d8800 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -37,6 +37,7 @@
 class ArtField;
 class ArtMethod;
 template <typename T> class Handle;
+template <typename T> class MutableHandle;
 union JValue;
 class ShadowFrame;
 class Thread;
@@ -158,6 +159,25 @@
       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
 };
 
+class Instrumentation;
+// A helper to send instrumentation events while popping the stack in a safe way.
+class InstrumentationStackPopper {
+ public:
+  explicit InstrumentationStackPopper(Thread* self);
+  ~InstrumentationStackPopper() REQUIRES_SHARED(Locks::mutator_lock_);
+
+  // Increase the number of frames being popped to 'desired_pops' return true if the frames were
+  // popped without any exceptions, false otherwise. The exception that caused the pop is
+  // 'exception'.
+  bool PopFramesTo(uint32_t desired_pops, /*in-out*/MutableHandle<mirror::Throwable>& exception)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
+ private:
+  Thread* self_;
+  Instrumentation* instrumentation_;
+  uint32_t frames_to_remove_;
+};
+
 // Instrumentation is a catch-all for when extra information is required from the runtime. The
 // typical use for instrumentation is for profiling and debugging. Instrumentation may add stubs
 // to method entry and exit, it may also force execution to be switched to the interpreter and
@@ -292,6 +312,10 @@
   void UpdateMethodsCodeForJavaDebuggable(ArtMethod* method, const void* quick_code)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
 
+  // Return the code that we can execute for an invoke including from the JIT.
+  const void* GetCodeForInvoke(ArtMethod* method) const
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
   // Get the quick code for the given method. More efficient than asking the class linker as it
   // will short-cut to GetCode if instrumentation and static method resolution stubs aren't
   // installed.
@@ -494,9 +518,9 @@
                                              uint64_t* gpr_result, uint64_t* fpr_result)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
 
-  // Pops an instrumentation frame from the current thread and generate an unwind event.
-  // Returns the return pc for the instrumentation frame that's popped.
-  uintptr_t PopMethodForUnwind(Thread* self, bool is_deoptimization) const
+  // Pops nframes instrumentation frames from the current thread. Returns the return pc for the last
+  // instrumentation frame that's popped.
+  uintptr_t PopFramesForDeoptimization(Thread* self, size_t nframes) const
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Call back for configure stubs.
@@ -696,7 +720,7 @@
 
   // The set of methods being deoptimized (by the debugger) which must be executed with interpreter
   // only.
-  mutable ReaderWriterMutex deoptimized_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+  mutable ReaderWriterMutex deoptimized_methods_lock_ BOTTOM_MUTEX_ACQUIRED_AFTER;
   std::unordered_set<ArtMethod*> deoptimized_methods_ GUARDED_BY(deoptimized_methods_lock_);
   bool deoptimization_enabled_;
 
@@ -713,6 +737,7 @@
   bool alloc_entrypoints_instrumented_;
 
   friend class InstrumentationTest;  // For GetCurrentInstrumentationLevel and ConfigureStubs.
+  friend class InstrumentationStackPopper;  // For popping instrumentation frames.
 
   DISALLOW_COPY_AND_ASSIGN(Instrumentation);
 };
diff --git a/runtime/interpreter/mterp/arm/alt_stub.S b/runtime/interpreter/mterp/arm/alt_stub.S
index 9db5bf7..8799d95 100644
--- a/runtime/interpreter/mterp/arm/alt_stub.S
+++ b/runtime/interpreter/mterp/arm/alt_stub.S
@@ -5,7 +5,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (${opnum} * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_${opcode}
+    sub    lr, lr, #(.L_ALT_${opcode} - .L_${opcode})               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
diff --git a/runtime/interpreter/mterp/arm/footer.S b/runtime/interpreter/mterp/arm/footer.S
index f3a3ad2..8e9c3c2 100644
--- a/runtime/interpreter/mterp/arm/footer.S
+++ b/runtime/interpreter/mterp/arm/footer.S
@@ -148,7 +148,7 @@
 #endif
     cmp     rPROFILE, #JIT_CHECK_OSR
     beq     .L_osr_check
-    subgts  rPROFILE, #1
+    subsgt  rPROFILE, #1
     beq     .L_add_batch                @ counted down to zero - report
 .L_resume_backward_branch:
     ldr     lr, [rSELF, #THREAD_FLAGS_OFFSET]
diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S
index 53ea365..73b957f 100644
--- a/runtime/interpreter/mterp/out/mterp_arm.S
+++ b/runtime/interpreter/mterp/out/mterp_arm.S
@@ -7613,7 +7613,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (0 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_nop
+    sub    lr, lr, #(.L_ALT_op_nop - .L_op_nop)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7630,7 +7631,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (1 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move
+    sub    lr, lr, #(.L_ALT_op_move - .L_op_move)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7647,7 +7649,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (2 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_from16
+    sub    lr, lr, #(.L_ALT_op_move_from16 - .L_op_move_from16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7664,7 +7667,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (3 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_16
+    sub    lr, lr, #(.L_ALT_op_move_16 - .L_op_move_16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7681,7 +7685,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (4 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_wide
+    sub    lr, lr, #(.L_ALT_op_move_wide - .L_op_move_wide)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7698,7 +7703,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (5 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_wide_from16
+    sub    lr, lr, #(.L_ALT_op_move_wide_from16 - .L_op_move_wide_from16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7715,7 +7721,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (6 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_wide_16
+    sub    lr, lr, #(.L_ALT_op_move_wide_16 - .L_op_move_wide_16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7732,7 +7739,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (7 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_object
+    sub    lr, lr, #(.L_ALT_op_move_object - .L_op_move_object)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7749,7 +7757,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (8 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_object_from16
+    sub    lr, lr, #(.L_ALT_op_move_object_from16 - .L_op_move_object_from16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7766,7 +7775,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (9 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_object_16
+    sub    lr, lr, #(.L_ALT_op_move_object_16 - .L_op_move_object_16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7783,7 +7793,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (10 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_result
+    sub    lr, lr, #(.L_ALT_op_move_result - .L_op_move_result)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7800,7 +7811,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (11 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_result_wide
+    sub    lr, lr, #(.L_ALT_op_move_result_wide - .L_op_move_result_wide)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7817,7 +7829,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (12 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_result_object
+    sub    lr, lr, #(.L_ALT_op_move_result_object - .L_op_move_result_object)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7834,7 +7847,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (13 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_move_exception
+    sub    lr, lr, #(.L_ALT_op_move_exception - .L_op_move_exception)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7851,7 +7865,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (14 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_return_void
+    sub    lr, lr, #(.L_ALT_op_return_void - .L_op_return_void)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7868,7 +7883,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (15 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_return
+    sub    lr, lr, #(.L_ALT_op_return - .L_op_return)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7885,7 +7901,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (16 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_return_wide
+    sub    lr, lr, #(.L_ALT_op_return_wide - .L_op_return_wide)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7902,7 +7919,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (17 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_return_object
+    sub    lr, lr, #(.L_ALT_op_return_object - .L_op_return_object)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7919,7 +7937,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (18 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_4
+    sub    lr, lr, #(.L_ALT_op_const_4 - .L_op_const_4)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7936,7 +7955,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (19 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_16
+    sub    lr, lr, #(.L_ALT_op_const_16 - .L_op_const_16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7953,7 +7973,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (20 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const
+    sub    lr, lr, #(.L_ALT_op_const - .L_op_const)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7970,7 +7991,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (21 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_high16
+    sub    lr, lr, #(.L_ALT_op_const_high16 - .L_op_const_high16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -7987,7 +8009,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (22 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_wide_16
+    sub    lr, lr, #(.L_ALT_op_const_wide_16 - .L_op_const_wide_16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8004,7 +8027,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (23 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_wide_32
+    sub    lr, lr, #(.L_ALT_op_const_wide_32 - .L_op_const_wide_32)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8021,7 +8045,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (24 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_wide
+    sub    lr, lr, #(.L_ALT_op_const_wide - .L_op_const_wide)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8038,7 +8063,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (25 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_wide_high16
+    sub    lr, lr, #(.L_ALT_op_const_wide_high16 - .L_op_const_wide_high16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8055,7 +8081,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (26 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_string
+    sub    lr, lr, #(.L_ALT_op_const_string - .L_op_const_string)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8072,7 +8099,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (27 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_string_jumbo
+    sub    lr, lr, #(.L_ALT_op_const_string_jumbo - .L_op_const_string_jumbo)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8089,7 +8117,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (28 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_class
+    sub    lr, lr, #(.L_ALT_op_const_class - .L_op_const_class)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8106,7 +8135,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (29 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_monitor_enter
+    sub    lr, lr, #(.L_ALT_op_monitor_enter - .L_op_monitor_enter)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8123,7 +8153,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (30 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_monitor_exit
+    sub    lr, lr, #(.L_ALT_op_monitor_exit - .L_op_monitor_exit)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8140,7 +8171,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (31 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_check_cast
+    sub    lr, lr, #(.L_ALT_op_check_cast - .L_op_check_cast)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8157,7 +8189,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (32 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_instance_of
+    sub    lr, lr, #(.L_ALT_op_instance_of - .L_op_instance_of)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8174,7 +8207,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (33 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_array_length
+    sub    lr, lr, #(.L_ALT_op_array_length - .L_op_array_length)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8191,7 +8225,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (34 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_new_instance
+    sub    lr, lr, #(.L_ALT_op_new_instance - .L_op_new_instance)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8208,7 +8243,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (35 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_new_array
+    sub    lr, lr, #(.L_ALT_op_new_array - .L_op_new_array)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8225,7 +8261,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (36 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_filled_new_array
+    sub    lr, lr, #(.L_ALT_op_filled_new_array - .L_op_filled_new_array)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8242,7 +8279,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (37 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_filled_new_array_range
+    sub    lr, lr, #(.L_ALT_op_filled_new_array_range - .L_op_filled_new_array_range)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8259,7 +8297,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (38 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_fill_array_data
+    sub    lr, lr, #(.L_ALT_op_fill_array_data - .L_op_fill_array_data)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8276,7 +8315,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (39 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_throw
+    sub    lr, lr, #(.L_ALT_op_throw - .L_op_throw)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8293,7 +8333,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (40 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_goto
+    sub    lr, lr, #(.L_ALT_op_goto - .L_op_goto)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8310,7 +8351,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (41 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_goto_16
+    sub    lr, lr, #(.L_ALT_op_goto_16 - .L_op_goto_16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8327,7 +8369,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (42 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_goto_32
+    sub    lr, lr, #(.L_ALT_op_goto_32 - .L_op_goto_32)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8344,7 +8387,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (43 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_packed_switch
+    sub    lr, lr, #(.L_ALT_op_packed_switch - .L_op_packed_switch)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8361,7 +8405,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (44 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sparse_switch
+    sub    lr, lr, #(.L_ALT_op_sparse_switch - .L_op_sparse_switch)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8378,7 +8423,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (45 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_cmpl_float
+    sub    lr, lr, #(.L_ALT_op_cmpl_float - .L_op_cmpl_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8395,7 +8441,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (46 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_cmpg_float
+    sub    lr, lr, #(.L_ALT_op_cmpg_float - .L_op_cmpg_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8412,7 +8459,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (47 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_cmpl_double
+    sub    lr, lr, #(.L_ALT_op_cmpl_double - .L_op_cmpl_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8429,7 +8477,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (48 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_cmpg_double
+    sub    lr, lr, #(.L_ALT_op_cmpg_double - .L_op_cmpg_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8446,7 +8495,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (49 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_cmp_long
+    sub    lr, lr, #(.L_ALT_op_cmp_long - .L_op_cmp_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8463,7 +8513,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (50 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_eq
+    sub    lr, lr, #(.L_ALT_op_if_eq - .L_op_if_eq)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8480,7 +8531,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (51 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_ne
+    sub    lr, lr, #(.L_ALT_op_if_ne - .L_op_if_ne)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8497,7 +8549,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (52 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_lt
+    sub    lr, lr, #(.L_ALT_op_if_lt - .L_op_if_lt)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8514,7 +8567,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (53 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_ge
+    sub    lr, lr, #(.L_ALT_op_if_ge - .L_op_if_ge)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8531,7 +8585,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (54 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_gt
+    sub    lr, lr, #(.L_ALT_op_if_gt - .L_op_if_gt)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8548,7 +8603,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (55 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_le
+    sub    lr, lr, #(.L_ALT_op_if_le - .L_op_if_le)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8565,7 +8621,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (56 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_eqz
+    sub    lr, lr, #(.L_ALT_op_if_eqz - .L_op_if_eqz)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8582,7 +8639,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (57 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_nez
+    sub    lr, lr, #(.L_ALT_op_if_nez - .L_op_if_nez)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8599,7 +8657,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (58 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_ltz
+    sub    lr, lr, #(.L_ALT_op_if_ltz - .L_op_if_ltz)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8616,7 +8675,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (59 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_gez
+    sub    lr, lr, #(.L_ALT_op_if_gez - .L_op_if_gez)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8633,7 +8693,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (60 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_gtz
+    sub    lr, lr, #(.L_ALT_op_if_gtz - .L_op_if_gtz)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8650,7 +8711,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (61 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_if_lez
+    sub    lr, lr, #(.L_ALT_op_if_lez - .L_op_if_lez)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8667,7 +8729,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (62 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_3e
+    sub    lr, lr, #(.L_ALT_op_unused_3e - .L_op_unused_3e)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8684,7 +8747,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (63 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_3f
+    sub    lr, lr, #(.L_ALT_op_unused_3f - .L_op_unused_3f)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8701,7 +8765,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (64 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_40
+    sub    lr, lr, #(.L_ALT_op_unused_40 - .L_op_unused_40)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8718,7 +8783,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (65 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_41
+    sub    lr, lr, #(.L_ALT_op_unused_41 - .L_op_unused_41)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8735,7 +8801,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (66 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_42
+    sub    lr, lr, #(.L_ALT_op_unused_42 - .L_op_unused_42)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8752,7 +8819,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (67 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_43
+    sub    lr, lr, #(.L_ALT_op_unused_43 - .L_op_unused_43)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8769,7 +8837,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (68 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aget
+    sub    lr, lr, #(.L_ALT_op_aget - .L_op_aget)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8786,7 +8855,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (69 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aget_wide
+    sub    lr, lr, #(.L_ALT_op_aget_wide - .L_op_aget_wide)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8803,7 +8873,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (70 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aget_object
+    sub    lr, lr, #(.L_ALT_op_aget_object - .L_op_aget_object)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8820,7 +8891,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (71 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aget_boolean
+    sub    lr, lr, #(.L_ALT_op_aget_boolean - .L_op_aget_boolean)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8837,7 +8909,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (72 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aget_byte
+    sub    lr, lr, #(.L_ALT_op_aget_byte - .L_op_aget_byte)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8854,7 +8927,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (73 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aget_char
+    sub    lr, lr, #(.L_ALT_op_aget_char - .L_op_aget_char)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8871,7 +8945,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (74 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aget_short
+    sub    lr, lr, #(.L_ALT_op_aget_short - .L_op_aget_short)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8888,7 +8963,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (75 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aput
+    sub    lr, lr, #(.L_ALT_op_aput - .L_op_aput)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8905,7 +8981,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (76 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aput_wide
+    sub    lr, lr, #(.L_ALT_op_aput_wide - .L_op_aput_wide)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8922,7 +8999,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (77 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aput_object
+    sub    lr, lr, #(.L_ALT_op_aput_object - .L_op_aput_object)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8939,7 +9017,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (78 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aput_boolean
+    sub    lr, lr, #(.L_ALT_op_aput_boolean - .L_op_aput_boolean)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8956,7 +9035,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (79 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aput_byte
+    sub    lr, lr, #(.L_ALT_op_aput_byte - .L_op_aput_byte)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8973,7 +9053,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (80 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aput_char
+    sub    lr, lr, #(.L_ALT_op_aput_char - .L_op_aput_char)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -8990,7 +9071,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (81 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_aput_short
+    sub    lr, lr, #(.L_ALT_op_aput_short - .L_op_aput_short)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9007,7 +9089,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (82 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget
+    sub    lr, lr, #(.L_ALT_op_iget - .L_op_iget)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9024,7 +9107,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (83 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_wide
+    sub    lr, lr, #(.L_ALT_op_iget_wide - .L_op_iget_wide)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9041,7 +9125,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (84 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_object
+    sub    lr, lr, #(.L_ALT_op_iget_object - .L_op_iget_object)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9058,7 +9143,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (85 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_boolean
+    sub    lr, lr, #(.L_ALT_op_iget_boolean - .L_op_iget_boolean)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9075,7 +9161,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (86 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_byte
+    sub    lr, lr, #(.L_ALT_op_iget_byte - .L_op_iget_byte)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9092,7 +9179,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (87 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_char
+    sub    lr, lr, #(.L_ALT_op_iget_char - .L_op_iget_char)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9109,7 +9197,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (88 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_short
+    sub    lr, lr, #(.L_ALT_op_iget_short - .L_op_iget_short)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9126,7 +9215,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (89 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput
+    sub    lr, lr, #(.L_ALT_op_iput - .L_op_iput)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9143,7 +9233,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (90 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_wide
+    sub    lr, lr, #(.L_ALT_op_iput_wide - .L_op_iput_wide)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9160,7 +9251,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (91 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_object
+    sub    lr, lr, #(.L_ALT_op_iput_object - .L_op_iput_object)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9177,7 +9269,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (92 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_boolean
+    sub    lr, lr, #(.L_ALT_op_iput_boolean - .L_op_iput_boolean)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9194,7 +9287,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (93 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_byte
+    sub    lr, lr, #(.L_ALT_op_iput_byte - .L_op_iput_byte)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9211,7 +9305,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (94 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_char
+    sub    lr, lr, #(.L_ALT_op_iput_char - .L_op_iput_char)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9228,7 +9323,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (95 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_short
+    sub    lr, lr, #(.L_ALT_op_iput_short - .L_op_iput_short)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9245,7 +9341,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (96 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sget
+    sub    lr, lr, #(.L_ALT_op_sget - .L_op_sget)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9262,7 +9359,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (97 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sget_wide
+    sub    lr, lr, #(.L_ALT_op_sget_wide - .L_op_sget_wide)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9279,7 +9377,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (98 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sget_object
+    sub    lr, lr, #(.L_ALT_op_sget_object - .L_op_sget_object)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9296,7 +9395,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (99 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sget_boolean
+    sub    lr, lr, #(.L_ALT_op_sget_boolean - .L_op_sget_boolean)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9313,7 +9413,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (100 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sget_byte
+    sub    lr, lr, #(.L_ALT_op_sget_byte - .L_op_sget_byte)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9330,7 +9431,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (101 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sget_char
+    sub    lr, lr, #(.L_ALT_op_sget_char - .L_op_sget_char)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9347,7 +9449,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (102 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sget_short
+    sub    lr, lr, #(.L_ALT_op_sget_short - .L_op_sget_short)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9364,7 +9467,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (103 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sput
+    sub    lr, lr, #(.L_ALT_op_sput - .L_op_sput)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9381,7 +9485,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (104 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sput_wide
+    sub    lr, lr, #(.L_ALT_op_sput_wide - .L_op_sput_wide)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9398,7 +9503,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (105 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sput_object
+    sub    lr, lr, #(.L_ALT_op_sput_object - .L_op_sput_object)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9415,7 +9521,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (106 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sput_boolean
+    sub    lr, lr, #(.L_ALT_op_sput_boolean - .L_op_sput_boolean)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9432,7 +9539,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (107 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sput_byte
+    sub    lr, lr, #(.L_ALT_op_sput_byte - .L_op_sput_byte)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9449,7 +9557,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (108 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sput_char
+    sub    lr, lr, #(.L_ALT_op_sput_char - .L_op_sput_char)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9466,7 +9575,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (109 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sput_short
+    sub    lr, lr, #(.L_ALT_op_sput_short - .L_op_sput_short)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9483,7 +9593,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (110 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_virtual
+    sub    lr, lr, #(.L_ALT_op_invoke_virtual - .L_op_invoke_virtual)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9500,7 +9611,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (111 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_super
+    sub    lr, lr, #(.L_ALT_op_invoke_super - .L_op_invoke_super)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9517,7 +9629,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (112 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_direct
+    sub    lr, lr, #(.L_ALT_op_invoke_direct - .L_op_invoke_direct)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9534,7 +9647,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (113 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_static
+    sub    lr, lr, #(.L_ALT_op_invoke_static - .L_op_invoke_static)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9551,7 +9665,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (114 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_interface
+    sub    lr, lr, #(.L_ALT_op_invoke_interface - .L_op_invoke_interface)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9568,7 +9683,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (115 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_return_void_no_barrier
+    sub    lr, lr, #(.L_ALT_op_return_void_no_barrier - .L_op_return_void_no_barrier)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9585,7 +9701,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (116 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_virtual_range
+    sub    lr, lr, #(.L_ALT_op_invoke_virtual_range - .L_op_invoke_virtual_range)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9602,7 +9719,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (117 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_super_range
+    sub    lr, lr, #(.L_ALT_op_invoke_super_range - .L_op_invoke_super_range)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9619,7 +9737,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (118 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_direct_range
+    sub    lr, lr, #(.L_ALT_op_invoke_direct_range - .L_op_invoke_direct_range)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9636,7 +9755,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (119 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_static_range
+    sub    lr, lr, #(.L_ALT_op_invoke_static_range - .L_op_invoke_static_range)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9653,7 +9773,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (120 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_interface_range
+    sub    lr, lr, #(.L_ALT_op_invoke_interface_range - .L_op_invoke_interface_range)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9670,7 +9791,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (121 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_79
+    sub    lr, lr, #(.L_ALT_op_unused_79 - .L_op_unused_79)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9687,7 +9809,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (122 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_7a
+    sub    lr, lr, #(.L_ALT_op_unused_7a - .L_op_unused_7a)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9704,7 +9827,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (123 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_neg_int
+    sub    lr, lr, #(.L_ALT_op_neg_int - .L_op_neg_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9721,7 +9845,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (124 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_not_int
+    sub    lr, lr, #(.L_ALT_op_not_int - .L_op_not_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9738,7 +9863,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (125 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_neg_long
+    sub    lr, lr, #(.L_ALT_op_neg_long - .L_op_neg_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9755,7 +9881,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (126 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_not_long
+    sub    lr, lr, #(.L_ALT_op_not_long - .L_op_not_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9772,7 +9899,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (127 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_neg_float
+    sub    lr, lr, #(.L_ALT_op_neg_float - .L_op_neg_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9789,7 +9917,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (128 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_neg_double
+    sub    lr, lr, #(.L_ALT_op_neg_double - .L_op_neg_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9806,7 +9935,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (129 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_int_to_long
+    sub    lr, lr, #(.L_ALT_op_int_to_long - .L_op_int_to_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9823,7 +9953,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (130 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_int_to_float
+    sub    lr, lr, #(.L_ALT_op_int_to_float - .L_op_int_to_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9840,7 +9971,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (131 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_int_to_double
+    sub    lr, lr, #(.L_ALT_op_int_to_double - .L_op_int_to_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9857,7 +9989,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (132 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_long_to_int
+    sub    lr, lr, #(.L_ALT_op_long_to_int - .L_op_long_to_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9874,7 +10007,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (133 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_long_to_float
+    sub    lr, lr, #(.L_ALT_op_long_to_float - .L_op_long_to_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9891,7 +10025,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (134 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_long_to_double
+    sub    lr, lr, #(.L_ALT_op_long_to_double - .L_op_long_to_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9908,7 +10043,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (135 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_float_to_int
+    sub    lr, lr, #(.L_ALT_op_float_to_int - .L_op_float_to_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9925,7 +10061,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (136 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_float_to_long
+    sub    lr, lr, #(.L_ALT_op_float_to_long - .L_op_float_to_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9942,7 +10079,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (137 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_float_to_double
+    sub    lr, lr, #(.L_ALT_op_float_to_double - .L_op_float_to_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9959,7 +10097,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (138 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_double_to_int
+    sub    lr, lr, #(.L_ALT_op_double_to_int - .L_op_double_to_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9976,7 +10115,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (139 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_double_to_long
+    sub    lr, lr, #(.L_ALT_op_double_to_long - .L_op_double_to_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -9993,7 +10133,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (140 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_double_to_float
+    sub    lr, lr, #(.L_ALT_op_double_to_float - .L_op_double_to_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10010,7 +10151,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (141 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_int_to_byte
+    sub    lr, lr, #(.L_ALT_op_int_to_byte - .L_op_int_to_byte)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10027,7 +10169,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (142 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_int_to_char
+    sub    lr, lr, #(.L_ALT_op_int_to_char - .L_op_int_to_char)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10044,7 +10187,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (143 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_int_to_short
+    sub    lr, lr, #(.L_ALT_op_int_to_short - .L_op_int_to_short)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10061,7 +10205,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (144 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_add_int
+    sub    lr, lr, #(.L_ALT_op_add_int - .L_op_add_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10078,7 +10223,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (145 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sub_int
+    sub    lr, lr, #(.L_ALT_op_sub_int - .L_op_sub_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10095,7 +10241,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (146 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_mul_int
+    sub    lr, lr, #(.L_ALT_op_mul_int - .L_op_mul_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10112,7 +10259,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (147 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_div_int
+    sub    lr, lr, #(.L_ALT_op_div_int - .L_op_div_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10129,7 +10277,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (148 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rem_int
+    sub    lr, lr, #(.L_ALT_op_rem_int - .L_op_rem_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10146,7 +10295,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (149 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_and_int
+    sub    lr, lr, #(.L_ALT_op_and_int - .L_op_and_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10163,7 +10313,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (150 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_or_int
+    sub    lr, lr, #(.L_ALT_op_or_int - .L_op_or_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10180,7 +10331,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (151 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_xor_int
+    sub    lr, lr, #(.L_ALT_op_xor_int - .L_op_xor_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10197,7 +10349,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (152 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_shl_int
+    sub    lr, lr, #(.L_ALT_op_shl_int - .L_op_shl_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10214,7 +10367,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (153 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_shr_int
+    sub    lr, lr, #(.L_ALT_op_shr_int - .L_op_shr_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10231,7 +10385,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (154 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_ushr_int
+    sub    lr, lr, #(.L_ALT_op_ushr_int - .L_op_ushr_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10248,7 +10403,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (155 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_add_long
+    sub    lr, lr, #(.L_ALT_op_add_long - .L_op_add_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10265,7 +10421,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (156 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sub_long
+    sub    lr, lr, #(.L_ALT_op_sub_long - .L_op_sub_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10282,7 +10439,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (157 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_mul_long
+    sub    lr, lr, #(.L_ALT_op_mul_long - .L_op_mul_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10299,7 +10457,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (158 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_div_long
+    sub    lr, lr, #(.L_ALT_op_div_long - .L_op_div_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10316,7 +10475,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (159 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rem_long
+    sub    lr, lr, #(.L_ALT_op_rem_long - .L_op_rem_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10333,7 +10493,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (160 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_and_long
+    sub    lr, lr, #(.L_ALT_op_and_long - .L_op_and_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10350,7 +10511,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (161 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_or_long
+    sub    lr, lr, #(.L_ALT_op_or_long - .L_op_or_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10367,7 +10529,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (162 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_xor_long
+    sub    lr, lr, #(.L_ALT_op_xor_long - .L_op_xor_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10384,7 +10547,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (163 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_shl_long
+    sub    lr, lr, #(.L_ALT_op_shl_long - .L_op_shl_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10401,7 +10565,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (164 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_shr_long
+    sub    lr, lr, #(.L_ALT_op_shr_long - .L_op_shr_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10418,7 +10583,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (165 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_ushr_long
+    sub    lr, lr, #(.L_ALT_op_ushr_long - .L_op_ushr_long)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10435,7 +10601,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (166 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_add_float
+    sub    lr, lr, #(.L_ALT_op_add_float - .L_op_add_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10452,7 +10619,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (167 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sub_float
+    sub    lr, lr, #(.L_ALT_op_sub_float - .L_op_sub_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10469,7 +10637,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (168 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_mul_float
+    sub    lr, lr, #(.L_ALT_op_mul_float - .L_op_mul_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10486,7 +10655,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (169 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_div_float
+    sub    lr, lr, #(.L_ALT_op_div_float - .L_op_div_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10503,7 +10673,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (170 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rem_float
+    sub    lr, lr, #(.L_ALT_op_rem_float - .L_op_rem_float)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10520,7 +10691,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (171 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_add_double
+    sub    lr, lr, #(.L_ALT_op_add_double - .L_op_add_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10537,7 +10709,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (172 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sub_double
+    sub    lr, lr, #(.L_ALT_op_sub_double - .L_op_sub_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10554,7 +10727,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (173 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_mul_double
+    sub    lr, lr, #(.L_ALT_op_mul_double - .L_op_mul_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10571,7 +10745,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (174 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_div_double
+    sub    lr, lr, #(.L_ALT_op_div_double - .L_op_div_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10588,7 +10763,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (175 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rem_double
+    sub    lr, lr, #(.L_ALT_op_rem_double - .L_op_rem_double)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10605,7 +10781,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (176 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_add_int_2addr
+    sub    lr, lr, #(.L_ALT_op_add_int_2addr - .L_op_add_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10622,7 +10799,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (177 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sub_int_2addr
+    sub    lr, lr, #(.L_ALT_op_sub_int_2addr - .L_op_sub_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10639,7 +10817,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (178 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_mul_int_2addr
+    sub    lr, lr, #(.L_ALT_op_mul_int_2addr - .L_op_mul_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10656,7 +10835,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (179 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_div_int_2addr
+    sub    lr, lr, #(.L_ALT_op_div_int_2addr - .L_op_div_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10673,7 +10853,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (180 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rem_int_2addr
+    sub    lr, lr, #(.L_ALT_op_rem_int_2addr - .L_op_rem_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10690,7 +10871,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (181 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_and_int_2addr
+    sub    lr, lr, #(.L_ALT_op_and_int_2addr - .L_op_and_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10707,7 +10889,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (182 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_or_int_2addr
+    sub    lr, lr, #(.L_ALT_op_or_int_2addr - .L_op_or_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10724,7 +10907,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (183 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_xor_int_2addr
+    sub    lr, lr, #(.L_ALT_op_xor_int_2addr - .L_op_xor_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10741,7 +10925,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (184 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_shl_int_2addr
+    sub    lr, lr, #(.L_ALT_op_shl_int_2addr - .L_op_shl_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10758,7 +10943,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (185 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_shr_int_2addr
+    sub    lr, lr, #(.L_ALT_op_shr_int_2addr - .L_op_shr_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10775,7 +10961,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (186 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_ushr_int_2addr
+    sub    lr, lr, #(.L_ALT_op_ushr_int_2addr - .L_op_ushr_int_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10792,7 +10979,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (187 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_add_long_2addr
+    sub    lr, lr, #(.L_ALT_op_add_long_2addr - .L_op_add_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10809,7 +10997,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (188 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sub_long_2addr
+    sub    lr, lr, #(.L_ALT_op_sub_long_2addr - .L_op_sub_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10826,7 +11015,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (189 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_mul_long_2addr
+    sub    lr, lr, #(.L_ALT_op_mul_long_2addr - .L_op_mul_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10843,7 +11033,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (190 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_div_long_2addr
+    sub    lr, lr, #(.L_ALT_op_div_long_2addr - .L_op_div_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10860,7 +11051,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (191 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rem_long_2addr
+    sub    lr, lr, #(.L_ALT_op_rem_long_2addr - .L_op_rem_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10877,7 +11069,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (192 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_and_long_2addr
+    sub    lr, lr, #(.L_ALT_op_and_long_2addr - .L_op_and_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10894,7 +11087,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (193 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_or_long_2addr
+    sub    lr, lr, #(.L_ALT_op_or_long_2addr - .L_op_or_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10911,7 +11105,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (194 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_xor_long_2addr
+    sub    lr, lr, #(.L_ALT_op_xor_long_2addr - .L_op_xor_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10928,7 +11123,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (195 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_shl_long_2addr
+    sub    lr, lr, #(.L_ALT_op_shl_long_2addr - .L_op_shl_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10945,7 +11141,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (196 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_shr_long_2addr
+    sub    lr, lr, #(.L_ALT_op_shr_long_2addr - .L_op_shr_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10962,7 +11159,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (197 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_ushr_long_2addr
+    sub    lr, lr, #(.L_ALT_op_ushr_long_2addr - .L_op_ushr_long_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10979,7 +11177,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (198 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_add_float_2addr
+    sub    lr, lr, #(.L_ALT_op_add_float_2addr - .L_op_add_float_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -10996,7 +11195,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (199 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sub_float_2addr
+    sub    lr, lr, #(.L_ALT_op_sub_float_2addr - .L_op_sub_float_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11013,7 +11213,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (200 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_mul_float_2addr
+    sub    lr, lr, #(.L_ALT_op_mul_float_2addr - .L_op_mul_float_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11030,7 +11231,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (201 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_div_float_2addr
+    sub    lr, lr, #(.L_ALT_op_div_float_2addr - .L_op_div_float_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11047,7 +11249,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (202 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rem_float_2addr
+    sub    lr, lr, #(.L_ALT_op_rem_float_2addr - .L_op_rem_float_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11064,7 +11267,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (203 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_add_double_2addr
+    sub    lr, lr, #(.L_ALT_op_add_double_2addr - .L_op_add_double_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11081,7 +11285,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (204 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_sub_double_2addr
+    sub    lr, lr, #(.L_ALT_op_sub_double_2addr - .L_op_sub_double_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11098,7 +11303,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (205 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_mul_double_2addr
+    sub    lr, lr, #(.L_ALT_op_mul_double_2addr - .L_op_mul_double_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11115,7 +11321,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (206 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_div_double_2addr
+    sub    lr, lr, #(.L_ALT_op_div_double_2addr - .L_op_div_double_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11132,7 +11339,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (207 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rem_double_2addr
+    sub    lr, lr, #(.L_ALT_op_rem_double_2addr - .L_op_rem_double_2addr)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11149,7 +11357,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (208 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_add_int_lit16
+    sub    lr, lr, #(.L_ALT_op_add_int_lit16 - .L_op_add_int_lit16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11166,7 +11375,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (209 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rsub_int
+    sub    lr, lr, #(.L_ALT_op_rsub_int - .L_op_rsub_int)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11183,7 +11393,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (210 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_mul_int_lit16
+    sub    lr, lr, #(.L_ALT_op_mul_int_lit16 - .L_op_mul_int_lit16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11200,7 +11411,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (211 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_div_int_lit16
+    sub    lr, lr, #(.L_ALT_op_div_int_lit16 - .L_op_div_int_lit16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11217,7 +11429,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (212 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rem_int_lit16
+    sub    lr, lr, #(.L_ALT_op_rem_int_lit16 - .L_op_rem_int_lit16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11234,7 +11447,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (213 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_and_int_lit16
+    sub    lr, lr, #(.L_ALT_op_and_int_lit16 - .L_op_and_int_lit16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11251,7 +11465,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (214 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_or_int_lit16
+    sub    lr, lr, #(.L_ALT_op_or_int_lit16 - .L_op_or_int_lit16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11268,7 +11483,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (215 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_xor_int_lit16
+    sub    lr, lr, #(.L_ALT_op_xor_int_lit16 - .L_op_xor_int_lit16)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11285,7 +11501,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (216 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_add_int_lit8
+    sub    lr, lr, #(.L_ALT_op_add_int_lit8 - .L_op_add_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11302,7 +11519,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (217 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rsub_int_lit8
+    sub    lr, lr, #(.L_ALT_op_rsub_int_lit8 - .L_op_rsub_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11319,7 +11537,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (218 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_mul_int_lit8
+    sub    lr, lr, #(.L_ALT_op_mul_int_lit8 - .L_op_mul_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11336,7 +11555,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (219 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_div_int_lit8
+    sub    lr, lr, #(.L_ALT_op_div_int_lit8 - .L_op_div_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11353,7 +11573,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (220 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_rem_int_lit8
+    sub    lr, lr, #(.L_ALT_op_rem_int_lit8 - .L_op_rem_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11370,7 +11591,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (221 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_and_int_lit8
+    sub    lr, lr, #(.L_ALT_op_and_int_lit8 - .L_op_and_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11387,7 +11609,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (222 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_or_int_lit8
+    sub    lr, lr, #(.L_ALT_op_or_int_lit8 - .L_op_or_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11404,7 +11627,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (223 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_xor_int_lit8
+    sub    lr, lr, #(.L_ALT_op_xor_int_lit8 - .L_op_xor_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11421,7 +11645,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (224 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_shl_int_lit8
+    sub    lr, lr, #(.L_ALT_op_shl_int_lit8 - .L_op_shl_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11438,7 +11663,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (225 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_shr_int_lit8
+    sub    lr, lr, #(.L_ALT_op_shr_int_lit8 - .L_op_shr_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11455,7 +11681,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (226 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_ushr_int_lit8
+    sub    lr, lr, #(.L_ALT_op_ushr_int_lit8 - .L_op_ushr_int_lit8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11472,7 +11699,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (227 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_quick
+    sub    lr, lr, #(.L_ALT_op_iget_quick - .L_op_iget_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11489,7 +11717,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (228 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_wide_quick
+    sub    lr, lr, #(.L_ALT_op_iget_wide_quick - .L_op_iget_wide_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11506,7 +11735,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (229 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_object_quick
+    sub    lr, lr, #(.L_ALT_op_iget_object_quick - .L_op_iget_object_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11523,7 +11753,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (230 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_quick
+    sub    lr, lr, #(.L_ALT_op_iput_quick - .L_op_iput_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11540,7 +11771,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (231 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_wide_quick
+    sub    lr, lr, #(.L_ALT_op_iput_wide_quick - .L_op_iput_wide_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11557,7 +11789,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (232 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_object_quick
+    sub    lr, lr, #(.L_ALT_op_iput_object_quick - .L_op_iput_object_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11574,7 +11807,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (233 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_virtual_quick
+    sub    lr, lr, #(.L_ALT_op_invoke_virtual_quick - .L_op_invoke_virtual_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11591,7 +11825,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (234 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_virtual_range_quick
+    sub    lr, lr, #(.L_ALT_op_invoke_virtual_range_quick - .L_op_invoke_virtual_range_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11608,7 +11843,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (235 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_boolean_quick
+    sub    lr, lr, #(.L_ALT_op_iput_boolean_quick - .L_op_iput_boolean_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11625,7 +11861,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (236 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_byte_quick
+    sub    lr, lr, #(.L_ALT_op_iput_byte_quick - .L_op_iput_byte_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11642,7 +11879,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (237 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_char_quick
+    sub    lr, lr, #(.L_ALT_op_iput_char_quick - .L_op_iput_char_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11659,7 +11897,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (238 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iput_short_quick
+    sub    lr, lr, #(.L_ALT_op_iput_short_quick - .L_op_iput_short_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11676,7 +11915,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (239 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_boolean_quick
+    sub    lr, lr, #(.L_ALT_op_iget_boolean_quick - .L_op_iget_boolean_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11693,7 +11933,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (240 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_byte_quick
+    sub    lr, lr, #(.L_ALT_op_iget_byte_quick - .L_op_iget_byte_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11710,7 +11951,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (241 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_char_quick
+    sub    lr, lr, #(.L_ALT_op_iget_char_quick - .L_op_iget_char_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11727,7 +11969,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (242 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_iget_short_quick
+    sub    lr, lr, #(.L_ALT_op_iget_short_quick - .L_op_iget_short_quick)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11744,7 +11987,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (243 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_f3
+    sub    lr, lr, #(.L_ALT_op_unused_f3 - .L_op_unused_f3)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11761,7 +12005,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (244 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_f4
+    sub    lr, lr, #(.L_ALT_op_unused_f4 - .L_op_unused_f4)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11778,7 +12023,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (245 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_f5
+    sub    lr, lr, #(.L_ALT_op_unused_f5 - .L_op_unused_f5)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11795,7 +12041,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (246 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_f6
+    sub    lr, lr, #(.L_ALT_op_unused_f6 - .L_op_unused_f6)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11812,7 +12059,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (247 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_f7
+    sub    lr, lr, #(.L_ALT_op_unused_f7 - .L_op_unused_f7)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11829,7 +12077,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (248 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_f8
+    sub    lr, lr, #(.L_ALT_op_unused_f8 - .L_op_unused_f8)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11846,7 +12095,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (249 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_unused_f9
+    sub    lr, lr, #(.L_ALT_op_unused_f9 - .L_op_unused_f9)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11863,7 +12113,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (250 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_polymorphic
+    sub    lr, lr, #(.L_ALT_op_invoke_polymorphic - .L_op_invoke_polymorphic)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11880,7 +12131,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (251 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_polymorphic_range
+    sub    lr, lr, #(.L_ALT_op_invoke_polymorphic_range - .L_op_invoke_polymorphic_range)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11897,7 +12149,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (252 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_custom
+    sub    lr, lr, #(.L_ALT_op_invoke_custom - .L_op_invoke_custom)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11914,7 +12167,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (253 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_invoke_custom_range
+    sub    lr, lr, #(.L_ALT_op_invoke_custom_range - .L_op_invoke_custom_range)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11931,7 +12185,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (254 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_method_handle
+    sub    lr, lr, #(.L_ALT_op_const_method_handle - .L_op_const_method_handle)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -11948,7 +12203,8 @@
  */
     .extern MterpCheckBefore
     ldr    rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET]            @ refresh IBASE.
-    adrl   lr, artMterpAsmInstructionStart + (255 * 128)       @ Addr of primary handler.
+    adr    lr, .L_ALT_op_const_method_type
+    sub    lr, lr, #(.L_ALT_op_const_method_type - .L_op_const_method_type)               @ Addr of primary handler.
     mov    r0, rSELF
     add    r1, rFP, #OFF_FP_SHADOWFRAME
     mov    r2, rPC
@@ -12111,7 +12367,7 @@
 #endif
     cmp     rPROFILE, #JIT_CHECK_OSR
     beq     .L_osr_check
-    subgts  rPROFILE, #1
+    subsgt  rPROFILE, #1
     beq     .L_add_batch                @ counted down to zero - report
 .L_resume_backward_branch:
     ldr     lr, [rSELF, #THREAD_FLAGS_OFFSET]
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 5e73603..86f0606 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -735,8 +735,11 @@
 
   ProfilingInfo* profiling_info = method->GetProfilingInfo(kRuntimePointerSize);
   // Update the entrypoint if the ProfilingInfo has one. The interpreter will call it
-  // instead of interpreting the method.
-  if ((profiling_info != nullptr) && (profiling_info->GetSavedEntryPoint() != nullptr)) {
+  // instead of interpreting the method. We don't update it for instrumentation as the entrypoint
+  // must remain the instrumentation entrypoint.
+  if ((profiling_info != nullptr) &&
+      (profiling_info->GetSavedEntryPoint() != nullptr) &&
+      (method->GetEntryPointFromQuickCompiledCode() != GetQuickInstrumentationEntryPoint())) {
     Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(
         method, profiling_info->GetSavedEntryPoint());
   } else {
@@ -765,13 +768,20 @@
 void Jit::Stop() {
   Thread* self = Thread::Current();
   // TODO(ngeoffray): change API to not require calling WaitForCompilationToFinish twice.
+  // During shutdown and startup the thread-pool can be null.
+  if (GetThreadPool() == nullptr) {
+    return;
+  }
   WaitForCompilationToFinish(self);
   GetThreadPool()->StopWorkers(self);
   WaitForCompilationToFinish(self);
 }
 
 void Jit::Start() {
-  GetThreadPool()->StartWorkers(Thread::Current());
+  // During shutdown and startup the thread-pool can be null.
+  if (GetThreadPool() != nullptr) {
+    GetThreadPool()->StartWorkers(Thread::Current());
+  }
 }
 
 ScopedJitSuspend::ScopedJitSuspend() {
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index fe154a9..86582ef 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -174,7 +174,10 @@
   bool use_ashmem = !generate_debug_info && !kIsTargetLinux && !kIsTargetFuchsia;
 
   // With 'perf', we want a 1-1 mapping between an address and a method.
-  bool garbage_collect_code = !generate_debug_info;
+  // We aren't able to keep method pointers live during the instrumentation method entry trampoline
+  // so we will just disable jit-gc if we are doing that.
+  bool garbage_collect_code = !generate_debug_info &&
+      !Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled();
 
   // We need to have 32 bit offsets from method headers in code cache which point to things
   // in the data cache. If the maps are more than 4G apart, having multiple maps wouldn't work.
@@ -316,6 +319,17 @@
   return code_map_->Begin() <= ptr && ptr < code_map_->End();
 }
 
+bool JitCodeCache::WillExecuteJitCode(ArtMethod* method) {
+  ScopedObjectAccess soa(art::Thread::Current());
+  ScopedAssertNoThreadSuspension sants(__FUNCTION__);
+  if (ContainsPc(method->GetEntryPointFromQuickCompiledCode())) {
+    return true;
+  } else if (method->GetEntryPointFromQuickCompiledCode() == GetQuickInstrumentationEntryPoint()) {
+    return FindCompiledCodeForInstrumentation(method) != nullptr;
+  }
+  return false;
+}
+
 bool JitCodeCache::ContainsMethod(ArtMethod* method) {
   MutexLock mu(Thread::Current(), lock_);
   if (UNLIKELY(method->IsNative())) {
@@ -348,6 +362,35 @@
   return nullptr;
 }
 
+void JitCodeCache::ClearAllCompiledDexCode() {
+  MutexLock mu(Thread::Current(), lock_);
+  // Get rid of OSR code waiting to be put on a thread.
+  osr_code_map_.clear();
+
+  // We don't clear out or even touch method_code_map_ since that is what we use to go the other
+  // way, move from code currently-running to the method it's from. Getting rid of it would break
+  // the jit-gc, stack-walking and signal handling. Since we never look through it to go the other
+  // way (from method -> code) everything is fine.
+
+  for (ProfilingInfo* p : profiling_infos_) {
+    p->SetSavedEntryPoint(nullptr);
+  }
+}
+
+const void* JitCodeCache::FindCompiledCodeForInstrumentation(ArtMethod* method) {
+  if (LIKELY(!GetGarbageCollectCode())) {
+    return nullptr;
+  }
+  ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
+  if (info == nullptr) {
+    return nullptr;
+  }
+  // When GC is disabled for trampoline tracing we will use SavedEntrypoint to hold the actual
+  // jit-compiled version of the method. If jit-gc is disabled for other reasons this will just be
+  // nullptr.
+  return info->GetSavedEntryPoint();
+}
+
 class ScopedCodeCacheWrite : ScopedTrace {
  public:
   explicit ScopedCodeCacheWrite(const JitCodeCache* const code_cache)
@@ -464,21 +507,31 @@
   return stack_map_data - ComputeRootTableSize(GetNumberOfRoots(stack_map_data));
 }
 
-static void FillRootTable(uint8_t* roots_data, Handle<mirror::ObjectArray<mirror::Object>> roots)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
+static void DCheckRootsAreValid(Handle<mirror::ObjectArray<mirror::Object>> roots)
+    REQUIRES(!Locks::intern_table_lock_) REQUIRES_SHARED(Locks::mutator_lock_) {
+  if (!kIsDebugBuild) {
+    return;
+  }
+  const uint32_t length = roots->GetLength();
+  // Put all roots in `roots_data`.
+  for (uint32_t i = 0; i < length; ++i) {
+    ObjPtr<mirror::Object> object = roots->Get(i);
+    // Ensure the string is strongly interned. b/32995596
+    if (object->IsString()) {
+      ObjPtr<mirror::String> str = ObjPtr<mirror::String>::DownCast(object);
+      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+      CHECK(class_linker->GetInternTable()->LookupStrong(Thread::Current(), str) != nullptr);
+    }
+  }
+}
+
+void JitCodeCache::FillRootTable(uint8_t* roots_data,
+                                 Handle<mirror::ObjectArray<mirror::Object>> roots) {
   GcRoot<mirror::Object>* gc_roots = reinterpret_cast<GcRoot<mirror::Object>*>(roots_data);
   const uint32_t length = roots->GetLength();
   // Put all roots in `roots_data`.
   for (uint32_t i = 0; i < length; ++i) {
     ObjPtr<mirror::Object> object = roots->Get(i);
-    if (kIsDebugBuild) {
-      // Ensure the string is strongly interned. b/32995596
-      if (object->IsString()) {
-        ObjPtr<mirror::String> str = ObjPtr<mirror::String>::DownCast(object);
-        ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-        CHECK(class_linker->GetInternTable()->LookupStrong(Thread::Current(), str) != nullptr);
-      }
-    }
     gc_roots[i] = GcRoot<mirror::Object>(object);
   }
 }
@@ -810,6 +863,12 @@
           single_impl, method, method_header);
     }
 
+    if (!method->IsNative()) {
+      // We need to do this before grabbing the lock_ because it needs to be able to see the string
+      // InternTable. Native methods do not have roots.
+      DCheckRootsAreValid(roots);
+    }
+
     // The following needs to be guarded by cha_lock_ also. Otherwise it's
     // possible that the compiled code is considered invalidated by some class linking,
     // but below we still make the compiled code valid for the method.
@@ -978,6 +1037,8 @@
     // checks should always pass.
     DCHECK(!info->IsInUseByCompiler());
     new_method->SetProfilingInfo(info);
+    // Get rid of the old saved entrypoint if it is there.
+    info->SetSavedEntryPoint(nullptr);
     info->method_ = new_method;
   }
   // Update method_code_map_ to point to the new method.
@@ -1321,7 +1382,8 @@
       if (GetLiveBitmap()->Test(allocation)) {
         ++it;
       } else {
-        method_headers.insert(OatQuickMethodHeader::FromCodePointer(code_ptr));
+        OatQuickMethodHeader* header = OatQuickMethodHeader::FromCodePointer(code_ptr);
+        method_headers.insert(header);
         it = method_code_map_.erase(it);
       }
     }
@@ -1786,13 +1848,18 @@
                                              const OatQuickMethodHeader* header) {
   DCHECK(!method->IsNative());
   ProfilingInfo* profiling_info = method->GetProfilingInfo(kRuntimePointerSize);
+  const void* method_entrypoint = method->GetEntryPointFromQuickCompiledCode();
   if ((profiling_info != nullptr) &&
       (profiling_info->GetSavedEntryPoint() == header->GetEntryPoint())) {
+    // When instrumentation is set, the actual entrypoint is the one in the profiling info.
+    method_entrypoint = profiling_info->GetSavedEntryPoint();
     // Prevent future uses of the compiled code.
     profiling_info->SetSavedEntryPoint(nullptr);
   }
 
-  if (method->GetEntryPointFromQuickCompiledCode() == header->GetEntryPoint()) {
+  // Clear the method counter if we are running jitted code since we might want to jit this again in
+  // the future.
+  if (method_entrypoint == header->GetEntryPoint()) {
     // The entrypoint is the one to invalidate, so we just update it to the interpreter entry point
     // and clear the counter to get the method Jitted again.
     Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index b056bc3..ee6111a 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -154,6 +154,10 @@
   // Return true if the code cache contains this pc.
   bool ContainsPc(const void* pc) const;
 
+  // Returns true if either the method's entrypoint is JIT compiled code or it is the
+  // instrumentation entrypoint and we can jump to jit code for this method. For testing use only.
+  bool WillExecuteJitCode(ArtMethod* method) REQUIRES(!lock_);
+
   // Return true if the code cache contains this method.
   bool ContainsMethod(ArtMethod* method) REQUIRES(!lock_);
 
@@ -211,6 +215,8 @@
       REQUIRES(!lock_)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  void ClearAllCompiledDexCode() REQUIRES(!lock_, Locks::mutator_lock_);
+
   void CopyInlineCacheInto(const InlineCache& ic, Handle<mirror::ObjectArray<mirror::Class>> array)
       REQUIRES(!lock_)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -269,6 +275,16 @@
     garbage_collect_code_ = value;
   }
 
+  bool GetGarbageCollectCode() const {
+    return garbage_collect_code_;
+  }
+
+  // If Jit-gc has been disabled (and instrumentation has been enabled) this will return the
+  // jit-compiled entrypoint for this method.  Otherwise it will return null.
+  const void* FindCompiledCodeForInstrumentation(ArtMethod* method)
+      REQUIRES(!lock_)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
  private:
   // Take ownership of maps.
   JitCodeCache(MemMap* code_map,
@@ -299,6 +315,11 @@
       REQUIRES(!lock_)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  // Adds the given roots to the roots_data. Only a member for annotalysis.
+  void FillRootTable(uint8_t* roots_data, Handle<mirror::ObjectArray<mirror::Object>> roots)
+      REQUIRES(lock_)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
   ProfilingInfo* AddProfilingInfoInternal(Thread* self,
                                           ArtMethod* method,
                                           const std::vector<uint32_t>& entries)
@@ -375,7 +396,7 @@
   class JniStubData;
 
   // Lock for guarding allocations, collections, and the method_code_map_.
-  Mutex lock_;
+  Mutex lock_ BOTTOM_MUTEX_ACQUIRED_AFTER;
   // Condition to wait on during collection.
   ConditionVariable lock_cond_ GUARDED_BY(lock_);
   // Whether there is a code cache collection in progress.
diff --git a/runtime/oat.h b/runtime/oat.h
index 01ef424..ef2a5d7 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,8 +32,8 @@
 class PACKED(4) OatHeader {
  public:
   static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
-  // Last oat version changed reason: Add CodeInfo for JNI methods.
-  static constexpr uint8_t kOatVersion[] = { '1', '5', '2', '\0' };
+  // Last oat version changed reason: Added AllocStringObject Quick Entrypoint.
+  static constexpr uint8_t kOatVersion[] = { '1', '5', '3', '\0' };
 
   static constexpr const char* kImageLocationKey = "image-location";
   static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index e8d9658..7f5717f 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -60,18 +60,24 @@
 // Finds catch handler.
 class CatchBlockStackVisitor FINAL : public StackVisitor {
  public:
-  CatchBlockStackVisitor(Thread* self, Context* context, Handle<mirror::Throwable>* exception,
-                         QuickExceptionHandler* exception_handler)
+  CatchBlockStackVisitor(Thread* self,
+                         Context* context,
+                         Handle<mirror::Throwable>* exception,
+                         QuickExceptionHandler* exception_handler,
+                         uint32_t skip_frames)
       REQUIRES_SHARED(Locks::mutator_lock_)
       : StackVisitor(self, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
         exception_(exception),
-        exception_handler_(exception_handler) {
+        exception_handler_(exception_handler),
+        skip_frames_(skip_frames) {
   }
 
   bool VisitFrame() OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
     ArtMethod* method = GetMethod();
     exception_handler_->SetHandlerFrameDepth(GetFrameDepth());
     if (method == nullptr) {
+      DCHECK_EQ(skip_frames_, 0u)
+          << "We tried to skip an upcall! We should have returned to the upcall to finish delivery";
       // This is the upcall, we remember the frame and last pc so that we may long jump to them.
       exception_handler_->SetHandlerQuickFramePc(GetCurrentQuickFramePc());
       exception_handler_->SetHandlerQuickFrame(GetCurrentQuickFrame());
@@ -90,6 +96,10 @@
       }
       return false;  // End stack walk.
     }
+    if (skip_frames_ != 0) {
+      skip_frames_--;
+      return true;
+    }
     if (method->IsRuntimeMethod()) {
       // Ignore callee save method.
       DCHECK(method->IsCalleeSaveMethod());
@@ -138,48 +148,115 @@
   Handle<mirror::Throwable>* exception_;
   // The quick exception handler we're visiting for.
   QuickExceptionHandler* const exception_handler_;
+  // The number of frames to skip searching for catches in.
+  uint32_t skip_frames_;
 
   DISALLOW_COPY_AND_ASSIGN(CatchBlockStackVisitor);
 };
 
+// Counts instrumentation stack frame prior to catch handler or upcall.
+class InstrumentationStackVisitor : public StackVisitor {
+ public:
+  InstrumentationStackVisitor(Thread* self, size_t frame_depth)
+      REQUIRES_SHARED(Locks::mutator_lock_)
+      : StackVisitor(self, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
+        frame_depth_(frame_depth),
+        instrumentation_frames_to_pop_(0) {
+    CHECK_NE(frame_depth_, kInvalidFrameDepth);
+  }
+
+  bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+    size_t current_frame_depth = GetFrameDepth();
+    if (current_frame_depth < frame_depth_) {
+      CHECK(GetMethod() != nullptr);
+      if (UNLIKELY(reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc()) == GetReturnPc())) {
+        if (!IsInInlinedFrame()) {
+          // We do not count inlined frames, because we do not instrument them. The reason we
+          // include them in the stack walking is the check against `frame_depth_`, which is
+          // given to us by a visitor that visits inlined frames.
+          ++instrumentation_frames_to_pop_;
+        }
+      }
+      return true;
+    } else {
+      // We reached the frame of the catch handler or the upcall.
+      return false;
+    }
+  }
+
+  size_t GetInstrumentationFramesToPop() const {
+    return instrumentation_frames_to_pop_;
+  }
+
+ private:
+  const size_t frame_depth_;
+  size_t instrumentation_frames_to_pop_;
+
+  DISALLOW_COPY_AND_ASSIGN(InstrumentationStackVisitor);
+};
+
+// Finds the appropriate exception catch after calling all method exit instrumentation functions.
+// Note that this might change the exception being thrown.
 void QuickExceptionHandler::FindCatch(ObjPtr<mirror::Throwable> exception) {
   DCHECK(!is_deoptimization_);
+  instrumentation::InstrumentationStackPopper popper(self_);
+  // The number of total frames we have so far popped.
+  uint32_t already_popped = 0;
+  bool popped_to_top = true;
   StackHandleScope<1> hs(self_);
-  Handle<mirror::Throwable> exception_ref(hs.NewHandle(exception));
-  if (kDebugExceptionDelivery) {
-    ObjPtr<mirror::String> msg = exception_ref->GetDetailMessage();
-    std::string str_msg(msg != nullptr ? msg->ToModifiedUtf8() : "");
-    self_->DumpStack(LOG_STREAM(INFO) << "Delivering exception: " << exception_ref->PrettyTypeOf()
-                     << ": " << str_msg << "\n");
-  }
-
-  // Walk the stack to find catch handler.
-  CatchBlockStackVisitor visitor(self_, context_, &exception_ref, this);
-  visitor.WalkStack(true);
-
-  if (kDebugExceptionDelivery) {
-    if (*handler_quick_frame_ == nullptr) {
-      LOG(INFO) << "Handler is upcall";
+  MutableHandle<mirror::Throwable> exception_ref(hs.NewHandle(exception));
+  // Sending the instrumentation events (done by the InstrumentationStackPopper) can cause new
+  // exceptions to be thrown which will override the current exception. Therefore we need to perform
+  // the search for a catch in a loop until we have successfully popped all the way to a catch or
+  // the top of the stack.
+  do {
+    if (kDebugExceptionDelivery) {
+      ObjPtr<mirror::String> msg = exception_ref->GetDetailMessage();
+      std::string str_msg(msg != nullptr ? msg->ToModifiedUtf8() : "");
+      self_->DumpStack(LOG_STREAM(INFO) << "Delivering exception: " << exception_ref->PrettyTypeOf()
+                                        << ": " << str_msg << "\n");
     }
-    if (handler_method_ != nullptr) {
-      const DexFile* dex_file = handler_method_->GetDeclaringClass()->GetDexCache()->GetDexFile();
-      int line_number = annotations::GetLineNumFromPC(dex_file, handler_method_, handler_dex_pc_);
-      LOG(INFO) << "Handler: " << handler_method_->PrettyMethod() << " (line: "
-                << line_number << ")";
+
+    // Walk the stack to find catch handler.
+    CatchBlockStackVisitor visitor(self_, context_, &exception_ref, this, /*skip*/already_popped);
+    visitor.WalkStack(true);
+    uint32_t new_pop_count = handler_frame_depth_;
+    DCHECK_GE(new_pop_count, already_popped);
+    already_popped = new_pop_count;
+
+    // Figure out how many of those frames have instrumentation we need to remove (Should be the
+    // exact same as number of new_pop_count if there aren't inlined frames).
+    InstrumentationStackVisitor instrumentation_visitor(self_, handler_frame_depth_);
+    instrumentation_visitor.WalkStack(true);
+    size_t instrumentation_frames_to_pop = instrumentation_visitor.GetInstrumentationFramesToPop();
+
+    if (kDebugExceptionDelivery) {
+      if (*handler_quick_frame_ == nullptr) {
+        LOG(INFO) << "Handler is upcall";
+      }
+      if (handler_method_ != nullptr) {
+        const DexFile* dex_file = handler_method_->GetDeclaringClass()->GetDexCache()->GetDexFile();
+        int line_number = annotations::GetLineNumFromPC(dex_file, handler_method_, handler_dex_pc_);
+        LOG(INFO) << "Handler: " << handler_method_->PrettyMethod() << " (line: "
+                  << line_number << ")";
+      }
+      LOG(INFO) << "Will attempt to pop " << instrumentation_frames_to_pop
+                << " off of the instrumentation stack";
     }
-  }
-  // Exception was cleared as part of delivery.
-  DCHECK(!self_->IsExceptionPending());
+    // Exception was cleared as part of delivery.
+    DCHECK(!self_->IsExceptionPending());
+    // If the handler is in optimized code, we need to set the catch environment.
+    if (*handler_quick_frame_ != nullptr &&
+        handler_method_header_ != nullptr &&
+        handler_method_header_->IsOptimized()) {
+      SetCatchEnvironmentForOptimizedHandler(&visitor);
+    }
+    popped_to_top = popper.PopFramesTo(instrumentation_frames_to_pop, exception_ref);
+  } while (!popped_to_top);
   if (!clear_exception_) {
     // Put exception back in root set with clear throw location.
     self_->SetException(exception_ref.Get());
   }
-  // If the handler is in optimized code, we need to set the catch environment.
-  if (*handler_quick_frame_ != nullptr &&
-      handler_method_header_ != nullptr &&
-      handler_method_header_->IsOptimized()) {
-    SetCatchEnvironmentForOptimizedHandler(&visitor);
-  }
 }
 
 static VRegKind ToVRegKind(DexRegisterLocation::Kind kind) {
@@ -561,48 +638,8 @@
   }
 }
 
-// Unwinds all instrumentation stack frame prior to catch handler or upcall.
-class InstrumentationStackVisitor : public StackVisitor {
- public:
-  InstrumentationStackVisitor(Thread* self, size_t frame_depth)
-      REQUIRES_SHARED(Locks::mutator_lock_)
-      : StackVisitor(self, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
-        frame_depth_(frame_depth),
-        instrumentation_frames_to_pop_(0) {
-    CHECK_NE(frame_depth_, kInvalidFrameDepth);
-  }
-
-  bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
-    size_t current_frame_depth = GetFrameDepth();
-    if (current_frame_depth < frame_depth_) {
-      CHECK(GetMethod() != nullptr);
-      if (UNLIKELY(reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc()) == GetReturnPc())) {
-        if (!IsInInlinedFrame()) {
-          // We do not count inlined frames, because we do not instrument them. The reason we
-          // include them in the stack walking is the check against `frame_depth_`, which is
-          // given to us by a visitor that visits inlined frames.
-          ++instrumentation_frames_to_pop_;
-        }
-      }
-      return true;
-    } else {
-      // We reached the frame of the catch handler or the upcall.
-      return false;
-    }
-  }
-
-  size_t GetInstrumentationFramesToPop() const {
-    return instrumentation_frames_to_pop_;
-  }
-
- private:
-  const size_t frame_depth_;
-  size_t instrumentation_frames_to_pop_;
-
-  DISALLOW_COPY_AND_ASSIGN(InstrumentationStackVisitor);
-};
-
 uintptr_t QuickExceptionHandler::UpdateInstrumentationStack() {
+  DCHECK(is_deoptimization_) << "Non-deoptimization handlers should use FindCatch";
   uintptr_t return_pc = 0;
   if (method_tracing_active_) {
     InstrumentationStackVisitor visitor(self_, handler_frame_depth_);
@@ -610,9 +647,7 @@
 
     size_t instrumentation_frames_to_pop = visitor.GetInstrumentationFramesToPop();
     instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
-    for (size_t i = 0; i < instrumentation_frames_to_pop; ++i) {
-      return_pc = instrumentation->PopMethodForUnwind(self_, is_deoptimization_);
-    }
+    return_pc = instrumentation->PopFramesForDeoptimization(self_, instrumentation_frames_to_pop);
   }
   return return_pc;
 }
diff --git a/runtime/quick_exception_handler.h b/runtime/quick_exception_handler.h
index 1103dab..5579d36 100644
--- a/runtime/quick_exception_handler.h
+++ b/runtime/quick_exception_handler.h
@@ -47,7 +47,8 @@
     UNREACHABLE();
   }
 
-  // Find the catch handler for the given exception.
+  // Find the catch handler for the given exception and call all required Instrumentation methods.
+  // Note this might result in the exception being caught being different from 'exception'.
   void FindCatch(ObjPtr<mirror::Throwable> exception) REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Deoptimize the stack to the upcall/some code that's not deoptimizeable. For
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 19d9485..99a8829 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -3160,6 +3160,7 @@
   QUICK_ENTRY_POINT_INFO(pAllocObjectResolved)
   QUICK_ENTRY_POINT_INFO(pAllocObjectInitialized)
   QUICK_ENTRY_POINT_INFO(pAllocObjectWithChecks)
+  QUICK_ENTRY_POINT_INFO(pAllocStringObject)
   QUICK_ENTRY_POINT_INFO(pAllocStringFromBytes)
   QUICK_ENTRY_POINT_INFO(pAllocStringFromChars)
   QUICK_ENTRY_POINT_INFO(pAllocStringFromString)
@@ -3368,7 +3369,6 @@
   ClearException();
   QuickExceptionHandler exception_handler(this, false);
   exception_handler.FindCatch(exception);
-  exception_handler.UpdateInstrumentationStack();
   if (exception_handler.GetClearException()) {
     // Exception was cleared as part of delivery.
     DCHECK(!IsExceptionPending());
diff --git a/test/988-method-trace/expected.txt b/test/988-method-trace/expected.txt
index 6e16722..75ee112 100644
--- a/test/988-method-trace/expected.txt
+++ b/test/988-method-trace/expected.txt
@@ -145,10 +145,10 @@
 ......=> private static java.lang.Object java.lang.Throwable.nativeFillInStackTrace()
 ......<= private static java.lang.Object java.lang.Throwable.nativeFillInStackTrace() -> <class [Ljava.lang.Object;: <non-deterministic>>
 .....<= public synchronized java.lang.Throwable java.lang.Throwable.fillInStackTrace() -> <class java.lang.Error: java.lang.Error: Bad argument: -19 < 0
-	art.Test988.iter_fibonacci(Test988.java:235)
-	art.Test988$IterOp.applyAsInt(Test988.java:230)
-	art.Test988.doFibTest(Test988.java:339)
-	art.Test988.run(Test988.java:304)
+	art.Test988.iter_fibonacci(Test988.java:255)
+	art.Test988$IterOp.applyAsInt(Test988.java:250)
+	art.Test988.doFibTest(Test988.java:378)
+	art.Test988.run(Test988.java:336)
 	<additional hidden frames>
 >
 ....<= public java.lang.Throwable(java.lang.String) -> <null: null>
@@ -165,10 +165,10 @@
 ...<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
 ..<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
 fibonacci(-19) -> java.lang.Error: Bad argument: -19 < 0
-	art.Test988.iter_fibonacci(Test988.java:235)
-	art.Test988$IterOp.applyAsInt(Test988.java:230)
-	art.Test988.doFibTest(Test988.java:339)
-	art.Test988.run(Test988.java:304)
+	art.Test988.iter_fibonacci(Test988.java:255)
+	art.Test988$IterOp.applyAsInt(Test988.java:250)
+	art.Test988.doFibTest(Test988.java:378)
+	art.Test988.run(Test988.java:336)
 	<additional hidden frames>
 
 .<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
@@ -248,10 +248,10 @@
 ......=> private static java.lang.Object java.lang.Throwable.nativeFillInStackTrace()
 ......<= private static java.lang.Object java.lang.Throwable.nativeFillInStackTrace() -> <class [Ljava.lang.Object;: <non-deterministic>>
 .....<= public synchronized java.lang.Throwable java.lang.Throwable.fillInStackTrace() -> <class java.lang.Error: java.lang.Error: Bad argument: -19 < 0
-	art.Test988.fibonacci(Test988.java:257)
-	art.Test988$RecurOp.applyAsInt(Test988.java:252)
-	art.Test988.doFibTest(Test988.java:339)
-	art.Test988.run(Test988.java:305)
+	art.Test988.fibonacci(Test988.java:277)
+	art.Test988$RecurOp.applyAsInt(Test988.java:272)
+	art.Test988.doFibTest(Test988.java:378)
+	art.Test988.run(Test988.java:337)
 	<additional hidden frames>
 >
 ....<= public java.lang.Throwable(java.lang.String) -> <null: null>
@@ -268,14 +268,20 @@
 ...<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
 ..<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
 fibonacci(-19) -> java.lang.Error: Bad argument: -19 < 0
-	art.Test988.fibonacci(Test988.java:257)
-	art.Test988$RecurOp.applyAsInt(Test988.java:252)
-	art.Test988.doFibTest(Test988.java:339)
-	art.Test988.run(Test988.java:305)
+	art.Test988.fibonacci(Test988.java:277)
+	art.Test988$RecurOp.applyAsInt(Test988.java:272)
+	art.Test988.doFibTest(Test988.java:378)
+	art.Test988.run(Test988.java:337)
 	<additional hidden frames>
 
 .<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
 <= public static void art.Test988.doFibTest(int,java.util.function.IntUnaryOperator) -> <null: null>
+=> public final void <non-deterministic-type 0>.run()
+.=> private static java.lang.Object java.lang.reflect.Proxy.invoke(java.lang.reflect.Proxy,java.lang.reflect.Method,java.lang.Object[]) throws java.lang.Throwable
+..=> public java.lang.Object art.Test988$TestRunnableInvokeHandler.invoke(java.lang.Object,java.lang.reflect.Method,java.lang.Object[]) throws java.lang.Throwable
+..<= public java.lang.Object art.Test988$TestRunnableInvokeHandler.invoke(java.lang.Object,java.lang.reflect.Method,java.lang.Object[]) throws java.lang.Throwable -> <null: null>
+.<= private static java.lang.Object java.lang.reflect.Proxy.invoke(java.lang.reflect.Proxy,java.lang.reflect.Method,java.lang.Object[]) throws java.lang.Throwable -> <null: null>
+<= public final void <non-deterministic-type 0>.run() -> <null: null>
 => static void art.Test988$IntrinsicsTest.doTest()
 .=> static void art.Test988Intrinsics.test()
 ..=> public static long java.lang.Double.doubleToRawLongBits(double)
diff --git a/test/988-method-trace/src/art/Test988.java b/test/988-method-trace/src/art/Test988.java
index d7eda52..5720d1d 100644
--- a/test/988-method-trace/src/art/Test988.java
+++ b/test/988-method-trace/src/art/Test988.java
@@ -18,20 +18,25 @@
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.util.Arrays;
+import java.lang.reflect.Executable;
+import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.function.IntUnaryOperator;
 import java.util.function.Function;
+import java.util.function.IntUnaryOperator;
 
 public class Test988 {
 
     // Methods with non-deterministic output that should not be printed.
     static Set<Method> NON_DETERMINISTIC_OUTPUT_METHODS = new HashSet<>();
     static Set<Method> NON_DETERMINISTIC_OUTPUT_TYPE_METHODS = new HashSet<>();
+    static List<Class<?>> NON_DETERMINISTIC_TYPE_NAMES = new ArrayList<>();
 
     static {
       try {
@@ -42,6 +47,10 @@
         NON_DETERMINISTIC_OUTPUT_METHODS.add(Thread.class.getDeclaredMethod("currentThread"));
         NON_DETERMINISTIC_OUTPUT_TYPE_METHODS.add(Thread.class.getDeclaredMethod("currentThread"));
       } catch (Exception e) {}
+      try {
+        NON_DETERMINISTIC_TYPE_NAMES.add(
+            Proxy.getProxyClass(Test988.class.getClassLoader(), new Class[] { Runnable.class }));
+      } catch (Exception e) {}
     }
 
     static interface Printable {
@@ -49,9 +58,9 @@
     }
 
     static final class MethodEntry implements Printable {
-        private Object m;
+        private Executable m;
         private int cnt;
-        public MethodEntry(Object m, int cnt) {
+        public MethodEntry(Executable m, int cnt) {
             this.m = m;
             this.cnt = cnt;
         }
@@ -124,18 +133,26 @@
       }
     }
 
-    static String methodToString(Object m) {
+    static String methodToString(Executable m) {
       // Make the output more similar between ART and RI,
       // by removing the 'native' specifier from methods.
-      String methodStr = m.toString();
+      String methodStr;
+      if (NON_DETERMINISTIC_TYPE_NAMES.contains(m.getDeclaringClass())) {
+        methodStr = m.toString().replace(m.getDeclaringClass().getName(),
+            "<non-deterministic-type " +
+            NON_DETERMINISTIC_TYPE_NAMES.indexOf(m.getDeclaringClass()) +
+            ">");
+      } else {
+        methodStr = m.toString();
+      }
       return methodStr.replaceFirst(" native", "");
     }
 
     static final class MethodReturn implements Printable {
-        private Object m;
+        private Executable m;
         private Object val;
         private int cnt;
-        public MethodReturn(Object m, Object val, int cnt) {
+        public MethodReturn(Executable m, Object val, int cnt) {
             this.m = m;
             this.val = val;
             this.cnt = cnt;
@@ -155,6 +172,9 @@
             String klass_print;
             if (klass == null) {
               klass_print =  "null";
+            } else if (NON_DETERMINISTIC_TYPE_NAMES.contains(klass)) {
+              klass_print = "<non-deterministic-class " +
+                  NON_DETERMINISTIC_TYPE_NAMES.indexOf(klass) + ">";
             } else if (NON_DETERMINISTIC_OUTPUT_TYPE_METHODS.contains(m)) {
               klass_print = "<non-deterministic>";
             } else {
@@ -166,9 +186,9 @@
     }
 
     static final class MethodThrownThrough implements Printable {
-        private Object m;
+        private Executable m;
         private int cnt;
-        public MethodThrownThrough(Object m, int cnt) {
+        public MethodThrownThrough(Executable m, int cnt) {
             this.m = m;
             this.cnt = cnt;
         }
@@ -262,10 +282,16 @@
         }
     }
 
+    static final class TestRunnableInvokeHandler implements InvocationHandler {
+      public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
+        return null;
+      }
+    }
+
     static final int METHOD_TRACING_IGNORE_DEPTH = 2;
     static boolean sMethodTracingIgnore = false;
 
-    public static void notifyMethodEntry(Object m) {
+    public static void notifyMethodEntry(Executable m) {
         // Called by native code when a method is entered. This method is ignored by the native
         // entry and exit hooks.
         cnt++;
@@ -275,7 +301,7 @@
         results.add(new MethodEntry(m, cnt - 1));
     }
 
-    public static void notifyMethodExit(Object m, boolean exception, Object result) {
+    public static void notifyMethodExit(Executable m, boolean exception, Object result) {
         cnt--;
 
         if (cnt > METHOD_TRACING_IGNORE_DEPTH && sMethodTracingIgnore) {
@@ -293,17 +319,25 @@
         // call this here so it is linked. It doesn't actually do anything here.
         loadAllClasses();
         Trace.disableTracing(Thread.currentThread());
+        // Call this prior to starting tracing since its implementation is so deep into reflection
+        // that it will be changing all the time and difficult to keep up with.
+        Runnable runnable = (Runnable)Proxy.newProxyInstance(
+                    Test988.class.getClassLoader(),
+                    new Class[]{ Runnable.class },
+                    new TestRunnableInvokeHandler());
         Trace.enableMethodTracing(
             Test988.class,
-            Test988.class.getDeclaredMethod("notifyMethodEntry", Object.class),
+            Test988.class.getDeclaredMethod("notifyMethodEntry", Executable.class),
             Test988.class.getDeclaredMethod(
-                "notifyMethodExit", Object.class, Boolean.TYPE, Object.class),
+                "notifyMethodExit", Executable.class, Boolean.TYPE, Object.class),
             Thread.currentThread());
         doFibTest(30, new IterOp());
         doFibTest(5, new RecurOp());
         doFibTest(-19, new IterOp());
         doFibTest(-19, new RecurOp());
 
+        runnable.run();
+
         sMethodTracingIgnore = true;
         IntrinsicsTest.doTest();
         sMethodTracingIgnore = false;
@@ -325,6 +359,11 @@
       RecurOp.class.toString();
       IterOp.class.toString();
       StringBuilder.class.toString();
+      Runnable.class.toString();
+      TestRunnableInvokeHandler.class.toString();
+      Proxy.class.toString();
+      Proxy.getProxyClass(
+          Test988.class.getClassLoader(), new Class[] { Runnable.class }).toString();
       IntrinsicsTest.initialize();  // ensure <clinit> is executed prior to tracing.
     }
 
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index f2da6fe..bd63389 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -176,7 +176,9 @@
   CHECK(chars.c_str() != nullptr);
   ArtMethod* method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName(
         chars.c_str(), kRuntimePointerSize);
-  return jit->GetCodeCache()->ContainsPc(method->GetEntryPointFromQuickCompiledCode());
+  ScopedAssertNoThreadSuspension sants(__FUNCTION__);
+  return jit->GetCodeCache()->ContainsPc(
+      Runtime::Current()->GetInstrumentation()->GetCodeForInvoke(method));
 }
 
 extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasJitCompiledCode(JNIEnv* env,
@@ -226,8 +228,7 @@
   // Note: this will apply to all JIT compilations.
   code_cache->SetGarbageCollectCode(false);
   while (true) {
-    const void* pc = method->GetEntryPointFromQuickCompiledCode();
-    if (code_cache->ContainsPc(pc)) {
+    if (code_cache->WillExecuteJitCode(method)) {
       break;
     } else {
       // Sleep to yield to the compiler thread.