Merge "ART: Support MIRGraph constant interface"
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index edfd57f..574b6ea 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -274,7 +274,7 @@
  */
 BasicBlock* MIRGraph::FindBlock(DexOffset code_offset, bool split, bool create,
                                 BasicBlock** immed_pred_block_p) {
-  if (code_offset >= cu_->code_item->insns_size_in_code_units_) {
+  if (code_offset >= current_code_item_->insns_size_in_code_units_) {
     return NULL;
   }
 
@@ -348,10 +348,10 @@
   // (We don't want to ignore all monitor-exit catches since one could enclose a synchronized
   // block in a try-block and catch the NPE, Error or Throwable and we should let it through;
   // even though a throwing monitor-exit certainly indicates a bytecode error.)
-  const Instruction* monitor_exit = Instruction::At(cu_->code_item->insns_ + monitor_exit_offset);
+  const Instruction* monitor_exit = Instruction::At(current_code_item_->insns_ + monitor_exit_offset);
   DCHECK(monitor_exit->Opcode() == Instruction::MONITOR_EXIT);
   int monitor_reg = monitor_exit->VRegA_11x();
-  const Instruction* check_insn = Instruction::At(cu_->code_item->insns_ + catch_offset);
+  const Instruction* check_insn = Instruction::At(current_code_item_->insns_ + catch_offset);
   DCHECK(check_insn->Opcode() == Instruction::MOVE_EXCEPTION);
   if (check_insn->VRegA_11x() == monitor_reg) {
     // Unexpected move-exception to the same register. Probably not the pattern we're looking for.
@@ -1228,8 +1228,6 @@
   bool nop = false;
   SSARepresentation* ssa_rep = mir->ssa_rep;
   Instruction::Format dalvik_format = Instruction::k10x;  // Default to no-operand format.
-  int defs = (ssa_rep != NULL) ? ssa_rep->num_defs : 0;
-  int uses = (ssa_rep != NULL) ? ssa_rep->num_uses : 0;
 
   // Handle special cases.
   if ((opcode == kMirOpCheck) || (opcode == kMirOpCheckPart2)) {
@@ -1238,8 +1236,6 @@
     // Recover the original Dex instruction.
     insn = mir->meta.throw_insn->dalvikInsn;
     ssa_rep = mir->meta.throw_insn->ssa_rep;
-    defs = ssa_rep->num_defs;
-    uses = ssa_rep->num_uses;
     opcode = insn.opcode;
   } else if (opcode == kMirOpNop) {
     str.append("[");
@@ -1248,6 +1244,8 @@
     opcode = insn.opcode;
     nop = true;
   }
+  int defs = (ssa_rep != NULL) ? ssa_rep->num_defs : 0;
+  int uses = (ssa_rep != NULL) ? ssa_rep->num_uses : 0;
 
   if (MIR::DecodedInstruction::IsPseudoMirOp(opcode)) {
     str.append(extended_mir_op_names_[opcode - kMirOpFirst]);
@@ -1259,40 +1257,21 @@
 
   if (opcode == kMirOpPhi) {
     BasicBlockId* incoming = mir->meta.phi_incoming;
-    str.append(StringPrintf(" %s = (%s",
-               GetSSANameWithConst(ssa_rep->defs[0], true).c_str(),
-               GetSSANameWithConst(ssa_rep->uses[0], true).c_str()));
-    str.append(StringPrintf(":%d", incoming[0]));
-    int i;
-    for (i = 1; i < uses; i++) {
-      str.append(StringPrintf(", %s:%d",
-                              GetSSANameWithConst(ssa_rep->uses[i], true).c_str(),
-                              incoming[i]));
+    if (defs > 0 && uses > 0) {
+      str.append(StringPrintf(" %s = (%s",
+                 GetSSANameWithConst(ssa_rep->defs[0], true).c_str(),
+                 GetSSANameWithConst(ssa_rep->uses[0], true).c_str()));
+      str.append(StringPrintf(":%d", incoming[0]));
+      int i;
+      for (i = 1; i < uses; i++) {
+        str.append(StringPrintf(", %s:%d",
+                                GetSSANameWithConst(ssa_rep->uses[i], true).c_str(),
+                                incoming[i]));
+      }
+      str.append(")");
+    } else {
+      str.append(StringPrintf(" v%d", mir->dalvikInsn.vA));
     }
-    str.append(")");
-  } else if ((flags & Instruction::kBranch) != 0) {
-    // For branches, decode the instructions to print out the branch targets.
-    int offset = 0;
-    switch (dalvik_format) {
-      case Instruction::k21t:
-        str.append(StringPrintf(" %s,", GetSSANameWithConst(ssa_rep->uses[0], false).c_str()));
-        offset = insn.vB;
-        break;
-      case Instruction::k22t:
-        str.append(StringPrintf(" %s, %s,", GetSSANameWithConst(ssa_rep->uses[0], false).c_str(),
-                   GetSSANameWithConst(ssa_rep->uses[1], false).c_str()));
-        offset = insn.vC;
-        break;
-      case Instruction::k10t:
-      case Instruction::k20t:
-      case Instruction::k30t:
-        offset = insn.vA;
-        break;
-      default:
-        LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode;
-    }
-    str.append(StringPrintf(" 0x%x (%c%x)", mir->offset + offset,
-                            offset > 0 ? '+' : '-', offset > 0 ? offset : -offset));
   } else {
     // For invokes-style formats, treat wide regs as a pair of singles.
     bool show_singles = ((dalvik_format == Instruction::k35c) ||
@@ -1339,6 +1318,27 @@
         // Nothing left to print.
       }
     }
+    if ((flags & Instruction::kBranch) != 0) {
+      // For branches, decode the instructions to print out the branch targets.
+      int offset = 0;
+      switch (dalvik_format) {
+        case Instruction::k21t:
+          offset = insn.vB;
+          break;
+        case Instruction::k22t:
+          offset = insn.vC;
+          break;
+        case Instruction::k10t:
+        case Instruction::k20t:
+        case Instruction::k30t:
+          offset = insn.vA;
+          break;
+        default:
+          LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode;
+      }
+      str.append(StringPrintf(" 0x%x (%c%x)", mir->offset + offset,
+                              offset > 0 ? '+' : '-', offset > 0 ? offset : -offset));
+    }
   }
   if (nop) {
     str.append("]--optimized away");
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 75bc49b..2114ada 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -427,12 +427,13 @@
       Runtime* runtime = Runtime::Current();
       if (runtime != nullptr) {
         ScopedObjectAccess soa(Thread::Current());
-        StackHandleScope<1> hs(soa.Self());
+        StackHandleScope<2> hs(soa.Self());
         Handle<mirror::DexCache> dex_cache(
             hs.NewHandle(runtime->GetClassLinker()->FindDexCache(dex_file)));
         NullHandle<mirror::ClassLoader> class_loader;
+        Handle<mirror::ArtMethod> method(hs.NewHandle<mirror::ArtMethod>(nullptr));
         verifier::MethodVerifier verifier(&dex_file, &dex_cache, &class_loader, &class_def,
-                                          code_item, dex_method_idx, nullptr, method_access_flags,
+                                          code_item, dex_method_idx, method, method_access_flags,
                                           true, true, true);
         verifier.Verify();
         DumpCode(*indent2_os, &verifier, oat_method, code_item);
@@ -698,12 +699,13 @@
                     uint32_t method_access_flags) {
     if ((method_access_flags & kAccNative) == 0) {
       ScopedObjectAccess soa(Thread::Current());
-      StackHandleScope<2> hs(soa.Self());
+      StackHandleScope<3> hs(soa.Self());
       Handle<mirror::DexCache> dex_cache(
           hs.NewHandle(Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file)));
       auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
+      Handle<mirror::ArtMethod> method(hs.NewHandle<mirror::ArtMethod>(nullptr));
       verifier::MethodVerifier::VerifyMethodAndDump(os, dex_method_idx, dex_file, dex_cache,
-                                                    class_loader, &class_def, code_item, nullptr,
+                                                    class_loader, &class_def, code_item, method,
                                                     method_access_flags);
     }
   }
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 6d2f21e..5b00a37 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -3031,12 +3031,13 @@
     // should never be null. We could just check we never encounter this case.
     return false;
   }
-  StackHandleScope<2> hs(self);
+  StackHandleScope<3> hs(self);
   mirror::Class* declaring_class = m->GetDeclaringClass();
   Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+  Handle<mirror::ArtMethod> method(hs.NewHandle(m));
   verifier::MethodVerifier verifier(dex_cache->GetDexFile(), &dex_cache, &class_loader,
-                                    &m->GetClassDef(), code_item, m->GetDexMethodIndex(), m,
+                                    &m->GetClassDef(), code_item, m->GetDexMethodIndex(), method,
                                     m->GetAccessFlags(), false, true, false);
   // Note: we don't need to verify the method.
   return InlineMethodAnalyser::AnalyseMethodCode(&verifier, nullptr);
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index f0b7685..1e01164 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -224,7 +224,7 @@
                                      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
   */
   bool support_homogeneous_space_compaction =
-      background_collector_type == gc::kCollectorTypeHomogeneousSpaceCompact ||
+      background_collector_type_ == gc::kCollectorTypeHomogeneousSpaceCompact ||
       use_homogeneous_space_compaction_for_oom;
   // We may use the same space the main space for the non moving space if we don't need to compact
   // from the main space.
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index 5dd16ef..a87d7c1 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -238,7 +238,7 @@
     }
     // Contended.
     const bool log_contention = (lock_profiling_threshold_ != 0);
-    uint64_t wait_start_ms = log_contention ? 0 : MilliTime();
+    uint64_t wait_start_ms = log_contention ? MilliTime() : 0;
     mirror::ArtMethod* owners_method = locking_method_;
     uint32_t owners_dex_pc = locking_dex_pc_;
     // Do this before releasing the lock so that we don't get deflated.
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 26360d7..9757ad9 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -394,10 +394,6 @@
     } else if (option == "-XX:IgnoreMaxFootprint") {
       ignore_max_footprint_ = true;
     } else if (option == "-XX:LowMemoryMode") {
-      if (background_collector_type_ == gc::kCollectorTypeHomogeneousSpaceCompact) {
-        // Use semispace instead of homogenous space compact for low memory mode.
-        background_collector_type_ = gc::kCollectorTypeSS;
-      }
       low_memory_mode_ = true;
       // TODO Might want to turn off must_relocate here.
     } else if (option == "-XX:UseTLAB") {
@@ -613,7 +609,7 @@
         return false;
       }
     } else if (StartsWith(option, "-XX:NativeBridge=")) {
-      if (!ParseStringAfterChar(option, '=', &native_bridge_library_path_)) {
+      if (!ParseStringAfterChar(option, '=', &native_bridge_library_filename_)) {
         return false;
       }
     } else if (StartsWith(option, "-ea") ||
diff --git a/runtime/parsed_options.h b/runtime/parsed_options.h
index 1afd610..5c71f98 100644
--- a/runtime/parsed_options.h
+++ b/runtime/parsed_options.h
@@ -46,7 +46,7 @@
   bool check_jni_;
   bool force_copy_;
   std::string jni_trace_;
-  std::string native_bridge_library_path_;
+  std::string native_bridge_library_filename_;
   CompilerCallbacks* compiler_callbacks_;
   bool is_zygote_;
   bool must_relocate_;
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 98eeda7..1e933a2 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -206,12 +206,13 @@
     const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
     uint32_t new_dex_pc = dex_pc + inst->SizeInCodeUnits();
     ShadowFrame* new_frame = ShadowFrame::Create(num_regs, nullptr, m, new_dex_pc);
-    StackHandleScope<2> hs(self_);
+    StackHandleScope<3> hs(self_);
     mirror::Class* declaring_class = m->GetDeclaringClass();
     Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
     Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+    Handle<mirror::ArtMethod> h_method(hs.NewHandle(m));
     verifier::MethodVerifier verifier(h_dex_cache->GetDexFile(), &h_dex_cache, &h_class_loader,
-                                      &m->GetClassDef(), code_item, m->GetDexMethodIndex(), m,
+                                      &m->GetClassDef(), code_item, m->GetDexMethodIndex(), h_method,
                                       m->GetAccessFlags(), false, true, true);
     verifier.Verify();
     const std::vector<int32_t> kinds(verifier.DescribeVRegs(dex_pc));
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index ee8cbe1..84df444 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -712,11 +712,12 @@
   self->ClearException();
 
   // Look for a native bridge.
-  native_bridge_library_path_ = options->native_bridge_library_path_;
-  if (!native_bridge_library_path_.empty()) {
-    android::SetupNativeBridge(native_bridge_library_path_.c_str(), &native_bridge_art_callbacks_);
-    VLOG(startup) << "Runtime::Setup native bridge library: " << native_bridge_library_path_;
-  }
+  native_bridge_library_filename_ = options->native_bridge_library_filename_;
+  android::SetupNativeBridge(native_bridge_library_filename_.c_str(), &native_bridge_art_callbacks_);
+  VLOG(startup) << "Runtime::Setup native bridge library: "
+                << (native_bridge_library_filename_.empty() ?
+                    "(empty)" : native_bridge_library_filename_);
+
   VLOG(startup) << "Runtime::Init exiting";
   return true;
 }
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 34ccdcb..259691a 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -617,13 +617,14 @@
   bool implicit_so_checks_;         // StackOverflow checks are implicit.
   bool implicit_suspend_checks_;    // Thread suspension checks are implicit.
 
-  // The path to the native bridge library. If this is not empty the native bridge will be
-  // initialized and loaded from the pointed path.
+  // The filename to the native bridge library. If this is not empty the native bridge will be
+  // initialized and loaded from the given file (initialized and available). An empty value means
+  // that there's no native bridge (initialized but not available).
   //
   // The native bridge allows running native code compiled for a foreign ISA. The way it works is,
   // if standard dlopen fails to load native library associated with native activity, it calls to
   // the native bridge to load it and then gets the trampoline for the entry to native activity.
-  std::string native_bridge_library_path_;
+  std::string native_bridge_library_filename_;
 
   // Native bridge library runtime callbacks. They represent the runtime interface to native bridge.
   //
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 69627f5..6019453 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -138,6 +138,7 @@
   while (it.HasNextStaticField() || it.HasNextInstanceField()) {
     it.Next();
   }
+  Thread* self = Thread::Current();
   size_t error_count = 0;
   bool hard_fail = false;
   ClassLinker* linker = Runtime::Current()->GetClassLinker();
@@ -156,17 +157,19 @@
         linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
                               NullHandle<mirror::ArtMethod>(), type);
     if (method == NULL) {
-      DCHECK(Thread::Current()->IsExceptionPending());
+      DCHECK(self->IsExceptionPending());
       // We couldn't resolve the method, but continue regardless.
-      Thread::Current()->ClearException();
+      self->ClearException();
     }
+    StackHandleScope<1> hs(self);
+    Handle<mirror::ArtMethod> h_method(hs.NewHandle(method));
     MethodVerifier::FailureKind result = VerifyMethod(method_idx,
                                                       dex_file,
                                                       dex_cache,
                                                       class_loader,
                                                       class_def,
                                                       it.GetMethodCodeItem(),
-                                                      method,
+                                                      h_method,
                                                       it.GetMemberAccessFlags(),
                                                       allow_soft_failures,
                                                       false);
@@ -200,17 +203,19 @@
         linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
                               NullHandle<mirror::ArtMethod>(), type);
     if (method == NULL) {
-      DCHECK(Thread::Current()->IsExceptionPending());
+      DCHECK(self->IsExceptionPending());
       // We couldn't resolve the method, but continue regardless.
-      Thread::Current()->ClearException();
+      self->ClearException();
     }
+    StackHandleScope<1> hs(self);
+    Handle<mirror::ArtMethod> h_method(hs.NewHandle(method));
     MethodVerifier::FailureKind result = VerifyMethod(method_idx,
                                                       dex_file,
                                                       dex_cache,
                                                       class_loader,
                                                       class_def,
                                                       it.GetMethodCodeItem(),
-                                                      method,
+                                                      h_method,
                                                       it.GetMemberAccessFlags(),
                                                       allow_soft_failures,
                                                       false);
@@ -242,7 +247,7 @@
                                                          Handle<mirror::ClassLoader> class_loader,
                                                          const DexFile::ClassDef* class_def,
                                                          const DexFile::CodeItem* code_item,
-                                                         mirror::ArtMethod* method,
+                                                         Handle<mirror::ArtMethod> method,
                                                          uint32_t method_access_flags,
                                                          bool allow_soft_failures,
                                                          bool need_precise_constants) {
@@ -250,8 +255,8 @@
   uint64_t start_ns = NanoTime();
 
   MethodVerifier verifier(dex_file, &dex_cache, &class_loader, class_def, code_item,
-                           method_idx, method, method_access_flags, true, allow_soft_failures,
-                           need_precise_constants);
+                          method_idx, method, method_access_flags, true, allow_soft_failures,
+                          need_precise_constants);
   if (verifier.Verify()) {
     // Verification completed, however failures may be pending that didn't cause the verification
     // to hard fail.
@@ -289,7 +294,7 @@
                                          Handle<mirror::ClassLoader> class_loader,
                                          const DexFile::ClassDef* class_def,
                                          const DexFile::CodeItem* code_item,
-                                         mirror::ArtMethod* method,
+                                         Handle<mirror::ArtMethod> method,
                                          uint32_t method_access_flags) {
   MethodVerifier verifier(dex_file, &dex_cache, &class_loader, class_def, code_item,
                           dex_method_idx, method, method_access_flags, true, true, true);
@@ -303,7 +308,7 @@
                                Handle<mirror::ClassLoader>* class_loader,
                                const DexFile::ClassDef* class_def,
                                const DexFile::CodeItem* code_item, uint32_t dex_method_idx,
-                               mirror::ArtMethod* method, uint32_t method_access_flags,
+                               Handle<mirror::ArtMethod> method, uint32_t method_access_flags,
                                bool can_load_classes, bool allow_soft_failures,
                                bool need_precise_constants)
     : reg_types_(can_load_classes),
@@ -340,12 +345,13 @@
 
 void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc,
                                       std::vector<uint32_t>* monitor_enter_dex_pcs) {
-  StackHandleScope<2> hs(Thread::Current());
+  StackHandleScope<3> hs(Thread::Current());
   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+  Handle<mirror::ArtMethod> method(hs.NewHandle(m));
   MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
-                          m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false,
-                          true, false);
+                          m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
+                          false, true, false);
   verifier.interesting_dex_pc_ = dex_pc;
   verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs;
   verifier.FindLocksAtDexPc();
@@ -364,12 +370,13 @@
 
 mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
                                                            uint32_t dex_pc) {
-  StackHandleScope<2> hs(Thread::Current());
+  StackHandleScope<3> hs(Thread::Current());
   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+  Handle<mirror::ArtMethod> method(hs.NewHandle(m));
   MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
-                          m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
-                          true, false);
+                          m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
+                          true, true, false);
   return verifier.FindAccessedFieldAtDexPc(dex_pc);
 }
 
@@ -394,12 +401,13 @@
 
 mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(mirror::ArtMethod* m,
                                                             uint32_t dex_pc) {
-  StackHandleScope<2> hs(Thread::Current());
+  StackHandleScope<3> hs(Thread::Current());
   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+  Handle<mirror::ArtMethod> method(hs.NewHandle(m));
   MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
-                          m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
-                          true, false);
+                          m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
+                          true, true, false);
   return verifier.FindInvokedMethodAtDexPc(dex_pc);
 }
 
@@ -3644,6 +3652,11 @@
   } else if (obj_type.IsZero()) {
     // Cannot infer and check type, however, access will cause null pointer exception
     return field;
+  } else if (!obj_type.IsReferenceTypes()) {
+    // Trying to read a field from something that isn't a reference
+    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has "
+                                      << "non-reference type " << obj_type;
+    return NULL;
   } else {
     mirror::Class* klass = field->GetDeclaringClass();
     RegType& field_klass =
@@ -4017,14 +4030,10 @@
 
 RegType& MethodVerifier::GetMethodReturnType() {
   if (return_type_ == nullptr) {
-    if (mirror_method_ != NULL) {
+    if (mirror_method_.Get() != nullptr) {
       Thread* self = Thread::Current();
-      StackHandleScope<1> hs(self);
       mirror::Class* return_type_class;
-      {
-        HandleWrapper<mirror::ArtMethod> h_mirror_method(hs.NewHandleWrapper(&mirror_method_));
-        return_type_class = MethodHelper(h_mirror_method).GetReturnType(can_load_classes_);
-      }
+      return_type_class = MethodHelper(mirror_method_).GetReturnType(can_load_classes_);
       if (return_type_class != nullptr) {
         return_type_ = &reg_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(),
                                              return_type_class,
@@ -4050,7 +4059,7 @@
     const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
     const char* descriptor
         = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
-    if (mirror_method_ != NULL) {
+    if (mirror_method_.Get() != nullptr) {
       mirror::Class* klass = mirror_method_->GetDeclaringClass();
       declaring_class_ = &reg_types_.FromClass(descriptor, klass,
                                                klass->CannotBeAssignedFromOtherTypes());
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index e63a90c..78cbe06 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -27,6 +27,7 @@
 #include "class_reference.h"
 #include "dex_file.h"
 #include "dex_instruction.h"
+#include "handle.h"
 #include "instruction_flags.h"
 #include "method_reference.h"
 #include "reg_type.h"
@@ -152,7 +153,7 @@
                                   Handle<mirror::ClassLoader> class_loader,
                                   const DexFile::ClassDef* class_def,
                                   const DexFile::CodeItem* code_item,
-                                  mirror::ArtMethod* method, uint32_t method_access_flags)
+                                  Handle<mirror::ArtMethod> method, uint32_t method_access_flags)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   uint8_t EncodePcToReferenceMapData() const;
@@ -203,7 +204,7 @@
 
   MethodVerifier(const DexFile* dex_file, Handle<mirror::DexCache>* dex_cache,
                  Handle<mirror::ClassLoader>* class_loader, const DexFile::ClassDef* class_def,
-                 const DexFile::CodeItem* code_item, uint32_t method_idx, mirror::ArtMethod* method,
+                 const DexFile::CodeItem* code_item, uint32_t method_idx, Handle<mirror::ArtMethod> method,
                  uint32_t access_flags, bool can_load_classes, bool allow_soft_failures,
                  bool need_precise_constants)
           SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -256,7 +257,7 @@
                                   Handle<mirror::ClassLoader> class_loader,
                                   const DexFile::ClassDef* class_def_idx,
                                   const DexFile::CodeItem* code_item,
-                                  mirror::ArtMethod* method, uint32_t method_access_flags,
+                                  Handle<mirror::ArtMethod> method, uint32_t method_access_flags,
                                   bool allow_soft_failures, bool need_precise_constants)
           SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
@@ -639,7 +640,7 @@
 
   const uint32_t dex_method_idx_;  // The method we're working on.
   // Its object representation if known.
-  mirror::ArtMethod* mirror_method_ GUARDED_BY(Locks::mutator_lock_);
+  Handle<mirror::ArtMethod> mirror_method_ GUARDED_BY(Locks::mutator_lock_);
   const uint32_t method_access_flags_;  // Method's access flags.
   RegType* return_type_;  // Lazily computed return type of the method.
   const DexFile* const dex_file_;  // The dex file containing the method.