diff options
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 175 |
1 files changed, 133 insertions, 42 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 67872d76ae..a89196d830 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -56,6 +56,7 @@ #include "mirror/class-inl.h" #include "mirror/class_loader.h" #include "mirror/dex_cache-inl.h" +#include "mirror/field.h" #include "mirror/iftable-inl.h" #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" @@ -313,7 +314,7 @@ void ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b java_lang_String->SetObjectSize(mirror::String::InstanceSize()); mirror::Class::SetStatus(java_lang_String, mirror::Class::kStatusResolved, self); - // Setup Reference. + // Setup java.lang.ref.Reference. Handle<mirror::Class> java_lang_ref_Reference(hs.NewHandle( AllocClass(self, java_lang_Class.Get(), mirror::Reference::ClassSize()))); mirror::Reference::SetClass(java_lang_ref_Reference.Get()); @@ -321,7 +322,7 @@ void ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b mirror::Class::SetStatus(java_lang_ref_Reference, mirror::Class::kStatusResolved, self); // Create storage for root classes, save away our work so far (requires descriptors). - class_roots_ = GcRoot<mirror::ObjectArray<mirror::Class> >( + class_roots_ = GcRoot<mirror::ObjectArray<mirror::Class>>( mirror::ObjectArray<mirror::Class>::Alloc(self, object_array_class.Get(), kClassRootsMax)); CHECK(!class_roots_.IsNull()); @@ -531,6 +532,19 @@ void ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b mirror::Class* java_lang_reflect_Proxy = FindSystemClass(self, "Ljava/lang/reflect/Proxy;"); SetClassRoot(kJavaLangReflectProxy, java_lang_reflect_Proxy); + // Create java.lang.reflect.Field.class root. + mirror::Class* java_lang_reflect_Field = FindSystemClass(self, "Ljava/lang/reflect/Field;"); + CHECK(java_lang_reflect_Field != nullptr); + SetClassRoot(kJavaLangReflectField, java_lang_reflect_Field); + mirror::Field::SetClass(java_lang_reflect_Field); + + // Create java.lang.reflect.Field array root. + mirror::Class* java_lang_reflect_Field_array = + FindSystemClass(self, "[Ljava/lang/reflect/Field;"); + CHECK(java_lang_reflect_Field_array != nullptr); + SetClassRoot(kJavaLangReflectFieldArrayClass, java_lang_reflect_Field_array); + mirror::Field::SetArrayClass(java_lang_reflect_Field_array); + // java.lang.ref classes need to be specially flagged, but otherwise are normal classes // finish initializing Reference class mirror::Class::SetStatus(java_lang_ref_Reference, mirror::Class::kStatusNotReady, self); @@ -818,9 +832,10 @@ void ClassLinker::InitFromImage() { VLOG(startup) << "ClassLinker::InitFromImage entering"; CHECK(!init_done_); - Thread* self = Thread::Current(); - gc::Heap* heap = Runtime::Current()->GetHeap(); - gc::space::ImageSpace* space = heap->GetImageSpace(); + Runtime* const runtime = Runtime::Current(); + Thread* const self = Thread::Current(); + gc::Heap* const heap = runtime->GetHeap(); + gc::space::ImageSpace* const space = heap->GetImageSpace(); dex_cache_image_class_lookup_required_ = true; CHECK(space != nullptr); OatFile& oat_file = GetImageOatFile(space); @@ -875,7 +890,7 @@ void ClassLinker::InitFromImage() { // bitmap walk. mirror::ArtMethod::SetClass(GetClassRoot(kJavaLangReflectArtMethod)); size_t art_method_object_size = mirror::ArtMethod::GetJavaLangReflectArtMethod()->GetObjectSize(); - if (!Runtime::Current()->IsAotCompiler()) { + if (!runtime->IsAotCompiler()) { // Aot compiler supports having an image with a different pointer size than the runtime. This // happens on the host for compile 32 bit tests since we use a 64 bit libart compiler. We may // also use 32 bit dex2oat on a system with 64 bit apps. @@ -890,7 +905,6 @@ void ClassLinker::InitFromImage() { } // Set entry point to interpreter if in InterpretOnly mode. - Runtime* runtime = Runtime::Current(); if (!runtime->IsAotCompiler() && runtime->GetInstrumentation()->InterpretOnly()) { heap->VisitObjects(InitFromImageInterpretOnlyCallback, this); } @@ -903,6 +917,8 @@ void ClassLinker::InitFromImage() { array_iftable_ = GcRoot<mirror::IfTable>(GetClassRoot(kObjectArrayClass)->GetIfTable()); DCHECK_EQ(array_iftable_.Read(), GetClassRoot(kBooleanArrayClass)->GetIfTable()); // String class root was set above + mirror::Field::SetClass(GetClassRoot(kJavaLangReflectField)); + mirror::Field::SetArrayClass(GetClassRoot(kJavaLangReflectFieldArrayClass)); mirror::Reference::SetClass(GetClassRoot(kJavaLangRefReference)); mirror::ArtField::SetClass(GetClassRoot(kJavaLangReflectArtField)); mirror::BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass)); @@ -1088,6 +1104,8 @@ ClassLinker::~ClassLinker() { mirror::Reference::ResetClass(); mirror::ArtField::ResetClass(); mirror::ArtMethod::ResetClass(); + mirror::Field::ResetClass(); + mirror::Field::ResetArrayClass(); mirror::BooleanArray::ResetArrayClass(); mirror::ByteArray::ResetArrayClass(); mirror::CharArray::ResetArrayClass(); @@ -1372,38 +1390,6 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, self->SetException(pre_allocated); return nullptr; } - } else if (Runtime::Current()->UseCompileTimeClassPath()) { - // First try with the bootstrap class loader. - if (class_loader.Get() != nullptr) { - klass = LookupClass(self, descriptor, hash, nullptr); - if (klass != nullptr) { - return EnsureResolved(self, descriptor, klass); - } - } - // If the lookup failed search the boot class path. We don't perform a recursive call to avoid - // a NoClassDefFoundError being allocated. - ClassPathEntry pair = FindInClassPath(descriptor, hash, boot_class_path_); - if (pair.second != nullptr) { - return DefineClass(self, descriptor, hash, NullHandle<mirror::ClassLoader>(), *pair.first, - *pair.second); - } - // Next try the compile time class path. - const std::vector<const DexFile*>* class_path; - { - ScopedObjectAccessUnchecked soa(self); - ScopedLocalRef<jobject> jclass_loader(soa.Env(), - soa.AddLocalReference<jobject>(class_loader.Get())); - class_path = &Runtime::Current()->GetCompileTimeClassPath(jclass_loader.get()); - } - pair = FindInClassPath(descriptor, hash, *class_path); - if (pair.second != nullptr) { - return DefineClass(self, descriptor, hash, class_loader, *pair.first, *pair.second); - } else { - // Use the pre-allocated NCDFE at compile time to avoid wasting time constructing exceptions. - mirror::Throwable* pre_allocated = Runtime::Current()->GetPreAllocatedNoClassDefFoundError(); - self->SetException(pre_allocated); - return nullptr; - } } else { ScopedObjectAccessUnchecked soa(self); mirror::Class* cp_klass = FindClassInPathClassLoader(soa, self, descriptor, hash, @@ -1411,6 +1397,14 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, if (cp_klass != nullptr) { return cp_klass; } + + if (Runtime::Current()->IsAotCompiler()) { + // Oops, compile-time, can't run actual class-loader code. + mirror::Throwable* pre_allocated = Runtime::Current()->GetPreAllocatedNoClassDefFoundError(); + self->SetException(pre_allocated); + return nullptr; + } + ScopedLocalRef<jobject> class_loader_object(soa.Env(), soa.AddLocalReference<jobject>(class_loader.Get())); std::string class_name_string(DescriptorToDot(descriptor)); @@ -1767,7 +1761,7 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { return; // No direct methods => no static methods. } Runtime* runtime = Runtime::Current(); - if (!runtime->IsStarted() || runtime->UseCompileTimeClassPath()) { + if (!runtime->IsStarted()) { if (runtime->IsAotCompiler() || runtime->GetHeap()->HasImageSpace()) { return; // OAT file unavailable. } @@ -1907,7 +1901,7 @@ void ClassLinker::LoadClass(Thread* self, const DexFile& dex_file, bool has_oat_class = false; - if (Runtime::Current()->IsStarted() && !Runtime::Current()->UseCompileTimeClassPath()) { + if (Runtime::Current()->IsStarted() && !Runtime::Current()->IsAotCompiler()) { OatFile::OatClass oat_class = FindOatClass(dex_file, klass->GetDexClassDefIndex(), &has_oat_class); if (has_oat_class) { @@ -2808,7 +2802,7 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class // classes. if (Runtime::Current()->IsAotCompiler()) { // Are we compiling the bootclasspath? - if (!Runtime::Current()->UseCompileTimeClassPath()) { + if (Runtime::Current()->GetCompilerCallbacks()->IsBootImage()) { return false; } // We are compiling an app (not the image). @@ -5213,10 +5207,12 @@ const char* ClassLinker::GetClassRootDescriptor(ClassRoot class_root) { "Ljava/lang/ref/Reference;", "Ljava/lang/reflect/ArtField;", "Ljava/lang/reflect/ArtMethod;", + "Ljava/lang/reflect/Field;", "Ljava/lang/reflect/Proxy;", "[Ljava/lang/String;", "[Ljava/lang/reflect/ArtField;", "[Ljava/lang/reflect/ArtMethod;", + "[Ljava/lang/reflect/Field;", "Ljava/lang/ClassLoader;", "Ljava/lang/Throwable;", "Ljava/lang/ClassNotFoundException;", @@ -5286,6 +5282,10 @@ std::size_t ClassLinker::ClassDescriptorHashEquals::operator()(const char* descr } bool ClassLinker::MayBeCalledWithDirectCodePointer(mirror::ArtMethod* m) { + if (Runtime::Current()->UseJit()) { + // JIT can have direct code pointers from any method to any other method. + return true; + } // Non-image methods don't use direct code pointer. if (!m->GetDeclaringClass()->IsBootStrapClassLoaded()) { return false; @@ -5315,4 +5315,95 @@ bool ClassLinker::MayBeCalledWithDirectCodePointer(mirror::ArtMethod* m) { } } +jobject ClassLinker::CreatePathClassLoader(Thread* self, std::vector<const DexFile*>& dex_files) { + // 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); + + // Register the dex files. + for (const DexFile* dex_file : dex_files) { + RegisterDexFile(*dex_file); + } + + // For now, create a libcore-level DexFile for each ART DexFile. This "explodes" multidex. + StackHandleScope<11> hs(self); + + Handle<mirror::ArtField> h_dex_elements_field = + hs.NewHandle(soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements)); + + mirror::Class* dex_elements_class = h_dex_elements_field->GetType<true>(); + DCHECK(dex_elements_class != nullptr); + DCHECK(dex_elements_class->IsArrayClass()); + Handle<mirror::ObjectArray<mirror::Object>> h_dex_elements(hs.NewHandle( + mirror::ObjectArray<mirror::Object>::Alloc(self, dex_elements_class, dex_files.size()))); + Handle<mirror::Class> h_dex_element_class = + hs.NewHandle(dex_elements_class->GetComponentType()); + + Handle<mirror::ArtField> h_element_file_field = + hs.NewHandle( + soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile)); + DCHECK_EQ(h_dex_element_class.Get(), h_element_file_field->GetDeclaringClass()); + + Handle<mirror::ArtField> h_cookie_field = + hs.NewHandle(soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie)); + DCHECK_EQ(h_cookie_field->GetDeclaringClass(), h_element_file_field->GetType<false>()); + + // Fill the elements array. + int32_t index = 0; + for (const DexFile* dex_file : dex_files) { + StackHandleScope<3> hs2(self); + + Handle<mirror::LongArray> h_long_array = hs2.NewHandle(mirror::LongArray::Alloc(self, 1)); + DCHECK(h_long_array.Get() != nullptr); + h_long_array->Set(0, reinterpret_cast<intptr_t>(dex_file)); + + Handle<mirror::Object> h_dex_file = hs2.NewHandle( + h_cookie_field->GetDeclaringClass()->AllocObject(self)); + DCHECK(h_dex_file.Get() != nullptr); + h_cookie_field->SetObject<false>(h_dex_file.Get(), h_long_array.Get()); + + Handle<mirror::Object> h_element = hs2.NewHandle(h_dex_element_class->AllocObject(self)); + DCHECK(h_element.Get() != nullptr); + h_element_file_field->SetObject<false>(h_element.Get(), h_dex_file.Get()); + + h_dex_elements->Set(index, h_element.Get()); + index++; + } + DCHECK_EQ(index, h_dex_elements->GetLength()); + + // Create DexPathList. + Handle<mirror::Object> h_dex_path_list = hs.NewHandle( + h_dex_elements_field->GetDeclaringClass()->AllocObject(self)); + DCHECK(h_dex_path_list.Get() != nullptr); + // Set elements. + h_dex_elements_field->SetObject<false>(h_dex_path_list.Get(), h_dex_elements.Get()); + + // Create PathClassLoader. + Handle<mirror::Class> h_path_class_class = hs.NewHandle( + soa.Decode<mirror::Class*>(WellKnownClasses::dalvik_system_PathClassLoader)); + Handle<mirror::Object> h_path_class_loader = hs.NewHandle( + h_path_class_class->AllocObject(self)); + DCHECK(h_path_class_loader.Get() != nullptr); + // Set DexPathList. + Handle<mirror::ArtField> h_path_list_field = hs.NewHandle( + soa.DecodeField(WellKnownClasses::dalvik_system_PathClassLoader_pathList)); + DCHECK(h_path_list_field.Get() != nullptr); + h_path_list_field->SetObject<false>(h_path_class_loader.Get(), h_dex_path_list.Get()); + + // Make a pretend boot-classpath. + // TODO: Should we scan the image? + Handle<mirror::ArtField> h_parent_field = hs.NewHandle( + mirror::Class::FindField(self, hs.NewHandle(h_path_class_loader->GetClass()), "parent", + "Ljava/lang/ClassLoader;")); + DCHECK(h_parent_field.Get() != nullptr); + mirror::Object* boot_cl = + soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_BootClassLoader)->AllocObject(self); + h_parent_field->SetObject<false>(h_path_class_loader.Get(), boot_cl); + + // Make it a global ref and return. + ScopedLocalRef<jobject> local_ref( + soa.Env(), soa.Env()->AddLocalReference<jobject>(h_path_class_loader.Get())); + return soa.Env()->NewGlobalRef(local_ref.get()); +} + } // namespace art |