Remove GcRoot<> static from Throwable and related classes.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 31113334
Change-Id: I8115e6413a07419ec261af3ec5068833b72b5218
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index a2e2686..b882f65 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -759,7 +759,6 @@
   class_root = FindSystemClass(self, "Ldalvik/system/EmulatedStackFrame;");
   CHECK(class_root != nullptr);
   SetClassRoot(ClassRoot::kDalvikSystemEmulatedStackFrame, class_root);
-  mirror::EmulatedStackFrame::SetClass(class_root);
 
   // java.lang.ref classes need to be specially flagged, but otherwise are normal classes
   // finish initializing Reference class
@@ -790,14 +789,12 @@
   // Set up java.lang.Throwable, java.lang.ClassNotFoundException, and
   // java.lang.StackTraceElement as a convenience.
   SetClassRoot(ClassRoot::kJavaLangThrowable, FindSystemClass(self, "Ljava/lang/Throwable;"));
-  mirror::Throwable::SetClass(GetClassRoot(ClassRoot::kJavaLangThrowable, this));
   SetClassRoot(ClassRoot::kJavaLangClassNotFoundException,
                FindSystemClass(self, "Ljava/lang/ClassNotFoundException;"));
   SetClassRoot(ClassRoot::kJavaLangStackTraceElement,
                FindSystemClass(self, "Ljava/lang/StackTraceElement;"));
   SetClassRoot(ClassRoot::kJavaLangStackTraceElementArrayClass,
                FindSystemClass(self, "[Ljava/lang/StackTraceElement;"));
-  mirror::StackTraceElement::SetClass(GetClassRoot(ClassRoot::kJavaLangStackTraceElement, this));
 
   // Create conflict tables that depend on the class linker.
   runtime->FixupConflictTables();
@@ -1033,10 +1030,6 @@
       GcRoot<mirror::IfTable>(GetClassRoot(ClassRoot::kObjectArrayClass, this)->GetIfTable());
   DCHECK_EQ(array_iftable_.Read(), GetClassRoot(ClassRoot::kBooleanArrayClass, this)->GetIfTable());
   // String class root was set above
-  mirror::Throwable::SetClass(GetClassRoot(ClassRoot::kJavaLangThrowable, this));
-  mirror::StackTraceElement::SetClass(GetClassRoot(ClassRoot::kJavaLangStackTraceElement, this));
-  mirror::EmulatedStackFrame::SetClass(
-      GetClassRoot(ClassRoot::kDalvikSystemEmulatedStackFrame, this).Ptr());
   mirror::ClassExt::SetClass(GetClassRoot(ClassRoot::kDalvikSystemClassExt, this));
 
   for (gc::space::ImageSpace* image_space : spaces) {
@@ -2116,10 +2109,7 @@
 
 ClassLinker::~ClassLinker() {
   mirror::Class::ResetClass();
-  mirror::StackTraceElement::ResetClass();
   mirror::String::ResetClass();
-  mirror::Throwable::ResetClass();
-  mirror::EmulatedStackFrame::ResetClass();
   Thread* const self = Thread::Current();
   for (const ClassLoaderData& data : class_loaders_) {
     // CHA unloading analysis is not needed. No negative consequences are expected because
diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc
index 98fe8b2..9bb760c 100644
--- a/runtime/interpreter/unstarted_runtime_test.cc
+++ b/runtime/interpreter/unstarted_runtime_test.cc
@@ -1348,7 +1348,7 @@
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
 
   // Get Throwable.
-  Handle<mirror::Class> throw_class = hs.NewHandle(mirror::Throwable::GetJavaLangThrowable());
+  Handle<mirror::Class> throw_class = hs.NewHandle(GetClassRoot<mirror::Throwable>());
   ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));
 
   // Get an input object.
@@ -1387,8 +1387,8 @@
 
   // Should be a new object.
   ASSERT_NE(result.GetL(), input.Get());
-  // Should be a String.
-  ASSERT_EQ(mirror::Throwable::GetJavaLangThrowable(), result.GetL()->GetClass());
+  // Should be of type Throwable.
+  ASSERT_OBJ_PTR_EQ(GetClassRoot<mirror::Throwable>(), result.GetL()->GetClass());
   // Should have the right string.
   ObjPtr<mirror::String> result_msg =
       reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
diff --git a/runtime/mirror/emulated_stack_frame.cc b/runtime/mirror/emulated_stack_frame.cc
index 527408b..5595102 100644
--- a/runtime/mirror/emulated_stack_frame.cc
+++ b/runtime/mirror/emulated_stack_frame.cc
@@ -27,8 +27,6 @@
 namespace art {
 namespace mirror {
 
-GcRoot<mirror::Class> EmulatedStackFrame::static_class_;
-
 // Calculates the size of a stack frame based on the size of its argument
 // types and return types.
 static void CalculateFrameAndReferencesSize(ObjPtr<mirror::ObjectArray<mirror::Class>> p_types,
@@ -192,7 +190,7 @@
 
   // Step 5: Construct the EmulatedStackFrame object.
   Handle<EmulatedStackFrame> sf(hs.NewHandle(
-      ObjPtr<EmulatedStackFrame>::DownCast(StaticClass()->AllocObject(self))));
+      ObjPtr<EmulatedStackFrame>::DownCast(GetClassRoot<EmulatedStackFrame>()->AllocObject(self))));
   sf->SetFieldObject<false>(CallsiteTypeOffset(), caller_type.Get());
   sf->SetFieldObject<false>(TypeOffset(), callee_type.Get());
   sf->SetFieldObject<false>(ReferencesOffset(), references.Get());
@@ -272,20 +270,5 @@
   }
 }
 
-void EmulatedStackFrame::SetClass(Class* klass) {
-  CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
-  CHECK(klass != nullptr);
-  static_class_ = GcRoot<Class>(klass);
-}
-
-void EmulatedStackFrame::ResetClass() {
-  CHECK(!static_class_.IsNull());
-  static_class_ = GcRoot<Class>(nullptr);
-}
-
-void EmulatedStackFrame::VisitRoots(RootVisitor* visitor) {
-  static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-}
-
 }  // namespace mirror
 }  // namespace art
diff --git a/runtime/mirror/emulated_stack_frame.h b/runtime/mirror/emulated_stack_frame.h
index 23626f4..ec45f57 100644
--- a/runtime/mirror/emulated_stack_frame.h
+++ b/runtime/mirror/emulated_stack_frame.h
@@ -64,15 +64,7 @@
     return GetReferences()->Get(0);
   }
 
-  static void SetClass(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
-  static void ResetClass() REQUIRES_SHARED(Locks::mutator_lock_);
-  static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
-
  private:
-  static mirror::Class* StaticClass() REQUIRES_SHARED(Locks::mutator_lock_) {
-    return static_class_.Read();
-  }
-
   mirror::ObjectArray<mirror::Object>* GetReferences() REQUIRES_SHARED(Locks::mutator_lock_) {
     return GetFieldObject<mirror::ObjectArray<mirror::Object>>(
         OFFSET_OF_OBJECT_MEMBER(EmulatedStackFrame, references_));
@@ -104,8 +96,6 @@
   HeapReference<mirror::ByteArray> stack_frame_;
   HeapReference<mirror::MethodType> type_;
 
-  static GcRoot<mirror::Class> static_class_;  // dalvik.system.EmulatedStackFrame.class
-
   friend struct art::EmulatedStackFrameOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(EmulatedStackFrame);
 };
diff --git a/runtime/mirror/stack_trace_element.cc b/runtime/mirror/stack_trace_element.cc
index bb3242e..ff353d8 100644
--- a/runtime/mirror/stack_trace_element.cc
+++ b/runtime/mirror/stack_trace_element.cc
@@ -18,6 +18,7 @@
 
 #include "class-inl.h"
 #include "class.h"
+#include "class_root.h"
 #include "gc/accounting/card_table-inl.h"
 #include "gc_root-inl.h"
 #include "handle_scope-inl.h"
@@ -27,26 +28,13 @@
 namespace art {
 namespace mirror {
 
-GcRoot<Class> StackTraceElement::java_lang_StackTraceElement_;
-
-void StackTraceElement::SetClass(ObjPtr<Class> java_lang_StackTraceElement) {
-  CHECK(java_lang_StackTraceElement_.IsNull());
-  CHECK(java_lang_StackTraceElement != nullptr);
-  java_lang_StackTraceElement_ = GcRoot<Class>(java_lang_StackTraceElement);
-}
-
-void StackTraceElement::ResetClass() {
-  CHECK(!java_lang_StackTraceElement_.IsNull());
-  java_lang_StackTraceElement_ = GcRoot<Class>(nullptr);
-}
-
 StackTraceElement* StackTraceElement::Alloc(Thread* self,
                                             Handle<String> declaring_class,
                                             Handle<String> method_name,
                                             Handle<String> file_name,
                                             int32_t line_number) {
   ObjPtr<StackTraceElement> trace =
-      ObjPtr<StackTraceElement>::DownCast(GetStackTraceElement()->AllocObject(self));
+      ObjPtr<StackTraceElement>::DownCast(GetClassRoot<StackTraceElement>()->AllocObject(self));
   if (LIKELY(trace != nullptr)) {
     if (Runtime::Current()->IsActiveTransaction()) {
       trace->Init<true>(declaring_class.Get(), method_name.Get(), file_name.Get(), line_number);
@@ -72,10 +60,5 @@
                                  line_number);
 }
 
-void StackTraceElement::VisitRoots(RootVisitor* visitor) {
-  java_lang_StackTraceElement_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-}
-
-
 }  // namespace mirror
 }  // namespace art
diff --git a/runtime/mirror/stack_trace_element.h b/runtime/mirror/stack_trace_element.h
index 87e8a1f..f25211c 100644
--- a/runtime/mirror/stack_trace_element.h
+++ b/runtime/mirror/stack_trace_element.h
@@ -53,15 +53,6 @@
                                   int32_t line_number)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
 
-  static void SetClass(ObjPtr<Class> java_lang_StackTraceElement);
-  static void ResetClass();
-  static void VisitRoots(RootVisitor* visitor)
-      REQUIRES_SHARED(Locks::mutator_lock_);
-  static Class* GetStackTraceElement() REQUIRES_SHARED(Locks::mutator_lock_) {
-    DCHECK(!java_lang_StackTraceElement_.IsNull());
-    return java_lang_StackTraceElement_.Read();
-  }
-
  private:
   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
   HeapReference<String> declaring_class_;
@@ -76,8 +67,6 @@
             int32_t line_number)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  static GcRoot<Class> java_lang_StackTraceElement_;
-
   friend struct art::StackTraceElementOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(StackTraceElement);
 };
diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc
index 7006973..82e295a 100644
--- a/runtime/mirror/throwable.cc
+++ b/runtime/mirror/throwable.cc
@@ -22,6 +22,7 @@
 #include "base/enums.h"
 #include "base/utils.h"
 #include "class-inl.h"
+#include "class_root.h"
 #include "dex/dex_file-inl.h"
 #include "gc/accounting/card_table-inl.h"
 #include "object-inl.h"
@@ -36,8 +37,6 @@
 
 using android::base::StringPrintf;
 
-GcRoot<Class> Throwable::java_lang_Throwable_;
-
 void Throwable::SetDetailMessage(ObjPtr<String> new_detail_message) {
   if (Runtime::Current()->IsActiveTransaction()) {
     SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Throwable, detail_message_), new_detail_message);
@@ -128,8 +127,7 @@
   } else {
     ObjPtr<Object> stack_trace = GetStackTrace();
     if (stack_trace != nullptr && stack_trace->IsObjectArray()) {
-      CHECK_EQ(stack_trace->GetClass()->GetComponentType(),
-               StackTraceElement::GetStackTraceElement());
+      CHECK_EQ(stack_trace->GetClass()->GetComponentType(), GetClassRoot<StackTraceElement>());
       ObjPtr<ObjectArray<StackTraceElement>> ste_array =
           ObjPtr<ObjectArray<StackTraceElement>>::DownCast(stack_trace);
       if (ste_array->GetLength() == 0) {
@@ -159,21 +157,6 @@
   return result;
 }
 
-void Throwable::SetClass(ObjPtr<Class> java_lang_Throwable) {
-  CHECK(java_lang_Throwable_.IsNull());
-  CHECK(java_lang_Throwable != nullptr);
-  java_lang_Throwable_ = GcRoot<Class>(java_lang_Throwable);
-}
-
-void Throwable::ResetClass() {
-  CHECK(!java_lang_Throwable_.IsNull());
-  java_lang_Throwable_ = GcRoot<Class>(nullptr);
-}
-
-void Throwable::VisitRoots(RootVisitor* visitor) {
-  java_lang_Throwable_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-}
-
 Object* Throwable::GetStackState() {
   return GetFieldObjectVolatile<Object>(OFFSET_OF_OBJECT_MEMBER(Throwable, backtrace_));
 }
diff --git a/runtime/mirror/throwable.h b/runtime/mirror/throwable.h
index b901ca2..42c612f 100644
--- a/runtime/mirror/throwable.h
+++ b/runtime/mirror/throwable.h
@@ -46,18 +46,8 @@
   bool IsCheckedException() REQUIRES_SHARED(Locks::mutator_lock_);
   bool IsError() REQUIRES_SHARED(Locks::mutator_lock_);
 
-  static Class* GetJavaLangThrowable() REQUIRES_SHARED(Locks::mutator_lock_) {
-    DCHECK(!java_lang_Throwable_.IsNull());
-    return java_lang_Throwable_.Read();
-  }
-
   int32_t GetStackDepth() REQUIRES_SHARED(Locks::mutator_lock_);
 
-  static void SetClass(ObjPtr<Class> java_lang_Throwable);
-  static void ResetClass();
-  static void VisitRoots(RootVisitor* visitor)
-      REQUIRES_SHARED(Locks::mutator_lock_);
-
  private:
   Object* GetStackState() REQUIRES_SHARED(Locks::mutator_lock_);
   Object* GetStackTrace() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -69,8 +59,6 @@
   HeapReference<Object> stack_trace_;
   HeapReference<Object> suppressed_exceptions_;
 
-  static GcRoot<Class> java_lang_Throwable_;
-
   friend struct art::ThrowableOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(Throwable);
 };
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 630053a..32d9d68 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1979,10 +1979,7 @@
   // Visit the classes held as static in mirror classes, these can be visited concurrently and only
   // need to be visited once per GC since they never change.
   mirror::Class::VisitRoots(visitor);
-  mirror::StackTraceElement::VisitRoots(visitor);
   mirror::String::VisitRoots(visitor);
-  mirror::Throwable::VisitRoots(visitor);
-  mirror::EmulatedStackFrame::VisitRoots(visitor);
   mirror::ClassExt::VisitRoots(visitor);
   // Visiting the roots of these ArtMethods is not currently required since all the GcRoots are
   // null.
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 129bae6..f5d2ffb 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2461,7 +2461,7 @@
     // save frame)
     ArtMethod* m = GetMethod();
     if (skipping_ && !m->IsRuntimeMethod() &&
-        !mirror::Throwable::GetJavaLangThrowable()->IsAssignableFrom(m->GetDeclaringClass())) {
+        !GetClassRoot<mirror::Throwable>()->IsAssignableFrom(m->GetDeclaringClass())) {
       skipping_ = false;
     }
     if (!skipping_) {
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 3a49e4d..287e3d6 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3529,7 +3529,7 @@
         ObjPtr<mirror::Class> klass =
             linker->ResolveType(handler_type_idx, dex_cache_, class_loader_);
         if (klass != nullptr) {
-          if (klass == mirror::Throwable::GetJavaLangThrowable()) {
+          if (klass == GetClassRoot<mirror::Throwable>()) {
             has_catch_all_handler = true;
           }
         } else {
diff --git a/runtime/verifier/reg_type_cache-inl.h b/runtime/verifier/reg_type_cache-inl.h
index 43c0ab9..0469a3b 100644
--- a/runtime/verifier/reg_type_cache-inl.h
+++ b/runtime/verifier/reg_type_cache-inl.h
@@ -124,36 +124,42 @@
 }
 
 inline const PreciseReferenceType& RegTypeCache::JavaLangClass() {
-  const RegType* result = &FromClass("Ljava/lang/Class;", mirror::Class::GetJavaLangClass(), true);
+  const RegType* result = &FromClass("Ljava/lang/Class;",
+                                     GetClassRoot<mirror::Class>().Ptr(),
+                                     /* precise */ true);
   DCHECK(result->IsPreciseReference());
   return *down_cast<const PreciseReferenceType*>(result);
 }
 
 inline const PreciseReferenceType& RegTypeCache::JavaLangString() {
   // String is final and therefore always precise.
-  const RegType* result = &FromClass("Ljava/lang/String;", mirror::String::GetJavaLangString(),
-                                     true);
+  const RegType* result = &FromClass("Ljava/lang/String;",
+                                     GetClassRoot<mirror::String>().Ptr(),
+                                     /* precise */ true);
   DCHECK(result->IsPreciseReference());
   return *down_cast<const PreciseReferenceType*>(result);
 }
 
 inline const PreciseReferenceType& RegTypeCache::JavaLangInvokeMethodHandle() {
   const RegType* result = &FromClass("Ljava/lang/invoke/MethodHandle;",
-                                     GetClassRoot<mirror::MethodHandle>().Ptr(), true);
+                                     GetClassRoot<mirror::MethodHandle>().Ptr(),
+                                     /* precise */ true);
   DCHECK(result->IsPreciseReference());
   return *down_cast<const PreciseReferenceType*>(result);
 }
 
 inline const PreciseReferenceType& RegTypeCache::JavaLangInvokeMethodType() {
   const RegType* result = &FromClass("Ljava/lang/invoke/MethodType;",
-                                     GetClassRoot<mirror::MethodType>().Ptr(), true);
+                                     GetClassRoot<mirror::MethodType>().Ptr(),
+                                     /* precise */ true);
   DCHECK(result->IsPreciseReference());
   return *down_cast<const PreciseReferenceType*>(result);
 }
 
 inline const RegType&  RegTypeCache::JavaLangThrowable(bool precise) {
   const RegType* result = &FromClass("Ljava/lang/Throwable;",
-                                     mirror::Throwable::GetJavaLangThrowable(), precise);
+                                     GetClassRoot<mirror::Throwable>().Ptr(),
+                                     precise);
   if (precise) {
     DCHECK(result->IsPreciseReference());
     return *down_cast<const PreciseReferenceType*>(result);
@@ -165,7 +171,8 @@
 
 inline const RegType& RegTypeCache::JavaLangObject(bool precise) {
   const RegType* result = &FromClass("Ljava/lang/Object;",
-                                     mirror::Class::GetJavaLangClass()->GetSuperClass(), precise);
+                                     GetClassRoot<mirror::Object>().Ptr(),
+                                     precise);
   if (precise) {
     DCHECK(result->IsPreciseReference());
     return *down_cast<const PreciseReferenceType*>(result);