diff options
author | 2022-11-29 08:47:02 +0000 | |
---|---|---|
committer | 2022-12-02 08:38:22 +0000 | |
commit | addc2d15385721950ce977bbddc9221edc4c8c49 (patch) | |
tree | b49dd895b1ed0d49087d5237d99c364ac65cf347 | |
parent | 7dde6edda2bc0091f54a2d07ff80d124090fa964 (diff) |
Change remaining well known methods to `ArtMethod*`.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I9cfef2a2c302f70826ac762202421388213e60e6
-rw-r--r-- | dex2oat/dex2oat.cc | 2 | ||||
-rw-r--r-- | openjdkjvmti/ti_thread.cc | 7 | ||||
-rw-r--r-- | runtime/class_linker.cc | 31 | ||||
-rw-r--r-- | runtime/common_runtime_test.cc | 1 | ||||
-rw-r--r-- | runtime/entrypoints/entrypoint_utils.cc | 65 | ||||
-rw-r--r-- | runtime/gc/heap.cc | 11 | ||||
-rw-r--r-- | runtime/gc/reference_processor.cc | 5 | ||||
-rw-r--r-- | runtime/instrumentation.cc | 3 | ||||
-rw-r--r-- | runtime/jni/jni_internal.cc | 3 | ||||
-rw-r--r-- | runtime/native/java_lang_reflect_Executable.cc | 46 | ||||
-rw-r--r-- | runtime/proxy_test.cc | 11 | ||||
-rw-r--r-- | runtime/reflection.cc | 14 | ||||
-rw-r--r-- | runtime/runtime.cc | 36 | ||||
-rw-r--r-- | runtime/runtime.h | 2 | ||||
-rw-r--r-- | runtime/well_known_classes.cc | 172 | ||||
-rw-r--r-- | runtime/well_known_classes.h | 29 |
16 files changed, 205 insertions, 233 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index f2e0a6edab..1754a68955 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 @@ class Dex2Oat final { 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 0c0b569739..b5bc35e7e6 100644 --- a/openjdkjvmti/ti_thread.cc +++ b/openjdkjvmti/ti_thread.cc @@ -174,12 +174,7 @@ void ThreadUtil::VMInitEventSent() { 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 a421461d96..a51e28f70c 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1108,8 +1108,17 @@ void ClassLinker::RunEarlyRootClinits(Thread* self) { 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 @@ void ClassLinker::RunRootClinits(Thread* self) { 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 @@ void ClassLinker::RunRootClinits(Thread* self) { 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 @@ void ClassLinker::CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod* // 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 6a22a6680d..0e8a96278b 100644 --- a/runtime/common_runtime_test.cc +++ b/runtime/common_runtime_test.cc @@ -160,7 +160,6 @@ void CommonRuntimeTestImpl::FinalizeSetup() { 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 63d2aa4351..ae6e98a544 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 @@ JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, 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 55af72097e..3bda43d1ff 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -3826,12 +3826,11 @@ void Heap::ClearGrowthLimit() { 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 772174f885..f24c94279c 100644 --- a/runtime/gc/reference_processor.cc +++ b/runtime/gc/reference_processor.cc @@ -363,9 +363,8 @@ class ClearedReferenceTask : public HeapTask { } 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 c7393eb25f..6c68cdb701 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -196,8 +196,7 @@ static bool IsProxyInit(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) // 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 8e6e84fc8c..ad2efc5944 100644 --- a/runtime/jni/jni_internal.cc +++ b/runtime/jni/jni_internal.cc @@ -393,8 +393,7 @@ static ObjPtr<mirror::ClassLoader> GetClassLoader(const ScopedObjectAccess& soa) 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 adf81dcb17..87c9f6c341 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_getParameterAnnotationsNative(JNIEnv* env, jobjec 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 @@ static jobjectArray Executable_getParameters0(JNIEnv* env, jobject javaMethod) { 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(); - 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())) { + DCHECK(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 7b662106b3..ac8ec56f09 100644 --- a/runtime/proxy_test.cc +++ b/runtime/proxy_test.cc @@ -33,17 +33,6 @@ class ProxyTest : public CommonRuntimeTest { 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 7ddf64d7dd..bfe9c8ff07 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 @@ bool InvokeMethodImpl(const ScopedObjectAccessAlreadyRunnable& soa, << 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 e0c2ea9000..f25d446a79 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -434,8 +434,8 @@ Runtime::~Runtime() { 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 @@ bool Runtime::Start() { 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 @@ void Runtime::StartDaemonThreads() { 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 @@ void Runtime::InitNativeMethods() { // 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 89f4b82be9..d6f0e81a71 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -1188,7 +1188,7 @@ class Runtime { 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 6f994316fc..771df58d89 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_NeverCompile; 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_Byte_valueOf; 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_MethodHandle_invokeExact; 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 @@ static ArtField* CacheField(ObjPtr<mirror::Class> klass, 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 @@ void WellKnownClasses::Init(JNIEnv* env) { 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 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { 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 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { 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 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { 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 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { 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 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { 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 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { "(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::InitFieldsAndMethodsOnly(JNIEnv* env) { } 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 @@ void WellKnownClasses::Clear() { 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 @@ void WellKnownClasses::Clear() { 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 f3da722f9e..56e49dbf72 100644 --- a/runtime/well_known_classes.h +++ b/runtime/well_known_classes.h @@ -96,16 +96,12 @@ struct WellKnownClasses { 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 @@ struct WellKnownClasses { 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 @@ struct WellKnownClasses { 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 @@ struct WellKnownClasses { 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> |