Change remaining well known methods to `ArtMethod*`.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I9cfef2a2c302f70826ac762202421388213e60e6
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index f2e0a6e..1754a68 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -110,7 +110,6 @@
 #include "stream/file_output_stream.h"
 #include "vdex_file.h"
 #include "verifier/verifier_deps.h"
-#include "well_known_classes.h"
 
 namespace art {
 
@@ -2754,7 +2753,6 @@
     Thread* self = Thread::Current();
     runtime_->GetClassLinker()->RunEarlyRootClinits(self);
     InitializeIntrinsics();
-    WellKnownClasses::Init(self->GetJniEnv());
     runtime_->RunRootClinits(self);
 
     // Runtime::Create acquired the mutator_lock_ that is normally given away when we
diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc
index 0c0b569..b5bc35e 100644
--- a/openjdkjvmti/ti_thread.cc
+++ b/openjdkjvmti/ti_thread.cc
@@ -174,12 +174,7 @@
 
 
 static void WaitForSystemDaemonStart(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) {
-  {
-    art::ScopedThreadStateChange strc(self, art::ThreadState::kNative);
-    JNIEnv* jni = self->GetJniEnv();
-    jni->CallStaticVoidMethod(art::WellKnownClasses::java_lang_Daemons,
-                              art::WellKnownClasses::java_lang_Daemons_waitForDaemonStart);
-  }
+  art::WellKnownClasses::java_lang_Daemons_waitForDaemonStart->InvokeStatic<'V'>(self);
   if (self->IsExceptionPending()) {
     LOG(WARNING) << "Exception occurred when waiting for system daemons to start: "
                  << self->GetException()->Dump();
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index a421461..a51e28f 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1108,8 +1108,17 @@
   Handle<mirror::ObjectArray<mirror::Class>> class_roots = hs.NewHandle(GetClassRoots());
   EnsureRootInitialized(this, self, GetClassRoot<mirror::Class>(class_roots.Get()));
   EnsureRootInitialized(this, self, GetClassRoot<mirror::String>(class_roots.Get()));
-  // Field class is needed for register_java_net_InetAddress in libcore, b/28153851.
+  // `Field` class is needed for register_java_net_InetAddress in libcore, b/28153851.
   EnsureRootInitialized(this, self, GetClassRoot<mirror::Field>(class_roots.Get()));
+
+  WellKnownClasses::Init(self->GetJniEnv());
+
+  // `FinalizerReference` class is needed for initialization of `java.net.InetAddress`.
+  // (Indirectly by constructing a `ObjectStreamField` which uses a `StringBuilder`
+  // and, when resizing, initializes the `System` class for `System.arraycopy()`
+  // and `System.<clinit> creates a finalizable object.)
+  EnsureRootInitialized(
+      this, self, WellKnownClasses::java_lang_ref_FinalizerReference_add->GetDeclaringClass());
 }
 
 void ClassLinker::RunRootClinits(Thread* self) {
@@ -1142,15 +1151,25 @@
       WellKnownClasses::java_lang_Long_valueOf,
       WellKnownClasses::java_lang_Short_valueOf,
       // Ensure class loader classes are initialized (avoid check at runtime).
-      // Superclasses `ClassLoader` and `BaseDexClassLoader` are initialized implicitly.
+      // Superclass `ClassLoader` is a class root and already initialized above.
+      // Superclass `BaseDexClassLoader` is initialized implicitly.
       WellKnownClasses::dalvik_system_DelegateLastClassLoader_init,
       WellKnownClasses::dalvik_system_DexClassLoader_init,
       WellKnownClasses::dalvik_system_InMemoryDexClassLoader_init,
       WellKnownClasses::dalvik_system_PathClassLoader_init,
       WellKnownClasses::java_lang_BootClassLoader_init,
+      // Ensure `Daemons` class is initialized (avoid check at runtime).
+      WellKnownClasses::java_lang_Daemons_start,
       // Ensure `Thread` and `ThreadGroup` classes are initialized (avoid check at runtime).
       WellKnownClasses::java_lang_Thread_init,
       WellKnownClasses::java_lang_ThreadGroup_add,
+      // Ensure reference classes are initialized (avoid check at runtime).
+      // The `FinalizerReference` class was initialized in `RunEarlyRootClinits()`.
+      WellKnownClasses::java_lang_ref_ReferenceQueue_add,
+      // Ensure `InvocationTargetException` class is initialized (avoid check at runtime).
+      WellKnownClasses::java_lang_reflect_InvocationTargetException_init,
+      // Ensure `Parameter` class is initialized (avoid check at runtime).
+      WellKnownClasses::java_lang_reflect_Parameter_init,
       // Ensure `MethodHandles` class is initialized (avoid check at runtime).
       WellKnownClasses::java_lang_invoke_MethodHandles_lookup,
       // Ensure `DirectByteBuffer` class is initialized (avoid check at runtime).
@@ -1179,6 +1198,11 @@
   for (ArtField* field : static_fields_of_classes_to_initialize) {
     EnsureRootInitialized(this, self, field->GetDeclaringClass());
   }
+
+  // This invariant is important since otherwise we will have the entire proxy invoke system
+  // confused.
+  DCHECK_NE(WellKnownClasses::java_lang_reflect_Proxy_init->GetEntryPointFromQuickCompiledCode(),
+            GetQuickInstrumentationEntryPoint());
 }
 
 ALWAYS_INLINE
@@ -5103,8 +5127,7 @@
 
   // Find the <init>(InvocationHandler)V method. The exact method offset varies depending
   // on which front-end compiler was used to build the libcore DEX files.
-  ArtMethod* proxy_constructor =
-      jni::DecodeArtMethod(WellKnownClasses::java_lang_reflect_Proxy_init);
+  ArtMethod* proxy_constructor = WellKnownClasses::java_lang_reflect_Proxy_init;
   DCHECK(proxy_constructor != nullptr)
       << "Could not find <init> method in java.lang.reflect.Proxy";
 
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 6a22a66..0e8a962 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -160,7 +160,6 @@
     ScopedObjectAccess soa(Thread::Current());
     runtime_->GetClassLinker()->RunEarlyRootClinits(soa.Self());
     InitializeIntrinsics();
-    WellKnownClasses::Init(Thread::Current()->GetJniEnv());
     runtime_->RunRootClinits(soa.Self());
   }
 
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index 63d2aa4..ae6e98a 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -22,6 +22,7 @@
 #include "base/mutex.h"
 #include "base/sdk_version.h"
 #include "class_linker-inl.h"
+#include "class_root-inl.h"
 #include "dex/dex_file-inl.h"
 #include "dex/method_reference.h"
 #include "entrypoints/entrypoint_utils-inl.h"
@@ -33,14 +34,14 @@
 #include "mirror/class-inl.h"
 #include "mirror/method.h"
 #include "mirror/object-inl.h"
-#include "mirror/object_array-inl.h"
+#include "mirror/object_array-alloc-inl.h"
 #include "nth_caller_visitor.h"
 #include "oat_file.h"
 #include "oat_file-inl.h"
 #include "oat_quick_method_header.h"
 #include "reflection.h"
 #include "scoped_thread_state_change-inl.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
 
 namespace art {
 
@@ -65,60 +66,70 @@
                                     jobject rcvr_jobj,
                                     jobject interface_method_jobj,
                                     std::vector<jvalue>& args) {
-  DCHECK(soa.Env()->IsInstanceOf(rcvr_jobj, WellKnownClasses::java_lang_reflect_Proxy));
+  StackHandleScope<4u> hs(soa.Self());
+  DCHECK(rcvr_jobj != nullptr);
+  Handle<mirror::Object> h_receiver = hs.NewHandle(soa.Decode<mirror::Object>(rcvr_jobj));
+  DCHECK(h_receiver->InstanceOf(GetClassRoot(ClassRoot::kJavaLangReflectProxy)));
+  Handle<mirror::Method> h_interface_method =
+      hs.NewHandle(soa.Decode<mirror::Method>(interface_method_jobj));
 
   // Build argument array possibly triggering GC.
   soa.Self()->AssertThreadSuspensionIsAllowable();
-  jobjectArray args_jobj = nullptr;
+  auto h_args = hs.NewHandle<mirror::ObjectArray<mirror::Object>>(nullptr);
   const JValue zero;
-  uint32_t target_sdk_version = Runtime::Current()->GetTargetSdkVersion();
+  Runtime* runtime = Runtime::Current();
+  uint32_t target_sdk_version = runtime->GetTargetSdkVersion();
   // Do not create empty arrays unless needed to maintain Dalvik bug compatibility.
   if (args.size() > 0 || IsSdkVersionSetAndAtMost(target_sdk_version, SdkVersion::kL)) {
-    args_jobj = soa.Env()->NewObjectArray(args.size(), WellKnownClasses::java_lang_Object, nullptr);
-    if (args_jobj == nullptr) {
+    h_args.Assign(mirror::ObjectArray<mirror::Object>::Alloc(
+        soa.Self(), GetClassRoot<mirror::ObjectArray<mirror::Object>>(), args.size()));
+    if (h_args == nullptr) {
       CHECK(soa.Self()->IsExceptionPending());
       return zero;
     }
     for (size_t i = 0; i < args.size(); ++i) {
+      ObjPtr<mirror::Object> value;
       if (shorty[i + 1] == 'L') {
-        jobject val = args[i].l;
-        soa.Env()->SetObjectArrayElement(args_jobj, i, val);
+        value = soa.Decode<mirror::Object>(args[i].l);
       } else {
         JValue jv;
         jv.SetJ(args[i].j);
-        ObjPtr<mirror::Object> val = BoxPrimitive(Primitive::GetType(shorty[i + 1]), jv);
-        if (val == nullptr) {
+        value = BoxPrimitive(Primitive::GetType(shorty[i + 1]), jv);
+        if (value == nullptr) {
           CHECK(soa.Self()->IsExceptionPending());
           return zero;
         }
-        soa.Decode<mirror::ObjectArray<mirror::Object>>(args_jobj)->Set<false>(i, val);
       }
+      // We do not support `Proxy.invoke()` in a transaction.
+      h_args->SetWithoutChecks</*kActiveTransaction=*/ false>(i, value);
     }
   }
 
   // Call Proxy.invoke(Proxy proxy, Method method, Object[] args).
-  jvalue invocation_args[3];
-  invocation_args[0].l = rcvr_jobj;
-  invocation_args[1].l = interface_method_jobj;
-  invocation_args[2].l = args_jobj;
-  jobject result =
-      soa.Env()->CallStaticObjectMethodA(WellKnownClasses::java_lang_reflect_Proxy,
-                                         WellKnownClasses::java_lang_reflect_Proxy_invoke,
-                                         invocation_args);
+  Handle<mirror::Object> h_result = hs.NewHandle(
+      WellKnownClasses::java_lang_reflect_Proxy_invoke->InvokeStatic<'L', 'L', 'L', 'L'>(
+          soa.Self(), h_receiver.Get(), h_interface_method.Get(), h_args.Get()));
 
   // Unbox result and handle error conditions.
   if (LIKELY(!soa.Self()->IsExceptionPending())) {
-    if (shorty[0] == 'V' || (shorty[0] == 'L' && result == nullptr)) {
+    if (shorty[0] == 'V' || (shorty[0] == 'L' && h_result == nullptr)) {
       // Do nothing.
       return zero;
     } else {
-      ArtMethod* interface_method =
-          soa.Decode<mirror::Method>(interface_method_jobj)->GetArtMethod();
-      // This can cause thread suspension.
-      ObjPtr<mirror::Class> result_type = interface_method->ResolveReturnType();
-      ObjPtr<mirror::Object> result_ref = soa.Decode<mirror::Object>(result);
+      ObjPtr<mirror::Class> result_type;
+      if (shorty[0] == 'L') {
+        // This can cause thread suspension.
+        result_type = h_interface_method->GetArtMethod()->ResolveReturnType();
+        if (result_type == nullptr) {
+          DCHECK(soa.Self()->IsExceptionPending());
+          return zero;
+        }
+      } else {
+        result_type = runtime->GetClassLinker()->LookupPrimitiveClass(shorty[0]);
+        DCHECK(result_type != nullptr);
+      }
       JValue result_unboxed;
-      if (!UnboxPrimitiveForResult(result_ref, result_type, &result_unboxed)) {
+      if (!UnboxPrimitiveForResult(h_result.Get(), result_type, &result_unboxed)) {
         DCHECK(soa.Self()->IsExceptionPending());
         return zero;
       }
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 55af720..3bda43d 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -3826,12 +3826,11 @@
 
 void Heap::AddFinalizerReference(Thread* self, ObjPtr<mirror::Object>* object) {
   ScopedObjectAccess soa(self);
-  ScopedLocalRef<jobject> arg(self->GetJniEnv(), soa.AddLocalReference<jobject>(*object));
-  jvalue args[1];
-  args[0].l = arg.get();
-  InvokeWithJValues(soa, nullptr, WellKnownClasses::java_lang_ref_FinalizerReference_add, args);
-  // Restore object in case it gets moved.
-  *object = soa.Decode<mirror::Object>(arg.get());
+  StackHandleScope<1u> hs(self);
+  // Use handle wrapper to update the `*object` if the object gets moved.
+  HandleWrapperObjPtr<mirror::Object> h_object = hs.NewHandleWrapper(object);
+  WellKnownClasses::java_lang_ref_FinalizerReference_add->InvokeStatic<'V', 'L'>(
+      self, h_object.Get());
 }
 
 void Heap::RequestConcurrentGCAndSaveObject(Thread* self,
diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc
index 772174f..f24c942 100644
--- a/runtime/gc/reference_processor.cc
+++ b/runtime/gc/reference_processor.cc
@@ -363,9 +363,8 @@
   }
   void Run(Thread* thread) override {
     ScopedObjectAccess soa(thread);
-    jvalue args[1];
-    args[0].l = cleared_references_;
-    InvokeWithJValues(soa, nullptr, WellKnownClasses::java_lang_ref_ReferenceQueue_add, args);
+    WellKnownClasses::java_lang_ref_ReferenceQueue_add->InvokeStatic<'V', 'L'>(
+        thread, soa.Decode<mirror::Object>(cleared_references_));
     soa.Env()->DeleteGlobalRef(cleared_references_);
   }
 
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index c7393eb..6c68cdb 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -196,8 +196,7 @@
   // Annoyingly this can be called before we have actually initialized WellKnownClasses so therefore
   // we also need to check this based on the declaring-class descriptor. The check is valid because
   // Proxy only has a single constructor.
-  ArtMethod* well_known_proxy_init = jni::DecodeArtMethod(
-      WellKnownClasses::java_lang_reflect_Proxy_init);
+  ArtMethod* well_known_proxy_init = WellKnownClasses::java_lang_reflect_Proxy_init;
   if (well_known_proxy_init == method) {
     return true;
   }
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index 8e6e84f..ad2efc5 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -393,8 +393,7 @@
     REQUIRES_SHARED(Locks::mutator_lock_) {
   ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
   // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
-  if (method ==
-      jni::DecodeArtMethod<kEnableIndexIds>(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
+  if (method == WellKnownClasses::java_lang_Runtime_nativeLoad) {
     return soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
   }
   // If we have a method, use its ClassLoader for context.
diff --git a/runtime/native/java_lang_reflect_Executable.cc b/runtime/native/java_lang_reflect_Executable.cc
index adf81dc..87c9f6c 100644
--- a/runtime/native/java_lang_reflect_Executable.cc
+++ b/runtime/native/java_lang_reflect_Executable.cc
@@ -19,7 +19,7 @@
 #include "android-base/stringprintf.h"
 #include "nativehelper/jni_macros.h"
 
-#include "art_method-inl.h"
+#include "art_method-alloc-inl.h"
 #include "class_root-inl.h"
 #include "dex/dex_file_annotations.h"
 #include "handle.h"
@@ -157,7 +157,7 @@
 static jobjectArray Executable_getParameters0(JNIEnv* env, jobject javaMethod) {
   ScopedFastNativeObjectAccess soa(env);
   Thread* self = soa.Self();
-  StackHandleScope<8> hs(self);
+  StackHandleScope<6> hs(self);
 
   Handle<mirror::Method> executable = hs.NewHandle(soa.Decode<mirror::Method>(javaMethod));
   ArtMethod* art_method = executable.Get()->GetArtMethod();
@@ -198,56 +198,36 @@
   Handle<mirror::Class> parameter_array_class =
       hs.NewHandle(
           WellKnownClasses::ToClass(WellKnownClasses::java_lang_reflect_Parameter__array));
-  Handle<mirror::ObjectArray<mirror::Object>> parameter_array =
-      hs.NewHandle(
-          mirror::ObjectArray<mirror::Object>::Alloc(self,
-                                                     parameter_array_class.Get(),
-                                                     names_count));
+  Handle<mirror::ObjectArray<mirror::Object>> parameter_array = hs.NewHandle(
+      mirror::ObjectArray<mirror::Object>::Alloc(self, parameter_array_class.Get(), names_count));
   if (UNLIKELY(parameter_array == nullptr)) {
     self->AssertPendingException();
     return nullptr;
   }
 
-  Handle<mirror::Class> parameter_class =
-      hs.NewHandle(WellKnownClasses::ToClass(WellKnownClasses::java_lang_reflect_Parameter));
-  ArtMethod* parameter_init =
-      jni::DecodeArtMethod(WellKnownClasses::java_lang_reflect_Parameter_init);
+  ArtMethod* parameter_init = WellKnownClasses::java_lang_reflect_Parameter_init;
 
   // Mutable handles used in the loop below to ensure cleanup without scaling the number of
   // handles by the number of parameters.
   MutableHandle<mirror::String> name = hs.NewHandle<mirror::String>(nullptr);
-  MutableHandle<mirror::Object> parameter = hs.NewHandle<mirror::Object>(nullptr);
 
   // Populate the Parameter[] to return.
   for (int32_t parameter_index = 0; parameter_index < names_count; parameter_index++) {
     name.Assign(names.Get()->Get(parameter_index));
     int32_t modifiers = access_flags.Get()->Get(parameter_index);
 
-    // Allocate / initialize the Parameter to add to parameter_array.
-    parameter.Assign(parameter_class->AllocObject(self));
+    // Create the Parameter to add to parameter_array.
+    ObjPtr<mirror::Object> parameter = parameter_init->NewObject<'L', 'I', 'L', 'I'>(
+        self, name, modifiers, executable, parameter_index);
     if (UNLIKELY(parameter == nullptr)) {
-      self->AssertPendingOOMException();
+      DCHECK(self->IsExceptionPending());
       return nullptr;
     }
 
-    uint32_t args[5] = { PointerToLowMemUInt32(parameter.Get()),
-                         PointerToLowMemUInt32(name.Get()),
-                         static_cast<uint32_t>(modifiers),
-                         PointerToLowMemUInt32(executable.Get()),
-                         static_cast<uint32_t>(parameter_index)
-    };
-    JValue result;
-    static const char* method_signature = "VLILI";  // return + parameter types
-    parameter_init->Invoke(self, args, sizeof(args), &result, method_signature);
-    if (UNLIKELY(self->IsExceptionPending())) {
-      return nullptr;
-    }
-
-    // Store the Parameter in the Parameter[].
-    parameter_array.Get()->Set(parameter_index, parameter.Get());
-    if (UNLIKELY(self->IsExceptionPending())) {
-      return nullptr;
-    }
+    // We're initializing a newly allocated array object, so we do not need to record that under
+    // a transaction. If the transaction is aborted, the whole object shall be unreachable.
+    parameter_array->SetWithoutChecks</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
+        parameter_index, parameter);
   }
   return soa.AddLocalReference<jobjectArray>(parameter_array.Get());
 }
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index 7b66210..ac8ec56 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -33,17 +33,6 @@
   ProxyTest() {
     use_boot_image_ = true;  // Make the Runtime creation cheaper.
   }
-
-  void SetUp() override {
-    CommonRuntimeTest::SetUp();
-    // The creation of a Proxy class uses WellKnownClasses. These are not normally initialized by
-    // CommonRuntimeTest so we need to do that now.
-    WellKnownClasses::Clear();
-    WellKnownClasses::Init(art::Thread::Current()->GetJniEnv());
-    // Since we aren't actually calling any of the native functions we can just immediately call
-    // LateInit after calling Init.
-    WellKnownClasses::LateInit(art::Thread::Current()->GetJniEnv());
-  }
 };
 
 // Creates a proxy class and check ClassHelper works correctly.
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index 7ddf64d..bfe9c8f 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -17,7 +17,7 @@
 #include "reflection-inl.h"
 
 #include "art_field-inl.h"
-#include "art_method-inl.h"
+#include "art_method-alloc-inl.h"
 #include "base/enums.h"
 #include "class_linker.h"
 #include "common_throws.h"
@@ -502,17 +502,17 @@
           << soa.Self()->GetException()->GetClass()->PrettyDescriptor();
     } else {
       // If we get another exception when we are trying to wrap, then just use that instead.
-      ScopedLocalRef<jthrowable> th(soa.Env(), soa.Env()->ExceptionOccurred());
+      StackHandleScope<2u> hs(soa.Self());
+      Handle<mirror::Throwable> cause = hs.NewHandle(soa.Self()->GetException());
       soa.Self()->ClearException();
-      jobject exception_instance =
-          soa.Env()->NewObject(WellKnownClasses::java_lang_reflect_InvocationTargetException,
-                               WellKnownClasses::java_lang_reflect_InvocationTargetException_init,
-                               th.get());
+      Handle<mirror::Object> exception_instance =
+          WellKnownClasses::java_lang_reflect_InvocationTargetException_init->NewObject<'L'>(
+              hs, soa.Self(), cause);
       if (exception_instance == nullptr) {
         soa.Self()->AssertPendingException();
         return false;
       }
-      soa.Env()->Throw(reinterpret_cast<jthrowable>(exception_instance));
+      soa.Self()->SetException(exception_instance->AsThrowable());
     }
     return false;
   }
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index e0c2ea9..f25d446 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -434,8 +434,8 @@
   if (IsFinishedStarting()) {
     ScopedTrace trace2("Waiting for Daemons");
     self->ClearException();
-    self->GetJniEnv()->CallStaticVoidMethod(WellKnownClasses::java_lang_Daemons,
-                                            WellKnownClasses::java_lang_Daemons_stop);
+    ScopedObjectAccess soa(self);
+    WellKnownClasses::java_lang_Daemons_stop->InvokeStatic<'V'>(self);
   }
 
   // Shutdown any trace running.
@@ -1030,24 +1030,14 @@
                             GetInstructionSetString(kRuntimeISA));
   }
 
-  StartDaemonThreads();
-
-  // Make sure the environment is still clean (no lingering local refs from starting daemon
-  // threads).
   {
     ScopedObjectAccess soa(self);
+    StartDaemonThreads();
     self->GetJniEnv()->AssertLocalsEmpty();
-  }
 
-  // Send the initialized phase event. Send it after starting the Daemon threads so that agents
-  // cannot delay the daemon threads from starting forever.
-  {
-    ScopedObjectAccess soa(self);
+    // Send the initialized phase event. Send it after starting the Daemon threads so that agents
+    // cannot delay the daemon threads from starting forever.
     callbacks_->NextRuntimePhase(RuntimePhaseCallback::RuntimePhase::kInit);
-  }
-
-  {
-    ScopedObjectAccess soa(self);
     self->GetJniEnv()->AssertLocalsEmpty();
   }
 
@@ -1259,15 +1249,11 @@
 
   Thread* self = Thread::Current();
 
-  // Must be in the kNative state for calling native methods.
-  CHECK_EQ(self->GetState(), ThreadState::kNative);
+  DCHECK_EQ(self->GetState(), ThreadState::kRunnable);
 
-  JNIEnv* env = self->GetJniEnv();
-  env->CallStaticVoidMethod(WellKnownClasses::java_lang_Daemons,
-                            WellKnownClasses::java_lang_Daemons_start);
-  if (env->ExceptionCheck()) {
-    env->ExceptionDescribe();
-    LOG(FATAL) << "Error starting java.lang.Daemons";
+  WellKnownClasses::java_lang_Daemons_start->InvokeStatic<'V'>(self);
+  if (UNLIKELY(self->IsExceptionPending())) {
+    LOG(FATAL) << "Error starting java.lang.Daemons: " << self->GetException()->Dump();
   }
 
   VLOG(startup) << "Runtime::StartDaemonThreads exiting";
@@ -2172,10 +2158,6 @@
   // Set up the native methods provided by the runtime itself.
   RegisterRuntimeNativeMethods(env);
 
-  // Initialize classes used in JNI. The initialization requires runtime native
-  // methods to be loaded first.
-  WellKnownClasses::Init(env);
-
   // Then set up libjavacore / libopenjdk / libicu_jni ,which are just
   // a regular JNI libraries with a regular JNI_OnLoad. Most JNI libraries can
   // just use System.loadLibrary, but libcore can't because it's the library
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 89f4b82..d6f0e81 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -1188,7 +1188,7 @@
   void RegisterRuntimeNativeMethods(JNIEnv* env);
   void InitMetrics();
 
-  void StartDaemonThreads();
+  void StartDaemonThreads() REQUIRES_SHARED(Locks::mutator_lock_);
   void StartSignalCatcher();
 
   void MaybeSaveJitProfilingInfo();
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 6f99431..771df58 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -24,11 +24,11 @@
 #include <android-base/stringprintf.h>
 
 #include "art_method-inl.h"
+#include "base/casts.h"
 #include "base/enums.h"
 #include "class_linker.h"
 #include "class_root-inl.h"
 #include "entrypoints/quick/quick_entrypoints_enum.h"
-#include "entrypoints/runtime_asm_entrypoints.h"
 #include "handle_scope-inl.h"
 #include "hidden_api.h"
 #include "jni/java_vm_ext.h"
@@ -51,16 +51,12 @@
 jclass WellKnownClasses::dalvik_annotation_optimization_NeverInline;
 jclass WellKnownClasses::dalvik_system_EmulatedStackFrame;
 jclass WellKnownClasses::java_lang_annotation_Annotation__array;
-jclass WellKnownClasses::java_lang_Daemons;
 jclass WellKnownClasses::java_lang_Error;
 jclass WellKnownClasses::java_lang_IllegalAccessError;
 jclass WellKnownClasses::java_lang_NoClassDefFoundError;
 jclass WellKnownClasses::java_lang_Object;
 jclass WellKnownClasses::java_lang_OutOfMemoryError;
-jclass WellKnownClasses::java_lang_reflect_InvocationTargetException;
-jclass WellKnownClasses::java_lang_reflect_Parameter;
 jclass WellKnownClasses::java_lang_reflect_Parameter__array;
-jclass WellKnownClasses::java_lang_reflect_Proxy;
 jclass WellKnownClasses::java_lang_RuntimeException;
 jclass WellKnownClasses::java_lang_StackOverflowError;
 jclass WellKnownClasses::java_lang_StringFactory;
@@ -80,9 +76,9 @@
 ArtMethod* WellKnownClasses::java_lang_Character_valueOf;
 ArtMethod* WellKnownClasses::java_lang_ClassLoader_loadClass;
 ArtMethod* WellKnownClasses::java_lang_ClassNotFoundException_init;
-jmethodID WellKnownClasses::java_lang_Daemons_start;
-jmethodID WellKnownClasses::java_lang_Daemons_stop;
-jmethodID WellKnownClasses::java_lang_Daemons_waitForDaemonStart;
+ArtMethod* WellKnownClasses::java_lang_Daemons_start;
+ArtMethod* WellKnownClasses::java_lang_Daemons_stop;
+ArtMethod* WellKnownClasses::java_lang_Daemons_waitForDaemonStart;
 ArtMethod* WellKnownClasses::java_lang_Double_doubleToRawLongBits;
 ArtMethod* WellKnownClasses::java_lang_Double_valueOf;
 ArtMethod* WellKnownClasses::java_lang_Float_floatToRawIntBits;
@@ -93,13 +89,13 @@
 ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandles_lookup;
 ArtMethod* WellKnownClasses::java_lang_invoke_MethodHandles_Lookup_findConstructor;
 ArtMethod* WellKnownClasses::java_lang_Long_valueOf;
-jmethodID WellKnownClasses::java_lang_ref_FinalizerReference_add;
-jmethodID WellKnownClasses::java_lang_ref_ReferenceQueue_add;
-jmethodID WellKnownClasses::java_lang_reflect_InvocationTargetException_init;
-jmethodID WellKnownClasses::java_lang_reflect_Parameter_init;
-jmethodID WellKnownClasses::java_lang_reflect_Proxy_init;
-jmethodID WellKnownClasses::java_lang_reflect_Proxy_invoke;
-jmethodID WellKnownClasses::java_lang_Runtime_nativeLoad;
+ArtMethod* WellKnownClasses::java_lang_ref_FinalizerReference_add;
+ArtMethod* WellKnownClasses::java_lang_ref_ReferenceQueue_add;
+ArtMethod* WellKnownClasses::java_lang_reflect_InvocationTargetException_init;
+ArtMethod* WellKnownClasses::java_lang_reflect_Parameter_init;
+ArtMethod* WellKnownClasses::java_lang_reflect_Proxy_init;
+ArtMethod* WellKnownClasses::java_lang_reflect_Proxy_invoke;
+ArtMethod* WellKnownClasses::java_lang_Runtime_nativeLoad;
 ArtMethod* WellKnownClasses::java_lang_Short_valueOf;
 ArtMethod* WellKnownClasses::java_lang_String_charAt;
 ArtMethod* WellKnownClasses::java_lang_Thread_dispatchUncaughtException;
@@ -194,38 +190,6 @@
   return field;
 }
 
-static jmethodID CacheMethod(JNIEnv* env, jclass c, bool is_static,
-                             const char* name, const char* signature) {
-  jmethodID mid;
-  {
-    ScopedObjectAccess soa(env);
-    if (Runtime::Current()->GetJniIdType() != JniIdType::kSwapablePointer) {
-      mid = jni::EncodeArtMethod</*kEnableIndexIds*/ true>(
-          FindMethodJNI(soa, c, name, signature, is_static));
-    } else {
-      mid = jni::EncodeArtMethod</*kEnableIndexIds*/ false>(
-          FindMethodJNI(soa, c, name, signature, is_static));
-    }
-  }
-  if (mid == nullptr) {
-    ScopedObjectAccess soa(env);
-    if (soa.Self()->IsExceptionPending()) {
-      LOG(FATAL_WITHOUT_ABORT) << soa.Self()->GetException()->Dump();
-    }
-    std::ostringstream os;
-    WellKnownClasses::ToClass(c)->DumpClass(os, mirror::Class::kDumpClassFullDetail);
-    LOG(FATAL) << "Couldn't find method \"" << name << "\" with signature \"" << signature << "\": "
-               << os.str();
-  }
-  return mid;
-}
-
-static jmethodID CacheMethod(JNIEnv* env, const char* klass, bool is_static,
-                      const char* name, const char* signature) {
-  ScopedLocalRef<jclass> java_class(env, env->FindClass(klass));
-  return CacheMethod(env, java_class.get(), is_static, name, signature);
-}
-
 static ArtMethod* CacheMethod(ObjPtr<mirror::Class> klass,
                               bool is_static,
                               const char* name,
@@ -357,16 +321,12 @@
   dalvik_system_EmulatedStackFrame = CacheClass(env, "dalvik/system/EmulatedStackFrame");
 
   java_lang_annotation_Annotation__array = CacheClass(env, "[Ljava/lang/annotation/Annotation;");
-  java_lang_Daemons = CacheClass(env, "java/lang/Daemons");
   java_lang_Object = CacheClass(env, "java/lang/Object");
   java_lang_OutOfMemoryError = CacheClass(env, "java/lang/OutOfMemoryError");
   java_lang_Error = CacheClass(env, "java/lang/Error");
   java_lang_IllegalAccessError = CacheClass(env, "java/lang/IllegalAccessError");
   java_lang_NoClassDefFoundError = CacheClass(env, "java/lang/NoClassDefFoundError");
-  java_lang_reflect_InvocationTargetException = CacheClass(env, "java/lang/reflect/InvocationTargetException");
-  java_lang_reflect_Parameter = CacheClass(env, "java/lang/reflect/Parameter");
   java_lang_reflect_Parameter__array = CacheClass(env, "[Ljava/lang/reflect/Parameter;");
-  java_lang_reflect_Proxy = CacheClass(env, "java/lang/reflect/Proxy");
   java_lang_RuntimeException = CacheClass(env, "java/lang/RuntimeException");
   java_lang_StackOverflowError = CacheClass(env, "java/lang/StackOverflowError");
   java_lang_StringFactory = CacheClass(env, "java/lang/StringFactory");
@@ -381,7 +341,7 @@
   hiddenapi::ScopedHiddenApiEnforcementPolicySetting hiddenapi_exemption(
       hiddenapi::EnforcementPolicy::kDisabled);
 
-  Thread* self = Thread::Current();
+  Thread* self = down_cast<JNIEnvExt*>(env)->GetSelf();
   ScopedObjectAccess soa(self);
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
 
@@ -402,17 +362,7 @@
   java_lang_Short_valueOf =
       CachePrimitiveBoxingMethod(class_linker, self, 'S', "Ljava/lang/Short;");
 
-  java_lang_Daemons_start = CacheMethod(env, java_lang_Daemons, true, "start", "()V");
-  java_lang_Daemons_stop = CacheMethod(env, java_lang_Daemons, true, "stop", "()V");
-  java_lang_Daemons_waitForDaemonStart = CacheMethod(env, java_lang_Daemons, true, "waitForDaemonStart", "()V");
-
-  java_lang_ref_FinalizerReference_add = CacheMethod(env, "java/lang/ref/FinalizerReference", true, "add", "(Ljava/lang/Object;)V");
-  java_lang_ref_ReferenceQueue_add = CacheMethod(env, "java/lang/ref/ReferenceQueue", true, "add", "(Ljava/lang/ref/Reference;)V");
-
-  java_lang_reflect_InvocationTargetException_init = CacheMethod(env, java_lang_reflect_InvocationTargetException, false, "<init>", "(Ljava/lang/Throwable;)V");
-  java_lang_reflect_Parameter_init = CacheMethod(env, java_lang_reflect_Parameter, false, "<init>", "(Ljava/lang/String;ILjava/lang/reflect/Executable;I)V");
-
-  StackHandleScope<28u> hs(self);
+  StackHandleScope<33u> hs(self);
   Handle<mirror::Class> d_s_bdcl =
       hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/BaseDexClassLoader;"));
   Handle<mirror::Class> d_s_dlcl =
@@ -439,6 +389,8 @@
       hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/ClassLoader;"));
   Handle<mirror::Class> j_l_cnfe =
       hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/ClassNotFoundException;"));
+  Handle<mirror::Class> j_l_Daemons =
+      hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/Daemons;"));
   Handle<mirror::Class> j_l_Thread =
       hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/Thread;"));
   Handle<mirror::Class> j_l_tg =
@@ -449,6 +401,14 @@
       hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/invoke/MethodHandles;"));
   Handle<mirror::Class> j_l_i_MethodHandles_Lookup =
       hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/invoke/MethodHandles$Lookup;"));
+  Handle<mirror::Class> j_l_r_fr =
+      hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/ref/FinalizerReference;"));
+  Handle<mirror::Class> j_l_r_rq =
+      hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/ref/ReferenceQueue;"));
+  Handle<mirror::Class> j_l_rl_ite = hs.NewHandle(
+      FindSystemClass(class_linker, self, "Ljava/lang/reflect/InvocationTargetException;"));
+  Handle<mirror::Class> j_l_rl_Parameter =
+      hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/reflect/Parameter;"));
   Handle<mirror::Class> j_n_b =
       hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/nio/Buffer;"));
   Handle<mirror::Class> j_n_bb =
@@ -534,6 +494,13 @@
   java_lang_Float_floatToRawIntBits =
       CacheMethod(j_l_Float, /*is_static=*/ true, "floatToRawIntBits", "(F)I", pointer_size);
 
+  java_lang_Daemons_start = CacheMethod(
+      j_l_Daemons.Get(), /*is_static=*/ true, "start", "()V", pointer_size);
+  java_lang_Daemons_stop = CacheMethod(
+      j_l_Daemons.Get(), /*is_static=*/ true, "stop", "()V", pointer_size);
+  java_lang_Daemons_waitForDaemonStart = CacheMethod(
+      j_l_Daemons.Get(), /*is_static=*/ true, "waitForDaemonStart", "()V", pointer_size);
+
   ObjPtr<mirror::Class> j_l_String = GetClassRoot<mirror::String>(class_linker);
   java_lang_String_charAt = CacheMethod(
       j_l_String, /*is_static=*/ false, "charAt", "(I)C", pointer_size);
@@ -586,6 +553,34 @@
       "(Ljava/lang/Class;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;",
       pointer_size);
 
+  java_lang_ref_FinalizerReference_add = CacheMethod(
+      j_l_r_fr.Get(), /*is_static=*/ true, "add", "(Ljava/lang/Object;)V", pointer_size);
+  java_lang_ref_ReferenceQueue_add = CacheMethod(
+      j_l_r_rq.Get(), /*is_static=*/ true, "add", "(Ljava/lang/ref/Reference;)V", pointer_size);
+
+  java_lang_reflect_InvocationTargetException_init = CacheMethod(
+      j_l_rl_ite.Get(), /*is_static=*/ false, "<init>", "(Ljava/lang/Throwable;)V", pointer_size);
+  java_lang_reflect_Parameter_init = CacheMethod(
+      j_l_rl_Parameter.Get(),
+      /*is_static=*/ false,
+      "<init>",
+      "(Ljava/lang/String;ILjava/lang/reflect/Executable;I)V",
+      pointer_size);
+
+  ObjPtr<mirror::Class> j_l_rl_Proxy = GetClassRoot<mirror::Proxy>(class_linker);
+  java_lang_reflect_Proxy_init = CacheMethod(
+      j_l_rl_Proxy,
+      /*is_static=*/ false,
+      "<init>",
+      "(Ljava/lang/reflect/InvocationHandler;)V",
+      pointer_size);
+  java_lang_reflect_Proxy_invoke = CacheMethod(
+      j_l_rl_Proxy,
+      /*is_static=*/ true,
+      "invoke",
+      "(Ljava/lang/reflect/Proxy;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;",
+      pointer_size);
+
   java_nio_Buffer_isDirect =
       CacheMethod(j_n_b.Get(), /*is_static=*/ false, "isDirect", "()Z", pointer_size);
   java_nio_DirectByteBuffer_init =
@@ -716,26 +711,32 @@
 }
 
 void WellKnownClasses::LateInit(JNIEnv* env) {
-  // CacheField and CacheMethod will initialize their classes. Classes below
-  // have clinit sections that call JNI methods. Late init is required
-  // to make sure these JNI methods are available.
-  ScopedLocalRef<jclass> java_lang_Runtime(env, env->FindClass("java/lang/Runtime"));
-  java_lang_Runtime_nativeLoad =
-      CacheMethod(env, java_lang_Runtime.get(), true, "nativeLoad",
-                  "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/Class;)"
-                      "Ljava/lang/String;");
-  java_lang_reflect_Proxy_init =
-    CacheMethod(env, java_lang_reflect_Proxy, false, "<init>",
-                "(Ljava/lang/reflect/InvocationHandler;)V");
-  // This invariant is important since otherwise we will have the entire proxy invoke system
-  // confused.
-  DCHECK_NE(
-      jni::DecodeArtMethod(java_lang_reflect_Proxy_init)->GetEntryPointFromQuickCompiledCode(),
-      GetQuickInstrumentationEntryPoint());
-  java_lang_reflect_Proxy_invoke =
-    CacheMethod(env, java_lang_reflect_Proxy, true, "invoke",
-                "(Ljava/lang/reflect/Proxy;Ljava/lang/reflect/Method;"
-                    "[Ljava/lang/Object;)Ljava/lang/Object;");
+  // Initialize the `Runtime` class that was previously initialized
+  // by `CacheMethod()` calling `FindMethodJNI()`.
+  // TODO: Move this initialization to `ClassLinker`.
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  Thread* self = down_cast<JNIEnvExt*>(env)->GetSelf();
+  ScopedObjectAccess soa(self);
+  StackHandleScope<1u> hs(self);
+  Handle<mirror::Class> j_l_Runtime =
+      hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/Runtime;"));
+  bool success = class_linker->EnsureInitialized(
+      self, j_l_Runtime, /*can_init_fields=*/ true, /*can_init_parents=*/ true);
+  CHECK(success) << "Failed to initialize " << j_l_Runtime->PrettyDescriptor();
+
+  // The function `GetClassLoader()` in `jni_internal.cc` is checking if the caller
+  // is `java_lang_Runtime_nativeLoad` and, if so, returns the class loader override.
+  // However, this function is used several times between `WellKnownClasses::Init()`
+  // and setting up the override by the `Runtime` and requires that we take the other
+  // path, rather than returning the uninitialized override. Therefore we cannot
+  // initialize this well-known method early and require the `LateInit()`.
+  // TODO: Clean up the initialization steps.
+  java_lang_Runtime_nativeLoad = CacheMethod(
+      j_l_Runtime.Get(),
+      /*is_static=*/ true,
+      "nativeLoad",
+      "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/String;",
+      class_linker->GetImagePointerSize());
 }
 
 void WellKnownClasses::HandleJniIdTypeChange(JNIEnv* env) {
@@ -750,16 +751,12 @@
   dalvik_annotation_optimization_NeverInline = nullptr;
   dalvik_system_EmulatedStackFrame = nullptr;
   java_lang_annotation_Annotation__array = nullptr;
-  java_lang_Daemons = nullptr;
   java_lang_Error = nullptr;
   java_lang_IllegalAccessError = nullptr;
   java_lang_NoClassDefFoundError = nullptr;
   java_lang_Object = nullptr;
   java_lang_OutOfMemoryError = nullptr;
-  java_lang_reflect_InvocationTargetException = nullptr;
-  java_lang_reflect_Parameter = nullptr;
   java_lang_reflect_Parameter__array = nullptr;
-  java_lang_reflect_Proxy = nullptr;
   java_lang_RuntimeException = nullptr;
   java_lang_StackOverflowError = nullptr;
   java_lang_StringFactory = nullptr;
@@ -782,6 +779,7 @@
   java_lang_ClassNotFoundException_init = nullptr;
   java_lang_Daemons_start = nullptr;
   java_lang_Daemons_stop = nullptr;
+  java_lang_Daemons_waitForDaemonStart = nullptr;
   java_lang_Double_doubleToRawLongBits = nullptr;
   java_lang_Double_valueOf = nullptr;
   java_lang_Float_floatToRawIntBits = nullptr;
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index f3da722..56e49db 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -96,16 +96,12 @@
   static jclass dalvik_annotation_optimization_NeverInline;
   static jclass dalvik_system_EmulatedStackFrame;
   static jclass java_lang_annotation_Annotation__array;
-  static jclass java_lang_Daemons;
   static jclass java_lang_Error;
   static jclass java_lang_IllegalAccessError;
   static jclass java_lang_NoClassDefFoundError;
   static jclass java_lang_Object;
   static jclass java_lang_OutOfMemoryError;
-  static jclass java_lang_reflect_InvocationTargetException;
-  static jclass java_lang_reflect_Parameter;
   static jclass java_lang_reflect_Parameter__array;
-  static jclass java_lang_reflect_Proxy;
   static jclass java_lang_RuntimeException;
   static jclass java_lang_StackOverflowError;
   static jclass java_lang_StringFactory;
@@ -125,9 +121,9 @@
   static ArtMethod* java_lang_Character_valueOf;
   static ArtMethod* java_lang_ClassLoader_loadClass;
   static ArtMethod* java_lang_ClassNotFoundException_init;
-  static jmethodID java_lang_Daemons_start;
-  static jmethodID java_lang_Daemons_stop;
-  static jmethodID java_lang_Daemons_waitForDaemonStart;
+  static ArtMethod* java_lang_Daemons_start;
+  static ArtMethod* java_lang_Daemons_stop;
+  static ArtMethod* java_lang_Daemons_waitForDaemonStart;
   static ArtMethod* java_lang_Double_doubleToRawLongBits;
   static ArtMethod* java_lang_Double_valueOf;
   static ArtMethod* java_lang_Float_floatToRawIntBits;
@@ -138,13 +134,13 @@
   static ArtMethod* java_lang_invoke_MethodHandles_lookup;
   static ArtMethod* java_lang_invoke_MethodHandles_Lookup_findConstructor;
   static ArtMethod* java_lang_Long_valueOf;
-  static jmethodID java_lang_ref_FinalizerReference_add;
-  static jmethodID java_lang_ref_ReferenceQueue_add;
-  static jmethodID java_lang_reflect_InvocationTargetException_init;
-  static jmethodID java_lang_reflect_Parameter_init;
-  static jmethodID java_lang_reflect_Proxy_init;
-  static jmethodID java_lang_reflect_Proxy_invoke;
-  static jmethodID java_lang_Runtime_nativeLoad;
+  static ArtMethod* java_lang_ref_FinalizerReference_add;
+  static ArtMethod* java_lang_ref_ReferenceQueue_add;
+  static ArtMethod* java_lang_reflect_InvocationTargetException_init;
+  static ArtMethod* java_lang_reflect_Parameter_init;
+  static ArtMethod* java_lang_reflect_Proxy_init;
+  static ArtMethod* java_lang_reflect_Proxy_invoke;
+  static ArtMethod* java_lang_Runtime_nativeLoad;
   static ArtMethod* java_lang_Short_valueOf;
   static ArtMethod* java_lang_String_charAt;
   static ArtMethod* java_lang_Thread_dispatchUncaughtException;
@@ -222,8 +218,13 @@
       dalvik_system_PathClassLoader;
   static constexpr ClassFromMethod<&java_lang_BootClassLoader_init> java_lang_BootClassLoader;
   static constexpr ClassFromField<&java_lang_ClassLoader_parent> java_lang_ClassLoader;
+  static constexpr ClassFromMethod<&java_lang_Daemons_start> java_lang_Daemons;
   static constexpr ClassFromField<&java_lang_Thread_daemon> java_lang_Thread;
   static constexpr ClassFromField<&java_lang_ThreadGroup_groups> java_lang_ThreadGroup;
+  static constexpr ClassFromMethod<&java_lang_reflect_InvocationTargetException_init>
+      java_lang_reflect_InvocationTargetException;
+  static constexpr ClassFromMethod<&java_lang_reflect_Parameter_init>
+      java_lang_reflect_Parameter;
   static constexpr ClassFromField<&java_nio_Buffer_address> java_nio_Buffer;
   static constexpr ClassFromField<&java_util_Collections_EMPTY_LIST> java_util_Collections;
   static constexpr ClassFromField<&libcore_util_EmptyArray_STACK_TRACE_ELEMENT>