diff options
author | 2014-12-02 15:43:52 -0800 | |
---|---|---|
committer | 2016-10-25 11:18:05 -0700 | |
commit | 34ee6842a283afe107f0c1df941393f955323b52 (patch) | |
tree | 63614db22d589a42f843f1b96e2332e8c89d4860 /runtime/native/java_lang_VMClassLoader.cc | |
parent | 5b6fbd02f03fd41829c7dd4bfce97a62346be854 (diff) |
ART: Refactor class-linker methods
Hide the LookupClass with hash version. Clients should not have to
know about that performance detail.
Hide FindClassInPathClassLoader. This is an implementation detail.
Test: m test-art-host
Change-Id: I2378c6fed8d7d1fb1ead8e042b4cf07228adf25c
Diffstat (limited to 'runtime/native/java_lang_VMClassLoader.cc')
-rw-r--r-- | runtime/native/java_lang_VMClassLoader.cc | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/runtime/native/java_lang_VMClassLoader.cc b/runtime/native/java_lang_VMClassLoader.cc index ff082845e1..e5bab36870 100644 --- a/runtime/native/java_lang_VMClassLoader.cc +++ b/runtime/native/java_lang_VMClassLoader.cc @@ -20,12 +20,41 @@ #include "jni_internal.h" #include "mirror/class_loader.h" #include "mirror/object-inl.h" +#include "obj_ptr.h" #include "scoped_fast_native_object_access-inl.h" #include "ScopedUtfChars.h" #include "zip_archive.h" namespace art { +// A class so we can be friends with ClassLinker and access internal methods. +class VMClassLoader { + public: + static mirror::Class* LookupClass(ClassLinker* cl, + Thread* self, + const char* descriptor, + size_t hash, + ObjPtr<mirror::ClassLoader> class_loader) + REQUIRES(!Locks::classlinker_classes_lock_) + REQUIRES_SHARED(Locks::mutator_lock_) { + return cl->LookupClass(self, descriptor, hash, class_loader); + } + + static ObjPtr<mirror::Class> FindClassInPathClassLoader(ClassLinker* cl, + ScopedObjectAccessAlreadyRunnable& soa, + Thread* self, + const char* descriptor, + size_t hash, + Handle<mirror::ClassLoader> class_loader) + REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::Class> result; + if (cl->FindClassInPathClassLoader(soa, self, descriptor, hash, class_loader, &result)) { + return result; + } + return nullptr; + } +}; + static jclass VMClassLoader_findLoadedClass(JNIEnv* env, jclass, jobject javaLoader, jstring javaName) { ScopedFastNativeObjectAccess soa(env); @@ -35,12 +64,16 @@ static jclass VMClassLoader_findLoadedClass(JNIEnv* env, jclass, jobject javaLoa return nullptr; } ClassLinker* cl = Runtime::Current()->GetClassLinker(); + + // Compute hash once. std::string descriptor(DotToDescriptor(name.c_str())); const size_t descriptor_hash = ComputeModifiedUtf8Hash(descriptor.c_str()); - ObjPtr<mirror::Class> c = cl->LookupClass(soa.Self(), - descriptor.c_str(), - descriptor_hash, - loader.Ptr()); + + ObjPtr<mirror::Class> c = VMClassLoader::LookupClass(cl, + soa.Self(), + descriptor.c_str(), + descriptor_hash, + loader); if (c != nullptr && c->IsResolved()) { return soa.AddLocalReference<jclass>(c); } @@ -61,17 +94,26 @@ static jclass VMClassLoader_findLoadedClass(JNIEnv* env, jclass, jobject javaLoa } return nullptr; } + + // Hard-coded performance optimization: We know that all failed libcore calls to findLoadedClass + // are followed by a call to the the classloader to actually + // load the class. if (loader != nullptr) { // Try the common case. StackHandleScope<1> hs(soa.Self()); - cl->FindClassInPathClassLoader(soa, soa.Self(), descriptor.c_str(), descriptor_hash, - hs.NewHandle(loader), &c); + c = VMClassLoader::FindClassInPathClassLoader(cl, + soa, + soa.Self(), + descriptor.c_str(), + descriptor_hash, + hs.NewHandle(loader)); if (c != nullptr) { return soa.AddLocalReference<jclass>(c); } } - // Class wasn't resolved so it may be erroneous or not yet ready, force the caller to go into - // the regular loadClass code. + + // The class wasn't loaded, yet, and our fast-path did not apply (e.g., we didn't understand the + // classloader chain). return nullptr; } |