diff options
Diffstat (limited to 'runtime/class_linker.cc')
| -rw-r--r-- | runtime/class_linker.cc | 86 |
1 files changed, 59 insertions, 27 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index d3d30d4cea..6d45dad28f 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -63,10 +63,12 @@ #include "jit/jit.h" #include "jit/jit_code_cache.h" #include "jit/offline_profiling_info.h" +#include "jni_internal.h" #include "leb128.h" #include "linear_alloc.h" #include "mirror/class.h" #include "mirror/class-inl.h" +#include "mirror/class_ext.h" #include "mirror/class_loader.h" #include "mirror/dex_cache.h" #include "mirror/dex_cache-inl.h" @@ -136,10 +138,22 @@ static bool HasInitWithString(Thread* self, ClassLinker* class_linker, const cha return exception_init_method != nullptr; } +static mirror::Object* GetVerifyError(ObjPtr<mirror::Class> c) + REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::ClassExt> ext(c->GetExtData()); + if (ext == nullptr) { + return nullptr; + } else { + return ext->GetVerifyError(); + } +} + // Helper for ThrowEarlierClassFailure. Throws the stored error. -static void HandleEarlierVerifyError(Thread* self, ClassLinker* class_linker, ObjPtr<mirror::Class> c) +static void HandleEarlierVerifyError(Thread* self, + ClassLinker* class_linker, + ObjPtr<mirror::Class> c) REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<mirror::Object> obj = c->GetVerifyError(); + ObjPtr<mirror::Object> obj = GetVerifyError(c); DCHECK(obj != nullptr); self->AssertNoPendingException(); if (obj->IsClass()) { @@ -173,8 +187,8 @@ void ClassLinker::ThrowEarlierClassFailure(ObjPtr<mirror::Class> c, bool wrap_in Runtime* const runtime = Runtime::Current(); if (!runtime->IsAotCompiler()) { // Give info if this occurs at runtime. std::string extra; - if (c->GetVerifyError() != nullptr) { - ObjPtr<mirror::Object> verify_error = c->GetVerifyError(); + if (GetVerifyError(c) != nullptr) { + ObjPtr<mirror::Object> verify_error = GetVerifyError(c); if (verify_error->IsClass()) { extra = mirror::Class::PrettyDescriptor(verify_error->AsClass()); } else { @@ -192,11 +206,14 @@ void ClassLinker::ThrowEarlierClassFailure(ObjPtr<mirror::Class> c, bool wrap_in ObjPtr<mirror::Throwable> pre_allocated = runtime->GetPreAllocatedNoClassDefFoundError(); self->SetException(pre_allocated); } else { - if (c->GetVerifyError() != nullptr) { + if (GetVerifyError(c) != nullptr) { // Rethrow stored error. HandleEarlierVerifyError(self, this, c); } - if (c->GetVerifyError() == nullptr || wrap_in_no_class_def) { + // TODO This might be wrong if we hit an OOME while allocating the ClassExt. In that case we + // might have meant to go down the earlier if statement with the original error but it got + // swallowed by the OOM so we end up here. + if (GetVerifyError(c) == nullptr || wrap_in_no_class_def) { // If there isn't a recorded earlier error, or this is a repeat throw from initialization, // the top-level exception must be a NoClassDefFoundError. The potentially already pending // exception will be a cause. @@ -378,8 +395,8 @@ bool ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b CHECK(java_lang_Class.Get() != nullptr); mirror::Class::SetClassClass(java_lang_Class.Get()); java_lang_Class->SetClass(java_lang_Class.Get()); - if (kUseBakerOrBrooksReadBarrier) { - java_lang_Class->AssertReadBarrierPointer(); + if (kUseBakerReadBarrier) { + java_lang_Class->AssertReadBarrierState(); } java_lang_Class->SetClassSize(class_class_size); java_lang_Class->SetPrimitiveType(Primitive::kPrimNot); @@ -495,6 +512,14 @@ bool ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b java_lang_DexCache->SetObjectSize(mirror::DexCache::InstanceSize()); mirror::Class::SetStatus(java_lang_DexCache, mirror::Class::kStatusResolved, self); + + // Setup dalvik.system.ClassExt + Handle<mirror::Class> dalvik_system_ClassExt(hs.NewHandle( + AllocClass(self, java_lang_Class.Get(), mirror::ClassExt::ClassSize(image_pointer_size_)))); + SetClassRoot(kDalvikSystemClassExt, dalvik_system_ClassExt.Get()); + mirror::ClassExt::SetClass(dalvik_system_ClassExt.Get()); + mirror::Class::SetStatus(dalvik_system_ClassExt, mirror::Class::kStatusResolved, self); + // Set up array classes for string, field, method Handle<mirror::Class> object_array_string(hs.NewHandle( AllocClass(self, java_lang_Class.Get(), @@ -540,7 +565,7 @@ bool ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b quick_to_interpreter_bridge_trampoline_ = GetQuickToInterpreterBridge(); } - // Object, String and DexCache need to be rerun through FindSystemClass to finish init + // Object, String, ClassExt and DexCache need to be rerun through FindSystemClass to finish init mirror::Class::SetStatus(java_lang_Object, mirror::Class::kStatusNotReady, self); CheckSystemClass(self, java_lang_Object, "Ljava/lang/Object;"); CHECK_EQ(java_lang_Object->GetObjectSize(), mirror::Object::InstanceSize()); @@ -549,6 +574,9 @@ bool ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b mirror::Class::SetStatus(java_lang_DexCache, mirror::Class::kStatusNotReady, self); CheckSystemClass(self, java_lang_DexCache, "Ljava/lang/DexCache;"); CHECK_EQ(java_lang_DexCache->GetObjectSize(), mirror::DexCache::InstanceSize()); + mirror::Class::SetStatus(dalvik_system_ClassExt, mirror::Class::kStatusNotReady, self); + CheckSystemClass(self, dalvik_system_ClassExt, "Ldalvik/system/ClassExt;"); + CHECK_EQ(dalvik_system_ClassExt->GetObjectSize(), mirror::ClassExt::InstanceSize()); // Setup the primitive array type classes - can't be done until Object has a vtable. SetClassRoot(kBooleanArrayClass, FindSystemClass(self, "[Z")); @@ -1066,6 +1094,7 @@ bool ClassLinker::InitFromBootImage(std::string* error_msg) { mirror::Throwable::SetClass(GetClassRoot(kJavaLangThrowable)); mirror::StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement)); mirror::EmulatedStackFrame::SetClass(GetClassRoot(kDalvikSystemEmulatedStackFrame)); + mirror::ClassExt::SetClass(GetClassRoot(kDalvikSystemClassExt)); for (gc::space::ImageSpace* image_space : spaces) { // Boot class loader, use a null handle. @@ -1096,13 +1125,12 @@ bool ClassLinker::IsBootClassLoader(ScopedObjectAccessAlreadyRunnable& soa, class_loader->GetClass(); } -static mirror::String* GetDexPathListElementName(ScopedObjectAccessUnchecked& soa, - ObjPtr<mirror::Object> element) +static mirror::String* GetDexPathListElementName(ObjPtr<mirror::Object> element) REQUIRES_SHARED(Locks::mutator_lock_) { ArtField* const dex_file_field = - soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); + jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); ArtField* const dex_file_name_field = - soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_fileName); + jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_fileName); DCHECK(dex_file_field != nullptr); DCHECK(dex_file_name_field != nullptr); DCHECK(element != nullptr); @@ -1126,9 +1154,9 @@ static bool FlattenPathClassLoader(ObjPtr<mirror::ClassLoader> class_loader, DCHECK(error_msg != nullptr); ScopedObjectAccessUnchecked soa(Thread::Current()); ArtField* const dex_path_list_field = - soa.DecodeField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList); + jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList); ArtField* const dex_elements_field = - soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements); + jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements); CHECK(dex_path_list_field != nullptr); CHECK(dex_elements_field != nullptr); while (!ClassLinker::IsBootClassLoader(soa, class_loader)) { @@ -1155,7 +1183,7 @@ static bool FlattenPathClassLoader(ObjPtr<mirror::ClassLoader> class_loader, *error_msg = StringPrintf("Null dex element at index %d", i); return false; } - ObjPtr<mirror::String> const name = GetDexPathListElementName(soa, element); + ObjPtr<mirror::String> const name = GetDexPathListElementName(element); if (name == nullptr) { *error_msg = StringPrintf("Null name for dex element at index %d", i); return false; @@ -1705,7 +1733,7 @@ bool ClassLinker::AddImageSpace( ObjPtr<mirror::Object> element = elements->GetWithoutChecks(i); if (element != nullptr) { // If we are somewhere in the middle of the array, there may be nulls at the end. - loader_dex_file_names.push_back(GetDexPathListElementName(soa, element)); + loader_dex_file_names.push_back(GetDexPathListElementName(element)); } } // Ignore the number of image dex files since we are adding those to the class loader anyways. @@ -2397,16 +2425,17 @@ bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnabl // Handle as if this is the child PathClassLoader. // The class loader is a PathClassLoader which inherits from BaseDexClassLoader. // We need to get the DexPathList and loop through it. - ArtField* const cookie_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie); + ArtField* const cookie_field = + jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie); ArtField* const dex_file_field = - soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); + jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); ObjPtr<mirror::Object> dex_path_list = - soa.DecodeField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)-> - GetObject(class_loader.Get()); + jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)-> + GetObject(class_loader.Get()); if (dex_path_list != nullptr && dex_file_field != nullptr && cookie_field != nullptr) { // DexPathList has an array dexElements of Elements[] which each contain a dex file. ObjPtr<mirror::Object> dex_elements_obj = - soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements)-> + jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)-> GetObject(dex_path_list); // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look // at the mCookie which is a DexFile vector. @@ -2578,6 +2607,8 @@ mirror::Class* ClassLinker::DefineClass(Thread* self, klass.Assign(GetClassRoot(kJavaLangRefReference)); } else if (strcmp(descriptor, "Ljava/lang/DexCache;") == 0) { klass.Assign(GetClassRoot(kJavaLangDexCache)); + } else if (strcmp(descriptor, "Ldalvik/system/ClassExt;") == 0) { + klass.Assign(GetClassRoot(kDalvikSystemClassExt)); } } @@ -8087,6 +8118,7 @@ const char* ClassLinker::GetClassRootDescriptor(ClassRoot class_root) { "[J", "[S", "[Ljava/lang/StackTraceElement;", + "Ldalvik/system/ClassExt;", }; static_assert(arraysize(class_roots_descriptors) == size_t(kClassRootsMax), "Mismatch between class descriptors and class-root enum"); @@ -8106,7 +8138,7 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, StackHandleScope<11> hs(self); ArtField* dex_elements_field = - soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements); + jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements); Handle<mirror::Class> dex_elements_class(hs.NewHandle(dex_elements_field->GetType<true>())); DCHECK(dex_elements_class.Get() != nullptr); @@ -8119,13 +8151,13 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, hs.NewHandle(dex_elements_class->GetComponentType()); ArtField* element_file_field = - soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); + jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); DCHECK_EQ(h_dex_element_class.Get(), element_file_field->GetDeclaringClass()); - ArtField* cookie_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie); + ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie); DCHECK_EQ(cookie_field->GetDeclaringClass(), element_file_field->GetType<false>()); - ArtField* file_name_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_fileName); + ArtField* file_name_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_fileName); DCHECK_EQ(file_name_field->GetDeclaringClass(), element_file_field->GetType<false>()); // Fill the elements array. @@ -8175,7 +8207,7 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, DCHECK(h_path_class_loader.Get() != nullptr); // Set DexPathList. ArtField* path_list_field = - soa.DecodeField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList); + jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList); DCHECK(path_list_field != nullptr); path_list_field->SetObject<false>(h_path_class_loader.Get(), h_dex_path_list.Get()); |