Merge "Pass current thread as argument to alloc instrumentation."
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index bf1e016..b4a09e5 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1147,6 +1147,7 @@
       callee_save_methods_[i].VisitRoot(callback, arg, 0, kRootVMInternal);
     }
   }
+  verifier::MethodVerifier::VisitStaticRoots(callback, arg);
   {
     MutexLock mu(Thread::Current(), method_verifier_lock_);
     for (verifier::MethodVerifier* verifier : method_verifiers_) {
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index f90da15..b799588 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -4181,6 +4181,10 @@
   verifier::RegTypeCache::ShutDown();
 }
 
+void MethodVerifier::VisitStaticRoots(RootCallback* callback, void* arg) {
+  RegTypeCache::VisitStaticRoots(callback, arg);
+}
+
 void MethodVerifier::VisitRoots(RootCallback* callback, void* arg) {
   reg_types_.VisitRoots(callback, arg);
 }
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 81ab960..eef2b9e 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -221,6 +221,8 @@
   // Describe VRegs at the given dex pc.
   std::vector<int32_t> DescribeVRegs(uint32_t dex_pc);
 
+  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_);
 
   // Accessors used by the compiler via CompilerCallback
diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc
index 121fccb..bffec4b 100644
--- a/runtime/verifier/reg_type_cache.cc
+++ b/runtime/verifier/reg_type_cache.cc
@@ -555,6 +555,28 @@
   }
 }
 
+void RegTypeCache::VisitStaticRoots(RootCallback* callback, void* arg) {
+  // 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);
+    for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) {
+      small_precise_constants_[value - kMinSmallConstant]->VisitRoots(callback, arg);
+    }
+  }
+}
+
 void RegTypeCache::VisitRoots(RootCallback* callback, void* arg) {
   for (const RegType* entry : entries_) {
     entry->VisitRoots(callback, arg);
diff --git a/runtime/verifier/reg_type_cache.h b/runtime/verifier/reg_type_cache.h
index eb17a52..29933cf 100644
--- a/runtime/verifier/reg_type_cache.h
+++ b/runtime/verifier/reg_type_cache.h
@@ -80,34 +80,34 @@
   const BooleanType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *BooleanType::GetInstance();
   }
-  const ByteType& Byte() {
+  const RegType& Byte() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *ByteType::GetInstance();
   }
-  const CharType& Char()  {
+  const RegType& Char() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *CharType::GetInstance();
   }
-  const ShortType& Short()  {
+  const RegType& Short() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *ShortType::GetInstance();
   }
-  const IntegerType& Integer() {
+  const RegType& Integer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *IntegerType::GetInstance();
   }
-  const FloatType& Float() {
+  const RegType& Float() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *FloatType::GetInstance();
   }
-  const LongLoType& LongLo() {
+  const RegType& LongLo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *LongLoType::GetInstance();
   }
-  const LongHiType& LongHi() {
+  const RegType& LongHi() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *LongHiType::GetInstance();
   }
-  const DoubleLoType& DoubleLo() {
+  const RegType& DoubleLo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *DoubleLoType::GetInstance();
   }
-  const DoubleHiType& DoubleHi() {
+  const RegType& DoubleHi() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *DoubleHiType::GetInstance();
   }
-  const UndefinedType& Undefined() {
+  const RegType& Undefined() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return *UndefinedType::GetInstance();
   }
   const ConflictType& Conflict() {
@@ -138,6 +138,8 @@
   const RegType& RegTypeFromPrimitiveType(Primitive::Type) const;
 
   void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static void VisitStaticRoots(RootCallback* callback, void* arg)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
  private:
   void FillPrimitiveAndSmallConstantTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);