Revert "Delay init of classes of pre-allocated exceptions."

This reverts commit cd5c181baa6f919c1156a7b640b99056baf124d5.

Reason for revert: To fix build breakage

Change-Id: I4ee1a28d3aeb630975ea60ae5606fc92bc5c4652
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 1bd57ec..779128f 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -2615,11 +2615,11 @@
     // set up.
     interpreter::UnstartedRuntime::Initialize();
 
-    Thread* self = Thread::Current();
-    runtime_->RunRootClinits(self);
+    runtime_->GetClassLinker()->RunRootClinits();
 
     // Runtime::Create acquired the mutator_lock_ that is normally given away when we
     // Runtime::Start, give it away now so that we don't starve GC.
+    Thread* self = Thread::Current();
     self->TransitionFromRunnableToSuspended(kNative);
 
     return true;
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 38212da..7b92ba4 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -864,7 +864,8 @@
   VLOG(startup) << "ClassLinker::FinishInit exiting";
 }
 
-void ClassLinker::RunRootClinits(Thread* self) {
+void ClassLinker::RunRootClinits() {
+  Thread* self = Thread::Current();
   for (size_t i = 0; i < static_cast<size_t>(ClassRoot::kMax); ++i) {
     ObjPtr<mirror::Class> c = GetClassRoot(ClassRoot(i), this);
     if (!c->IsArrayClass() && !c->IsPrimitive()) {
@@ -872,8 +873,6 @@
       Handle<mirror::Class> h_class(hs.NewHandle(c));
       EnsureInitialized(self, h_class, true, true);
       self->AssertNoPendingException();
-    } else {
-      DCHECK(c->IsInitialized());
     }
   }
 }
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index e4d9c96..30c2423 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -405,7 +405,7 @@
 
   // Initializes classes that have instances in the image but that have
   // <clinit> methods so they could not be initialized by the compiler.
-  void RunRootClinits(Thread* self)
+  void RunRootClinits()
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
 
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index be39631..75b091d 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -182,7 +182,7 @@
 
   {
     ScopedObjectAccess soa(Thread::Current());
-    runtime_->RunRootClinits(soa.Self());
+    class_linker_->RunRootClinits();
   }
 
   // We're back in native, take the opportunity to initialize well known classes.
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index fe95940..3b4d177 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -713,23 +713,6 @@
   return compiler_executable;
 }
 
-void Runtime::RunRootClinits(Thread* self) {
-  class_linker_->RunRootClinits(self);
-
-  GcRoot<mirror::Throwable>* exceptions[] = {
-      &pre_allocated_OutOfMemoryError_when_throwing_exception_,
-      // &pre_allocated_OutOfMemoryError_when_throwing_oome_,             // Same class as above.
-      // &pre_allocated_OutOfMemoryError_when_handling_stack_overflow_,   // Same class as above.
-      &pre_allocated_NoClassDefFoundError_,
-  };
-  for (GcRoot<mirror::Throwable>* exception : exceptions) {
-    StackHandleScope<1> hs(self);
-    Handle<mirror::Class> klass = hs.NewHandle<mirror::Class>(exception->Read()->GetClass());
-    class_linker_->EnsureInitialized(self, klass, true, true);
-    self->AssertNoPendingException();
-  }
-}
-
 bool Runtime::Start() {
   VLOG(startup) << "Runtime::Start entering";
 
@@ -759,10 +742,8 @@
     auto field_class(hs.NewHandle<mirror::Class>(GetClassRoot<mirror::Field>(class_roots)));
 
     class_linker_->EnsureInitialized(soa.Self(), class_class, true, true);
-    self->AssertNoPendingException();
     // Field class is needed for register_java_net_InetAddress in libcore, b/28153851.
     class_linker_->EnsureInitialized(soa.Self(), field_class, true, true);
-    self->AssertNoPendingException();
   }
 
   // InitNativeMethods needs to be after started_ so that the classes
@@ -1109,30 +1090,15 @@
   sentinel_ = GcRoot<mirror::Object>(sentinel);
 }
 
-static inline void CreatePreAllocatedException(Thread* self,
-                                               Runtime* runtime,
-                                               GcRoot<mirror::Throwable>* exception,
-                                               const char* exception_class_descriptor,
-                                               const char* msg)
+static inline void InitPreAllocatedException(Thread* self,
+                                             GcRoot<mirror::Throwable>* exception,
+                                             const char* exception_class_descriptor,
+                                             const char* msg)
     REQUIRES_SHARED(Locks::mutator_lock_) {
   DCHECK_EQ(self, Thread::Current());
-  ClassLinker* class_linker = runtime->GetClassLinker();
-  // Allocate an object without initializing the class to allow non-trivial Throwable.<clinit>().
-  ObjPtr<mirror::Class> klass = class_linker->FindSystemClass(self, exception_class_descriptor);
-  CHECK(klass != nullptr);
-  gc::AllocatorType allocator_type = runtime->GetHeap()->GetCurrentAllocator();
-  ObjPtr<mirror::Throwable> exception_object = ObjPtr<mirror::Throwable>::DownCast(
-      klass->Alloc</* kIsInstrumented */ false>(self, allocator_type));
-  CHECK(exception_object != nullptr);
-  *exception = GcRoot<mirror::Throwable>(exception_object);
-  // Initialize the "detailMessage" field.
-  ObjPtr<mirror::String> message = mirror::String::AllocFromModifiedUtf8(self, msg);
-  CHECK(message != nullptr);
-  ObjPtr<mirror::Class> throwable = GetClassRoot<mirror::Throwable>(class_linker);
-  ArtField* detailMessageField =
-      throwable->FindDeclaredInstanceField("detailMessage", "Ljava/lang/String;");
-  CHECK(detailMessageField != nullptr);
-  detailMessageField->SetObject</* kTransactionActive */ false>(exception->Read(), message);
+  self->ThrowNewException(exception_class_descriptor, msg);
+  *exception = GcRoot<mirror::Throwable>(self->GetException());
+  self->ClearException();
 }
 
 bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
@@ -1577,36 +1543,32 @@
   } else {
     // Pre-allocate an OutOfMemoryError for the case when we fail to
     // allocate the exception to be thrown.
-    CreatePreAllocatedException(self,
-                                this,
-                                &pre_allocated_OutOfMemoryError_when_throwing_exception_,
-                                "Ljava/lang/OutOfMemoryError;",
-                                "OutOfMemoryError thrown while trying to throw an exception; "
-                                    "no stack trace available");
+    InitPreAllocatedException(self,
+                              &pre_allocated_OutOfMemoryError_when_throwing_exception_,
+                              "Ljava/lang/OutOfMemoryError;",
+                              "OutOfMemoryError thrown while trying to throw an exception; "
+                              "no stack trace available");
     // Pre-allocate an OutOfMemoryError for the double-OOME case.
-    CreatePreAllocatedException(self,
-                                this,
-                                &pre_allocated_OutOfMemoryError_when_throwing_oome_,
-                                "Ljava/lang/OutOfMemoryError;",
-                                "OutOfMemoryError thrown while trying to throw OutOfMemoryError; "
-                                    "no stack trace available");
+    InitPreAllocatedException(self,
+                              &pre_allocated_OutOfMemoryError_when_throwing_oome_,
+                              "Ljava/lang/OutOfMemoryError;",
+                              "OutOfMemoryError thrown while trying to throw OutOfMemoryError; "
+                              "no stack trace available");
     // Pre-allocate an OutOfMemoryError for the case when we fail to
     // allocate while handling a stack overflow.
-    CreatePreAllocatedException(self,
-                                this,
-                                &pre_allocated_OutOfMemoryError_when_handling_stack_overflow_,
-                                "Ljava/lang/OutOfMemoryError;",
-                                "OutOfMemoryError thrown while trying to handle a stack overflow; "
-                                    "no stack trace available");
+    InitPreAllocatedException(self,
+                              &pre_allocated_OutOfMemoryError_when_handling_stack_overflow_,
+                              "Ljava/lang/OutOfMemoryError;",
+                              "OutOfMemoryError thrown while trying to handle a stack overflow; "
+                              "no stack trace available");
 
     // Pre-allocate a NoClassDefFoundError for the common case of failing to find a system class
     // ahead of checking the application's class loader.
-    CreatePreAllocatedException(self,
-                                this,
-                                &pre_allocated_NoClassDefFoundError_,
-                                "Ljava/lang/NoClassDefFoundError;",
-                                "Class not found using the boot class loader; "
-                                    "no stack trace available");
+    InitPreAllocatedException(self,
+                              &pre_allocated_NoClassDefFoundError_,
+                              "Ljava/lang/NoClassDefFoundError;",
+                              "Class not found using the boot class loader; "
+                              "no stack trace available");
   }
 
   // Runtime initialization is largely done now.
diff --git a/runtime/runtime.h b/runtime/runtime.h
index f413733..d85490c 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -212,8 +212,6 @@
     return finished_starting_;
   }
 
-  void RunRootClinits(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
-
   static Runtime* Current() {
     return instance_;
   }
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 19d9485..1a078d5 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2045,15 +2045,15 @@
 
   // Finish attaching the main thread.
   ScopedObjectAccess soa(Thread::Current());
-  soa.Self()->CreatePeer("main", false, runtime->GetMainThreadGroup());
-  soa.Self()->AssertNoPendingException();
+  Thread::Current()->CreatePeer("main", false, runtime->GetMainThreadGroup());
+  Thread::Current()->AssertNoPendingException();
 
-  runtime->RunRootClinits(soa.Self());
+  Runtime::Current()->GetClassLinker()->RunRootClinits();
 
   // The thread counts as started from now on. We need to add it to the ThreadGroup. For regular
   // threads, this is done in Thread.start() on the Java side.
-  soa.Self()->NotifyThreadGroup(soa, runtime->GetMainThreadGroup());
-  soa.Self()->AssertNoPendingException();
+  Thread::Current()->NotifyThreadGroup(soa, runtime->GetMainThreadGroup());
+  Thread::Current()->AssertNoPendingException();
 }
 
 void Thread::Shutdown() {