Change method verifiers to be thread local roots

Bug: 10921004

Change-Id: I3a1425d76cd380587ba67ef6d5ec1227564e55bf
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_;