Merge "Add ClassLoader to app-image roots."
diff --git a/build/art.go b/build/art.go
index ccaa11d..0af1767 100644
--- a/build/art.go
+++ b/build/art.go
@@ -259,7 +259,7 @@
 }
 
 func artLibrary() (blueprint.Module, []interface{}) {
-	library, _ := cc.NewLibrary(android.HostAndDeviceSupported, true, true)
+	library, _ := cc.NewLibrary(android.HostAndDeviceSupported)
 	module, props := library.Init()
 
 	props = installCodegenCustomizer(module, props, true)
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index 2c6df38..55f3c3c 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -57,6 +57,9 @@
 using helpers::RegisterFrom;
 using helpers::SRegisterFrom;
 
+using vixl::ExactAssemblyScope;
+using vixl::CodeBufferCheckScope;
+
 using RegisterList = vixl32::RegisterList;
 
 static bool ExpectedPairLayout(Location location) {
@@ -843,9 +846,9 @@
     __ Subs(tmp, tmp, expected);
 
     {
-      AssemblerAccurateScope aas(arm_codegen->GetVIXLAssembler(),
-                                 2 * kMaxInstructionSizeInBytes,
-                                 CodeBufferCheckScope::kMaximumSize);
+      ExactAssemblyScope aas(arm_codegen->GetVIXLAssembler(),
+                             2 * kMaxInstructionSizeInBytes,
+                             CodeBufferCheckScope::kMaximumSize);
 
       __ it(ne);
       __ clrex(ne);
@@ -1261,9 +1264,9 @@
   // We are about to use the assembler to place literals directly. Make sure we have enough
   // underlying code buffer and we have generated a jump table of the right size, using
   // codegen->GetVIXLAssembler()->GetBuffer().Align();
-  AssemblerAccurateScope aas(codegen->GetVIXLAssembler(),
-                             num_entries * sizeof(int32_t),
-                             CodeBufferCheckScope::kMaximumSize);
+  ExactAssemblyScope aas(codegen->GetVIXLAssembler(),
+                         num_entries * sizeof(int32_t),
+                         CodeBufferCheckScope::kMaximumSize);
   // TODO(VIXL): Check that using lower case bind is fine here.
   codegen->GetVIXLAssembler()->bind(&table_start_);
   for (uint32_t i = 0; i < num_entries; i++) {
@@ -1377,9 +1380,9 @@
     vixl32::Register temp = temps.Acquire();
     __ Sub(temp, sp, static_cast<int32_t>(GetStackOverflowReservedBytes(kArm)));
     // The load must immediately precede RecordPcInfo.
-    AssemblerAccurateScope aas(GetVIXLAssembler(),
-                               vixl32::kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(GetVIXLAssembler(),
+                           vixl32::kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
     __ ldr(temp, MemOperand(temp));
     RecordPcInfo(nullptr, 0);
   }
@@ -1637,9 +1640,9 @@
   __ Ldr(lr, MemOperand(tr, GetThreadOffset<kArmPointerSize>(entrypoint).Int32Value()));
   // Ensure the pc position is recorded immediately after the `blx` instruction.
   // blx in T32 has only 16bit encoding that's why a stricter check for the scope is used.
-  AssemblerAccurateScope aas(GetVIXLAssembler(),
-                             vixl32::k16BitT32InstructionSizeInBytes,
-                             CodeBufferCheckScope::kExactSize);
+  ExactAssemblyScope aas(GetVIXLAssembler(),
+                         vixl32::k16BitT32InstructionSizeInBytes,
+                         CodeBufferCheckScope::kExactSize);
   __ blx(lr);
   if (EntrypointRequiresStackMap(entrypoint)) {
     RecordPcInfo(instruction, dex_pc, slow_path);
@@ -2082,9 +2085,9 @@
         __ Cmp(InputRegisterAt(cond, 0),
                CodeGenerator::GetInt32ValueOf(right.GetConstant()));
       }
-      AssemblerAccurateScope aas(GetVIXLAssembler(),
-                                 3 * vixl32::kMaxInstructionSizeInBytes,
-                                 CodeBufferCheckScope::kMaximumSize);
+      ExactAssemblyScope aas(GetVIXLAssembler(),
+                             3 * vixl32::kMaxInstructionSizeInBytes,
+                             CodeBufferCheckScope::kMaximumSize);
       __ ite(ARMCondition(cond->GetCondition()));
       __ mov(ARMCondition(cond->GetCondition()), OutputRegister(cond), 1);
       __ mov(ARMCondition(cond->GetOppositeCondition()), OutputRegister(cond), 0);
@@ -2370,9 +2373,9 @@
 
   // Ensure the pc position is recorded immediately after the `ldr` instruction.
   {
-    AssemblerAccurateScope aas(GetVIXLAssembler(),
-                               vixl32::kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(GetVIXLAssembler(),
+                           vixl32::kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
     // /* HeapReference<Class> */ temp = receiver->klass_
     __ ldr(temp, MemOperand(RegisterFrom(receiver), class_offset));
     codegen_->MaybeRecordImplicitNullCheck(invoke);
@@ -2418,7 +2421,7 @@
   {
     // Ensure the pc position is recorded immediately after the `blx` instruction.
     // blx in T32 has only 16bit encoding that's why a stricter check for the scope is used.
-    AssemblerAccurateScope aas(GetVIXLAssembler(),
+    ExactAssemblyScope aas(GetVIXLAssembler(),
                            vixl32::k16BitT32InstructionSizeInBytes,
                            CodeBufferCheckScope::kExactSize);
     // LR();
@@ -3793,9 +3796,9 @@
           // If the shift is > 32 bits, override the high part
           __ Subs(temp, o_l, Operand::From(kArmBitsPerWord));
           {
-            AssemblerAccurateScope guard(GetVIXLAssembler(),
-                                         2 * vixl32::kMaxInstructionSizeInBytes,
-                                         CodeBufferCheckScope::kMaximumSize);
+            ExactAssemblyScope guard(GetVIXLAssembler(),
+                                     2 * vixl32::kMaxInstructionSizeInBytes,
+                                     CodeBufferCheckScope::kMaximumSize);
             __ it(pl);
             __ lsl(pl, o_h, low, temp);
           }
@@ -3812,9 +3815,9 @@
           // If the shift is > 32 bits, override the low part
           __ Subs(temp, o_h, Operand::From(kArmBitsPerWord));
           {
-            AssemblerAccurateScope guard(GetVIXLAssembler(),
-                                         2 * vixl32::kMaxInstructionSizeInBytes,
-                                         CodeBufferCheckScope::kMaximumSize);
+            ExactAssemblyScope guard(GetVIXLAssembler(),
+                                     2 * vixl32::kMaxInstructionSizeInBytes,
+                                     CodeBufferCheckScope::kMaximumSize);
             __ it(pl);
             __ asr(pl, o_l, high, temp);
           }
@@ -3829,9 +3832,9 @@
           __ Orr(o_l, o_l, temp);
           __ Subs(temp, o_h, Operand::From(kArmBitsPerWord));
           {
-            AssemblerAccurateScope guard(GetVIXLAssembler(),
-                                         2 * vixl32::kMaxInstructionSizeInBytes,
-                                         CodeBufferCheckScope::kMaximumSize);
+            ExactAssemblyScope guard(GetVIXLAssembler(),
+                                     2 * vixl32::kMaxInstructionSizeInBytes,
+                                     CodeBufferCheckScope::kMaximumSize);
           __ it(pl);
           __ lsr(pl, o_l, high, temp);
           }
@@ -3948,9 +3951,9 @@
     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.
-    AssemblerAccurateScope aas(GetVIXLAssembler(),
-                               vixl32::k16BitT32InstructionSizeInBytes,
-                               CodeBufferCheckScope::kExactSize);
+    ExactAssemblyScope aas(GetVIXLAssembler(),
+                           vixl32::k16BitT32InstructionSizeInBytes,
+                           CodeBufferCheckScope::kExactSize);
     __ blx(lr);
     codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
   } else {
@@ -4192,9 +4195,9 @@
   __ Bind(&fail);
   {
     // Ensure the pc position is recorded immediately after the `ldrexd` instruction.
-    AssemblerAccurateScope aas(GetVIXLAssembler(),
-                               vixl32::kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(GetVIXLAssembler(),
+                           vixl32::kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
     // We need a load followed by store. (The address used in a STREX instruction must
     // be the same as the address in the most recently executed LDREX instruction.)
     __ ldrexd(temp1, temp2, MemOperand(addr));
@@ -4715,9 +4718,9 @@
 
   UseScratchRegisterScope temps(GetVIXLAssembler());
   // Ensure the pc position is recorded immediately after the `ldr` instruction.
-  AssemblerAccurateScope aas(GetVIXLAssembler(),
-                             vixl32::kMaxInstructionSizeInBytes,
-                             CodeBufferCheckScope::kMaximumSize);
+  ExactAssemblyScope aas(GetVIXLAssembler(),
+                         vixl32::kMaxInstructionSizeInBytes,
+                         CodeBufferCheckScope::kMaximumSize);
   __ ldr(temps.Acquire(), MemOperand(InputRegisterAt(instruction, 0)));
   RecordPcInfo(instruction, instruction->GetDexPc());
 }
@@ -5233,9 +5236,9 @@
 
         {
           // Ensure we record the pc position immediately after the `ldr` instruction.
-          AssemblerAccurateScope aas(GetVIXLAssembler(),
-                                     vixl32::kMaxInstructionSizeInBytes,
-                                     CodeBufferCheckScope::kMaximumSize);
+          ExactAssemblyScope aas(GetVIXLAssembler(),
+                                 vixl32::kMaxInstructionSizeInBytes,
+                                 CodeBufferCheckScope::kMaximumSize);
           // /* HeapReference<Class> */ temp1 = array->klass_
           __ ldr(temp1, MemOperand(array, class_offset));
           codegen_->MaybeRecordImplicitNullCheck(instruction);
@@ -5384,9 +5387,9 @@
   vixl32::Register obj = InputRegisterAt(instruction, 0);
   vixl32::Register out = OutputRegister(instruction);
   {
-    AssemblerAccurateScope aas(GetVIXLAssembler(),
-                               vixl32::kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(GetVIXLAssembler(),
+                           vixl32::kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
     __ ldr(out, MemOperand(obj, offset));
     codegen_->MaybeRecordImplicitNullCheck(instruction);
   }
@@ -7351,9 +7354,9 @@
       relative_call_patches_.emplace_back(*invoke->GetTargetMethod().dex_file,
                                           invoke->GetTargetMethod().dex_method_index);
       {
-        AssemblerAccurateScope aas(GetVIXLAssembler(),
-                                   vixl32::kMaxInstructionSizeInBytes,
-                                   CodeBufferCheckScope::kMaximumSize);
+        ExactAssemblyScope aas(GetVIXLAssembler(),
+                               vixl32::kMaxInstructionSizeInBytes,
+                               CodeBufferCheckScope::kMaximumSize);
         __ bind(&relative_call_patches_.back().label);
         // Arbitrarily branch to the BL itself, override at link time.
         __ bl(&relative_call_patches_.back().label);
@@ -7365,9 +7368,9 @@
       // LR()
       {
         // blx in T32 has only 16bit encoding that's why a stricter check for the scope is used.
-        AssemblerAccurateScope aas(GetVIXLAssembler(),
-                                   vixl32::k16BitT32InstructionSizeInBytes,
-                                   CodeBufferCheckScope::kExactSize);
+        ExactAssemblyScope aas(GetVIXLAssembler(),
+                               vixl32::k16BitT32InstructionSizeInBytes,
+                               CodeBufferCheckScope::kExactSize);
         __ blx(lr);
       }
       break;
@@ -7380,9 +7383,9 @@
             ArtMethod::EntryPointFromQuickCompiledCodeOffset(kArmPointerSize).Int32Value());
       {
         // blx in T32 has only 16bit encoding that's why a stricter check for the scope is used.
-        AssemblerAccurateScope aas(GetVIXLAssembler(),
-                                   vixl32::k16BitT32InstructionSizeInBytes,
-                                   CodeBufferCheckScope::kExactSize);
+        ExactAssemblyScope aas(GetVIXLAssembler(),
+                               vixl32::k16BitT32InstructionSizeInBytes,
+                               CodeBufferCheckScope::kExactSize);
         // LR()
         __ blx(lr);
       }
@@ -7406,9 +7409,9 @@
   uint32_t class_offset = mirror::Object::ClassOffset().Int32Value();
   {
     // Make sure the pc is recorded immediately after the `ldr` instruction.
-    AssemblerAccurateScope aas(GetVIXLAssembler(),
-                               vixl32::kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(GetVIXLAssembler(),
+                           vixl32::kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
     // /* HeapReference<Class> */ temp = receiver->klass_
     __ ldr(temp, MemOperand(receiver, class_offset));
     MaybeRecordImplicitNullCheck(invoke);
@@ -7433,9 +7436,9 @@
   // `RecordPcInfo()` immediately following record the correct pc. Use a scope to help guarantee
   // that.
   // blx in T32 has only 16bit encoding that's why a stricter check for the scope is used.
-  AssemblerAccurateScope aas(GetVIXLAssembler(),
-                             vixl32::k16BitT32InstructionSizeInBytes,
-                             CodeBufferCheckScope::kExactSize);
+  ExactAssemblyScope aas(GetVIXLAssembler(),
+                         vixl32::k16BitT32InstructionSizeInBytes,
+                         CodeBufferCheckScope::kExactSize);
   __ blx(lr);
 }
 
@@ -7702,9 +7705,9 @@
 void CodeGeneratorARMVIXL::EmitMovwMovtPlaceholder(
     CodeGeneratorARMVIXL::PcRelativePatchInfo* labels,
     vixl32::Register out) {
-  AssemblerAccurateScope aas(GetVIXLAssembler(),
-                             3 * vixl32::kMaxInstructionSizeInBytes,
-                             CodeBufferCheckScope::kMaximumSize);
+  ExactAssemblyScope aas(GetVIXLAssembler(),
+                         3 * vixl32::kMaxInstructionSizeInBytes,
+                         CodeBufferCheckScope::kMaximumSize);
   // TODO(VIXL): Think about using mov instead of movw.
   __ bind(&labels->movw_label);
   __ movw(out, /* placeholder */ 0u);
diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h
index 5ec3da4..93ea601 100644
--- a/compiler/optimizing/code_generator_arm_vixl.h
+++ b/compiler/optimizing/code_generator_arm_vixl.h
@@ -120,7 +120,7 @@
         bb_addresses_(switch_instr->GetArena()->Adapter(kArenaAllocCodeGenerator)) {
     uint32_t num_entries = switch_instr_->GetNumEntries();
     for (uint32_t i = 0; i < num_entries; i++) {
-      IntLiteral *lit = new IntLiteral(0);
+      IntLiteral *lit = new IntLiteral(0, vixl32::RawLiteral::kManuallyPlaced);
       bb_addresses_.emplace_back(lit);
     }
   }
diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc
index 433dced..95551c8 100644
--- a/compiler/optimizing/intrinsics_arm_vixl.cc
+++ b/compiler/optimizing/intrinsics_arm_vixl.cc
@@ -47,6 +47,9 @@
 
 using namespace vixl::aarch32;  // NOLINT(build/namespaces)
 
+using vixl::ExactAssemblyScope;
+using vixl::CodeBufferCheckScope;
+
 ArmVIXLAssembler* IntrinsicCodeGeneratorARMVIXL::GetAssembler() {
   return codegen_->GetAssembler();
 }
@@ -467,9 +470,9 @@
   __ Cmp(op1, op2);
 
   {
-    AssemblerAccurateScope aas(assembler->GetVIXLAssembler(),
-                               3 * kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(assembler->GetVIXLAssembler(),
+                           3 * kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
 
     __ ite(is_min ? lt : gt);
     __ mov(is_min ? lt : gt, out, op1);
@@ -1050,9 +1053,9 @@
   __ Subs(tmp, tmp, expected);
 
   {
-    AssemblerAccurateScope aas(assembler->GetVIXLAssembler(),
-                               3 * kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(assembler->GetVIXLAssembler(),
+                           3 * kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
 
     __ itt(eq);
     __ strex(eq, tmp, value, MemOperand(tmp_ptr));
@@ -1066,9 +1069,9 @@
   __ Rsbs(out, tmp, 1);
 
   {
-    AssemblerAccurateScope aas(assembler->GetVIXLAssembler(),
-                               2 * kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(assembler->GetVIXLAssembler(),
+                           2 * kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
 
     __ it(cc);
     __ mov(cc, out, 0);
@@ -1185,9 +1188,9 @@
   // temp0 = min(len(str), len(arg)).
 
   {
-    AssemblerAccurateScope aas(assembler->GetVIXLAssembler(),
-                               2 * kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(assembler->GetVIXLAssembler(),
+                           2 * kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
 
     __ it(gt);
     __ mov(gt, temp0, temp1);
@@ -1207,9 +1210,9 @@
     // This could in theory exceed INT32_MAX, so treat temp0 as unsigned.
     __ Lsls(temp3, temp3, 31u);  // Extract purely the compression flag.
 
-    AssemblerAccurateScope aas(assembler->GetVIXLAssembler(),
-                               2 * kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(assembler->GetVIXLAssembler(),
+                           2 * kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
 
     __ it(ne);
     __ add(ne, temp0, temp0, temp0);
@@ -1324,9 +1327,9 @@
     __ Mov(temp2, arg);
     __ Lsrs(temp3, temp3, 1u);                // Continue the move of the compression flag.
     {
-      AssemblerAccurateScope aas(assembler->GetVIXLAssembler(),
-                                 3 * kMaxInstructionSizeInBytes,
-                                 CodeBufferCheckScope::kMaximumSize);
+      ExactAssemblyScope aas(assembler->GetVIXLAssembler(),
+                             3 * kMaxInstructionSizeInBytes,
+                             CodeBufferCheckScope::kMaximumSize);
       __ itt(cs);                             // Interleave with selection of temp1 and temp2.
       __ mov(cs, temp1, arg);                 // Preserves flags.
       __ mov(cs, temp2, str);                 // Preserves flags.
@@ -1361,9 +1364,9 @@
     static_assert(static_cast<uint32_t>(mirror::StringCompressionFlag::kCompressed) == 0u,
                   "Expecting 0=compressed, 1=uncompressed");
 
-    AssemblerAccurateScope aas(assembler->GetVIXLAssembler(),
-                               2 * kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(assembler->GetVIXLAssembler(),
+                           2 * kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
     __ it(cc);
     __ rsb(cc, out, out, 0);
   }
@@ -1457,9 +1460,9 @@
     // For string compression, calculate the number of bytes to compare (not chars).
     // This could in theory exceed INT32_MAX, so treat temp as unsigned.
     __ Lsrs(temp, temp, 1u);                        // Extract length and check compression flag.
-    AssemblerAccurateScope aas(assembler->GetVIXLAssembler(),
-                               2 * kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope aas(assembler->GetVIXLAssembler(),
+                           2 * kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
     __ it(cs);                                      // If uncompressed,
     __ add(cs, temp, temp, temp);                   //   double the byte count.
   }
diff --git a/compiler/utils/arm/assembler_arm_vixl.cc b/compiler/utils/arm/assembler_arm_vixl.cc
index 1614d04..76a94e8 100644
--- a/compiler/utils/arm/assembler_arm_vixl.cc
+++ b/compiler/utils/arm/assembler_arm_vixl.cc
@@ -23,6 +23,9 @@
 
 using namespace vixl::aarch32;  // NOLINT(build/namespaces)
 
+using vixl::ExactAssemblyScope;
+using vixl::CodeBufferCheckScope;
+
 namespace art {
 namespace arm {
 
@@ -459,9 +462,9 @@
   if (!label->IsBound()) {
     // Try to use 16-bit T2 encoding of B instruction.
     DCHECK(OutsideITBlock());
-    AssemblerAccurateScope ass(this,
-                               kMaxInstructionSizeInBytes,
-                               CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope ass(this,
+                           kMaxInstructionSizeInBytes,
+                           CodeBufferCheckScope::kMaximumSize);
     b(al, Narrow, label);
     AddBranchLabel(label);
     return;
diff --git a/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc b/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc
index 2d026b8..4e64f13 100644
--- a/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc
+++ b/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc
@@ -24,6 +24,9 @@
 using namespace vixl::aarch32;  // NOLINT(build/namespaces)
 namespace vixl32 = vixl::aarch32;
 
+using vixl::ExactAssemblyScope;
+using vixl::CodeBufferCheckScope;
+
 namespace art {
 namespace arm {
 
@@ -455,16 +458,16 @@
 
     if (asm_.ShifterOperandCanHold(ADD, handle_scope_offset.Int32Value(), kCcDontCare)) {
       if (!out_reg.Equals(in_reg)) {
-        AssemblerAccurateScope guard(asm_.GetVIXLAssembler(),
-                                     3 * vixl32::kMaxInstructionSizeInBytes,
-                                     CodeBufferCheckScope::kMaximumSize);
+        ExactAssemblyScope guard(asm_.GetVIXLAssembler(),
+                                 3 * vixl32::kMaxInstructionSizeInBytes,
+                                 CodeBufferCheckScope::kMaximumSize);
         ___ it(eq, 0xc);
         ___ mov(eq, out_reg.AsVIXLRegister(), 0);
         asm_.AddConstantInIt(out_reg.AsVIXLRegister(), sp, handle_scope_offset.Int32Value(), ne);
       } else {
-        AssemblerAccurateScope guard(asm_.GetVIXLAssembler(),
-                                     2 * vixl32::kMaxInstructionSizeInBytes,
-                                     CodeBufferCheckScope::kMaximumSize);
+        ExactAssemblyScope guard(asm_.GetVIXLAssembler(),
+                                 2 * vixl32::kMaxInstructionSizeInBytes,
+                                 CodeBufferCheckScope::kMaximumSize);
         ___ it(ne, 0x8);
         asm_.AddConstantInIt(out_reg.AsVIXLRegister(), sp, handle_scope_offset.Int32Value(), ne);
       }
@@ -493,9 +496,9 @@
     ___ Cmp(scratch.AsVIXLRegister(), 0);
 
     if (asm_.ShifterOperandCanHold(ADD, handle_scope_offset.Int32Value(), kCcDontCare)) {
-      AssemblerAccurateScope guard(asm_.GetVIXLAssembler(),
-                                   2 * vixl32::kMaxInstructionSizeInBytes,
-                                   CodeBufferCheckScope::kMaximumSize);
+      ExactAssemblyScope guard(asm_.GetVIXLAssembler(),
+                               2 * vixl32::kMaxInstructionSizeInBytes,
+                               CodeBufferCheckScope::kMaximumSize);
       ___ it(ne, 0x8);
       asm_.AddConstantInIt(scratch.AsVIXLRegister(), sp, handle_scope_offset.Int32Value(), ne);
     } else {
@@ -586,9 +589,9 @@
 
   ___ Cmp(scratch.AsVIXLRegister(), 0);
   {
-    AssemblerAccurateScope guard(asm_.GetVIXLAssembler(),
-                                 vixl32::kMaxInstructionSizeInBytes,
-                                 CodeBufferCheckScope::kMaximumSize);
+    ExactAssemblyScope guard(asm_.GetVIXLAssembler(),
+                             vixl32::kMaxInstructionSizeInBytes,
+                             CodeBufferCheckScope::kMaximumSize);
     ___ b(ne, Narrow, exception_blocks_.back()->Entry());
   }
   // TODO: think about using CBNZ here.
diff --git a/compiler/utils/mips64/assembler_mips64_test.cc b/compiler/utils/mips64/assembler_mips64_test.cc
index 31d3e4c..f62822d 100644
--- a/compiler/utils/mips64/assembler_mips64_test.cc
+++ b/compiler/utils/mips64/assembler_mips64_test.cc
@@ -605,15 +605,18 @@
 }
 
 TEST_F(AssemblerMIPS64Test, LongBalc) {
+  constexpr uint32_t kNopCount1 = (1u << 25) + 1;
+  constexpr uint32_t kNopCount2 = (1u << 25) + 1;
+  constexpr uint32_t kRequiredCapacity = (kNopCount1 + kNopCount2 + 6u) * 4u;
+  ASSERT_LT(__ GetBuffer()->Capacity(), kRequiredCapacity);
+  __ GetBuffer()->ExtendCapacity(kRequiredCapacity);
   mips64::Mips64Label label1, label2;
   __ Balc(&label1);
-  constexpr uint32_t kNopCount1 = (1u << 25) + 1;
   for (uint32_t i = 0; i != kNopCount1; ++i) {
     __ Nop();
   }
   __ Bind(&label1);
   __ Balc(&label2);
-  constexpr uint32_t kNopCount2 = (1u << 25) + 1;
   for (uint32_t i = 0; i != kNopCount2; ++i) {
     __ Nop();
   }
diff --git a/runtime/cha.cc b/runtime/cha.cc
index be675a8..d94b091 100644
--- a/runtime/cha.cc
+++ b/runtime/cha.cc
@@ -100,7 +100,11 @@
 
   bool VisitFrame() OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
     ArtMethod* method = GetMethod();
-    if (method == nullptr || method->IsRuntimeMethod() || method->IsNative()) {
+    // Avoid types of methods that do not have an oat quick method header.
+    if (method == nullptr ||
+        method->IsRuntimeMethod() ||
+        method->IsNative() ||
+        method->IsProxyMethod()) {
       return true;
     }
     if (GetCurrentQuickFrame() == nullptr) {
@@ -110,6 +114,7 @@
     // Method may have multiple versions of compiled code. Check
     // the method header to see if it has should_deoptimize flag.
     const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
+    DCHECK(method_header != nullptr);
     if (!method_header->HasShouldDeoptimizeFlag()) {
       // This compiled version doesn't have should_deoptimize flag. Skip.
       return true;
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 0a65cd1..213986a 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -25,6 +25,7 @@
 #include "mirror/class_loader.h"
 #include "mirror/dex_cache-inl.h"
 #include "mirror/iftable.h"
+#include "mirror/throwable.h"
 #include "mirror/object_array.h"
 #include "handle_scope-inl.h"
 #include "scoped_thread_state_change-inl.h"
@@ -89,17 +90,28 @@
 
 inline mirror::Class* ClassLinker::ResolveType(dex::TypeIndex type_idx, ArtMethod* referrer) {
   Thread::PoisonObjectPointersIfDebug();
+  if (kIsDebugBuild) {
+    Thread::Current()->AssertNoPendingException();
+  }
   ObjPtr<mirror::Class> resolved_type =
       referrer->GetDexCacheResolvedType(type_idx, image_pointer_size_);
   if (UNLIKELY(resolved_type == nullptr)) {
-    ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
     StackHandleScope<2> hs(Thread::Current());
-    Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
-    Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
-    const DexFile& dex_file = *dex_cache->GetDexFile();
-    resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
-    // Note: We cannot check here to see whether we added the type to the cache. The type
-    //       might be an erroneous class, which results in it being hidden from us.
+    // There could be an out of bounds exception from GetDexCacheResolvedType, don't call
+    // ResolveType for this case.
+    if (LIKELY(!hs.Self()->IsExceptionPending())) {
+      ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
+      Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
+      Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+      const DexFile& dex_file = *dex_cache->GetDexFile();
+      resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
+      // Note: We cannot check here to see whether we added the type to the cache. The type
+      //       might be an erroneous class, which results in it being hidden from us.
+    } else {
+      // Make sure its an array out of bounds exception.
+      DCHECK(hs.Self()->GetException()->GetClass()->DescriptorEquals(
+          "Ljava/lang/ArrayIndexOutOfBoundsException;"));
+    }
   }
   return resolved_type.Ptr();
 }
diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc
index 2cde7d5..081be96 100644
--- a/runtime/gc/reference_processor.cc
+++ b/runtime/gc/reference_processor.cc
@@ -75,11 +75,10 @@
   MutexLock mu(self, *Locks::reference_processor_lock_);
   while ((!kUseReadBarrier && SlowPathEnabled()) ||
          (kUseReadBarrier && !self->GetWeakRefAccessEnabled())) {
-    mirror::HeapReference<mirror::Object>* const referent_addr =
-        reference->GetReferentReferenceAddr();
+    ObjPtr<mirror::Object> referent = reference->GetReferent<kWithoutReadBarrier>();
     // If the referent became cleared, return it. Don't need barrier since thread roots can't get
     // updated until after we leave the function due to holding the mutator lock.
-    if (referent_addr->AsMirrorPtr() == nullptr) {
+    if (referent == nullptr) {
       return nullptr;
     }
     // Try to see if the referent is already marked by using the is_marked_callback. We can return
@@ -91,10 +90,15 @@
       // case only black nodes can be safely returned. If the GC is preserving references, the
       // mutator could take a white field from a grey or white node and move it somewhere else
       // in the heap causing corruption since this field would get swept.
-      if (collector_->IsMarkedHeapReference(referent_addr)) {
+      // Use the cached referent instead of calling GetReferent since other threads could call
+      // Reference.clear() after we did the null check resulting in a null pointer being
+      // incorrectly passed to IsMarked. b/33569625
+      ObjPtr<mirror::Object> forwarded_ref = collector_->IsMarked(referent.Ptr());
+      if (forwarded_ref != nullptr) {
+        // Non null means that it is marked.
         if (!preserving_references_ ||
            (LIKELY(!reference->IsFinalizerReferenceInstance()) && reference->IsUnprocessed())) {
-          return referent_addr->AsMirrorPtr();
+          return forwarded_ref;
         }
       }
     }
@@ -265,11 +269,23 @@
   }
 }
 
-bool ReferenceProcessor::MakeCircularListIfUnenqueued(
-    ObjPtr<mirror::FinalizerReference> reference) {
+void ReferenceProcessor::ClearReferent(ObjPtr<mirror::Reference> ref) {
   Thread* self = Thread::Current();
   MutexLock mu(self, *Locks::reference_processor_lock_);
-  // Wait untul we are done processing reference.
+  // Need to wait until reference processing is done since IsMarkedHeapReference does not have a
+  // CAS. If we do not wait, it can result in the GC un-clearing references due to race conditions.
+  // This also handles the race where the referent gets cleared after a null check but before
+  // IsMarkedHeapReference is called.
+  WaitUntilDoneProcessingReferences(self);
+  if (Runtime::Current()->IsActiveTransaction()) {
+    ref->ClearReferent<true>();
+  } else {
+    ref->ClearReferent<false>();
+  }
+}
+
+void ReferenceProcessor::WaitUntilDoneProcessingReferences(Thread* self) {
+  // Wait until we are done processing reference.
   while ((!kUseReadBarrier && SlowPathEnabled()) ||
          (kUseReadBarrier && !self->GetWeakRefAccessEnabled())) {
     // Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
@@ -277,6 +293,13 @@
     self->CheckEmptyCheckpoint();
     condition_.WaitHoldingLocks(self);
   }
+}
+
+bool ReferenceProcessor::MakeCircularListIfUnenqueued(
+    ObjPtr<mirror::FinalizerReference> reference) {
+  Thread* self = Thread::Current();
+  MutexLock mu(self, *Locks::reference_processor_lock_);
+  WaitUntilDoneProcessingReferences(self);
   // At this point, since the sentinel of the reference is live, it is guaranteed to not be
   // enqueued if we just finished processing references. Otherwise, we may be doing the main GC
   // phase. Since we are holding the reference processor lock, it guarantees that reference
diff --git a/runtime/gc/reference_processor.h b/runtime/gc/reference_processor.h
index 759b7e1..b15544d 100644
--- a/runtime/gc/reference_processor.h
+++ b/runtime/gc/reference_processor.h
@@ -73,6 +73,9 @@
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Locks::reference_processor_lock_,
                !Locks::reference_queue_finalizer_references_lock_);
+  void ClearReferent(ObjPtr<mirror::Reference> ref)
+      REQUIRES_SHARED(Locks::mutator_lock_)
+      REQUIRES(!Locks::reference_processor_lock_);
 
  private:
   bool SlowPathEnabled() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -84,6 +87,10 @@
   // referents.
   void StartPreservingReferences(Thread* self) REQUIRES(!Locks::reference_processor_lock_);
   void StopPreservingReferences(Thread* self) REQUIRES(!Locks::reference_processor_lock_);
+  // Wait until reference processing is done.
+  void WaitUntilDoneProcessingReferences(Thread* self)
+      REQUIRES_SHARED(Locks::mutator_lock_)
+      REQUIRES(Locks::reference_processor_lock_);
   // Collector which is clearing references, used by the GetReferent to return referents which are
   // already marked.
   collector::GarbageCollector* collector_ GUARDED_BY(Locks::reference_processor_lock_);
diff --git a/runtime/native/java_lang_ref_Reference.cc b/runtime/native/java_lang_ref_Reference.cc
index bedca10..c778068 100644
--- a/runtime/native/java_lang_ref_Reference.cc
+++ b/runtime/native/java_lang_ref_Reference.cc
@@ -33,8 +33,15 @@
   return soa.AddLocalReference<jobject>(referent);
 }
 
+static void Reference_clearReferent(JNIEnv* env, jobject javaThis) {
+  ScopedFastNativeObjectAccess soa(env);
+  ObjPtr<mirror::Reference> ref = soa.Decode<mirror::Reference>(javaThis);
+  Runtime::Current()->GetHeap()->GetReferenceProcessor()->ClearReferent(ref);
+}
+
 static JNINativeMethod gMethods[] = {
   NATIVE_METHOD(Reference, getReferent, "!()Ljava/lang/Object;"),
+  NATIVE_METHOD(Reference, clearReferent, "!()V"),
 };
 
 void register_java_lang_ref_Reference(JNIEnv* env) {
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
index 1ad3f08..5f97b60 100644
--- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
@@ -700,7 +700,7 @@
                                        jmethodID method,
                                        jint* entry_count_ptr,
                                        jvmtiLineNumberEntry** table_ptr) {
-    return ERR(NOT_IMPLEMENTED);
+    return MethodUtil::GetLineNumberTable(env, method, entry_count_ptr, table_ptr);
   }
 
   static jvmtiError GetMethodLocation(jvmtiEnv* env,
diff --git a/runtime/openjdkjvmti/ti_method.cc b/runtime/openjdkjvmti/ti_method.cc
index ffa5ac7..a0a0923 100644
--- a/runtime/openjdkjvmti/ti_method.cc
+++ b/runtime/openjdkjvmti/ti_method.cc
@@ -130,4 +130,63 @@
   return ERR(NONE);
 }
 
+using LineNumberContext = std::vector<jvmtiLineNumberEntry>;
+
+static bool CollectLineNumbers(void* void_context, const art::DexFile::PositionInfo& entry) {
+  LineNumberContext* context = reinterpret_cast<LineNumberContext*>(void_context);
+  jvmtiLineNumberEntry jvmti_entry = { static_cast<jlocation>(entry.address_),
+                                       static_cast<jint>(entry.line_) };
+  context->push_back(jvmti_entry);
+  return false;  // Collect all, no early exit.
+}
+
+jvmtiError MethodUtil::GetLineNumberTable(jvmtiEnv* env,
+                                          jmethodID method,
+                                          jint* entry_count_ptr,
+                                          jvmtiLineNumberEntry** table_ptr) {
+  if (method == nullptr) {
+    return ERR(NULL_POINTER);
+  }
+  art::ArtMethod* art_method = art::jni::DecodeArtMethod(method);
+  DCHECK(!art_method->IsRuntimeMethod());
+
+  const art::DexFile::CodeItem* code_item;
+  const art::DexFile* dex_file;
+  {
+    art::ScopedObjectAccess soa(art::Thread::Current());
+
+    if (art_method->IsProxyMethod()) {
+      return ERR(ABSENT_INFORMATION);
+    }
+    if (art_method->IsNative()) {
+      return ERR(NATIVE_METHOD);
+    }
+    if (entry_count_ptr == nullptr || table_ptr == nullptr) {
+      return ERR(NULL_POINTER);
+    }
+
+    code_item = art_method->GetCodeItem();
+    dex_file = art_method->GetDexFile();
+    DCHECK(code_item != nullptr) << art_method->PrettyMethod() << " " << dex_file->GetLocation();
+  }
+
+  LineNumberContext context;
+  bool success = dex_file->DecodeDebugPositionInfo(code_item, CollectLineNumbers, &context);
+  if (!success) {
+    return ERR(ABSENT_INFORMATION);
+  }
+
+  unsigned char* data;
+  jlong mem_size = context.size() * sizeof(jvmtiLineNumberEntry);
+  jvmtiError alloc_error = env->Allocate(mem_size, &data);
+  if (alloc_error != ERR(NONE)) {
+    return alloc_error;
+  }
+  *table_ptr = reinterpret_cast<jvmtiLineNumberEntry*>(data);
+  memcpy(*table_ptr, context.data(), mem_size);
+  *entry_count_ptr = static_cast<jint>(context.size());
+
+  return ERR(NONE);
+}
+
 }  // namespace openjdkjvmti
diff --git a/runtime/openjdkjvmti/ti_method.h b/runtime/openjdkjvmti/ti_method.h
index 43f11f9..fb2fbb2 100644
--- a/runtime/openjdkjvmti/ti_method.h
+++ b/runtime/openjdkjvmti/ti_method.h
@@ -52,6 +52,11 @@
   static jvmtiError GetMethodModifiers(jvmtiEnv* env,
                                        jmethodID method,
                                        jint* modifiers_ptr);
+
+  static jvmtiError GetLineNumberTable(jvmtiEnv* env,
+                                       jmethodID method,
+                                       jint* entry_count_ptr,
+                                       jvmtiLineNumberEntry** table_ptr);
 };
 
 }  // namespace openjdkjvmti
diff --git a/test/153-reference-stress/expected.txt b/test/153-reference-stress/expected.txt
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/test/153-reference-stress/expected.txt
@@ -0,0 +1 @@
+PASS
diff --git a/test/153-reference-stress/info.txt b/test/153-reference-stress/info.txt
new file mode 100644
index 0000000..6bc0040
--- /dev/null
+++ b/test/153-reference-stress/info.txt
@@ -0,0 +1 @@
+Tests java.lang.ref.Reference.get() and GC running in parallel.
diff --git a/test/153-reference-stress/src/Main.java b/test/153-reference-stress/src/Main.java
new file mode 100644
index 0000000..fc6f9cc
--- /dev/null
+++ b/test/153-reference-stress/src/Main.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.ref.WeakReference;
+
+public class Main {
+    static final int numWeakReferences = 16 * 1024;
+    static WeakReference[] weakReferences = new WeakReference[numWeakReferences];
+    static volatile boolean done = false;
+    static Object keepAlive;
+
+    public static void main(String[] args) throws Exception {
+        // Try to call Reference.get repeatedly while the GC is running.
+        Thread gcThread = new GcThread();
+        Thread[] readerThread = new ReaderThread[4];
+        for (int i = 0; i < readerThread.length; ++i) {
+            readerThread[i] = new ReaderThread();
+        }
+        gcThread.start();
+        for (int i = 0; i < readerThread.length; ++i) {
+            readerThread[i].start();
+        }
+        gcThread.join();
+        for (int i = 0; i < readerThread.length; ++i) {
+            readerThread[i].join();
+        }
+        System.out.println("PASS");
+    }
+
+    static class GcThread extends Thread {
+        GcThread() {
+            Object temp = new Object();
+            for (int j = 0; j < weakReferences.length; ++j) {
+                weakReferences[j] = new WeakReference(temp);
+            }
+        }
+        public void run() {
+            for (int i = 0; i < 1000; ++i) {
+                Object o = new Object();
+                for (int j = 0; j < weakReferences.length; ++j) {
+                    weakReferences[j] = new WeakReference(o);
+                }
+            }
+            done = true;
+        }
+    }
+
+    static class ReaderThread extends Thread {
+        public void run() {
+            while (!done) {
+                for (int j = 0; j < weakReferences.length; ++j) {
+                    keepAlive = weakReferences[j].get();
+                }
+                for (int j = 0; j < weakReferences.length; ++j) {
+                    weakReferences[j].clear();
+                }
+            }
+        }
+    }
+}
diff --git a/test/616-cha-regression-proxy-method/expected.txt b/test/616-cha-regression-proxy-method/expected.txt
new file mode 100644
index 0000000..6a5618e
--- /dev/null
+++ b/test/616-cha-regression-proxy-method/expected.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/616-cha-regression-proxy-method/info.txt b/test/616-cha-regression-proxy-method/info.txt
new file mode 100644
index 0000000..386a07f
--- /dev/null
+++ b/test/616-cha-regression-proxy-method/info.txt
@@ -0,0 +1 @@
+Regression test for Class Hierarchy Analysis (CHA) on visiting proxy method frame.
diff --git a/test/616-cha-regression-proxy-method/src/Main.java b/test/616-cha-regression-proxy-method/src/Main.java
new file mode 100644
index 0000000..19c92be
--- /dev/null
+++ b/test/616-cha-regression-proxy-method/src/Main.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+class Main1 {
+  void foo(int i) {
+    if (i != 1) {
+      printError("error1");
+    }
+  }
+
+  void printError(String msg) {
+    System.out.println(msg);
+  }
+}
+
+class Main2 extends Main1 {
+  void foo(int i) {
+    if (i != 2) {
+      printError("error2");
+    }
+  }
+}
+
+class Proxied implements Runnable {
+  public void run() {
+    synchronized(Main.class) {
+      Main.sOtherThreadStarted = true;
+      // Wait for Main2 to be linked and deoptimization is triggered.
+      try {
+        Main.class.wait();
+      } catch (Exception e) {
+      }
+    }
+  }
+}
+
+class MyInvocationHandler implements InvocationHandler {
+  private final Proxied proxied;
+
+  public MyInvocationHandler(Proxied proxied) {
+    this.proxied = proxied;
+  }
+
+  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+    return method.invoke(proxied, args);
+  }
+}
+
+public class Main {
+  static Main1 sMain1;
+  static Main1 sMain2;
+  static volatile boolean sOtherThreadStarted;
+
+  // sMain1.foo() will be always be Main1.foo() before Main2 is loaded/linked.
+  // So sMain1.foo() can be devirtualized to Main1.foo() and be inlined.
+  // After Dummy.createMain2() which links in Main2, live testOverride() on stack
+  // should be deoptimized.
+  static void testOverride() {
+    sMain1.foo(sMain1.getClass() == Main1.class ? 1 : 2);
+
+    // Wait for the other thread to start.
+    while (!sOtherThreadStarted);
+    // Create an Main2 instance and assign it to sMain2.
+    // sMain1 is kept the same.
+    sMain2 = Dummy.createMain2();
+    // Wake up the other thread.
+    synchronized(Main.class) {
+      Main.class.notify();
+    }
+
+    // There should be a deoptimization here right after Main2 is linked by
+    // calling Dummy.createMain2(), even though sMain1 didn't change.
+    // The behavior here would be different if inline-cache is used, which
+    // doesn't deoptimize since sMain1 still hits the type cache.
+    sMain1.foo(sMain1.getClass() == Main1.class ? 1 : 2);
+    if (sMain2 != null) {
+      sMain2.foo(sMain2.getClass() == Main1.class ? 1 : 2);
+    }
+  }
+
+  // Test scenarios under which CHA-based devirtualization happens,
+  // and class loading that overrides a method can invalidate compiled code.
+  // Also create a proxy method such that a proxy method's frame is visited
+  // during stack walking.
+  public static void main(String[] args) {
+    System.loadLibrary(args[0]);
+    // sMain1 is an instance of Main1. Main2 hasn't bee loaded yet.
+    sMain1 = new Main1();
+
+    // Create another thread that calls a proxy method.
+    new Thread() {
+      public void run() {
+        Runnable proxy = (Runnable)Proxy.newProxyInstance(
+            Proxied.class.getClassLoader(),
+            new Class[] { Runnable.class },
+            new MyInvocationHandler(new Proxied()));
+        proxy.run();
+      }
+    }.start();
+
+    ensureJitCompiled(Main.class, "testOverride");
+    // This will create Main2 instance in the middle of testOverride().
+    testOverride();
+  }
+
+  private static native void ensureJitCompiled(Class<?> itf, String method_name);
+}
+
+// Put createMain2() in another class to avoid class loading due to verifier.
+class Dummy {
+  static Main1 createMain2() {
+    return new Main2();
+  }
+}
diff --git a/test/616-cha/src/Main.java b/test/616-cha/src/Main.java
index 787318d..b617944 100644
--- a/test/616-cha/src/Main.java
+++ b/test/616-cha/src/Main.java
@@ -179,7 +179,7 @@
     }
   }
 
-  // Test scanerios under which CHA-based devirtualization happens,
+  // Test scenarios under which CHA-based devirtualization happens,
   // and class loading that overrides a method can invalidate compiled code.
   // Also test pure non-overriding case, which is more for checking generated
   // code form.
@@ -206,11 +206,6 @@
     // sMain1 is an instance of Main1. Main2 hasn't bee loaded yet.
     sMain1 = new Main1();
 
-    // Loop enough to get testOverride() JITed.
-    for (int i=0; i<100; i++) {
-      testOverride(false, false, false);
-    }
-
     ensureJitCompiled(Main.class, "testOverride");
     testOverride(false, false, true);
 
@@ -244,7 +239,7 @@
   private static native boolean hasSingleImplementation(Class<?> clazz, String method_name);
 }
 
-// Do it in another class to avoid class loading due to verifier.
+// Put createMain2() in another class to avoid class loading due to verifier.
 class Dummy {
   static Main1 createMain2() {
     return new Main2();
diff --git a/test/911-get-stack-trace/expected.txt b/test/911-get-stack-trace/expected.txt
index 77c77ca..f8c97ce 100644
--- a/test/911-get-stack-trace/expected.txt
+++ b/test/911-get-stack-trace/expected.txt
@@ -3,206 +3,206 @@
 ###################
 From top
 ---------
- getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1
- print (Ljava/lang/Thread;II)V 0
- printOrWait (IILMain$ControlData;)V 6
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- doTest ()V 38
- main ([Ljava/lang/String;)V 6
+ getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1 -2
+ print (Ljava/lang/Thread;II)V 0 124
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ doTest ()V 38 34
+ main ([Ljava/lang/String;)V 6 24
 ---------
- print (Ljava/lang/Thread;II)V 0
- printOrWait (IILMain$ControlData;)V 6
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- doTest ()V 42
- main ([Ljava/lang/String;)V 6
+ print (Ljava/lang/Thread;II)V 0 124
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ doTest ()V 42 35
+ main ([Ljava/lang/String;)V 6 24
 ---------
- getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1
- print (Ljava/lang/Thread;II)V 0
- printOrWait (IILMain$ControlData;)V 6
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
+ getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1 -2
+ print (Ljava/lang/Thread;II)V 0 124
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
 ---------
- printOrWait (IILMain$ControlData;)V 6
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
 From bottom
 ---------
- main ([Ljava/lang/String;)V 6
+ main ([Ljava/lang/String;)V 6 24
 ---------
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- doTest ()V 65
- main ([Ljava/lang/String;)V 6
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ doTest ()V 65 41
+ main ([Ljava/lang/String;)V 6 24
 ---------
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
 
 ################################
 ### Other thread (suspended) ###
 ################################
 From top
 ---------
- wait ()V -1
- printOrWait (IILMain$ControlData;)V 24
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
+ wait ()V -1 -2
+ printOrWait (IILMain$ControlData;)V 24 157
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 54
 ---------
- printOrWait (IILMain$ControlData;)V 24
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
+ printOrWait (IILMain$ControlData;)V 24 157
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 54
 ---------
- wait ()V -1
- printOrWait (IILMain$ControlData;)V 24
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
+ wait ()V -1 -2
+ printOrWait (IILMain$ControlData;)V 24 157
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
 ---------
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
 From bottom
 ---------
- run ()V 4
+ run ()V 4 54
 ---------
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 54
 ---------
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
 
 ###########################
 ### Other thread (live) ###
 ###########################
 From top
 ---------
- printOrWait (IILMain$ControlData;)V 44
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
+ printOrWait (IILMain$ControlData;)V 44 164
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 88
 ---------
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 88
 ---------
- printOrWait (IILMain$ControlData;)V 44
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
+ printOrWait (IILMain$ControlData;)V 44 164
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
 ---------
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
 From bottom
 ---------
- run ()V 4
+ run ()V 4 88
 ---------
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 88
 ---------
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
diff --git a/test/911-get-stack-trace/stack_trace.cc b/test/911-get-stack-trace/stack_trace.cc
index b5b5678..9092f2f 100644
--- a/test/911-get-stack-trace/stack_trace.cc
+++ b/test/911-get-stack-trace/stack_trace.cc
@@ -32,6 +32,23 @@
 namespace art {
 namespace Test911GetStackTrace {
 
+static jint FindLineNumber(jint line_number_count,
+                           jvmtiLineNumberEntry* line_number_table,
+                           jlocation location) {
+  if (line_number_table == nullptr) {
+    return -2;
+  }
+
+  jint line_number = -1;
+  for (jint i = 0; i != line_number_count; ++i) {
+    if (line_number_table[i].start_location > location) {
+      return line_number;
+    }
+    line_number = line_number_table[i].line_number;
+  }
+  return line_number;
+}
+
 extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace(
     JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jthread thread, jint start, jint max) {
   std::unique_ptr<jvmtiFrameInfo[]> frames(new jvmtiFrameInfo[max]);
@@ -61,6 +78,26 @@
       }
     }
 
+    jint line_number_count;
+    jvmtiLineNumberEntry* line_number_table;
+    {
+      jvmtiError line_result = jvmti_env->GetLineNumberTable(frames[method_index].method,
+                                                             &line_number_count,
+                                                             &line_number_table);
+      if (line_result != JVMTI_ERROR_NONE) {
+        // Accept absent info and native method errors.
+        if (line_result != JVMTI_ERROR_ABSENT_INFORMATION &&
+            line_result != JVMTI_ERROR_NATIVE_METHOD) {
+          char* err;
+          jvmti_env->GetErrorName(line_result, &err);
+          printf("Failure running GetLineNumberTable: %s\n", err);
+          return nullptr;
+        }
+        line_number_table = nullptr;
+        line_number_count = 0;
+      }
+    }
+
     auto inner_callback = [&](jint component_index) -> jstring {
       switch (component_index) {
         case 0:
@@ -69,11 +106,17 @@
           return (sig == nullptr) ? nullptr : env->NewStringUTF(sig);
         case 2:
           return env->NewStringUTF(StringPrintf("%" PRId64, frames[method_index].location).c_str());
+        case 3: {
+          jint line_number = FindLineNumber(line_number_count,
+                                            line_number_table,
+                                            frames[method_index].location);
+          return env->NewStringUTF(StringPrintf("%d", line_number).c_str());
+        }
       }
       LOG(FATAL) << "Unreachable";
       UNREACHABLE();
     };
-    jobjectArray inner_array = CreateObjectArray(env, 3, "java/lang/String", inner_callback);
+    jobjectArray inner_array = CreateObjectArray(env, 4, "java/lang/String", inner_callback);
 
     if (name != nullptr) {
       jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(name));
@@ -84,6 +127,9 @@
     if (gen != nullptr) {
       jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(gen));
     }
+    if (line_number_table != nullptr) {
+      jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(line_number_table));
+    }
 
     return inner_array;
   };
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index b515130..c02999b 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -492,6 +492,24 @@
       $(PICTEST_TYPES),$(DEBUGGABLE_TYPES), $(TEST_ART_BROKEN_TRACING_RUN_TESTS),$(ALL_ADDRESS_SIZES))
 endif
 
+TEST_ART_BROKEN_TRACING_RUN_TESTS :=
+
+# These tests expect JIT compilation, which is suppressed when tracing.
+TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS := \
+  604-hot-static-interface \
+  612-jit-dex-cache \
+  613-inlining-dex-cache \
+  616-cha \
+  626-set-resolved-string \
+
+ifneq (,$(filter trace stream,$(TRACE_TYPES)))
+  ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
+      jit,$(RELOCATE_TYPES),trace stream,$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \
+      $(PICTEST_TYPES),$(DEBUGGABLE_TYPES), $(TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+endif
+
+TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS :=
+
 # Known broken tests for the interpreter.
 # CFI unwinding expects managed frames.
 # 629 requires compilation.