diff options
-rw-r--r-- | dex2oat/driver/compiler_driver.cc | 14 | ||||
-rw-r--r-- | openjdkjvmti/ti_class.cc | 84 | ||||
-rw-r--r-- | openjdkjvmti/ti_class_loader.cc | 6 | ||||
-rw-r--r-- | openjdkjvmti/ti_search.cc | 45 | ||||
-rw-r--r-- | runtime/class_linker.cc | 105 | ||||
-rw-r--r-- | runtime/class_linker.h | 30 | ||||
-rw-r--r-- | runtime/class_loader_context.cc | 12 | ||||
-rw-r--r-- | runtime/class_loader_context_test.cc | 117 | ||||
-rw-r--r-- | runtime/class_loader_utils.h | 18 | ||||
-rw-r--r-- | runtime/common_runtime_test.cc | 75 | ||||
-rw-r--r-- | runtime/common_runtime_test.h | 9 | ||||
-rw-r--r-- | runtime/debug_print.cc | 10 | ||||
-rw-r--r-- | runtime/hidden_api_test.cc | 6 | ||||
-rw-r--r-- | runtime/interpreter/unstarted_runtime.cc | 5 | ||||
-rw-r--r-- | runtime/jni/java_vm_ext.cc | 12 | ||||
-rw-r--r-- | runtime/native/java_lang_Class.cc | 29 | ||||
-rw-r--r-- | runtime/well_known_classes.cc | 122 | ||||
-rw-r--r-- | runtime/well_known_classes.h | 31 | ||||
-rw-r--r-- | test/ti-agent/jni_helper.h | 2 |
19 files changed, 376 insertions, 356 deletions
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc index f374ab3b3e..bb3925613d 100644 --- a/dex2oat/driver/compiler_driver.cc +++ b/dex2oat/driver/compiler_driver.cc @@ -1043,16 +1043,16 @@ static void VerifyClassLoaderClassesAreImageClasses(/* out */ HashSet<std::strin ScopedObjectAccess soa(Thread::Current()); ScopedAssertNoThreadSuspension sants(__FUNCTION__); ObjPtr<mirror::Class> class_loader_classes[] = { - soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_BaseDexClassLoader), - soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader), - soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DexClassLoader), + WellKnownClasses::dalvik_system_BaseDexClassLoader.Get(), + WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(), + WellKnownClasses::dalvik_system_DexClassLoader.Get(), WellKnownClasses::dalvik_system_DexFile.Get(), WellKnownClasses::dalvik_system_DexPathList.Get(), WellKnownClasses::dalvik_system_DexPathList__Element.Get(), - soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_InMemoryDexClassLoader), - soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader), - soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader), - soa.Decode<mirror::Class>(WellKnownClasses::java_lang_ClassLoader), + WellKnownClasses::dalvik_system_InMemoryDexClassLoader.Get(), + WellKnownClasses::dalvik_system_PathClassLoader.Get(), + WellKnownClasses::java_lang_BootClassLoader.Get(), + WellKnownClasses::java_lang_ClassLoader.Get(), }; for (ObjPtr<mirror::Class> klass : class_loader_classes) { std::string temp; diff --git a/openjdkjvmti/ti_class.cc b/openjdkjvmti/ti_class.cc index 50dab1fe09..37ceb37958 100644 --- a/openjdkjvmti/ti_class.cc +++ b/openjdkjvmti/ti_class.cc @@ -80,7 +80,7 @@ #include "ti_phase.h" #include "ti_redefine.h" #include "transform.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace openjdkjvmti { @@ -927,40 +927,42 @@ jvmtiError ClassUtil::GetClassLoaderClassDescriptors(jvmtiEnv* env, } else if (count_ptr == nullptr || classes == nullptr) { return ERR(NULL_POINTER); } - art::JNIEnvExt* jnienv = self->GetJniEnv(); - if (loader == nullptr || - jnienv->IsInstanceOf(loader, art::WellKnownClasses::java_lang_BootClassLoader)) { + std::vector<const art::DexFile*> dex_files_storage; + const std::vector<const art::DexFile*>* dex_files = nullptr; + if (loader == nullptr) { // We can just get the dex files directly for the boot class path. - return CopyClassDescriptors(env, - art::Runtime::Current()->GetClassLinker()->GetBootClassPath(), - count_ptr, - classes); - } - if (!jnienv->IsInstanceOf(loader, art::WellKnownClasses::java_lang_ClassLoader)) { - return ERR(ILLEGAL_ARGUMENT); - } else if (!jnienv->IsInstanceOf(loader, - art::WellKnownClasses::dalvik_system_BaseDexClassLoader)) { - JVMTI_LOG(ERROR, env) << "GetClassLoaderClassDescriptors is only implemented for " - << "BootClassPath and dalvik.system.BaseDexClassLoader class loaders"; - // TODO Possibly return OK With no classes would be better since these ones cannot have any - // real classes associated with them. - return ERR(NOT_IMPLEMENTED); + dex_files = &art::Runtime::Current()->GetClassLinker()->GetBootClassPath(); + } else { + art::ScopedObjectAccess soa(self); + art::StackHandleScope<1> hs(self); + art::Handle<art::mirror::ClassLoader> class_loader( + hs.NewHandle(soa.Decode<art::mirror::ClassLoader>(loader))); + if (class_loader->InstanceOf(art::WellKnownClasses::java_lang_BootClassLoader.Get())) { + // We can just get the dex files directly for the boot class path. + dex_files = &art::Runtime::Current()->GetClassLinker()->GetBootClassPath(); + } else if (!class_loader->InstanceOf(art::WellKnownClasses::java_lang_ClassLoader.Get())) { + return ERR(ILLEGAL_ARGUMENT); + } else if (!class_loader->InstanceOf( + art::WellKnownClasses::dalvik_system_BaseDexClassLoader.Get())) { + JVMTI_LOG(ERROR, env) << "GetClassLoaderClassDescriptors is only implemented for " + << "BootClassPath and dalvik.system.BaseDexClassLoader class loaders"; + // TODO Possibly return OK With no classes would be better since these ones cannot have any + // real classes associated with them. + return ERR(NOT_IMPLEMENTED); + } else { + art::VisitClassLoaderDexFiles( + self, + class_loader, + [&](const art::DexFile* dex_file) { + dex_files_storage.push_back(dex_file); + return true; // Continue with other dex files. + }); + dex_files = &dex_files_storage; + } } - - art::ScopedObjectAccess soa(self); - art::StackHandleScope<1> hs(self); - art::Handle<art::mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<art::mirror::ClassLoader>(loader))); - std::vector<const art::DexFile*> dex_files; - art::VisitClassLoaderDexFiles( - self, - class_loader, - [&](const art::DexFile* dex_file) { - dex_files.push_back(dex_file); - return true; // Continue with other dex files. - }); // We hold the loader so the dex files won't go away until after this call at worst. - return CopyClassDescriptors(env, dex_files, count_ptr, classes); + DCHECK(dex_files != nullptr); + return CopyClassDescriptors(env, *dex_files, count_ptr, classes); } jvmtiError ClassUtil::GetClassLoaderClasses(jvmtiEnv* env, @@ -973,19 +975,17 @@ jvmtiError ClassUtil::GetClassLoaderClasses(jvmtiEnv* env, return ERR(NULL_POINTER); } art::Thread* self = art::Thread::Current(); - if (!self->GetJniEnv()->IsInstanceOf(initiating_loader, - art::WellKnownClasses::java_lang_ClassLoader)) { - return ERR(ILLEGAL_ARGUMENT); - } - if (self->GetJniEnv()->IsInstanceOf(initiating_loader, - art::WellKnownClasses::java_lang_BootClassLoader)) { - // Need to use null for the BootClassLoader. - initiating_loader = nullptr; - } - art::ScopedObjectAccess soa(self); art::ObjPtr<art::mirror::ClassLoader> class_loader = soa.Decode<art::mirror::ClassLoader>(initiating_loader); + if (class_loader == nullptr) { + // Keep null, meaning the boot class loader. + } else if (!class_loader->InstanceOf(art::WellKnownClasses::java_lang_ClassLoader.Get())) { + return ERR(ILLEGAL_ARGUMENT); + } else if (class_loader->InstanceOf(art::WellKnownClasses::java_lang_BootClassLoader.Get())) { + // Need to use null for the BootClassLoader. + class_loader = nullptr; + } art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker(); diff --git a/openjdkjvmti/ti_class_loader.cc b/openjdkjvmti/ti_class_loader.cc index 72d57f0588..c117937f5f 100644 --- a/openjdkjvmti/ti_class_loader.cc +++ b/openjdkjvmti/ti_class_loader.cc @@ -57,6 +57,7 @@ #include "object_lock.h" #include "runtime.h" #include "transform.h" +#include "well_known_classes-inl.h" namespace openjdkjvmti { @@ -139,9 +140,8 @@ art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> ClassLoaderHelper::Ge art::Handle<art::mirror::ClassLoader> loader) { art::StackHandleScope<4> hs(self); - art::Handle<art::mirror::Class> - base_dex_loader_class(hs.NewHandle(self->DecodeJObject( - art::WellKnownClasses::dalvik_system_BaseDexClassLoader)->AsClass())); + art::Handle<art::mirror::Class> base_dex_loader_class = + hs.NewHandle(art::WellKnownClasses::dalvik_system_BaseDexClassLoader.Get()); // Get all the ArtFields so we can look in the BaseDexClassLoader art::ArtField* path_list_field = diff --git a/openjdkjvmti/ti_search.cc b/openjdkjvmti/ti_search.cc index 5c1677fea3..4d96732494 100644 --- a/openjdkjvmti/ti_search.cc +++ b/openjdkjvmti/ti_search.cc @@ -60,7 +60,7 @@ #include "thread_list.h" #include "ti_logging.h" #include "ti_phase.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace openjdkjvmti { @@ -339,33 +339,33 @@ jvmtiError SearchUtil::AddToDexClassLoader(jvmtiEnv* jvmti_env, // exceptions are swallowed. art::Thread* self = art::Thread::Current(); - JNIEnv* env = self->GetJniEnv(); - if (!env->IsInstanceOf(classloader, art::WellKnownClasses::dalvik_system_BaseDexClassLoader)) { + art::ScopedObjectAccess soa(self); + art::StackHandleScope<2u> hs(self); + art::Handle<art::mirror::ClassLoader> class_loader = + hs.NewHandle(soa.Decode<art::mirror::ClassLoader>(classloader)); + if (!class_loader->InstanceOf(art::WellKnownClasses::dalvik_system_BaseDexClassLoader.Get())) { JVMTI_LOG(ERROR, jvmti_env) << "Unable to add " << segment << " to non BaseDexClassLoader!"; return ERR(CLASS_LOADER_UNSUPPORTED); } - jmethodID add_dex_path_id = env->GetMethodID( - art::WellKnownClasses::dalvik_system_BaseDexClassLoader, - "addDexPath", - "(Ljava/lang/String;)V"); + art::ArtMethod* add_dex_path_id = + art::WellKnownClasses::dalvik_system_BaseDexClassLoader->FindClassMethod( + "addDexPath", "(Ljava/lang/String;)V", art::kRuntimePointerSize); if (add_dex_path_id == nullptr) { return ERR(INTERNAL); } - ScopedLocalRef<jstring> dex_path(env, env->NewStringUTF(segment)); - if (dex_path.get() == nullptr) { + art::Handle<art::mirror::String> dex_path = + hs.NewHandle(art::mirror::String::AllocFromModifiedUtf8(self, segment)); + if (dex_path == nullptr) { return ERR(INTERNAL); } - env->CallVoidMethod(classloader, add_dex_path_id, dex_path.get()); - if (env->ExceptionCheck()) { - { - art::ScopedObjectAccess soa(self); - JVMTI_LOG(ERROR, jvmti_env) << "Failed to add " << segment << " to classloader. Error was " - << self->GetException()->Dump(); - } - env->ExceptionClear(); + add_dex_path_id->InvokeVirtual<'V', 'L'>(self, class_loader.Get(), dex_path.Get()); + if (self->IsExceptionPending()) { + JVMTI_LOG(ERROR, jvmti_env) << "Failed to add " << segment << " to classloader. Error was " + << self->GetException()->Dump(); + self->ClearException(); return ERR(ILLEGAL_ARGUMENT); } return OK; @@ -392,10 +392,13 @@ jvmtiError SearchUtil::AddToSystemClassLoaderSearch(jvmtiEnv* jvmti_env, const c return ERR(INTERNAL); } - art::Thread* self = art::Thread::Current(); - JNIEnv* env = self->GetJniEnv(); - if (!env->IsInstanceOf(loader, art::WellKnownClasses::dalvik_system_BaseDexClassLoader)) { - return ERR(INTERNAL); + { + art::ScopedObjectAccess soa(art::Thread::Current()); + art::ObjPtr<art::mirror::ClassLoader> class_loader = + soa.Decode<art::mirror::ClassLoader>(loader); + if (!class_loader->InstanceOf(art::WellKnownClasses::dalvik_system_BaseDexClassLoader.Get())) { + return ERR(INTERNAL); + } } return AddToDexClassLoader(jvmti_env, loader, segment); diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 6480dfd249..a421461d96 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1141,6 +1141,13 @@ void ClassLinker::RunRootClinits(Thread* self) { WellKnownClasses::java_lang_Integer_valueOf, 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. + 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 `Thread` and `ThreadGroup` classes are initialized (avoid check at runtime). WellKnownClasses::java_lang_Thread_init, WellKnownClasses::java_lang_ThreadGroup_add, @@ -1159,6 +1166,10 @@ void ClassLinker::RunRootClinits(Thread* self) { EnsureRootInitialized(this, self, method->GetDeclaringClass()); } ArtField* static_fields_of_classes_to_initialize[] = { + // Ensure classes used by class loaders are initialized (avoid check at runtime). + WellKnownClasses::dalvik_system_DexFile_cookie, + WellKnownClasses::dalvik_system_DexPathList_dexElements, + WellKnownClasses::dalvik_system_DexPathList__Element_dexFile, // Ensure `VMRuntime` is initialized (avoid check at runtime). WellKnownClasses::dalvik_system_VMRuntime_nonSdkApiUsageConsumer, // Initialize empty arrays needed by `StackOverflowError`. @@ -1410,8 +1421,7 @@ void ClassLinker::AddExtraBootDexFiles( bool ClassLinker::IsBootClassLoader(ObjPtr<mirror::ClassLoader> class_loader) { return class_loader == nullptr || - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader) == - class_loader->GetClass(); + WellKnownClasses::java_lang_BootClassLoader == class_loader->GetClass(); } class CHAOnDeleteUpdateClassVisitor { @@ -3054,29 +3064,23 @@ ObjPtr<mirror::Class> ClassLinker::FindClass(Thread* self, "%s", class_name_string.c_str()); } else { - ScopedLocalRef<jobject> class_loader_object( - soa.Env(), soa.AddLocalReference<jobject>(class_loader.Get())); - ScopedLocalRef<jobject> result(soa.Env(), nullptr); - { - ScopedThreadStateChange tsc(self, ThreadState::kNative); - ScopedLocalRef<jobject> class_name_object( - soa.Env(), soa.Env()->NewStringUTF(class_name_string.c_str())); - if (class_name_object.get() == nullptr) { - DCHECK(self->IsExceptionPending()); // OOME. - return nullptr; - } - CHECK(class_loader_object.get() != nullptr); - result.reset(soa.Env()->CallObjectMethod(class_loader_object.get(), - WellKnownClasses::java_lang_ClassLoader_loadClass, - class_name_object.get())); + StackHandleScope<1u> hs(self); + Handle<mirror::String> class_name_object = hs.NewHandle( + mirror::String::AllocFromModifiedUtf8(self, class_name_string.c_str())); + if (class_name_object == nullptr) { + DCHECK(self->IsExceptionPending()); // OOME. + return nullptr; } - if (result.get() == nullptr && !self->IsExceptionPending()) { + DCHECK(class_loader != nullptr); + result_ptr = ObjPtr<mirror::Class>::DownCast( + WellKnownClasses::java_lang_ClassLoader_loadClass->InvokeVirtual<'L', 'L'>( + self, class_loader.Get(), class_name_object.Get())); + if (result_ptr == nullptr && !self->IsExceptionPending()) { // broken loader - throw NPE to be compatible with Dalvik ThrowNullPointerException(StringPrintf("ClassLoader.loadClass returned null for %s", class_name_string.c_str()).c_str()); return nullptr; } - result_ptr = soa.Decode<mirror::Class>(result.get()); // Check the name of the returned class. descriptor_equals = (result_ptr != nullptr) && result_ptr->DescriptorEquals(descriptor); } @@ -10088,6 +10092,9 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader( Handle<mirror::ClassLoader> parent_loader, Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries, Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_after) { + CHECK(loader_class.Get() == WellKnownClasses::dalvik_system_PathClassLoader || + loader_class.Get() == WellKnownClasses::dalvik_system_DelegateLastClassLoader || + loader_class.Get() == WellKnownClasses::dalvik_system_InMemoryDexClassLoader); StackHandleScope<5> hs(self); @@ -10190,9 +10197,8 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader( ArtField* const parent_field = WellKnownClasses::java_lang_ClassLoader_parent; DCHECK(parent_field != nullptr); if (parent_loader.Get() == nullptr) { - ScopedObjectAccessUnchecked soa(self); - ObjPtr<mirror::Object> boot_loader(WellKnownClasses::ToClass( - WellKnownClasses::java_lang_BootClassLoader)->AllocObject(self)); + ObjPtr<mirror::Object> boot_loader( + WellKnownClasses::java_lang_BootClassLoader->AllocObject(self)); parent_field->SetObject<false>(h_class_loader.Get(), boot_loader); } else { parent_field->SetObject<false>(h_class_loader.Get(), parent_loader.Get()); @@ -10211,55 +10217,16 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader( return h_class_loader.Get(); } -jobject ClassLinker::CreateWellKnownClassLoader(Thread* self, - const std::vector<const DexFile*>& dex_files, - jclass loader_class, - jobject parent_loader, - jobject shared_libraries, - jobject shared_libraries_after) { - CHECK(self->GetJniEnv()->IsSameObject(loader_class, - WellKnownClasses::dalvik_system_PathClassLoader) || - self->GetJniEnv()->IsSameObject(loader_class, - WellKnownClasses::dalvik_system_DelegateLastClassLoader) || - self->GetJniEnv()->IsSameObject(loader_class, - WellKnownClasses::dalvik_system_InMemoryDexClassLoader)); - - // SOAAlreadyRunnable is protected, and we need something to add a global reference. - // We could move the jobject to the callers, but all call-sites do this... - ScopedObjectAccessUnchecked soa(self); - - // For now, create a libcore-level DexFile for each ART DexFile. This "explodes" multidex. - StackHandleScope<5> hs(self); - - Handle<mirror::Class> h_loader_class = - hs.NewHandle<mirror::Class>(soa.Decode<mirror::Class>(loader_class)); - Handle<mirror::ClassLoader> h_parent = - hs.NewHandle<mirror::ClassLoader>(soa.Decode<mirror::ClassLoader>(parent_loader)); - Handle<mirror::ObjectArray<mirror::ClassLoader>> h_shared_libraries = - hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::ClassLoader>>(shared_libraries)); - Handle<mirror::ObjectArray<mirror::ClassLoader>> h_shared_libraries_after = - hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::ClassLoader>>(shared_libraries_after)); - - ObjPtr<mirror::ClassLoader> loader = CreateWellKnownClassLoader( - self, - dex_files, - h_loader_class, - h_parent, - h_shared_libraries, - h_shared_libraries_after); - - // Make it a global ref and return. - ScopedLocalRef<jobject> local_ref( - soa.Env(), soa.Env()->AddLocalReference<jobject>(loader)); - return soa.Env()->NewGlobalRef(local_ref.get()); -} - jobject ClassLinker::CreatePathClassLoader(Thread* self, const std::vector<const DexFile*>& dex_files) { - return CreateWellKnownClassLoader(self, - dex_files, - WellKnownClasses::dalvik_system_PathClassLoader, - nullptr); + StackHandleScope<3u> hs(self); + Handle<mirror::Class> d_s_pcl = + hs.NewHandle(WellKnownClasses::dalvik_system_PathClassLoader.Get()); + auto null_parent = hs.NewHandle<mirror::ClassLoader>(nullptr); + auto null_libs = hs.NewHandle<mirror::ObjectArray<mirror::ClassLoader>>(nullptr); + ObjPtr<mirror::ClassLoader> class_loader = + CreateWellKnownClassLoader(self, dex_files, d_s_pcl, null_parent, null_libs, null_libs); + return Runtime::Current()->GetJavaVM()->AddGlobalRef(self, class_loader); } void ClassLinker::DropFindArrayClassCache() { diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 5f674b855a..37e9979395 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -670,31 +670,19 @@ class ClassLinker { REQUIRES(!Locks::classlinker_classes_lock_) REQUIRES_SHARED(Locks::mutator_lock_); - // Creates a GlobalRef PathClassLoader or DelegateLastClassLoader (specified by loader_class) - // that can be used to load classes from the given dex files. The parent of the class loader - // will be set to `parent_loader`. If `parent_loader` is null the parent will be - // the boot class loader. - // If class_loader points to a different class than PathClassLoader or DelegateLastClassLoader - // this method will abort. - // Note: the objects are not completely set up. Do not use this outside of tests and the compiler. - jobject CreateWellKnownClassLoader(Thread* self, - const std::vector<const DexFile*>& dex_files, - jclass loader_class, - jobject parent_loader, - jobject shared_libraries = nullptr, - jobject shared_libraries_after = nullptr) - REQUIRES_SHARED(Locks::mutator_lock_) - REQUIRES(!Locks::dex_lock_); - - // Calls CreateWellKnownClassLoader(self, - // dex_files, - // WellKnownClasses::dalvik_system_PathClassLoader, - // nullptr) + // Calls `CreateWellKnownClassLoader()` with `WellKnownClasses::dalvik_system_PathClassLoader`, + // and null parent and libraries. Wraps the result in a JNI global reference. jobject CreatePathClassLoader(Thread* self, const std::vector<const DexFile*>& dex_files) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_); - // Non-GlobalRef version of CreateWellKnownClassLoader + // Creates a `PathClassLoader`, `DelegateLastClassLoader` or `InMemoryDexClassLoader` + // (specified by loader_class) that can be used to load classes from the given dex files. + // The parent of the class loader will be set to `parent_loader`. If `parent_loader` is + // null the parent will be the boot class loader. + // If `loader_class` points to a different class than `PathClassLoader`, + // `DelegateLastClassLoader` or `InMemoryDexClassLoader` this method will abort. + // Note: the objects are not completely set up. Do not use this outside of tests and the compiler. ObjPtr<mirror::ClassLoader> CreateWellKnownClassLoader( Thread* self, const std::vector<const DexFile*>& dex_files, diff --git a/runtime/class_loader_context.cc b/runtime/class_loader_context.cc index f2988c1fbc..722b8f7a64 100644 --- a/runtime/class_loader_context.cc +++ b/runtime/class_loader_context.cc @@ -778,14 +778,15 @@ void ClassLoaderContext::EncodeSharedLibAndParent(const ClassLoaderInfo& info, } // Returns the WellKnownClass for the given class loader type. -static jclass GetClassLoaderClass(ClassLoaderContext::ClassLoaderType type) { +static ObjPtr<mirror::Class> GetClassLoaderClass(ClassLoaderContext::ClassLoaderType type) + REQUIRES_SHARED(Locks::mutator_lock_) { switch (type) { case ClassLoaderContext::kPathClassLoader: - return WellKnownClasses::dalvik_system_PathClassLoader; + return WellKnownClasses::dalvik_system_PathClassLoader.Get(); case ClassLoaderContext::kDelegateLastClassLoader: - return WellKnownClasses::dalvik_system_DelegateLastClassLoader; + return WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(); case ClassLoaderContext::kInMemoryDexClassLoader: - return WellKnownClasses::dalvik_system_InMemoryDexClassLoader; + return WellKnownClasses::dalvik_system_InMemoryDexClassLoader.Get(); case ClassLoaderContext::kInvalidClassLoader: break; // will fail after the switch. } LOG(FATAL) << "Invalid class loader type " << type; @@ -883,8 +884,7 @@ static ObjPtr<mirror::ClassLoader> CreateClassLoaderInternal( compilation_sources.begin(), compilation_sources.end()); } - Handle<mirror::Class> loader_class = hs.NewHandle<mirror::Class>( - soa.Decode<mirror::Class>(GetClassLoaderClass(info.type))); + Handle<mirror::Class> loader_class = hs.NewHandle<mirror::Class>(GetClassLoaderClass(info.type)); ObjPtr<mirror::ClassLoader> loader = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader( self, diff --git a/runtime/class_loader_context_test.cc b/runtime/class_loader_context_test.cc index cb7726d4ec..d89c5b6b33 100644 --- a/runtime/class_loader_context_test.cc +++ b/runtime/class_loader_context_test.cc @@ -40,7 +40,7 @@ #include "runtime.h" #include "scoped_thread_state_change-inl.h" #include "thread.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace art { @@ -240,14 +240,14 @@ class ClassLoaderContextTest : public CommonRuntimeTest { ASSERT_FALSE(context->owns_the_dex_files_); } - void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa, + void VerifyClassLoaderDexFiles(Thread* self, Handle<mirror::ClassLoader> class_loader, - jclass type, + ObjPtr<mirror::Class> type, std::vector<const DexFile*>& expected_dex_files) REQUIRES_SHARED(Locks::mutator_lock_) { - ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type)); + ASSERT_TRUE(class_loader->GetClass() == type); - std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa.Self(), class_loader); + std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(self, class_loader); ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size()); for (size_t i = 0; i < expected_dex_files.size(); i++) { @@ -677,10 +677,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoader) { Handle<mirror::ClassLoader> class_loader = hs.NewHandle( soa.Decode<mirror::ClassLoader>(jclass_loader)); - ASSERT_TRUE(class_loader->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_PathClassLoader)); + ASSERT_TRUE(class_loader->GetClass() == WellKnownClasses::dalvik_system_PathClassLoader); ASSERT_TRUE(class_loader->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); // For the first class loader the class path dex files must come first and then the // compilation sources. @@ -689,9 +688,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoader) { expected_classpath.push_back(dex); } - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), expected_classpath); } @@ -714,12 +713,12 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) { soa.Decode<mirror::ClassLoader>(jclass_loader)); // An empty context should create a single PathClassLoader with only the compilation sources. - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), compilation_sources_raw); ASSERT_TRUE(class_loader->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); } TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) { @@ -765,31 +764,31 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) { for (auto& dex : compilation_sources_raw) { class_loader_1_dex_files.push_back(dex); } - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_1, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_1_dex_files); // Verify the second class loader Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent()); std::vector<const DexFile*> class_loader_2_dex_files = MakeNonOwningPointerVector(classpath_dex_c); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_2, - WellKnownClasses::dalvik_system_DelegateLastClassLoader, + WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(), class_loader_2_dex_files); // Verify the third class loader Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent()); std::vector<const DexFile*> class_loader_3_dex_files = MakeNonOwningPointerVector(classpath_dex_d); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_3, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_3_dex_files); // The last class loader should have the BootClassLoader as a parent. ASSERT_TRUE(class_loader_3->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); } TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) { @@ -833,9 +832,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) { for (auto& dex : compilation_sources_raw) { class_loader_1_dex_files.push_back(dex); } - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_1, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_1_dex_files); // Verify the shared libraries. @@ -851,9 +850,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) { Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0)); std::vector<const DexFile*> class_loader_2_dex_files = MakeNonOwningPointerVector(classpath_dex_c); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_2, - WellKnownClasses::dalvik_system_DelegateLastClassLoader, + WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(), class_loader_2_dex_files); raw_shared_libraries = field->GetObject(class_loader_2.Get()); ASSERT_TRUE(raw_shared_libraries == nullptr); @@ -862,20 +861,20 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) { Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1)); std::vector<const DexFile*> class_loader_3_dex_files = MakeNonOwningPointerVector(classpath_dex_d); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_3, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_3_dex_files); raw_shared_libraries = field->GetObject(class_loader_3.Get()); ASSERT_TRUE(raw_shared_libraries == nullptr); // All class loaders should have the BootClassLoader as a parent. ASSERT_TRUE(class_loader_1->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); ASSERT_TRUE(class_loader_2->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); ASSERT_TRUE(class_loader_3->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); } TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) { @@ -917,9 +916,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) for (auto& dex : compilation_sources_raw) { class_loader_1_dex_files.push_back(dex); } - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_1, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_1_dex_files); // Verify its shared library. @@ -934,9 +933,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0)); std::vector<const DexFile*> class_loader_2_dex_files = MakeNonOwningPointerVector(classpath_dex_b); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_2, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_2_dex_files); raw_shared_libraries = field->GetObject(class_loader_2.Get()); ASSERT_TRUE(raw_shared_libraries == nullptr); @@ -945,9 +944,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent()); std::vector<const DexFile*> class_loader_3_dex_files = MakeNonOwningPointerVector(classpath_dex_c); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_3, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_3_dex_files); // Verify its shared library. @@ -961,20 +960,20 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0)); std::vector<const DexFile*> class_loader_4_dex_files = MakeNonOwningPointerVector(classpath_dex_d); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_4, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_4_dex_files); raw_shared_libraries = field->GetObject(class_loader_4.Get()); ASSERT_TRUE(raw_shared_libraries == nullptr); // Class loaders should have the BootClassLoader as a parent. ASSERT_TRUE(class_loader_2->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); ASSERT_TRUE(class_loader_3->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); ASSERT_TRUE(class_loader_4->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); } TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) { @@ -1016,9 +1015,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) for (auto& dex : compilation_sources_raw) { class_loader_1_dex_files.push_back(dex); } - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_1, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_1_dex_files); // Verify its shared library. @@ -1033,9 +1032,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0)); std::vector<const DexFile*> class_loader_2_dex_files = MakeNonOwningPointerVector(classpath_dex_b); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_2, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_2_dex_files); // Verify the shared library dependency of the shared library. @@ -1049,9 +1048,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0)); std::vector<const DexFile*> class_loader_3_dex_files = MakeNonOwningPointerVector(classpath_dex_c); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_3, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_3_dex_files); raw_shared_libraries = field->GetObject(class_loader_3.Get()); ASSERT_TRUE(raw_shared_libraries == nullptr); @@ -1060,20 +1059,20 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent()); std::vector<const DexFile*> class_loader_4_dex_files = MakeNonOwningPointerVector(classpath_dex_d); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_4, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_4_dex_files); raw_shared_libraries = field->GetObject(class_loader_4.Get()); ASSERT_TRUE(raw_shared_libraries == nullptr); // Class loaders should have the BootClassLoader as a parent. ASSERT_TRUE(class_loader_2->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); ASSERT_TRUE(class_loader_3->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); ASSERT_TRUE(class_loader_4->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); } TEST_F(ClassLoaderContextTest, RemoveSourceLocations) { @@ -1130,9 +1129,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) { for (auto& dex : compilation_sources_raw) { class_loader_1_dex_files.push_back(dex); } - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_1, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_1_dex_files); // Verify its shared library. @@ -1147,18 +1146,18 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) { Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0)); std::vector<const DexFile*> class_loader_2_dex_files = MakeNonOwningPointerVector(classpath_dex_b); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_2, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_2_dex_files); // Verify the parent. Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent()); std::vector<const DexFile*> class_loader_3_dex_files = MakeNonOwningPointerVector(classpath_dex_c); - VerifyClassLoaderDexFiles(soa, + VerifyClassLoaderDexFiles(soa.Self(), class_loader_3, - WellKnownClasses::dalvik_system_PathClassLoader, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), class_loader_3_dex_files); // Verify its shared library is the same as the child. @@ -1171,9 +1170,9 @@ TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) { // Class loaders should have the BootClassLoader as a parent. ASSERT_TRUE(class_loader_2->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); ASSERT_TRUE(class_loader_3->GetParent()->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::java_lang_BootClassLoader)); + WellKnownClasses::java_lang_BootClassLoader); } TEST_F(ClassLoaderContextTest, EncodeInOatFile) { diff --git a/runtime/class_loader_utils.h b/runtime/class_loader_utils.h index eae31cce30..908d06225b 100644 --- a/runtime/class_loader_utils.h +++ b/runtime/class_loader_utils.h @@ -26,15 +26,14 @@ #include "mirror/object.h" #include "native/dalvik_system_DexFile.h" #include "scoped_thread_state_change-inl.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace art { // Returns true if the given class loader derives from BaseDexClassLoader. inline bool IsInstanceOfBaseDexClassLoader(Handle<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_) { - return class_loader->InstanceOf( - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_BaseDexClassLoader)); + return class_loader->InstanceOf(WellKnownClasses::dalvik_system_BaseDexClassLoader.Get()); } // Returns true if the given class loader is either a PathClassLoader or a DexClassLoader. @@ -42,26 +41,21 @@ inline bool IsInstanceOfBaseDexClassLoader(Handle<mirror::ClassLoader> class_loa inline bool IsPathOrDexClassLoader(Handle<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_) { ObjPtr<mirror::Class> class_loader_class = class_loader->GetClass(); - return - (class_loader_class == - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_PathClassLoader)) || - (class_loader_class == - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DexClassLoader)); + return (class_loader_class == WellKnownClasses::dalvik_system_PathClassLoader) || + (class_loader_class == WellKnownClasses::dalvik_system_DexClassLoader); } // Returns true if the given class loader is an InMemoryDexClassLoader. inline bool IsInMemoryDexClassLoader(Handle<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_) { ObjPtr<mirror::Class> class_loader_class = class_loader->GetClass(); - return (class_loader_class == - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_InMemoryDexClassLoader)); + return (class_loader_class == WellKnownClasses::dalvik_system_InMemoryDexClassLoader); } inline bool IsDelegateLastClassLoader(Handle<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_) { ObjPtr<mirror::Class> class_loader_class = class_loader->GetClass(); - return class_loader_class == - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DelegateLastClassLoader); + return class_loader_class == WellKnownClasses::dalvik_system_DelegateLastClassLoader; } // Visit the DexPathList$Element instances in the given classloader with the given visitor. diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc index f1139d446f..6a22a6680d 100644 --- a/runtime/common_runtime_test.cc +++ b/runtime/common_runtime_test.cc @@ -63,7 +63,7 @@ #include "runtime_intrinsics.h" #include "scoped_thread_state_change-inl.h" #include "thread.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace art { @@ -199,11 +199,8 @@ std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_lo std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles( Thread* self, Handle<mirror::ClassLoader> class_loader) { - DCHECK( - (class_loader->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_PathClassLoader)) || - (class_loader->GetClass() == - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DelegateLastClassLoader))); + DCHECK((class_loader->GetClass() == WellKnownClasses::dalvik_system_PathClassLoader) || + (class_loader->GetClass() == WellKnownClasses::dalvik_system_DelegateLastClassLoader)); std::vector<const DexFile*> ret; VisitClassLoaderDexFiles(self, @@ -257,8 +254,9 @@ jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) { } jobject -CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::vector<std::string>& dex_names, - jclass loader_class, +CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(ScopedObjectAccess& soa, + const std::vector<std::string>& dex_names, + ObjPtr<mirror::Class> loader_class, jobject parent_loader, jobject shared_libraries, jobject shared_libraries_after) { @@ -271,39 +269,44 @@ CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::vector<std::stri loaded_dex_files_.push_back(std::move(dex_file)); } } - Thread* self = Thread::Current(); - ScopedObjectAccess soa(self); - - jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader( - self, + StackHandleScope<4> hs(soa.Self()); + Handle<mirror::Class> h_loader_class = hs.NewHandle(loader_class); + Handle<mirror::ClassLoader> h_parent_loader = + hs.NewHandle(soa.Decode<mirror::ClassLoader>(parent_loader)); + Handle<mirror::ObjectArray<mirror::ClassLoader>> h_shared_libraries = + hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::ClassLoader>>(shared_libraries)); + Handle<mirror::ObjectArray<mirror::ClassLoader>> h_shared_libraries_after = + hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::ClassLoader>>(shared_libraries_after)); + + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + ObjPtr<mirror::ClassLoader> result = class_linker->CreateWellKnownClassLoader( + soa.Self(), class_path, - loader_class, - parent_loader, - shared_libraries, - shared_libraries_after); + h_loader_class, + h_parent_loader, + h_shared_libraries, + h_shared_libraries_after); { // Verify we build the correct chain. - ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result); // Verify that the result has the correct class. - CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass()); + CHECK_EQ(h_loader_class.Get(), result->GetClass()); // Verify that the parent is not null. The boot class loader will be set up as a // proper object. - ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent()); + ObjPtr<mirror::ClassLoader> actual_parent(result->GetParent()); CHECK(actual_parent != nullptr); if (parent_loader != nullptr) { // We were given a parent. Verify that it's what we expect. - ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader); - CHECK_EQ(expected_parent, actual_parent); + CHECK_EQ(h_parent_loader.Get(), actual_parent); } else { // No parent given. The parent must be the BootClassLoader. - CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(actual_parent)); + CHECK(class_linker->IsBootClassLoader(actual_parent)); } } - return result; + return soa.Env()->GetVm()->AddGlobalRef(soa.Self(), result); } jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name, @@ -320,8 +323,10 @@ jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::vector<std::s jobject parent_loader, jobject shared_libraries, jobject shared_libraries_after) { - return LoadDexInWellKnownClassLoader(names, - WellKnownClasses::dalvik_system_PathClassLoader, + ScopedObjectAccess soa(Thread::Current()); + return LoadDexInWellKnownClassLoader(soa, + names, + WellKnownClasses::dalvik_system_PathClassLoader.Get(), parent_loader, shared_libraries, shared_libraries_after); @@ -329,16 +334,22 @@ jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::vector<std::s jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name, jobject parent_loader) { - return LoadDexInWellKnownClassLoader({ dex_name }, - WellKnownClasses::dalvik_system_DelegateLastClassLoader, - parent_loader); + ScopedObjectAccess soa(Thread::Current()); + return LoadDexInWellKnownClassLoader( + soa, + { dex_name }, + WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(), + parent_loader); } jobject CommonRuntimeTestImpl::LoadDexInInMemoryDexClassLoader(const std::string& dex_name, jobject parent_loader) { - return LoadDexInWellKnownClassLoader({ dex_name }, - WellKnownClasses::dalvik_system_InMemoryDexClassLoader, - parent_loader); + ScopedObjectAccess soa(Thread::Current()); + return LoadDexInWellKnownClassLoader( + soa, + { dex_name }, + WellKnownClasses::dalvik_system_InMemoryDexClassLoader.Get(), + parent_loader); } void CommonRuntimeTestImpl::FillHeap(Thread* self, diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h index 1b69c32b76..7904aeb086 100644 --- a/runtime/common_runtime_test.h +++ b/runtime/common_runtime_test.h @@ -152,6 +152,7 @@ class CommonRuntimeTestImpl : public CommonArtTestImpl { jobject LoadMultiDex(const char* first_dex_name, const char* second_dex_name) REQUIRES_SHARED(Locks::mutator_lock_); + // The following helper functions return global JNI references to the class loader. jobject LoadDexInPathClassLoader(const std::string& dex_name, jobject parent_loader, jobject shared_libraries = nullptr, @@ -162,11 +163,13 @@ class CommonRuntimeTestImpl : public CommonArtTestImpl { jobject shared_libraries_after = nullptr); jobject LoadDexInDelegateLastClassLoader(const std::string& dex_name, jobject parent_loader); jobject LoadDexInInMemoryDexClassLoader(const std::string& dex_name, jobject parent_loader); - jobject LoadDexInWellKnownClassLoader(const std::vector<std::string>& dex_names, - jclass loader_class, + jobject LoadDexInWellKnownClassLoader(ScopedObjectAccess& soa, + const std::vector<std::string>& dex_names, + ObjPtr<mirror::Class> loader_class, jobject parent_loader, jobject shared_libraries = nullptr, - jobject shared_libraries_after = nullptr); + jobject shared_libraries_after = nullptr) + REQUIRES_SHARED(Locks::mutator_lock_); void VisitDexes(ArrayRef<const std::string> dexes, const std::function<void(MethodReference)>& method_visitor, diff --git a/runtime/debug_print.cc b/runtime/debug_print.cc index f84b6b1d4a..fd9e050a7d 100644 --- a/runtime/debug_print.cc +++ b/runtime/debug_print.cc @@ -29,7 +29,7 @@ #include "runtime.h" #include "scoped_thread_state_change-inl.h" #include "thread-current-inl.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace art { @@ -63,12 +63,10 @@ std::string DescribeSpace(ObjPtr<mirror::Class> klass) { std::string DescribeLoaders(ObjPtr<mirror::ClassLoader> loader, const char* class_descriptor) { std::ostringstream oss; uint32_t hash = ComputeModifiedUtf8Hash(class_descriptor); - ObjPtr<mirror::Class> path_class_loader = - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_PathClassLoader); - ObjPtr<mirror::Class> dex_class_loader = - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DexClassLoader); + ObjPtr<mirror::Class> path_class_loader = WellKnownClasses::dalvik_system_PathClassLoader.Get(); + ObjPtr<mirror::Class> dex_class_loader = WellKnownClasses::dalvik_system_DexClassLoader.Get(); ObjPtr<mirror::Class> delegate_last_class_loader = - WellKnownClasses::ToClass(WellKnownClasses::dalvik_system_DelegateLastClassLoader); + WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(); // Print the class loader chain. bool found_class = false; diff --git a/runtime/hidden_api_test.cc b/runtime/hidden_api_test.cc index 781fcd1ffa..a3d5db1f79 100644 --- a/runtime/hidden_api_test.cc +++ b/runtime/hidden_api_test.cc @@ -26,7 +26,7 @@ #include "common_runtime_test.h" #include "jni/jni_internal.h" #include "proxy_test.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace art { @@ -75,8 +75,8 @@ static bool LoadDexFiles(const std::string& path, ClassLinker* const linker = Runtime::Current()->GetClassLinker(); StackHandleScope<2> hs(self); - Handle<mirror::Class> h_class = hs.NewHandle(WellKnownClasses::ToClass( - WellKnownClasses::dalvik_system_PathClassLoader)); + Handle<mirror::Class> h_class = + hs.NewHandle(WellKnownClasses::dalvik_system_PathClassLoader.Get()); Handle<mirror::ClassLoader> h_loader = hs.NewHandle(linker->CreateWellKnownClassLoader( self, MakeNonOwningPointerVector(*dex_files), diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index c1cae6f124..0d40e13f51 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -61,7 +61,7 @@ #include "thread-inl.h" #include "transaction.h" #include "unstarted_runtime_list.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace art { namespace interpreter { @@ -658,8 +658,7 @@ void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream( StackHandleScope<1> hs(self); Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass())); - if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) != - this_classloader_class.Get()) { + if (WellKnownClasses::java_lang_BootClassLoader != this_classloader_class.Get()) { AbortTransactionOrFail(self, "Unsupported classloader type %s for getResourceAsStream", mirror::Class::PrettyClass(this_classloader_class.Get()).c_str()); diff --git a/runtime/jni/java_vm_ext.cc b/runtime/jni/java_vm_ext.cc index c55c7be10b..f1d4c3b305 100644 --- a/runtime/jni/java_vm_ext.cc +++ b/runtime/jni/java_vm_ext.cc @@ -52,7 +52,7 @@ #include "thread-inl.h" #include "thread_list.h" #include "ti/agent.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace art { @@ -1185,12 +1185,14 @@ jstring JavaVMExt::GetLibrarySearchPath(JNIEnv* env, jobject class_loader) { if (class_loader == nullptr) { return nullptr; } - if (!env->IsInstanceOf(class_loader, WellKnownClasses::dalvik_system_BaseDexClassLoader)) { + ScopedObjectAccess soa(env); + ObjPtr<mirror::Object> mirror_class_loader = soa.Decode<mirror::Object>(class_loader); + if (!mirror_class_loader->InstanceOf(WellKnownClasses::dalvik_system_BaseDexClassLoader.Get())) { return nullptr; } - return reinterpret_cast<jstring>(env->CallObjectMethod( - class_loader, - WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath)); + return soa.AddLocalReference<jstring>( + WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath->InvokeVirtual<'L'>( + soa.Self(), mirror_class_loader)); } // JNI Invocation interface. diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index a861f25fab..fb48bb8d3c 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -19,7 +19,7 @@ #include <iostream> #include "art_field-inl.h" -#include "art_method-inl.h" +#include "art_method-alloc-inl.h" #include "base/enums.h" #include "class_linker-inl.h" #include "class_root-inl.h" @@ -54,7 +54,7 @@ #include "reflective_handle_scope-inl.h" #include "scoped_fast_native_object_access-inl.h" #include "scoped_thread_state_change-inl.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace art { @@ -90,14 +90,17 @@ ALWAYS_INLINE static inline ObjPtr<mirror::Class> DecodeClass( static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean initialize, jobject javaLoader) { ScopedFastNativeObjectAccess soa(env); - ScopedUtfChars name(env, javaName); - if (name.c_str() == nullptr) { + StackHandleScope<3> hs(soa.Self()); + Handle<mirror::String> mirror_name = hs.NewHandle(soa.Decode<mirror::String>(javaName)); + if (mirror_name == nullptr) { + soa.Self()->ThrowNewWrappedException("Ljava/lang/NullPointerException;", /*msg=*/ nullptr); return nullptr; } // We need to validate and convert the name (from x.y.z to x/y/z). This // is especially handy for array types, since we want to avoid // auto-generating bogus array classes. + std::string name = mirror_name->ToModifiedUtf8(); if (!IsValidBinaryClassName(name.c_str())) { soa.Self()->ThrowNewExceptionF("Ljava/lang/ClassNotFoundException;", "Invalid name: %s", name.c_str()); @@ -105,23 +108,21 @@ static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean } std::string descriptor(DotToDescriptor(name.c_str())); - StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( hs.NewHandle(soa.Decode<mirror::ClassLoader>(javaLoader))); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); Handle<mirror::Class> c( hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader))); - if (c == nullptr) { - ScopedLocalRef<jthrowable> cause(env, env->ExceptionOccurred()); - env->ExceptionClear(); - jthrowable cnfe = reinterpret_cast<jthrowable>( - env->NewObject(WellKnownClasses::java_lang_ClassNotFoundException, - WellKnownClasses::java_lang_ClassNotFoundException_init, - javaName, - cause.get())); + if (UNLIKELY(c == nullptr)) { + StackHandleScope<2> hs2(soa.Self()); + Handle<mirror::Object> cause = hs2.NewHandle(soa.Self()->GetException()); + soa.Self()->ClearException(); + Handle<mirror::Object> cnfe = + WellKnownClasses::java_lang_ClassNotFoundException_init->NewObject<'L', 'L'>( + hs2, soa.Self(), mirror_name, cause); if (cnfe != nullptr) { // Make sure allocation didn't fail with an OOME. - env->Throw(cnfe); + soa.Self()->SetException(ObjPtr<mirror::Throwable>::DownCast(cnfe.Get())); } return nullptr; } diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index c963de466c..4322a614af 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -48,16 +48,8 @@ jclass WellKnownClasses::dalvik_annotation_optimization_CriticalNative; jclass WellKnownClasses::dalvik_annotation_optimization_FastNative; jclass WellKnownClasses::dalvik_annotation_optimization_NeverCompile; jclass WellKnownClasses::dalvik_annotation_optimization_NeverInline; -jclass WellKnownClasses::dalvik_system_BaseDexClassLoader; -jclass WellKnownClasses::dalvik_system_DelegateLastClassLoader; -jclass WellKnownClasses::dalvik_system_DexClassLoader; jclass WellKnownClasses::dalvik_system_EmulatedStackFrame; -jclass WellKnownClasses::dalvik_system_InMemoryDexClassLoader; -jclass WellKnownClasses::dalvik_system_PathClassLoader; jclass WellKnownClasses::java_lang_annotation_Annotation__array; -jclass WellKnownClasses::java_lang_BootClassLoader; -jclass WellKnownClasses::java_lang_ClassLoader; -jclass WellKnownClasses::java_lang_ClassNotFoundException; jclass WellKnownClasses::java_lang_Daemons; jclass WellKnownClasses::java_lang_Error; jclass WellKnownClasses::java_lang_IllegalAccessError; @@ -76,13 +68,18 @@ jclass WellKnownClasses::java_lang_System; jclass WellKnownClasses::java_lang_Void; jclass WellKnownClasses::libcore_reflect_AnnotationMember__array; -jmethodID WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath; +ArtMethod* WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath; +ArtMethod* WellKnownClasses::dalvik_system_DelegateLastClassLoader_init; +ArtMethod* WellKnownClasses::dalvik_system_DexClassLoader_init; +ArtMethod* WellKnownClasses::dalvik_system_InMemoryDexClassLoader_init; +ArtMethod* WellKnownClasses::dalvik_system_PathClassLoader_init; ArtMethod* WellKnownClasses::dalvik_system_VMRuntime_hiddenApiUsed; ArtMethod* WellKnownClasses::java_lang_Boolean_valueOf; +ArtMethod* WellKnownClasses::java_lang_BootClassLoader_init; ArtMethod* WellKnownClasses::java_lang_Byte_valueOf; ArtMethod* WellKnownClasses::java_lang_Character_valueOf; -jmethodID WellKnownClasses::java_lang_ClassLoader_loadClass; -jmethodID WellKnownClasses::java_lang_ClassNotFoundException_init; +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; @@ -357,17 +354,9 @@ void WellKnownClasses::Init(JNIEnv* env) { CacheClass(env, "dalvik/annotation/optimization/NeverCompile"); dalvik_annotation_optimization_NeverInline = CacheClass(env, "dalvik/annotation/optimization/NeverInline"); - dalvik_system_BaseDexClassLoader = CacheClass(env, "dalvik/system/BaseDexClassLoader"); - dalvik_system_DelegateLastClassLoader = CacheClass(env, "dalvik/system/DelegateLastClassLoader"); - dalvik_system_DexClassLoader = CacheClass(env, "dalvik/system/DexClassLoader"); dalvik_system_EmulatedStackFrame = CacheClass(env, "dalvik/system/EmulatedStackFrame"); - dalvik_system_InMemoryDexClassLoader = CacheClass(env, "dalvik/system/InMemoryDexClassLoader"); - dalvik_system_PathClassLoader = CacheClass(env, "dalvik/system/PathClassLoader"); java_lang_annotation_Annotation__array = CacheClass(env, "[Ljava/lang/annotation/Annotation;"); - java_lang_BootClassLoader = CacheClass(env, "java/lang/BootClassLoader"); - java_lang_ClassLoader = CacheClass(env, "java/lang/ClassLoader"); - java_lang_ClassNotFoundException = CacheClass(env, "java/lang/ClassNotFoundException"); java_lang_Daemons = CacheClass(env, "java/lang/Daemons"); java_lang_Object = CacheClass(env, "java/lang/Object"); java_lang_OutOfMemoryError = CacheClass(env, "java/lang/OutOfMemoryError"); @@ -414,11 +403,6 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { java_lang_Short_valueOf = CachePrimitiveBoxingMethod(class_linker, self, 'S', "Ljava/lang/Short;"); - dalvik_system_BaseDexClassLoader_getLdLibraryPath = CacheMethod(env, dalvik_system_BaseDexClassLoader, false, "getLdLibraryPath", "()Ljava/lang/String;"); - - java_lang_ClassNotFoundException_init = CacheMethod(env, java_lang_ClassNotFoundException, false, "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V"); - java_lang_ClassLoader_loadClass = CacheMethod(env, java_lang_ClassLoader, false, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); - 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"); @@ -430,17 +414,33 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { java_lang_reflect_Parameter_init = CacheMethod(env, java_lang_reflect_Parameter, false, "<init>", "(Ljava/lang/String;ILjava/lang/reflect/Executable;I)V"); java_lang_String_charAt = CacheMethod(env, java_lang_String, false, "charAt", "(I)C"); - StackHandleScope<21u> hs(self); + StackHandleScope<29u> hs(self); + Handle<mirror::Class> d_s_bdcl = + hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/BaseDexClassLoader;")); + Handle<mirror::Class> d_s_dlcl = + hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/DelegateLastClassLoader;")); + Handle<mirror::Class> d_s_dcl = + hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/DexClassLoader;")); Handle<mirror::Class> d_s_df = hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/DexFile;")); Handle<mirror::Class> d_s_dpl = hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/DexPathList;")); Handle<mirror::Class> d_s_dpl_e = hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/DexPathList$Element;")); + Handle<mirror::Class> d_s_imdcl = + hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/InMemoryDexClassLoader;")); + Handle<mirror::Class> d_s_pcl = + hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/PathClassLoader;")); Handle<mirror::Class> d_s_vmr = hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/VMRuntime;")); Handle<mirror::Class> j_i_fd = hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/io/FileDescriptor;")); + Handle<mirror::Class> j_l_bcl = + hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/BootClassLoader;")); + Handle<mirror::Class> j_l_cl = + 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_Thread = hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/lang/Thread;")); Handle<mirror::Class> j_l_tg = @@ -477,6 +477,37 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { ScopedAssertNoThreadSuspension sants(__FUNCTION__); PointerSize pointer_size = class_linker->GetImagePointerSize(); + dalvik_system_BaseDexClassLoader_getLdLibraryPath = CacheMethod( + d_s_bdcl.Get(), + /*is_static=*/ false, + "getLdLibraryPath", + "()Ljava/lang/String;", + pointer_size); + dalvik_system_DelegateLastClassLoader_init = CacheMethod( + d_s_dlcl.Get(), + /*is_static=*/ false, + "<init>", + "(Ljava/lang/String;Ljava/lang/ClassLoader;)V", + pointer_size); + dalvik_system_DexClassLoader_init = CacheMethod( + d_s_dcl.Get(), + /*is_static=*/ false, + "<init>", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V", + pointer_size); + dalvik_system_InMemoryDexClassLoader_init = CacheMethod( + d_s_imdcl.Get(), + /*is_static=*/ false, + "<init>", + "(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V", + pointer_size); + dalvik_system_PathClassLoader_init = CacheMethod( + d_s_pcl.Get(), + /*is_static=*/ false, + "<init>", + "(Ljava/lang/String;Ljava/lang/ClassLoader;)V", + pointer_size); + dalvik_system_VMRuntime_hiddenApiUsed = CacheMethod( d_s_vmr.Get(), /*is_static=*/ true, @@ -484,6 +515,22 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { "(ILjava/lang/String;Ljava/lang/String;IZ)V", pointer_size); + java_lang_BootClassLoader_init = + CacheMethod(j_l_bcl.Get(), /*is_static=*/ false, "<init>", "()V", pointer_size); + java_lang_ClassLoader_loadClass = CacheMethod( + j_l_cl.Get(), + /*is_static=*/ false, + "loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + pointer_size); + + java_lang_ClassNotFoundException_init = CacheMethod( + j_l_cnfe.Get(), + /*is_static=*/ false, + "<init>", + "(Ljava/lang/String;Ljava/lang/Throwable;)V", + pointer_size); + ObjPtr<mirror::Class> j_l_Double = java_lang_Double_valueOf->GetDeclaringClass(); java_lang_Double_doubleToRawLongBits = CacheMethod(j_l_Double, /*is_static=*/ true, "doubleToRawLongBits", "(D)J", pointer_size); @@ -569,13 +616,15 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;", pointer_size); - ObjPtr<mirror::Class> d_s_bdcl = soa.Decode<mirror::Class>(dalvik_system_BaseDexClassLoader); dalvik_system_BaseDexClassLoader_pathList = CacheField( - d_s_bdcl, /*is_static=*/ false, "pathList", "Ldalvik/system/DexPathList;"); + d_s_bdcl.Get(), /*is_static=*/ false, "pathList", "Ldalvik/system/DexPathList;"); dalvik_system_BaseDexClassLoader_sharedLibraryLoaders = CacheField( - d_s_bdcl, /*is_static=*/ false, "sharedLibraryLoaders", "[Ljava/lang/ClassLoader;"); + d_s_bdcl.Get(), /*is_static=*/ false, "sharedLibraryLoaders", "[Ljava/lang/ClassLoader;"); dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter = CacheField( - d_s_bdcl, /*is_static=*/ false, "sharedLibraryLoadersAfter", "[Ljava/lang/ClassLoader;"); + d_s_bdcl.Get(), + /*is_static=*/ false, + "sharedLibraryLoadersAfter", + "[Ljava/lang/ClassLoader;"); dalvik_system_DexFile_cookie = CacheField( d_s_df.Get(), /*is_static=*/ false, "mCookie", "Ljava/lang/Object;"); dalvik_system_DexFile_fileName = CacheField( @@ -594,9 +643,8 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { java_io_FileDescriptor_descriptor = CacheField( j_i_fd.Get(), /*is_static=*/ false, "descriptor", "I"); - ObjPtr<mirror::Class> j_l_cl = soa.Decode<mirror::Class>(java_lang_ClassLoader); java_lang_ClassLoader_parent = CacheField( - j_l_cl, /*is_static=*/ false, "parent", "Ljava/lang/ClassLoader;"); + j_l_cl.Get(), /*is_static=*/ false, "parent", "Ljava/lang/ClassLoader;"); java_lang_Thread_parkBlocker = CacheField(j_l_Thread.Get(), /*is_static=*/ false, "parkBlocker", "Ljava/lang/Object;"); @@ -699,15 +747,8 @@ void WellKnownClasses::Clear() { dalvik_annotation_optimization_FastNative = nullptr; dalvik_annotation_optimization_NeverCompile = nullptr; dalvik_annotation_optimization_NeverInline = nullptr; - dalvik_system_BaseDexClassLoader = nullptr; - dalvik_system_DelegateLastClassLoader = nullptr; - dalvik_system_DexClassLoader = nullptr; dalvik_system_EmulatedStackFrame = nullptr; - dalvik_system_PathClassLoader = nullptr; java_lang_annotation_Annotation__array = nullptr; - java_lang_BootClassLoader = nullptr; - java_lang_ClassLoader = nullptr; - java_lang_ClassNotFoundException = nullptr; java_lang_Daemons = nullptr; java_lang_Error = nullptr; java_lang_IllegalAccessError = nullptr; @@ -727,11 +768,16 @@ void WellKnownClasses::Clear() { libcore_reflect_AnnotationMember__array = nullptr; dalvik_system_BaseDexClassLoader_getLdLibraryPath = nullptr; + WellKnownClasses::dalvik_system_DelegateLastClassLoader_init = nullptr; + WellKnownClasses::dalvik_system_DexClassLoader_init = nullptr; + WellKnownClasses::dalvik_system_InMemoryDexClassLoader_init = nullptr; + WellKnownClasses::dalvik_system_PathClassLoader_init = nullptr; dalvik_system_VMRuntime_hiddenApiUsed = nullptr; java_io_FileDescriptor_descriptor = nullptr; java_lang_Boolean_valueOf = nullptr; java_lang_Byte_valueOf = nullptr; java_lang_Character_valueOf = nullptr; + java_lang_BootClassLoader_init = nullptr; java_lang_ClassLoader_loadClass = nullptr; java_lang_ClassNotFoundException_init = nullptr; java_lang_Daemons_start = nullptr; diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h index f8b50e3dd1..1a07d9ccd4 100644 --- a/runtime/well_known_classes.h +++ b/runtime/well_known_classes.h @@ -94,16 +94,8 @@ struct WellKnownClasses { static jclass dalvik_annotation_optimization_FastNative; static jclass dalvik_annotation_optimization_NeverCompile; static jclass dalvik_annotation_optimization_NeverInline; - static jclass dalvik_system_BaseDexClassLoader; - static jclass dalvik_system_DelegateLastClassLoader; - static jclass dalvik_system_DexClassLoader; static jclass dalvik_system_EmulatedStackFrame; - static jclass dalvik_system_InMemoryDexClassLoader; - static jclass dalvik_system_PathClassLoader; static jclass java_lang_annotation_Annotation__array; - static jclass java_lang_BootClassLoader; - static jclass java_lang_ClassLoader; - static jclass java_lang_ClassNotFoundException; static jclass java_lang_Daemons; static jclass java_lang_Error; static jclass java_lang_IllegalAccessError; @@ -122,13 +114,18 @@ struct WellKnownClasses { static jclass java_lang_Void; static jclass libcore_reflect_AnnotationMember__array; - static jmethodID dalvik_system_BaseDexClassLoader_getLdLibraryPath; + static ArtMethod* dalvik_system_BaseDexClassLoader_getLdLibraryPath; + static ArtMethod* dalvik_system_DelegateLastClassLoader_init; // Only for the declaring class. + static ArtMethod* dalvik_system_DexClassLoader_init; // Only for the declaring class. + static ArtMethod* dalvik_system_InMemoryDexClassLoader_init; // Only for the declaring class. + static ArtMethod* dalvik_system_PathClassLoader_init; // Only for the declaring class. static ArtMethod* dalvik_system_VMRuntime_hiddenApiUsed; static ArtMethod* java_lang_Boolean_valueOf; + static ArtMethod* java_lang_BootClassLoader_init; // Only for the declaring class. static ArtMethod* java_lang_Byte_valueOf; static ArtMethod* java_lang_Character_valueOf; - static jmethodID java_lang_ClassLoader_loadClass; - static jmethodID java_lang_ClassNotFoundException_init; + 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; @@ -210,10 +207,22 @@ struct WellKnownClasses { static ArtField* org_apache_harmony_dalvik_ddmc_Chunk_offset; static ArtField* org_apache_harmony_dalvik_ddmc_Chunk_type; + static constexpr ClassFromField<&dalvik_system_BaseDexClassLoader_pathList> + dalvik_system_BaseDexClassLoader; + static constexpr ClassFromMethod<&dalvik_system_DelegateLastClassLoader_init> + dalvik_system_DelegateLastClassLoader; + static constexpr ClassFromMethod<&dalvik_system_DexClassLoader_init> + dalvik_system_DexClassLoader; static constexpr ClassFromField<&dalvik_system_DexFile_cookie> dalvik_system_DexFile; static constexpr ClassFromField<&dalvik_system_DexPathList_dexElements> dalvik_system_DexPathList; static constexpr ClassFromField<&dalvik_system_DexPathList__Element_dexFile> dalvik_system_DexPathList__Element; + static constexpr ClassFromMethod<&dalvik_system_InMemoryDexClassLoader_init> + dalvik_system_InMemoryDexClassLoader; + static constexpr ClassFromMethod<&dalvik_system_PathClassLoader_init> + 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 ClassFromField<&java_lang_Thread_daemon> java_lang_Thread; static constexpr ClassFromField<&java_lang_ThreadGroup_groups> java_lang_ThreadGroup; static constexpr ClassFromField<&java_lang_Throwable_cause> java_lang_Throwable; diff --git a/test/ti-agent/jni_helper.h b/test/ti-agent/jni_helper.h index 0cbc6341fc..f99e627338 100644 --- a/test/ti-agent/jni_helper.h +++ b/test/ti-agent/jni_helper.h @@ -61,7 +61,7 @@ inline bool JniThrowNullPointerException(JNIEnv* env, const char* msg) { ScopedLocalRef<jclass> exc_class(env, env->FindClass("java/lang/NullPointerException")); if (exc_class.get() == nullptr) { - return -1; + return false; } return env->ThrowNew(exc_class.get(), msg) == JNI_OK; |