Merge "Fix valgrind heap_test."
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index 2ec2b0c..13dcb8c 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -46,7 +46,6 @@
 Mutex* Locks::jni_libraries_lock_ = nullptr;
 Mutex* Locks::logging_lock_ = nullptr;
 Mutex* Locks::mem_maps_lock_ = nullptr;
-Mutex* Locks::method_verifiers_lock_ = nullptr;
 Mutex* Locks::modify_ldt_lock_ = nullptr;
 ReaderWriterMutex* Locks::mutator_lock_ = nullptr;
 Mutex* Locks::profiler_lock_ = nullptr;
@@ -1002,10 +1001,6 @@
     classlinker_classes_lock_ = new ReaderWriterMutex("ClassLinker classes lock",
                                                       current_lock_level);
 
-    UPDATE_CURRENT_LOCK_LEVEL(kMethodVerifiersLock);
-    DCHECK(method_verifiers_lock_ == nullptr);
-    method_verifiers_lock_ = new Mutex("Method verifiers lock", current_lock_level);
-
     UPDATE_CURRENT_LOCK_LEVEL(kMonitorPoolLock);
     DCHECK(allocated_monitor_ids_lock_ == nullptr);
     allocated_monitor_ids_lock_ =  new Mutex("allocated monitor ids lock", current_lock_level);
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index f9e1e62..6e7b04f 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -588,11 +588,9 @@
   // Guards lists of classes within the class linker.
   static ReaderWriterMutex* classlinker_classes_lock_ ACQUIRED_AFTER(breakpoint_lock_);
 
-  static Mutex* method_verifiers_lock_ ACQUIRED_AFTER(classlinker_classes_lock_);
-
   // When declaring any Mutex add DEFAULT_MUTEX_ACQUIRED_AFTER to use annotalysis to check the code
   // doesn't try to hold a higher level Mutex.
-  #define DEFAULT_MUTEX_ACQUIRED_AFTER ACQUIRED_AFTER(Locks::method_verifiers_lock_)
+  #define DEFAULT_MUTEX_ACQUIRED_AFTER ACQUIRED_AFTER(Locks::classlinker_classes_lock_)
 
   static Mutex* allocated_monitor_ids_lock_ ACQUIRED_AFTER(classlinker_classes_lock_);
 
diff --git a/runtime/entrypoints_order_test.cc b/runtime/entrypoints_order_test.cc
index 0fdfcb3..88209a3 100644
--- a/runtime/entrypoints_order_test.cc
+++ b/runtime/entrypoints_order_test.cc
@@ -129,7 +129,8 @@
     EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, held_mutexes, nested_signal_state,
                         sizeof(void*) * kLockLevelCount);
     EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, nested_signal_state, flip_function, sizeof(void*));
-    EXPECT_OFFSET_DIFF(Thread, tlsPtr_.flip_function, Thread, wait_mutex_, sizeof(void*),
+    EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, flip_function, method_verifier, sizeof(void*));
+    EXPECT_OFFSET_DIFF(Thread, tlsPtr_.method_verifier, Thread, wait_mutex_, sizeof(void*),
                        thread_tlsptr_end);
   }
 
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index a2f1481..189559e 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1331,12 +1331,6 @@
     callee_save_methods_[i].VisitRootIfNonNull(callback, arg, RootInfo(kRootVMInternal));
   }
   verifier::MethodVerifier::VisitStaticRoots(callback, arg);
-  {
-    MutexLock mu(Thread::Current(), *Locks::method_verifiers_lock_);
-    for (verifier::MethodVerifier* verifier : method_verifiers_) {
-      verifier->VisitRoots(callback, arg);
-    }
-  }
   VisitTransactionRoots(callback, arg);
   instrumentation_.VisitRoots(callback, arg);
 }
@@ -1508,26 +1502,6 @@
   compile_time_class_paths_.Put(class_loader, class_path);
 }
 
-void Runtime::AddMethodVerifier(verifier::MethodVerifier* verifier) {
-  DCHECK(verifier != nullptr);
-  if (gAborting) {
-    return;
-  }
-  MutexLock mu(Thread::Current(), *Locks::method_verifiers_lock_);
-  method_verifiers_.insert(verifier);
-}
-
-void Runtime::RemoveMethodVerifier(verifier::MethodVerifier* verifier) {
-  DCHECK(verifier != nullptr);
-  if (gAborting) {
-    return;
-  }
-  MutexLock mu(Thread::Current(), *Locks::method_verifiers_lock_);
-  auto it = method_verifiers_.find(verifier);
-  CHECK(it != method_verifiers_.end());
-  method_verifiers_.erase(it);
-}
-
 void Runtime::StartProfiler(const char* profile_output_filename) {
   profile_output_filename_ = profile_output_filename;
   profiler_started_ =
diff --git a/runtime/runtime.h b/runtime/runtime.h
index d54972c..3cf22bf 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -456,11 +456,6 @@
     return use_compile_time_class_path_;
   }
 
-  void AddMethodVerifier(verifier::MethodVerifier* verifier)
-      LOCKS_EXCLUDED(Locks::method_verifiers_lock_);
-  void RemoveMethodVerifier(verifier::MethodVerifier* verifier)
-      LOCKS_EXCLUDED(Locks::method_verifiers_lock_);
-
   const std::vector<const DexFile*>& GetCompileTimeClassPath(jobject class_loader);
 
   // The caller is responsible for ensuring the class_path DexFiles remain
@@ -642,9 +637,6 @@
   Mutex fault_message_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
   std::string fault_message_ GUARDED_BY(fault_message_lock_);
 
-  // Method verifier set, used so that we can update their GC roots.
-  std::set<verifier::MethodVerifier*> method_verifiers_ GUARDED_BY(Locks::method_verifiers_lock_);
-
   // A non-zero value indicates that a thread has been created but not yet initialized. Guarded by
   // the shutdown lock so that threads aren't born while we're shutting down.
   size_t threads_being_born_ GUARDED_BY(Locks::runtime_shutdown_lock_);
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 8e98d53..affb6cd 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -70,6 +70,7 @@
 #include "thread-inl.h"
 #include "utils.h"
 #include "verifier/dex_gc_map.h"
+#include "verifier/method_verifier.h"
 #include "verify_object-inl.h"
 #include "vmap_table.h"
 #include "well_known_classes.h"
@@ -2296,6 +2297,9 @@
       mapper.VisitShadowFrame(shadow_frame);
     }
   }
+  if (tlsPtr_.method_verifier != nullptr) {
+    tlsPtr_.method_verifier->VisitRoots(visitor, arg, RootInfo(kRootNativeStack, thread_id));
+  }
   // Visit roots on this thread's stack
   Context* context = GetLongJumpContext();
   RootCallbackVisitor visitor_to_callback(visitor, arg, thread_id);
@@ -2417,4 +2421,14 @@
   tlsPtr_.debug_invoke_req = nullptr;
 }
 
+void Thread::SetVerifier(verifier::MethodVerifier* verifier) {
+  CHECK(tlsPtr_.method_verifier == nullptr);
+  tlsPtr_.method_verifier = verifier;
+}
+
+void Thread::ClearVerifier(verifier::MethodVerifier* verifier) {
+  CHECK_EQ(tlsPtr_.method_verifier, verifier);
+  tlsPtr_.method_verifier = nullptr;
+}
+
 }  // namespace art
diff --git a/runtime/thread.h b/runtime/thread.h
index 2e9ae3c..da7af83 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -62,6 +62,11 @@
   class StackTraceElement;
   class Throwable;
 }  // namespace mirror
+
+namespace verifier {
+class MethodVerifier;
+}  // namespace verifier
+
 class BaseMutex;
 class ClassLinker;
 class Closure;
@@ -875,6 +880,9 @@
     return tls32_.suspended_at_suspend_check;
   }
 
+  void SetVerifier(verifier::MethodVerifier* verifier);
+  void ClearVerifier(verifier::MethodVerifier* verifier);
+
  private:
   explicit Thread(bool daemon);
   ~Thread() LOCKS_EXCLUDED(Locks::mutator_lock_,
@@ -1055,10 +1063,8 @@
       pthread_self(0), last_no_thread_suspension_cause(nullptr), thread_local_start(nullptr),
       thread_local_pos(nullptr), thread_local_end(nullptr), thread_local_objects(0),
       thread_local_alloc_stack_top(nullptr), thread_local_alloc_stack_end(nullptr),
-      nested_signal_state(nullptr), flip_function(nullptr) {
-        for (size_t i = 0; i < kLockLevelCount; ++i) {
-          held_mutexes[i] = nullptr;
-        }
+      nested_signal_state(nullptr), flip_function(nullptr), method_verifier(nullptr) {
+      std::fill(held_mutexes, held_mutexes + kLockLevelCount, nullptr);
     }
 
     // The biased card table, see CardTable for details.
@@ -1172,6 +1178,9 @@
 
     // The function used for thread flip.
     Closure* flip_function;
+
+    // Current method verifier, used for root marking.
+    verifier::MethodVerifier* method_verifier;
   } tlsPtr_;
 
   // Guards the 'interrupted_' and 'wait_monitor_' members.
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index b3f686d..9ceb6f4 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -395,12 +395,12 @@
       has_virtual_or_interface_invokes_(false),
       verify_to_dump_(verify_to_dump),
       allow_thread_suspension_(allow_thread_suspension) {
-  Runtime::Current()->AddMethodVerifier(this);
+  self->SetVerifier(this);
   DCHECK(class_def != nullptr);
 }
 
 MethodVerifier::~MethodVerifier() {
-  Runtime::Current()->RemoveMethodVerifier(this);
+  Thread::Current()->ClearVerifier(this);
   STLDeleteElements(&failure_messages_);
 }
 
@@ -4334,8 +4334,8 @@
   RegTypeCache::VisitStaticRoots(callback, arg);
 }
 
-void MethodVerifier::VisitRoots(RootCallback* callback, void* arg) {
-  reg_types_.VisitRoots(callback, arg);
+void MethodVerifier::VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info) {
+  reg_types_.VisitRoots(callback, arg, root_info);
 }
 
 }  // namespace verifier
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index d7c2071..6b813ef 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -227,7 +227,8 @@
 
   static void VisitStaticRoots(RootCallback* callback, void* arg)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void VisitRoots(RootCallback* callback, void* arg, const RootInfo& roots)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Accessors used by the compiler via CompilerCallback
   const DexFile::CodeItem* CodeItem() const;
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index 3510665..201169f 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -778,8 +778,8 @@
   }
 }
 
-void RegType::VisitRoots(RootCallback* callback, void* arg) const {
-  klass_.VisitRootIfNonNull(callback, arg, RootInfo(kRootUnknown));
+void RegType::VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info) const {
+  klass_.VisitRootIfNonNull(callback, arg, root_info);
 }
 
 void UninitializedThisReferenceType::CheckInvariants() const {
diff --git a/runtime/verifier/reg_type.h b/runtime/verifier/reg_type.h
index 05958b5..73e131e 100644
--- a/runtime/verifier/reg_type.h
+++ b/runtime/verifier/reg_type.h
@@ -250,7 +250,7 @@
 
   virtual ~RegType() {}
 
-  void VisitRoots(RootCallback* callback, void* arg) const
+  void VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info) const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
  protected:
diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc
index 22696c7..6e57857 100644
--- a/runtime/verifier/reg_type_cache.cc
+++ b/runtime/verifier/reg_type_cache.cc
@@ -238,9 +238,7 @@
   }
 }
 
-RegTypeCache::RegTypeCache(bool can_load_classes)
-    : entries_lock_("entries lock"),
-      can_load_classes_(can_load_classes) {
+RegTypeCache::RegTypeCache(bool can_load_classes) : can_load_classes_(can_load_classes) {
   if (kIsDebugBuild) {
     Thread::Current()->AssertThreadSuspensionIsAllowable(gAborting == 0);
   }
@@ -563,35 +561,33 @@
   // Visit the primitive types, this is required since if there are no active verifiers they wont
   // be in the entries array, and therefore not visited as roots.
   if (primitive_initialized_) {
-    UndefinedType::GetInstance()->VisitRoots(callback, arg);
-    ConflictType::GetInstance()->VisitRoots(callback, arg);
-    BooleanType::GetInstance()->VisitRoots(callback, arg);
-    ByteType::GetInstance()->VisitRoots(callback, arg);
-    ShortType::GetInstance()->VisitRoots(callback, arg);
-    CharType::GetInstance()->VisitRoots(callback, arg);
-    IntegerType::GetInstance()->VisitRoots(callback, arg);
-    LongLoType::GetInstance()->VisitRoots(callback, arg);
-    LongHiType::GetInstance()->VisitRoots(callback, arg);
-    FloatType::GetInstance()->VisitRoots(callback, arg);
-    DoubleLoType::GetInstance()->VisitRoots(callback, arg);
-    DoubleHiType::GetInstance()->VisitRoots(callback, arg);
+    RootInfo ri(kRootUnknown);
+    UndefinedType::GetInstance()->VisitRoots(callback, arg, ri);
+    ConflictType::GetInstance()->VisitRoots(callback, arg, ri);
+    BooleanType::GetInstance()->VisitRoots(callback, arg, ri);
+    ByteType::GetInstance()->VisitRoots(callback, arg, ri);
+    ShortType::GetInstance()->VisitRoots(callback, arg, ri);
+    CharType::GetInstance()->VisitRoots(callback, arg, ri);
+    IntegerType::GetInstance()->VisitRoots(callback, arg, ri);
+    LongLoType::GetInstance()->VisitRoots(callback, arg, ri);
+    LongHiType::GetInstance()->VisitRoots(callback, arg, ri);
+    FloatType::GetInstance()->VisitRoots(callback, arg, ri);
+    DoubleLoType::GetInstance()->VisitRoots(callback, arg, ri);
+    DoubleHiType::GetInstance()->VisitRoots(callback, arg, ri);
     for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) {
-      small_precise_constants_[value - kMinSmallConstant]->VisitRoots(callback, arg);
+      small_precise_constants_[value - kMinSmallConstant]->VisitRoots(callback, arg, ri);
     }
   }
 }
 
-void RegTypeCache::VisitRoots(RootCallback* callback, void* arg) {
-  MutexLock mu(Thread::Current(), entries_lock_);
+void RegTypeCache::VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info) {
   // Exclude the static roots that are visited by VisitStaticRoots().
   for (size_t i = primitive_count_; i < entries_.size(); ++i) {
-    entries_[i]->VisitRoots(callback, arg);
+    entries_[i]->VisitRoots(callback, arg, root_info);
   }
 }
 
 void RegTypeCache::AddEntry(RegType* new_entry) {
-  // TODO: There is probably a faster way to do this by using thread local roots.
-  MutexLock mu(Thread::Current(), entries_lock_);
   entries_.push_back(new_entry);
 }
 
diff --git a/runtime/verifier/reg_type_cache.h b/runtime/verifier/reg_type_cache.h
index 4b56fd6..01032a0 100644
--- a/runtime/verifier/reg_type_cache.h
+++ b/runtime/verifier/reg_type_cache.h
@@ -137,7 +137,8 @@
   void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const RegType& RegTypeFromPrimitiveType(Primitive::Type) const;
 
-  void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static void VisitStaticRoots(RootCallback* callback, void* arg)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
@@ -171,9 +172,6 @@
   // Number of well known primitives that will be copied into a RegTypeCache upon construction.
   static uint16_t primitive_count_;
 
-  // Guards adding and visitng roots to prevent race conditions.
-  Mutex entries_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
-
   // The actual storage for the RegTypes.
   std::vector<const RegType*> entries_;