diff options
35 files changed, 320 insertions, 337 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 16f2d0f2cc..653e9edb45 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -391,7 +391,7 @@ static optimizer::DexToDexCompiler::CompilationLevel GetDexToDexCompilationLevel DCHECK(driver.GetCompilerOptions().IsQuickeningCompilationEnabled()); const char* descriptor = dex_file.GetClassDescriptor(class_def); ClassLinker* class_linker = runtime->GetClassLinker(); - mirror::Class* klass = class_linker->FindClass(self, descriptor, class_loader); + ObjPtr<mirror::Class> klass = class_linker->FindClass(self, descriptor, class_loader); if (klass == nullptr) { CHECK(self->IsExceptionPending()); self->ClearException(); diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc index 856cb36266..491e61f9b5 100644 --- a/compiler/driver/compiler_driver_test.cc +++ b/compiler/driver/compiler_driver_test.cc @@ -88,7 +88,7 @@ class CompilerDriverTest : public CommonCompilerTest { StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> loader( hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); - mirror::Class* c = class_linker->FindClass(soa.Self(), descriptor, loader); + ObjPtr<mirror::Class> c = class_linker->FindClass(soa.Self(), descriptor, loader); CHECK(c != nullptr); const auto pointer_size = class_linker->GetImagePointerSize(); for (auto& m : c->GetMethods(pointer_size)) { @@ -115,14 +115,14 @@ TEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) { ObjPtr<mirror::DexCache> dex_cache = class_linker_->FindDexCache(soa.Self(), dex); EXPECT_EQ(dex.NumStringIds(), dex_cache->NumStrings()); for (size_t i = 0; i < dex_cache->NumStrings(); i++) { - const mirror::String* string = dex_cache->GetResolvedString(dex::StringIndex(i)); + const ObjPtr<mirror::String> string = dex_cache->GetResolvedString(dex::StringIndex(i)); EXPECT_TRUE(string != nullptr) << "string_idx=" << i; } EXPECT_EQ(dex.NumTypeIds(), dex_cache->NumResolvedTypes()); for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) { - mirror::Class* type = dex_cache->GetResolvedType(dex::TypeIndex(i)); - EXPECT_TRUE(type != nullptr) << "type_idx=" << i - << " " << dex.GetTypeDescriptor(dex.GetTypeId(dex::TypeIndex(i))); + const ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(dex::TypeIndex(i)); + EXPECT_TRUE(type != nullptr) + << "type_idx=" << i << " " << dex.GetTypeDescriptor(dex.GetTypeId(dex::TypeIndex(i))); } EXPECT_TRUE(dex_cache->StaticMethodSize() == dex_cache->NumResolvedMethods() || dex.NumMethodIds() == dex_cache->NumResolvedMethods()); @@ -228,7 +228,7 @@ class CompilerDriverProfileTest : public CompilerDriverTest { StackHandleScope<1> hs(self); Handle<mirror::ClassLoader> h_loader( hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); - mirror::Class* klass = class_linker->FindClass(self, clazz.c_str(), h_loader); + ObjPtr<mirror::Class> klass = class_linker->FindClass(self, clazz.c_str(), h_loader); ASSERT_NE(klass, nullptr); const auto pointer_size = class_linker->GetImagePointerSize(); @@ -289,7 +289,7 @@ class CompilerDriverVerifyTest : public CompilerDriverTest { StackHandleScope<1> hs(self); Handle<mirror::ClassLoader> h_loader( hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); - mirror::Class* klass = class_linker->FindClass(self, clazz.c_str(), h_loader); + ObjPtr<mirror::Class> klass = class_linker->FindClass(self, clazz.c_str(), h_loader); ASSERT_NE(klass, nullptr); EXPECT_TRUE(klass->IsVerified()); diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc index da1db4593b..15c07870a1 100644 --- a/compiler/exception_test.cc +++ b/compiler/exception_test.cc @@ -34,6 +34,7 @@ #include "mirror/object_array-inl.h" #include "mirror/stack_trace_element.h" #include "oat_quick_method_header.h" +#include "obj_ptr-inl.h" #include "optimizing/stack_map_stream.h" #include "runtime-inl.h" #include "scoped_thread_state_change-inl.h" @@ -122,7 +123,7 @@ class ExceptionTest : public CommonRuntimeTest { ArtMethod* method_g_; private: - mirror::Class* my_klass_; + ObjPtr<mirror::Class> my_klass_; }; TEST_F(ExceptionTest, FindCatchHandler) { diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index dfe6d791c6..056f533398 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -272,7 +272,8 @@ IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo ClassLinker* class_linker = runtime->GetClassLinker(); gc::Heap* heap = runtime->GetHeap(); IntegerValueOfInfo info; - info.integer_cache = class_linker->FindSystemClass(self, "Ljava/lang/Integer$IntegerCache;"); + info.integer_cache = + class_linker->FindSystemClass(self, "Ljava/lang/Integer$IntegerCache;").Ptr(); if (info.integer_cache == nullptr) { self->ClearException(); return info; @@ -281,7 +282,7 @@ IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo // Optimization only works if the class is initialized and in the boot image. return info; } - info.integer = class_linker->FindSystemClass(self, "Ljava/lang/Integer;"); + info.integer = class_linker->FindSystemClass(self, "Ljava/lang/Integer;").Ptr(); if (info.integer == nullptr) { self->ClearException(); return info; diff --git a/compiler/verifier_deps_test.cc b/compiler/verifier_deps_test.cc index c0892ff466..3fe2ec0ac0 100644 --- a/compiler/verifier_deps_test.cc +++ b/compiler/verifier_deps_test.cc @@ -65,17 +65,16 @@ class VerifierDepsTest : public CommonCompilerTest { callbacks_.reset(new VerifierDepsCompilerCallbacks()); } - mirror::Class* FindClassByName(const std::string& name, ScopedObjectAccess* soa) + ObjPtr<mirror::Class> FindClassByName(ScopedObjectAccess& soa, const std::string& name) REQUIRES_SHARED(Locks::mutator_lock_) { - StackHandleScope<1> hs(Thread::Current()); + StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader_handle( - hs.NewHandle(soa->Decode<mirror::ClassLoader>(class_loader_))); - mirror::Class* klass = class_linker_->FindClass(Thread::Current(), - name.c_str(), - class_loader_handle); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_))); + ObjPtr<mirror::Class> klass = + class_linker_->FindClass(soa.Self(), name.c_str(), class_loader_handle); if (klass == nullptr) { - DCHECK(Thread::Current()->IsExceptionPending()); - Thread::Current()->ClearException(); + DCHECK(soa.Self()->IsExceptionPending()); + soa.Self()->ClearException(); } return klass; } @@ -114,16 +113,16 @@ class VerifierDepsTest : public CommonCompilerTest { callbacks->SetVerifierDeps(verifier_deps_.get()); } - void LoadDexFile(ScopedObjectAccess* soa, const char* name1, const char* name2 = nullptr) + void LoadDexFile(ScopedObjectAccess& soa, const char* name1, const char* name2 = nullptr) REQUIRES_SHARED(Locks::mutator_lock_) { class_loader_ = (name2 == nullptr) ? LoadDex(name1) : LoadMultiDex(name1, name2); dex_files_ = GetDexFiles(class_loader_); primary_dex_file_ = dex_files_.front(); SetVerifierDeps(dex_files_); - StackHandleScope<1> hs(soa->Self()); + StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> loader = - hs.NewHandle(soa->Decode<mirror::ClassLoader>(class_loader_)); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)); for (const DexFile* dex_file : dex_files_) { class_linker_->RegisterDexFile(*dex_file, loader.Get()); } @@ -133,16 +132,16 @@ class VerifierDepsTest : public CommonCompilerTest { compiler_driver_->SetDexFilesForOatFile(dex_files_); } - void LoadDexFile(ScopedObjectAccess* soa) REQUIRES_SHARED(Locks::mutator_lock_) { + void LoadDexFile(ScopedObjectAccess& soa) REQUIRES_SHARED(Locks::mutator_lock_) { LoadDexFile(soa, "VerifierDeps"); CHECK_EQ(dex_files_.size(), 1u); - klass_Main_ = FindClassByName("LMain;", soa); + klass_Main_ = FindClassByName(soa, "LMain;"); CHECK(klass_Main_ != nullptr); } bool VerifyMethod(const std::string& method_name) { ScopedObjectAccess soa(Thread::Current()); - LoadDexFile(&soa); + LoadDexFile(soa); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader_handle( @@ -193,7 +192,7 @@ class VerifierDepsTest : public CommonCompilerTest { void VerifyDexFile(const char* multidex = nullptr) { { ScopedObjectAccess soa(Thread::Current()); - LoadDexFile(&soa, "VerifierDeps", multidex); + LoadDexFile(soa, "VerifierDeps", multidex); } SetupCompilerDriver(); VerifyWithCompilerDriver(/* verifier_deps */ nullptr); @@ -204,13 +203,14 @@ class VerifierDepsTest : public CommonCompilerTest { bool is_strict, bool is_assignable) { ScopedObjectAccess soa(Thread::Current()); - LoadDexFile(&soa); - mirror::Class* klass_dst = FindClassByName(dst, &soa); + LoadDexFile(soa); + StackHandleScope<1> hs(soa.Self()); + Handle<mirror::Class> klass_dst = hs.NewHandle(FindClassByName(soa, dst)); DCHECK(klass_dst != nullptr) << dst; - mirror::Class* klass_src = FindClassByName(src, &soa); + ObjPtr<mirror::Class> klass_src = FindClassByName(soa, src); DCHECK(klass_src != nullptr) << src; verifier_deps_->AddAssignability(*primary_dex_file_, - klass_dst, + klass_dst.Get(), klass_src, is_strict, is_assignable); @@ -453,12 +453,12 @@ class VerifierDepsTest : public CommonCompilerTest { std::vector<const DexFile*> dex_files_; const DexFile* primary_dex_file_; jobject class_loader_; - mirror::Class* klass_Main_; + ObjPtr<mirror::Class> klass_Main_; }; TEST_F(VerifierDepsTest, StringToId) { ScopedObjectAccess soa(Thread::Current()); - LoadDexFile(&soa); + LoadDexFile(soa); dex::StringIndex id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;"); ASSERT_LT(id_Main1.index_, primary_dex_file_->NumStringIds()); @@ -1441,7 +1441,7 @@ TEST_F(VerifierDepsTest, CompilerDriver) { for (bool verify_failure : { false, true }) { { ScopedObjectAccess soa(Thread::Current()); - LoadDexFile(&soa, "VerifierDeps", multi); + LoadDexFile(soa, "VerifierDeps", multi); } VerifyWithCompilerDriver(/* verifier_deps */ nullptr); @@ -1450,7 +1450,7 @@ TEST_F(VerifierDepsTest, CompilerDriver) { { ScopedObjectAccess soa(Thread::Current()); - LoadDexFile(&soa, "VerifierDeps", multi); + LoadDexFile(soa, "VerifierDeps", multi); } verifier::VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer)); if (verify_failure) { diff --git a/dex2oat/linker/image_test.cc b/dex2oat/linker/image_test.cc index ab6e7a875a..96c48b8798 100644 --- a/dex2oat/linker/image_test.cc +++ b/dex2oat/linker/image_test.cc @@ -111,18 +111,18 @@ TEST_F(ImageTest, TestDefaultMethods) { // Test the pointer to quick code is the same in origin method // and in the copied method form the same oat file. - mirror::Class* iface_klass = class_linker_->LookupClass( - self, "LIface;", ObjPtr<mirror::ClassLoader>()); + ObjPtr<mirror::Class> iface_klass = + class_linker_->LookupClass(self, "LIface;", /* class_loader */ nullptr); ASSERT_NE(nullptr, iface_klass); ArtMethod* origin = iface_klass->FindInterfaceMethod("defaultMethod", "()V", pointer_size); ASSERT_NE(nullptr, origin); - ASSERT_TRUE(origin->GetDeclaringClass() == iface_klass); + ASSERT_OBJ_PTR_EQ(origin->GetDeclaringClass(), iface_klass); const void* code = origin->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); // The origin method should have a pointer to quick code ASSERT_NE(nullptr, code); ASSERT_FALSE(class_linker_->IsQuickToInterpreterBridge(code)); - mirror::Class* impl_klass = class_linker_->LookupClass( - self, "LImpl;", ObjPtr<mirror::ClassLoader>()); + ObjPtr<mirror::Class> impl_klass = + class_linker_->LookupClass(self, "LImpl;", /* class_loader */ nullptr); ASSERT_NE(nullptr, impl_klass); ArtMethod* copied = FindCopiedMethod(origin, impl_klass); ASSERT_NE(nullptr, copied); @@ -132,20 +132,20 @@ TEST_F(ImageTest, TestDefaultMethods) { // Test the origin method has pointer to quick code // but the copied method has pointer to interpreter // because these methods are in different oat files. - mirror::Class* iterable_klass = class_linker_->LookupClass( - self, "Ljava/lang/Iterable;", ObjPtr<mirror::ClassLoader>()); + ObjPtr<mirror::Class> iterable_klass = + class_linker_->LookupClass(self, "Ljava/lang/Iterable;", /* class_loader */ nullptr); ASSERT_NE(nullptr, iterable_klass); origin = iterable_klass->FindClassMethod( "forEach", "(Ljava/util/function/Consumer;)V", pointer_size); ASSERT_NE(nullptr, origin); ASSERT_FALSE(origin->IsDirect()); - ASSERT_TRUE(origin->GetDeclaringClass() == iterable_klass); + ASSERT_OBJ_PTR_EQ(origin->GetDeclaringClass(), iterable_klass); code = origin->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); // the origin method should have a pointer to quick code ASSERT_NE(nullptr, code); ASSERT_FALSE(class_linker_->IsQuickToInterpreterBridge(code)); - mirror::Class* iterablebase_klass = class_linker_->LookupClass( - self, "LIterableBase;", ObjPtr<mirror::ClassLoader>()); + ObjPtr<mirror::Class> iterablebase_klass = + class_linker_->LookupClass(self, "LIterableBase;", /* class_loader */ nullptr); ASSERT_NE(nullptr, iterablebase_klass); copied = FindCopiedMethod(origin, iterablebase_klass); ASSERT_NE(nullptr, copied); diff --git a/dex2oat/linker/image_test.h b/dex2oat/linker/image_test.h index 4b231ed35c..f0daf69850 100644 --- a/dex2oat/linker/image_test.h +++ b/dex2oat/linker/image_test.h @@ -97,7 +97,7 @@ class ImageTest : public CommonCompilerTest { return new std::unordered_set<std::string>(image_classes_); } - ArtMethod* FindCopiedMethod(ArtMethod* origin, mirror::Class* klass) + ArtMethod* FindCopiedMethod(ArtMethod* origin, ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) { PointerSize pointer_size = class_linker_->GetImagePointerSize(); for (ArtMethod& m : klass->GetCopiedMethods(pointer_size)) { diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 1f197b81f5..6b626c21cf 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -41,6 +41,7 @@ #include "base/unix_file/fd_file.h" #include "class_linker-inl.h" #include "class_linker.h" +#include "class_root.h" #include "compiled_method.h" #include "debug/debug_info.h" #include "debug/elf_debug_writer.h" @@ -3253,7 +3254,7 @@ class IMTDumper { PrepareClass(runtime, klass, prepared); } - mirror::Class* object_class = mirror::Class::GetJavaLangClass()->GetSuperClass(); + ObjPtr<mirror::Class> object_class = GetClassRoot<mirror::Object>(); DCHECK(object_class->IsObjectClass()); bool result = klass->GetImt(pointer_size) == object_class->GetImt(pointer_size); @@ -3287,8 +3288,8 @@ class IMTDumper { Handle<mirror::ClassLoader> h_loader, const std::string& class_name, const PointerSize pointer_size, - mirror::Class** klass_out, - std::unordered_set<std::string>* prepared) + /*out*/ ObjPtr<mirror::Class>* klass_out, + /*inout*/ std::unordered_set<std::string>* prepared) REQUIRES_SHARED(Locks::mutator_lock_) { if (class_name.empty()) { return nullptr; @@ -3301,7 +3302,8 @@ class IMTDumper { descriptor = DotToDescriptor(class_name.c_str()); } - mirror::Class* klass = runtime->GetClassLinker()->FindClass(self, descriptor.c_str(), h_loader); + ObjPtr<mirror::Class> klass = + runtime->GetClassLinker()->FindClass(self, descriptor.c_str(), h_loader); if (klass == nullptr) { self->ClearException(); @@ -3321,7 +3323,7 @@ class IMTDumper { static ImTable* PrepareAndGetImTable(Runtime* runtime, Handle<mirror::Class> h_klass, const PointerSize pointer_size, - std::unordered_set<std::string>* prepared) + /*inout*/ std::unordered_set<std::string>* prepared) REQUIRES_SHARED(Locks::mutator_lock_) { PrepareClass(runtime, h_klass, prepared); return h_klass->GetImt(pointer_size); @@ -3333,7 +3335,7 @@ class IMTDumper { std::unordered_set<std::string>* prepared) REQUIRES_SHARED(Locks::mutator_lock_) { const PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize(); - mirror::Class* klass; + ObjPtr<mirror::Class> klass; ImTable* imt = PrepareAndGetImTable(runtime, Thread::Current(), h_loader, @@ -3389,10 +3391,10 @@ class IMTDumper { const std::string& class_name, const std::string& method, Handle<mirror::ClassLoader> h_loader, - std::unordered_set<std::string>* prepared) + /*inout*/ std::unordered_set<std::string>* prepared) REQUIRES_SHARED(Locks::mutator_lock_) { const PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize(); - mirror::Class* klass; + ObjPtr<mirror::Class> klass; ImTable* imt = PrepareAndGetImTable(runtime, Thread::Current(), h_loader, @@ -3495,7 +3497,7 @@ class IMTDumper { // and note in the given set that the work was done. static void PrepareClass(Runtime* runtime, Handle<mirror::Class> h_klass, - std::unordered_set<std::string>* done) + /*inout*/ std::unordered_set<std::string>* done) REQUIRES_SHARED(Locks::mutator_lock_) { if (!h_klass->ShouldHaveImt()) { return; diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc index bd44e491b0..370f59dc8a 100644 --- a/profman/profile_assistant_test.cc +++ b/profman/profile_assistant_test.cc @@ -22,6 +22,7 @@ #include "base/utils.h" #include "common_runtime_test.h" #include "dex/descriptors_names.h" +#include "dex/type_reference.h" #include "exec_utils.h" #include "linear_alloc.h" #include "mirror/class-inl.h" @@ -33,6 +34,7 @@ namespace art { using Hotness = ProfileCompilationInfo::MethodHotness; +using TypeReferenceSet = std::set<TypeReference, TypeReferenceValueComparator>; static constexpr size_t kMaxMethodIds = 65535; @@ -308,25 +310,24 @@ class ProfileAssistantTest : public CommonRuntimeTest { return true; } - mirror::Class* GetClass(jobject class_loader, const std::string& clazz) { + ObjPtr<mirror::Class> GetClass(ScopedObjectAccess& soa, + jobject class_loader, + const std::string& clazz) REQUIRES_SHARED(Locks::mutator_lock_) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - Thread* self = Thread::Current(); - ScopedObjectAccess soa(self); - StackHandleScope<1> hs(self); - Handle<mirror::ClassLoader> h_loader( - hs.NewHandle(ObjPtr<mirror::ClassLoader>::DownCast(self->DecodeJObject(class_loader)))); - return class_linker->FindClass(self, clazz.c_str(), h_loader); + StackHandleScope<1> hs(soa.Self()); + Handle<mirror::ClassLoader> h_loader(hs.NewHandle( + ObjPtr<mirror::ClassLoader>::DownCast(soa.Self()->DecodeJObject(class_loader)))); + return class_linker->FindClass(soa.Self(), clazz.c_str(), h_loader); } ArtMethod* GetVirtualMethod(jobject class_loader, const std::string& clazz, const std::string& name) { - mirror::Class* klass = GetClass(class_loader, clazz); + ScopedObjectAccess soa(Thread::Current()); + ObjPtr<mirror::Class> klass = GetClass(soa, class_loader, clazz); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); const auto pointer_size = class_linker->GetImagePointerSize(); ArtMethod* method = nullptr; - Thread* self = Thread::Current(); - ScopedObjectAccess soa(self); for (auto& m : klass->GetVirtualMethods(pointer_size)) { if (name == m.GetName()) { EXPECT_TRUE(method == nullptr); @@ -336,9 +337,14 @@ class ProfileAssistantTest : public CommonRuntimeTest { return method; } + static TypeReference MakeTypeReference(ObjPtr<mirror::Class> klass) + REQUIRES_SHARED(Locks::mutator_lock_) { + return TypeReference(&klass->GetDexFile(), klass->GetDexTypeIndex()); + } + // Verify that given method has the expected inline caches and nothing else. void AssertInlineCaches(ArtMethod* method, - const std::set<mirror::Class*>& expected_clases, + const TypeReferenceSet& expected_clases, const ProfileCompilationInfo& info, bool is_megamorphic, bool is_missing_types) @@ -355,12 +361,11 @@ class ProfileAssistantTest : public CommonRuntimeTest { ASSERT_EQ(dex_pc_data.is_missing_types, is_missing_types); ASSERT_EQ(expected_clases.size(), dex_pc_data.classes.size()); size_t found = 0; - for (mirror::Class* it : expected_clases) { + for (const TypeReference& type_ref : expected_clases) { for (const auto& class_ref : dex_pc_data.classes) { ProfileCompilationInfo::DexReference dex_ref = pmi->dex_references[class_ref.dex_profile_index]; - if (dex_ref.MatchesDex(&(it->GetDexFile())) && - class_ref.type_index == it->GetDexTypeIndex()) { + if (dex_ref.MatchesDex(type_ref.dex_file) && class_ref.type_index == type_ref.TypeIndex()) { found++; } } @@ -715,7 +720,7 @@ TEST_F(ProfileAssistantTest, TestProfileCreationGenerateMethods) { ASSERT_TRUE(info.Load(GetFd(profile_file))); // Verify that the profile has matching methods. ScopedObjectAccess soa(Thread::Current()); - ObjPtr<mirror::Class> klass = GetClass(nullptr, "Ljava/lang/Math;"); + ObjPtr<mirror::Class> klass = GetClass(soa, /* class_loader */ nullptr, "Ljava/lang/Math;"); ASSERT_TRUE(klass != nullptr); size_t method_count = 0; for (ArtMethod& method : klass->GetMethods(kRuntimePointerSize)) { @@ -907,9 +912,10 @@ TEST_F(ProfileAssistantTest, TestProfileCreateInlineCache) { jobject class_loader = LoadDex("ProfileTestMultiDex"); ASSERT_NE(class_loader, nullptr); - mirror::Class* sub_a = GetClass(class_loader, "LSubA;"); - mirror::Class* sub_b = GetClass(class_loader, "LSubB;"); - mirror::Class* sub_c = GetClass(class_loader, "LSubC;"); + StackHandleScope<3> hs(soa.Self()); + Handle<mirror::Class> sub_a = hs.NewHandle(GetClass(soa, class_loader, "LSubA;")); + Handle<mirror::Class> sub_b = hs.NewHandle(GetClass(soa, class_loader, "LSubB;")); + Handle<mirror::Class> sub_c = hs.NewHandle(GetClass(soa, class_loader, "LSubC;")); ASSERT_TRUE(sub_a != nullptr); ASSERT_TRUE(sub_b != nullptr); @@ -921,8 +927,8 @@ TEST_F(ProfileAssistantTest, TestProfileCreateInlineCache) { "LTestInline;", "inlineMonomorphic"); ASSERT_TRUE(inline_monomorphic != nullptr); - std::set<mirror::Class*> expected_monomorphic; - expected_monomorphic.insert(sub_a); + TypeReferenceSet expected_monomorphic; + expected_monomorphic.insert(MakeTypeReference(sub_a.Get())); AssertInlineCaches(inline_monomorphic, expected_monomorphic, info, @@ -936,10 +942,10 @@ TEST_F(ProfileAssistantTest, TestProfileCreateInlineCache) { "LTestInline;", "inlinePolymorphic"); ASSERT_TRUE(inline_polymorhic != nullptr); - std::set<mirror::Class*> expected_polymorphic; - expected_polymorphic.insert(sub_a); - expected_polymorphic.insert(sub_b); - expected_polymorphic.insert(sub_c); + TypeReferenceSet expected_polymorphic; + expected_polymorphic.insert(MakeTypeReference(sub_a.Get())); + expected_polymorphic.insert(MakeTypeReference(sub_b.Get())); + expected_polymorphic.insert(MakeTypeReference(sub_c.Get())); AssertInlineCaches(inline_polymorhic, expected_polymorphic, info, @@ -953,7 +959,7 @@ TEST_F(ProfileAssistantTest, TestProfileCreateInlineCache) { "LTestInline;", "inlineMegamorphic"); ASSERT_TRUE(inline_megamorphic != nullptr); - std::set<mirror::Class*> expected_megamorphic; + TypeReferenceSet expected_megamorphic; AssertInlineCaches(inline_megamorphic, expected_megamorphic, info, @@ -967,7 +973,7 @@ TEST_F(ProfileAssistantTest, TestProfileCreateInlineCache) { "LTestInline;", "inlineMissingTypes"); ASSERT_TRUE(inline_missing_types != nullptr); - std::set<mirror::Class*> expected_missing_Types; + TypeReferenceSet expected_missing_Types; AssertInlineCaches(inline_missing_types, expected_missing_Types, info, diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index 7a99d3dc5e..25eb85d675 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -33,8 +33,8 @@ namespace art { -inline mirror::Class* ClassLinker::FindArrayClass(Thread* self, - ObjPtr<mirror::Class>* element_class) { +inline ObjPtr<mirror::Class> ClassLinker::FindArrayClass(Thread* self, + ObjPtr<mirror::Class>* element_class) { for (size_t i = 0; i < kFindArrayCacheSize; ++i) { // Read the cached array class once to avoid races with other threads setting it. ObjPtr<mirror::Class> array_class = find_array_class_cache_[i].Read(); diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 095272394a..cd03401cf9 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2059,8 +2059,7 @@ void ClassLinker::VisitClassesWithoutClassesLock(ClassVisitor* visitor) { // Add 100 in case new classes get loaded when we are filling in the object array. class_table_size = NumZygoteClasses() + NumNonZygoteClasses() + 100; } - ObjPtr<mirror::Class> class_type = mirror::Class::GetJavaLangClass(); - ObjPtr<mirror::Class> array_of_class = FindArrayClass(self, &class_type); + ObjPtr<mirror::Class> array_of_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>(this); classes.Assign( mirror::ObjectArray<mirror::Class>::Alloc(self, array_of_class, class_table_size)); CHECK(classes != nullptr); // OOME. @@ -2163,9 +2162,9 @@ mirror::DexCache* ClassLinker::AllocAndInitializeDexCache(Thread* self, return dex_cache.Ptr(); } -mirror::Class* ClassLinker::AllocClass(Thread* self, - ObjPtr<mirror::Class> java_lang_Class, - uint32_t class_size) { +ObjPtr<mirror::Class> ClassLinker::AllocClass(Thread* self, + ObjPtr<mirror::Class> java_lang_Class, + uint32_t class_size) { DCHECK_GE(class_size, sizeof(mirror::Class)); gc::Heap* heap = Runtime::Current()->GetHeap(); mirror::Class::InitializeClassVisitor visitor(class_size); @@ -2179,7 +2178,7 @@ mirror::Class* ClassLinker::AllocClass(Thread* self, return k->AsClass(); } -mirror::Class* ClassLinker::AllocClass(Thread* self, uint32_t class_size) { +ObjPtr<mirror::Class> ClassLinker::AllocClass(Thread* self, uint32_t class_size) { return AllocClass(self, GetClassRoot<mirror::Class>(this), class_size); } @@ -2190,9 +2189,9 @@ mirror::ObjectArray<mirror::StackTraceElement>* ClassLinker::AllocStackTraceElem self, GetClassRoot<mirror::ObjectArray<mirror::StackTraceElement>>(this), length); } -mirror::Class* ClassLinker::EnsureResolved(Thread* self, - const char* descriptor, - ObjPtr<mirror::Class> klass) { +ObjPtr<mirror::Class> ClassLinker::EnsureResolved(Thread* self, + const char* descriptor, + ObjPtr<mirror::Class> klass) { DCHECK(klass != nullptr); if (kIsDebugBuild) { StackHandleScope<1> hs(self); @@ -2400,9 +2399,9 @@ ObjPtr<mirror::Class> ClassLinker::FindClassInBaseDexClassLoaderClassPath( return ret; } -mirror::Class* ClassLinker::FindClass(Thread* self, - const char* descriptor, - Handle<mirror::ClassLoader> class_loader) { +ObjPtr<mirror::Class> ClassLinker::FindClass(Thread* self, + const char* descriptor, + Handle<mirror::ClassLoader> class_loader) { DCHECK_NE(*descriptor, '\0') << "descriptor is empty string"; DCHECK(self != nullptr); self->AssertNoPendingException(); @@ -2571,12 +2570,12 @@ mirror::Class* ClassLinker::FindClass(Thread* self, return result_ptr.Ptr(); } -mirror::Class* ClassLinker::DefineClass(Thread* self, - const char* descriptor, - size_t hash, - Handle<mirror::ClassLoader> class_loader, - const DexFile& dex_file, - const DexFile::ClassDef& dex_class_def) { +ObjPtr<mirror::Class> ClassLinker::DefineClass(Thread* self, + const char* descriptor, + size_t hash, + Handle<mirror::ClassLoader> class_loader, + const DexFile& dex_file, + const DexFile::ClassDef& dex_class_def) { StackHandleScope<3> hs(self); auto klass = hs.NewHandle<mirror::Class>(nullptr); @@ -3534,7 +3533,7 @@ ClassLinker::DexCacheData ClassLinker::FindDexCacheDataLocked(const DexFile& dex return DexCacheData(); } -mirror::Class* ClassLinker::CreatePrimitiveClass(Thread* self, Primitive::Type type) { +ObjPtr<mirror::Class> ClassLinker::CreatePrimitiveClass(Thread* self, Primitive::Type type) { ObjPtr<mirror::Class> primitive_class = AllocClass(self, mirror::Class::PrimitiveClassSize(image_pointer_size_)); if (UNLIKELY(primitive_class == nullptr)) { @@ -3570,8 +3569,10 @@ mirror::Class* ClassLinker::CreatePrimitiveClass(Thread* self, Primitive::Type t // array class; that always comes from the base element class. // // Returns null with an exception raised on failure. -mirror::Class* ClassLinker::CreateArrayClass(Thread* self, const char* descriptor, size_t hash, - Handle<mirror::ClassLoader> class_loader) { +ObjPtr<mirror::Class> ClassLinker::CreateArrayClass(Thread* self, + const char* descriptor, + size_t hash, + Handle<mirror::ClassLoader> class_loader) { // Identify the underlying component type CHECK_EQ('[', descriptor[0]); StackHandleScope<2> hs(self); @@ -3718,27 +3719,27 @@ mirror::Class* ClassLinker::CreateArrayClass(Thread* self, const char* descripto return existing.Ptr(); } -mirror::Class* ClassLinker::FindPrimitiveClass(char type) { +ObjPtr<mirror::Class> ClassLinker::FindPrimitiveClass(char type) { ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots = GetClassRoots(); switch (type) { case 'B': - return GetClassRoot(ClassRoot::kPrimitiveByte, class_roots).Ptr(); + return GetClassRoot(ClassRoot::kPrimitiveByte, class_roots); case 'C': - return GetClassRoot(ClassRoot::kPrimitiveChar, class_roots).Ptr(); + return GetClassRoot(ClassRoot::kPrimitiveChar, class_roots); case 'D': - return GetClassRoot(ClassRoot::kPrimitiveDouble, class_roots).Ptr(); + return GetClassRoot(ClassRoot::kPrimitiveDouble, class_roots); case 'F': - return GetClassRoot(ClassRoot::kPrimitiveFloat, class_roots).Ptr(); + return GetClassRoot(ClassRoot::kPrimitiveFloat, class_roots); case 'I': - return GetClassRoot(ClassRoot::kPrimitiveInt, class_roots).Ptr(); + return GetClassRoot(ClassRoot::kPrimitiveInt, class_roots); case 'J': - return GetClassRoot(ClassRoot::kPrimitiveLong, class_roots).Ptr(); + return GetClassRoot(ClassRoot::kPrimitiveLong, class_roots); case 'S': - return GetClassRoot(ClassRoot::kPrimitiveShort, class_roots).Ptr(); + return GetClassRoot(ClassRoot::kPrimitiveShort, class_roots); case 'Z': - return GetClassRoot(ClassRoot::kPrimitiveBoolean, class_roots).Ptr(); + return GetClassRoot(ClassRoot::kPrimitiveBoolean, class_roots); case 'V': - return GetClassRoot(ClassRoot::kPrimitiveVoid, class_roots).Ptr(); + return GetClassRoot(ClassRoot::kPrimitiveVoid, class_roots); default: break; } @@ -3747,7 +3748,9 @@ mirror::Class* ClassLinker::FindPrimitiveClass(char type) { return nullptr; } -mirror::Class* ClassLinker::InsertClass(const char* descriptor, ObjPtr<mirror::Class> klass, size_t hash) { +ObjPtr<mirror::Class> ClassLinker::InsertClass(const char* descriptor, + ObjPtr<mirror::Class> klass, + size_t hash) { if (VLOG_IS_ON(class_linker)) { ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache(); std::string source; @@ -3802,16 +3805,16 @@ void ClassLinker::UpdateClassMethods(ObjPtr<mirror::Class> klass, Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(klass); } -mirror::Class* ClassLinker::LookupClass(Thread* self, - const char* descriptor, - ObjPtr<mirror::ClassLoader> class_loader) { +ObjPtr<mirror::Class> ClassLinker::LookupClass(Thread* self, + const char* descriptor, + ObjPtr<mirror::ClassLoader> class_loader) { return LookupClass(self, descriptor, ComputeModifiedUtf8Hash(descriptor), class_loader); } -mirror::Class* ClassLinker::LookupClass(Thread* self, - const char* descriptor, - size_t hash, - ObjPtr<mirror::ClassLoader> class_loader) { +ObjPtr<mirror::Class> ClassLinker::LookupClass(Thread* self, + const char* descriptor, + size_t hash, + ObjPtr<mirror::ClassLoader> class_loader) { ReaderMutexLock mu(self, *Locks::classlinker_classes_lock_); ClassTable* const class_table = ClassTableForClassLoader(class_loader); if (class_table != nullptr) { @@ -4264,12 +4267,12 @@ void ClassLinker::ResolveMethodExceptionHandlerTypes(ArtMethod* method) { } } -mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& soa, - jstring name, - jobjectArray interfaces, - jobject loader, - jobjectArray methods, - jobjectArray throws) { +ObjPtr<mirror::Class> ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& soa, + jstring name, + jobjectArray interfaces, + jobject loader, + jobjectArray methods, + jobjectArray throws) { Thread* self = soa.Self(); StackHandleScope<10> hs(self); MutableHandle<mirror::Class> temp_klass(hs.NewHandle( @@ -8112,8 +8115,7 @@ ObjPtr<mirror::MethodType> ClassLinker::ResolveMethodType( // other than by looking at the shorty ? const size_t num_method_args = strlen(dex_file.StringDataByIdx(proto_id.shorty_idx_)) - 1; - ObjPtr<mirror::Class> class_type = mirror::Class::GetJavaLangClass(); - ObjPtr<mirror::Class> array_of_class = FindArrayClass(self, &class_type); + ObjPtr<mirror::Class> array_of_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>(this); Handle<mirror::ObjectArray<mirror::Class>> method_params(hs.NewHandle( mirror::ObjectArray<mirror::Class>::Alloc(self, array_of_class, num_method_args))); if (method_params == nullptr) { @@ -8219,11 +8221,10 @@ mirror::MethodHandle* ClassLinker::ResolveMethodHandleForField( } StackHandleScope<4> hs(self); - ObjPtr<mirror::Class> class_type = mirror::Class::GetJavaLangClass(); - ObjPtr<mirror::Class> array_of_class = FindArrayClass(self, &class_type); + ObjPtr<mirror::Class> array_of_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>(this); Handle<mirror::ObjectArray<mirror::Class>> method_params(hs.NewHandle( mirror::ObjectArray<mirror::Class>::Alloc(self, array_of_class, num_params))); - if (UNLIKELY(method_params.Get() == nullptr)) { + if (UNLIKELY(method_params == nullptr)) { DCHECK(self->IsExceptionPending()); return nullptr; } @@ -8398,8 +8399,7 @@ mirror::MethodHandle* ClassLinker::ResolveMethodHandleForMethod( int32_t num_params = static_cast<int32_t>(shorty_length + receiver_count - 1); StackHandleScope<7> hs(self); - ObjPtr<mirror::Class> class_type = mirror::Class::GetJavaLangClass(); - ObjPtr<mirror::Class> array_of_class = FindArrayClass(self, &class_type); + ObjPtr<mirror::Class> array_of_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>(this); Handle<mirror::ObjectArray<mirror::Class>> method_params(hs.NewHandle( mirror::ObjectArray<mirror::Class>::Alloc(self, array_of_class, num_params))); if (method_params.Get() == nullptr) { @@ -8897,19 +8897,19 @@ class ClassLinker::FindVirtualMethodHolderVisitor : public ClassVisitor { const PointerSize pointer_size_; }; -mirror::Class* ClassLinker::GetHoldingClassOfCopiedMethod(ArtMethod* method) { +ObjPtr<mirror::Class> ClassLinker::GetHoldingClassOfCopiedMethod(ArtMethod* method) { ScopedTrace trace(__FUNCTION__); // Since this function is slow, have a trace to notify people. CHECK(method->IsCopied()); FindVirtualMethodHolderVisitor visitor(method, image_pointer_size_); VisitClasses(&visitor); - return visitor.holder_.Ptr(); + return visitor.holder_; } -mirror::IfTable* ClassLinker::AllocIfTable(Thread* self, size_t ifcount) { - return down_cast<mirror::IfTable*>( +ObjPtr<mirror::IfTable> ClassLinker::AllocIfTable(Thread* self, size_t ifcount) { + return ObjPtr<mirror::IfTable>::DownCast(ObjPtr<mirror::ObjectArray<mirror::Object>>( mirror::IfTable::Alloc(self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(this), - ifcount * mirror::IfTable::kMax)); + ifcount * mirror::IfTable::kMax))); } // Instantiate ResolveMethod. diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 1f94c43408..b38f01d835 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -146,22 +146,22 @@ class ClassLinker { // Finds a class by its descriptor, loading it if necessary. // If class_loader is null, searches boot_class_path_. - mirror::Class* FindClass(Thread* self, - const char* descriptor, - Handle<mirror::ClassLoader> class_loader) + ObjPtr<mirror::Class> FindClass(Thread* self, + const char* descriptor, + Handle<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_); // Finds a class by its descriptor using the "system" class loader, ie by searching the // boot_class_path_. - mirror::Class* FindSystemClass(Thread* self, const char* descriptor) + ObjPtr<mirror::Class> FindSystemClass(Thread* self, const char* descriptor) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_) { return FindClass(self, descriptor, ScopedNullHandle<mirror::ClassLoader>()); } // Finds the array class given for the element class. - mirror::Class* FindArrayClass(Thread* self, ObjPtr<mirror::Class>* element_class) + ObjPtr<mirror::Class> FindArrayClass(Thread* self, ObjPtr<mirror::Class>* element_class) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_); @@ -171,20 +171,20 @@ class ClassLinker { } // Define a new a class based on a ClassDef from a DexFile - mirror::Class* DefineClass(Thread* self, - const char* descriptor, - size_t hash, - Handle<mirror::ClassLoader> class_loader, - const DexFile& dex_file, - const DexFile::ClassDef& dex_class_def) + ObjPtr<mirror::Class> DefineClass(Thread* self, + const char* descriptor, + size_t hash, + Handle<mirror::ClassLoader> class_loader, + const DexFile& dex_file, + const DexFile::ClassDef& dex_class_def) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_); // Finds a class by its descriptor, returning null if it isn't wasn't loaded // by the given 'class_loader'. - mirror::Class* LookupClass(Thread* self, - const char* descriptor, - ObjPtr<mirror::ClassLoader> class_loader) + ObjPtr<mirror::Class> LookupClass(Thread* self, + const char* descriptor, + ObjPtr<mirror::ClassLoader> class_loader) REQUIRES(!Locks::classlinker_classes_lock_) REQUIRES_SHARED(Locks::mutator_lock_); @@ -193,7 +193,7 @@ class ClassLinker { REQUIRES(!Locks::classlinker_classes_lock_) REQUIRES_SHARED(Locks::mutator_lock_); - mirror::Class* FindPrimitiveClass(char type) REQUIRES_SHARED(Locks::mutator_lock_); + ObjPtr<mirror::Class> FindPrimitiveClass(char type) REQUIRES_SHARED(Locks::mutator_lock_); void DumpForSigQuit(std::ostream& os) REQUIRES(!Locks::classlinker_classes_lock_); @@ -456,7 +456,7 @@ class ClassLinker { REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); - mirror::IfTable* AllocIfTable(Thread* self, size_t ifcount) + ObjPtr<mirror::IfTable> AllocIfTable(Thread* self, size_t ifcount) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); @@ -483,12 +483,12 @@ class ClassLinker { REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_); - mirror::Class* CreateProxyClass(ScopedObjectAccessAlreadyRunnable& soa, - jstring name, - jobjectArray interfaces, - jobject loader, - jobjectArray methods, - jobjectArray throws) + ObjPtr<mirror::Class> CreateProxyClass(ScopedObjectAccessAlreadyRunnable& soa, + jstring name, + jobjectArray interfaces, + jobject loader, + jobjectArray methods, + jobjectArray throws) REQUIRES_SHARED(Locks::mutator_lock_); std::string GetDescriptorForProxy(ObjPtr<mirror::Class> proxy_class) REQUIRES_SHARED(Locks::mutator_lock_); @@ -531,7 +531,9 @@ class ClassLinker { // Attempts to insert a class into a class table. Returns null if // the class was inserted, otherwise returns an existing class with // the same descriptor and ClassLoader. - mirror::Class* InsertClass(const char* descriptor, ObjPtr<mirror::Class> klass, size_t hash) + ObjPtr<mirror::Class> InsertClass(const char* descriptor, + ObjPtr<mirror::Class> klass, + size_t hash) REQUIRES(!Locks::classlinker_classes_lock_) REQUIRES_SHARED(Locks::mutator_lock_); @@ -659,7 +661,7 @@ class ClassLinker { REQUIRES(!Locks::dex_lock_); // Get the actual holding class for a copied method. Pretty slow, don't call often. - mirror::Class* GetHoldingClassOfCopiedMethod(ArtMethod* method) + ObjPtr<mirror::Class> GetHoldingClassOfCopiedMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); // Returns null if not found. @@ -763,16 +765,16 @@ class ClassLinker { REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); // For early bootstrapping by Init - mirror::Class* AllocClass(Thread* self, - ObjPtr<mirror::Class> java_lang_Class, - uint32_t class_size) + ObjPtr<mirror::Class> AllocClass(Thread* self, + ObjPtr<mirror::Class> java_lang_Class, + uint32_t class_size) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); - // Alloc* convenience functions to avoid needing to pass in mirror::Class* - // values that are known to the ClassLinker such as - // kObjectArrayClass and kJavaLangString etc. - mirror::Class* AllocClass(Thread* self, uint32_t class_size) + // Alloc* convenience functions to avoid needing to pass in ObjPtr<mirror::Class> + // values that are known to the ClassLinker such as classes corresponding to + // ClassRoot::kObjectArrayClass and ClassRoot::kJavaLangString etc. + ObjPtr<mirror::Class> AllocClass(Thread* self, uint32_t class_size) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); @@ -790,14 +792,14 @@ class ClassLinker { REQUIRES(!Locks::dex_lock_) REQUIRES(!Roles::uninterruptible_); - mirror::Class* CreatePrimitiveClass(Thread* self, Primitive::Type type) + ObjPtr<mirror::Class> CreatePrimitiveClass(Thread* self, Primitive::Type type) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); - mirror::Class* CreateArrayClass(Thread* self, - const char* descriptor, - size_t hash, - Handle<mirror::ClassLoader> class_loader) + ObjPtr<mirror::Class> CreateArrayClass(Thread* self, + const char* descriptor, + size_t hash, + Handle<mirror::ClassLoader> class_loader) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); @@ -889,10 +891,10 @@ class ClassLinker { // Finds a class by its descriptor, returning NULL if it isn't wasn't loaded // by the given 'class_loader'. Uses the provided hash for the descriptor. - mirror::Class* LookupClass(Thread* self, - const char* descriptor, - size_t hash, - ObjPtr<mirror::ClassLoader> class_loader) + ObjPtr<mirror::Class> LookupClass(Thread* self, + const char* descriptor, + size_t hash, + ObjPtr<mirror::ClassLoader> class_loader) REQUIRES(!Locks::classlinker_classes_lock_) REQUIRES_SHARED(Locks::mutator_lock_); @@ -1163,7 +1165,9 @@ class ClassLinker { // when resolution has occurred. This happens in mirror::Class::SetStatus. As resolution may // retire a class, the version of the class in the table is returned and this may differ from // the class passed in. - mirror::Class* EnsureResolved(Thread* self, const char* descriptor, ObjPtr<mirror::Class> klass) + ObjPtr<mirror::Class> EnsureResolved(Thread* self, + const char* descriptor, + ObjPtr<mirror::Class> klass) WARN_UNUSED REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_); diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 48ec6b6c27..5d420aae04 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -198,7 +198,8 @@ class ClassLinkerTest : public CommonRuntimeTest { ASSERT_STREQ(array_descriptor.c_str(), array->GetDescriptor(&temp)); EXPECT_TRUE(array->GetSuperClass() != nullptr); Thread* self = Thread::Current(); - EXPECT_EQ(class_linker_->FindSystemClass(self, "Ljava/lang/Object;"), array->GetSuperClass()); + EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(self, "Ljava/lang/Object;"), + array->GetSuperClass()); EXPECT_TRUE(array->HasSuperClass()); ASSERT_TRUE(array->GetComponentType() != nullptr); ASSERT_GT(strlen(array->GetComponentType()->GetDescriptor(&temp)), 0U); @@ -1079,27 +1080,27 @@ TEST_F(ClassLinkerTest, ValidatePrimitiveArrayElementsOffset) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<5> hs(soa.Self()); Handle<mirror::LongArray> long_array(hs.NewHandle(mirror::LongArray::Alloc(soa.Self(), 0))); - EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[J"), long_array->GetClass()); + EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "[J"), long_array->GetClass()); uintptr_t data_offset = reinterpret_cast<uintptr_t>(long_array->GetData()); EXPECT_TRUE(IsAligned<8>(data_offset)); // Longs require 8 byte alignment Handle<mirror::DoubleArray> double_array(hs.NewHandle(mirror::DoubleArray::Alloc(soa.Self(), 0))); - EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[D"), double_array->GetClass()); + EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "[D"), double_array->GetClass()); data_offset = reinterpret_cast<uintptr_t>(double_array->GetData()); EXPECT_TRUE(IsAligned<8>(data_offset)); // Doubles require 8 byte alignment Handle<mirror::IntArray> int_array(hs.NewHandle(mirror::IntArray::Alloc(soa.Self(), 0))); - EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[I"), int_array->GetClass()); + EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "[I"), int_array->GetClass()); data_offset = reinterpret_cast<uintptr_t>(int_array->GetData()); EXPECT_TRUE(IsAligned<4>(data_offset)); // Ints require 4 byte alignment Handle<mirror::CharArray> char_array(hs.NewHandle(mirror::CharArray::Alloc(soa.Self(), 0))); - EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[C"), char_array->GetClass()); + EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "[C"), char_array->GetClass()); data_offset = reinterpret_cast<uintptr_t>(char_array->GetData()); EXPECT_TRUE(IsAligned<2>(data_offset)); // Chars require 2 byte alignment Handle<mirror::ShortArray> short_array(hs.NewHandle(mirror::ShortArray::Alloc(soa.Self(), 0))); - EXPECT_EQ(class_linker_->FindSystemClass(soa.Self(), "[S"), short_array->GetClass()); + EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "[S"), short_array->GetClass()); data_offset = reinterpret_cast<uintptr_t>(short_array->GetData()); EXPECT_TRUE(IsAligned<2>(data_offset)); // Shorts require 2 byte alignment diff --git a/runtime/gc/space/space_test.h b/runtime/gc/space/space_test.h index d5861ed5d8..c94b666695 100644 --- a/runtime/gc/space/space_test.h +++ b/runtime/gc/space/space_test.h @@ -53,13 +53,11 @@ class SpaceTest : public Super { } mirror::Class* GetByteArrayClass(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - StackHandleScope<1> hs(self); - auto null_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); if (byte_array_class_ == nullptr) { - mirror::Class* byte_array_class = - Runtime::Current()->GetClassLinker()->FindClass(self, "[B", null_loader); + ObjPtr<mirror::Class> byte_array_class = + Runtime::Current()->GetClassLinker()->FindSystemClass(self, "[B"); EXPECT_TRUE(byte_array_class != nullptr); - byte_array_class_ = self->GetJniEnv()->NewLocalRef(byte_array_class); + byte_array_class_ = self->GetJniEnv()->NewLocalRef(byte_array_class.Ptr()); EXPECT_TRUE(byte_array_class_ != nullptr); } return self->DecodeJObject(byte_array_class_)->AsClass(); diff --git a/runtime/hidden_api_test.cc b/runtime/hidden_api_test.cc index ab0c2901ff..a41d28492d 100644 --- a/runtime/hidden_api_test.cc +++ b/runtime/hidden_api_test.cc @@ -325,8 +325,8 @@ TEST_F(HiddenApiTest, CheckMemberSignatureForProxyClass) { ASSERT_TRUE(h_iface != nullptr); // Create the proxy class. - std::vector<mirror::Class*> interfaces; - interfaces.push_back(h_iface.Get()); + std::vector<Handle<mirror::Class>> interfaces; + interfaces.push_back(h_iface); Handle<mirror::Class> proxyClass = hs.NewHandle(proxy_test::GenerateProxyClass( soa, jclass_loader_, runtime_->GetClassLinker(), "$Proxy1234", interfaces)); ASSERT_TRUE(proxyClass != nullptr); diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index fab350942a..56658c3005 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -1128,9 +1128,9 @@ static ObjPtr<mirror::MethodType> BuildCallSiteForBootstrapMethod(Thread* self, StackHandleScope<2> hs(self); // Create array for parameter types. - ObjPtr<mirror::Class> class_type = mirror::Class::GetJavaLangClass(); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - ObjPtr<mirror::Class> class_array_type = class_linker->FindArrayClass(self, &class_type); + ObjPtr<mirror::Class> class_array_type = + GetClassRoot<mirror::ObjectArray<mirror::Class>>(class_linker); Handle<mirror::ObjectArray<mirror::Class>> ptypes = hs.NewHandle( mirror::ObjectArray<mirror::Class>::Alloc(self, class_array_type, diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc index 88cfafba47..fee837572b 100644 --- a/runtime/interpreter/unstarted_runtime_test.cc +++ b/runtime/interpreter/unstarted_runtime_test.cc @@ -196,7 +196,7 @@ class UnstartedRuntimeTest : public CommonRuntimeTest { // Prepare for aborts. Aborts assume that the exception class is already resolved, as the // loading code doesn't work under transactions. void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass( + ObjPtr<mirror::Object> result = Runtime::Current()->GetClassLinker()->FindClass( Thread::Current(), Transaction::kAbortExceptionSignature, ScopedNullHandle<mirror::ClassLoader>()); diff --git a/runtime/method_handles_test.cc b/runtime/method_handles_test.cc index a9473421cb..0db9551265 100644 --- a/runtime/method_handles_test.cc +++ b/runtime/method_handles_test.cc @@ -17,6 +17,7 @@ #include "method_handles.h" #include "class_linker-inl.h" +#include "class_root.h" #include "common_runtime_test.h" #include "handle_scope-inl.h" #include "jvalue-inl.h" @@ -49,12 +50,11 @@ namespace { REQUIRES_SHARED(Locks::mutator_lock_) { ClassLinker* cl = Runtime::Current()->GetClassLinker(); StackHandleScope<2> hs(self); - ObjPtr<mirror::Class> class_type = mirror::Class::GetJavaLangClass(); - ObjPtr<mirror::Class> class_array_type = cl->FindArrayClass(self, &class_type); + ObjPtr<mirror::Class> class_array_type = GetClassRoot<mirror::ObjectArray<mirror::Class>>(cl); auto parameter_types = hs.NewHandle( mirror::ObjectArray<mirror::Class>::Alloc(self, class_array_type, 1)); parameter_types->Set(0, parameter_type.Get()); - Handle<mirror::Class> void_class = hs.NewHandle(cl->FindPrimitiveClass('V')); + Handle<mirror::Class> void_class = hs.NewHandle(GetClassRoot(ClassRoot::kPrimitiveVoid, cl)); return mirror::MethodType::Create(self, void_class, parameter_types); } diff --git a/runtime/mirror/method_type.cc b/runtime/mirror/method_type.cc index a8be8b7019..483fff5b26 100644 --- a/runtime/mirror/method_type.cc +++ b/runtime/mirror/method_type.cc @@ -28,9 +28,7 @@ namespace { ObjPtr<ObjectArray<Class>> AllocatePTypesArray(Thread* self, int count) REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<Class> class_type = Class::GetJavaLangClass(); - ObjPtr<Class> class_array_type = - Runtime::Current()->GetClassLinker()->FindArrayClass(self, &class_type); + ObjPtr<Class> class_array_type = GetClassRoot<mirror::ObjectArray<mirror::Class>>(); return ObjectArray<Class>::Alloc(self, class_array_type, count); } diff --git a/runtime/mirror/method_type_test.cc b/runtime/mirror/method_type_test.cc index 16bfc73e04..2bdea72f14 100644 --- a/runtime/mirror/method_type_test.cc +++ b/runtime/mirror/method_type_test.cc @@ -22,6 +22,7 @@ #include "class-inl.h" #include "class_linker-inl.h" #include "class_loader.h" +#include "class_root.h" #include "common_runtime_test.h" #include "handle_scope-inl.h" #include "object_array-inl.h" @@ -53,8 +54,8 @@ static mirror::MethodType* CreateMethodType(const std::string& return_type, soa.Self(), FullyQualifiedType(return_type).c_str(), boot_class_loader)); CHECK(return_clazz != nullptr); - ObjPtr<mirror::Class> class_type = mirror::Class::GetJavaLangClass(); - ObjPtr<mirror::Class> class_array_type = class_linker->FindArrayClass(self, &class_type); + ObjPtr<mirror::Class> class_array_type = + GetClassRoot<mirror::ObjectArray<mirror::Class>>(class_linker); Handle<mirror::ObjectArray<mirror::Class>> param_classes = hs.NewHandle( mirror::ObjectArray<mirror::Class>::Alloc(self, class_array_type, param_types.size())); diff --git a/runtime/mirror/var_handle.cc b/runtime/mirror/var_handle.cc index 8311d911cc..71f41b9d12 100644 --- a/runtime/mirror/var_handle.cc +++ b/runtime/mirror/var_handle.cc @@ -27,6 +27,7 @@ #include "jvalue-inl.h" #include "method_handles-inl.h" #include "method_type.h" +#include "obj_ptr-inl.h" #include "well_known_classes.h" namespace art { @@ -266,31 +267,22 @@ int32_t BuildParameterArray(ObjPtr<Class> (¶meters)[VarHandle::kMaxAccessorP // Returns the return type associated with an AccessModeTemplate based // on the template and the variable type specified. -Class* GetReturnType(AccessModeTemplate access_mode_template, ObjPtr<Class> varType) +static ObjPtr<Class> GetReturnType(AccessModeTemplate access_mode_template, ObjPtr<Class> varType) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(varType != nullptr); switch (access_mode_template) { case AccessModeTemplate::kCompareAndSet: - return Runtime::Current()->GetClassLinker()->FindPrimitiveClass('Z'); + return GetClassRoot(ClassRoot::kPrimitiveBoolean); case AccessModeTemplate::kCompareAndExchange: case AccessModeTemplate::kGet: case AccessModeTemplate::kGetAndUpdate: - return varType.Ptr(); + return varType; case AccessModeTemplate::kSet: - return Runtime::Current()->GetClassLinker()->FindPrimitiveClass('V'); + return GetClassRoot(ClassRoot::kPrimitiveVoid); } return nullptr; } -ObjectArray<Class>* NewArrayOfClasses(Thread* self, int count) - REQUIRES_SHARED(Locks::mutator_lock_) { - Runtime* const runtime = Runtime::Current(); - ClassLinker* const class_linker = runtime->GetClassLinker(); - ObjPtr<mirror::Class> class_type = mirror::Class::GetJavaLangClass(); - ObjPtr<mirror::Class> array_of_class = class_linker->FindArrayClass(self, &class_type); - return ObjectArray<Class>::Alloc(Thread::Current(), array_of_class, count); -} - // Method to insert a read barrier for accessors to reference fields. inline void ReadBarrierForVarHandleAccess(ObjPtr<Object> obj, MemberOffset field_offset) REQUIRES_SHARED(Locks::mutator_lock_) { @@ -1410,15 +1402,15 @@ class ByteArrayViewAccessor { } // namespace -Class* VarHandle::GetVarType() { +ObjPtr<Class> VarHandle::GetVarType() { return GetFieldObject<Class>(VarTypeOffset()); } -Class* VarHandle::GetCoordinateType0() { +ObjPtr<Class> VarHandle::GetCoordinateType0() { return GetFieldObject<Class>(CoordinateType0Offset()); } -Class* VarHandle::GetCoordinateType1() { +ObjPtr<Class> VarHandle::GetCoordinateType1() { return GetFieldObject<Class>(CoordinateType1Offset()); } @@ -1438,7 +1430,7 @@ VarHandle::MatchKind VarHandle::GetMethodTypeMatchForAccessMode(AccessMode acces // Check return type first. If the return type of the method // of the VarHandle is immaterial. if (mt_rtype->GetPrimitiveType() != Primitive::Type::kPrimVoid) { - ObjPtr<Class> vh_rtype = GetReturnType(access_mode_template, var_type.Ptr()); + ObjPtr<Class> vh_rtype = GetReturnType(access_mode_template, var_type); if (vh_rtype != mt_rtype) { if (!IsReturnTypeConvertible(vh_rtype, mt_rtype)) { return MatchKind::kNone; @@ -1513,9 +1505,9 @@ bool VarHandle::IsInvokerMethodTypeCompatible(AccessMode access_mode, return true; } -MethodType* VarHandle::GetMethodTypeForAccessMode(Thread* self, - ObjPtr<VarHandle> var_handle, - AccessMode access_mode) { +ObjPtr<MethodType> VarHandle::GetMethodTypeForAccessMode(Thread* self, + ObjPtr<VarHandle> var_handle, + AccessMode access_mode) { // This is a static method as the var_handle might be moved by the GC during it's execution. AccessModeTemplate access_mode_template = GetAccessModeTemplate(access_mode); @@ -1525,7 +1517,9 @@ MethodType* VarHandle::GetMethodTypeForAccessMode(Thread* self, const int32_t ptypes_count = GetNumberOfParameters(access_mode_template, vh->GetCoordinateType0(), vh->GetCoordinateType1()); - Handle<ObjectArray<Class>> ptypes = hs.NewHandle(NewArrayOfClasses(self, ptypes_count)); + ObjPtr<Class> array_of_class = GetClassRoot<ObjectArray<Class>>(); + Handle<ObjectArray<Class>> ptypes = + hs.NewHandle(ObjectArray<Class>::Alloc(Thread::Current(), array_of_class, ptypes_count)); if (ptypes == nullptr) { return nullptr; } @@ -1537,12 +1531,12 @@ MethodType* VarHandle::GetMethodTypeForAccessMode(Thread* self, vh->GetCoordinateType0(), vh->GetCoordinateType1()); for (int32_t i = 0; i < ptypes_count; ++i) { - ptypes->Set(i, ptypes_array[i].Ptr()); + ptypes->Set(i, ptypes_array[i]); } return MethodType::Create(self, rtype, ptypes); } -MethodType* VarHandle::GetMethodTypeForAccessMode(Thread* self, AccessMode access_mode) { +ObjPtr<MethodType> VarHandle::GetMethodTypeForAccessMode(Thread* self, AccessMode access_mode) { return GetMethodTypeForAccessMode(self, this, access_mode); } diff --git a/runtime/mirror/var_handle.h b/runtime/mirror/var_handle.h index 9829456854..48c9d74e30 100644 --- a/runtime/mirror/var_handle.h +++ b/runtime/mirror/var_handle.h @@ -26,6 +26,7 @@ namespace art { template<class T> class Handle; class InstructionOperands; +template<class T> class ObjPtr; enum class Intrinsics; @@ -120,7 +121,7 @@ class MANAGED VarHandle : public Object { // AccessMode. No check is made for whether the AccessMode is a // supported operation so the MethodType can be used when raising a // WrongMethodTypeException exception. - MethodType* GetMethodTypeForAccessMode(Thread* self, AccessMode accessMode) + ObjPtr<MethodType> GetMethodTypeForAccessMode(Thread* self, AccessMode accessMode) REQUIRES_SHARED(Locks::mutator_lock_); // Returns a string representing the descriptor of the MethodType associated with @@ -135,7 +136,7 @@ class MANAGED VarHandle : public Object { REQUIRES_SHARED(Locks::mutator_lock_); // Gets the variable type that is operated on by this VarHandle instance. - Class* GetVarType() REQUIRES_SHARED(Locks::mutator_lock_); + ObjPtr<Class> GetVarType() REQUIRES_SHARED(Locks::mutator_lock_); // Gets the return type descriptor for a named accessor method, // nullptr if accessor_method is not supported. @@ -149,13 +150,13 @@ class MANAGED VarHandle : public Object { static bool GetAccessModeByMethodName(const char* method_name, AccessMode* access_mode); private: - Class* GetCoordinateType0() REQUIRES_SHARED(Locks::mutator_lock_); - Class* GetCoordinateType1() REQUIRES_SHARED(Locks::mutator_lock_); + ObjPtr<Class> GetCoordinateType0() REQUIRES_SHARED(Locks::mutator_lock_); + ObjPtr<Class> GetCoordinateType1() REQUIRES_SHARED(Locks::mutator_lock_); int32_t GetAccessModesBitMask() REQUIRES_SHARED(Locks::mutator_lock_); - static MethodType* GetMethodTypeForAccessMode(Thread* self, - ObjPtr<VarHandle> var_handle, - AccessMode access_mode) + static ObjPtr<MethodType> GetMethodTypeForAccessMode(Thread* self, + ObjPtr<VarHandle> var_handle, + AccessMode access_mode) REQUIRES_SHARED(Locks::mutator_lock_); static MemberOffset VarTypeOffset() { diff --git a/runtime/mirror/var_handle_test.cc b/runtime/mirror/var_handle_test.cc index cb2d628b5b..9df96ddbd1 100644 --- a/runtime/mirror/var_handle_test.cc +++ b/runtime/mirror/var_handle_test.cc @@ -130,17 +130,17 @@ class VarHandleTest : public CommonRuntimeTest { } // Helper to get the VarType of a VarHandle. - static Class* GetVarType(VarHandle* vh) REQUIRES_SHARED(Locks::mutator_lock_) { + static ObjPtr<Class> GetVarType(VarHandle* vh) REQUIRES_SHARED(Locks::mutator_lock_) { return vh->GetVarType(); } // Helper to get the CoordinateType0 of a VarHandle. - static Class* GetCoordinateType0(VarHandle* vh) REQUIRES_SHARED(Locks::mutator_lock_) { + static ObjPtr<Class> GetCoordinateType0(VarHandle* vh) REQUIRES_SHARED(Locks::mutator_lock_) { return vh->GetCoordinateType0(); } // Helper to get the CoordinateType1 of a VarHandle. - static Class* GetCoordinateType1(VarHandle* vh) REQUIRES_SHARED(Locks::mutator_lock_) { + static ObjPtr<Class> GetCoordinateType1(VarHandle* vh) REQUIRES_SHARED(Locks::mutator_lock_) { return vh->GetCoordinateType1(); } @@ -150,7 +150,7 @@ class VarHandleTest : public CommonRuntimeTest { } private: - static void InitializeVarHandle(VarHandle* vh, + static void InitializeVarHandle(ObjPtr<VarHandle> vh, Handle<Class> var_type, int32_t access_modes_bit_mask) REQUIRES_SHARED(Locks::mutator_lock_) { @@ -158,7 +158,7 @@ class VarHandleTest : public CommonRuntimeTest { vh->SetField32<false>(VarHandle::AccessModesBitMaskOffset(), access_modes_bit_mask); } - static void InitializeVarHandle(VarHandle* vh, + static void InitializeVarHandle(ObjPtr<VarHandle> vh, Handle<Class> var_type, Handle<Class> coordinate_type0, int32_t access_modes_bit_mask) @@ -167,7 +167,7 @@ class VarHandleTest : public CommonRuntimeTest { vh->SetFieldObject<false>(VarHandle::CoordinateType0Offset(), coordinate_type0.Get()); } - static void InitializeVarHandle(VarHandle* vh, + static void InitializeVarHandle(ObjPtr<VarHandle> vh, Handle<Class> var_type, Handle<Class> coordinate_type0, Handle<Class> coordinate_type1, diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index 261178b0ee..c6bdfa10c6 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -215,17 +215,9 @@ static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) { return soa.AddLocalReference<jstring>(mirror::Class::ComputeName(hs.NewHandle(c))); } -// TODO: Move this to mirror::Class ? Other mirror types that commonly appear -// as arrays have a GetArrayClass() method. -static ObjPtr<mirror::Class> GetClassArrayClass(Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass(); - return Runtime::Current()->GetClassLinker()->FindArrayClass(self, &class_class); -} - static jobjectArray Class_getInterfacesInternal(JNIEnv* env, jobject javaThis) { ScopedFastNativeObjectAccess soa(env); - StackHandleScope<4> hs(soa.Self()); + StackHandleScope<1> hs(soa.Self()); Handle<mirror::Class> klass = hs.NewHandle(DecodeClass(soa, javaThis)); if (klass->IsProxyClass()) { @@ -237,10 +229,12 @@ static jobjectArray Class_getInterfacesInternal(JNIEnv* env, jobject javaThis) { return nullptr; } + ClassLinker* linker = Runtime::Current()->GetClassLinker(); const uint32_t num_ifaces = iface_list->Size(); - Handle<mirror::Class> class_array_class = hs.NewHandle(GetClassArrayClass(soa.Self())); - Handle<mirror::ObjectArray<mirror::Class>> ifaces = hs.NewHandle( - mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class.Get(), num_ifaces)); + ObjPtr<mirror::Class> class_array_class = + GetClassRoot<mirror::ObjectArray<mirror::Class>>(linker); + ObjPtr<mirror::ObjectArray<mirror::Class>> ifaces = + mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, num_ifaces); if (ifaces.IsNull()) { DCHECK(soa.Self()->IsExceptionPending()); return nullptr; @@ -250,20 +244,21 @@ static jobjectArray Class_getInterfacesInternal(JNIEnv* env, jobject javaThis) { // with kActiveTransaction == false. DCHECK(!Runtime::Current()->IsActiveTransaction()); - ClassLinker* linker = Runtime::Current()->GetClassLinker(); - MutableHandle<mirror::Class> interface(hs.NewHandle<mirror::Class>(nullptr)); for (uint32_t i = 0; i < num_ifaces; ++i) { const dex::TypeIndex type_idx = iface_list->GetTypeItem(i).type_idx_; - interface.Assign(linker->LookupResolvedType(type_idx, klass.Get())); - ifaces->SetWithoutChecks<false>(i, interface.Get()); + ObjPtr<mirror::Class> interface = linker->LookupResolvedType(type_idx, klass.Get()); + DCHECK(interface != nullptr); + ifaces->SetWithoutChecks<false>(i, interface); } - return soa.AddLocalReference<jobjectArray>(ifaces.Get()); + return soa.AddLocalReference<jobjectArray>(ifaces); } -static mirror::ObjectArray<mirror::Field>* GetDeclaredFields( - Thread* self, ObjPtr<mirror::Class> klass, bool public_only, bool force_resolve) - REQUIRES_SHARED(Locks::mutator_lock_) { +static ObjPtr<mirror::ObjectArray<mirror::Field>> GetDeclaredFields( + Thread* self, + ObjPtr<mirror::Class> klass, + bool public_only, + bool force_resolve) REQUIRES_SHARED(Locks::mutator_lock_) { StackHandleScope<1> hs(self); IterationRange<StrideIterator<ArtField>> ifields = klass->GetIFields(); IterationRange<StrideIterator<ArtField>> sfields = klass->GetSFields(); @@ -672,10 +667,8 @@ static jobjectArray Class_getDeclaredClasses(JNIEnv* env, jobject javaThis) { // Pending exception from GetDeclaredClasses. return nullptr; } - ObjPtr<mirror::Class> class_array_class = GetClassArrayClass(soa.Self()); - if (class_array_class == nullptr) { - return nullptr; - } + ObjPtr<mirror::Class> class_array_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>(); + DCHECK(class_array_class != nullptr); ObjPtr<mirror::ObjectArray<mirror::Class>> empty_array = mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, 0); return soa.AddLocalReference<jobjectArray>(empty_array); diff --git a/runtime/native/java_lang_VMClassLoader.cc b/runtime/native/java_lang_VMClassLoader.cc index b1511c0d88..42c7ad5650 100644 --- a/runtime/native/java_lang_VMClassLoader.cc +++ b/runtime/native/java_lang_VMClassLoader.cc @@ -37,11 +37,11 @@ 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) + static ObjPtr<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); diff --git a/runtime/native/java_lang_reflect_Constructor.cc b/runtime/native/java_lang_reflect_Constructor.cc index 13a8d28267..a961cb2597 100644 --- a/runtime/native/java_lang_reflect_Constructor.cc +++ b/runtime/native/java_lang_reflect_Constructor.cc @@ -20,8 +20,8 @@ #include "art_method-inl.h" #include "base/enums.h" -#include "class_linker-inl.h" #include "class_linker.h" +#include "class_root.h" #include "dex/dex_file_annotations.h" #include "jni/jni_internal.h" #include "mirror/class-inl.h" @@ -42,12 +42,8 @@ static jobjectArray Constructor_getExceptionTypes(JNIEnv* env, jobject javaMetho annotations::GetExceptionTypesForMethod(method); if (result_array == nullptr) { // Return an empty array instead of a null pointer. - ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass(); - ObjPtr<mirror::Class> class_array_class = - Runtime::Current()->GetClassLinker()->FindArrayClass(soa.Self(), &class_class); - if (class_array_class == nullptr) { - return nullptr; - } + ObjPtr<mirror::Class> class_array_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>(); + DCHECK(class_array_class != nullptr); ObjPtr<mirror::ObjectArray<mirror::Class>> empty_array = mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, 0); return soa.AddLocalReference<jobjectArray>(empty_array); diff --git a/runtime/native/java_lang_reflect_Executable.cc b/runtime/native/java_lang_reflect_Executable.cc index 9a2d3020c0..a40cb9b2e6 100644 --- a/runtime/native/java_lang_reflect_Executable.cc +++ b/runtime/native/java_lang_reflect_Executable.cc @@ -20,6 +20,7 @@ #include "nativehelper/jni_macros.h" #include "art_method-inl.h" +#include "class_root.h" #include "dex/dex_file_annotations.h" #include "handle.h" #include "jni/jni_internal.h" @@ -335,15 +336,6 @@ static jclass Executable_getMethodReturnTypeInternal(JNIEnv* env, jobject javaMe return soa.AddLocalReference<jclass>(return_type); } -// TODO: Move this to mirror::Class ? Other mirror types that commonly appear -// as arrays have a GetArrayClass() method. This is duplicated in -// java_lang_Class.cc as well. -static ObjPtr<mirror::Class> GetClassArrayClass(Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass(); - return Runtime::Current()->GetClassLinker()->FindArrayClass(self, &class_class); -} - static jobjectArray Executable_getParameterTypesInternal(JNIEnv* env, jobject javaMethod) { ScopedFastNativeObjectAccess soa(env); ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); @@ -356,10 +348,10 @@ static jobjectArray Executable_getParameterTypesInternal(JNIEnv* env, jobject ja const uint32_t num_params = params->Size(); - StackHandleScope<3> hs(soa.Self()); - Handle<mirror::Class> class_array_class = hs.NewHandle(GetClassArrayClass(soa.Self())); + StackHandleScope<2> hs(soa.Self()); + ObjPtr<mirror::Class> class_array_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>(); Handle<mirror::ObjectArray<mirror::Class>> ptypes = hs.NewHandle( - mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class.Get(), num_params)); + mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, num_params)); if (ptypes.IsNull()) { DCHECK(soa.Self()->IsExceptionPending()); return nullptr; diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc index 52e04941c6..34455fe00f 100644 --- a/runtime/native/java_lang_reflect_Method.cc +++ b/runtime/native/java_lang_reflect_Method.cc @@ -22,6 +22,7 @@ #include "base/enums.h" #include "class_linker-inl.h" #include "class_linker.h" +#include "class_root.h" #include "dex/dex_file_annotations.h" #include "jni/jni_internal.h" #include "mirror/class-inl.h" @@ -66,12 +67,8 @@ static jobjectArray Method_getExceptionTypes(JNIEnv* env, jobject javaMethod) { annotations::GetExceptionTypesForMethod(method); if (result_array == nullptr) { // Return an empty array instead of a null pointer - ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass(); - ObjPtr<mirror::Class> class_array_class = - Runtime::Current()->GetClassLinker()->FindArrayClass(soa.Self(), &class_class); - if (class_array_class == nullptr) { - return nullptr; - } + ObjPtr<mirror::Class> class_array_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>(); + DCHECK(class_array_class != nullptr); mirror::ObjectArray<mirror::Class>* empty_array = mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, 0); return soa.AddLocalReference<jobjectArray>(empty_array); diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc index 4e0bf890db..946ea018f3 100644 --- a/runtime/proxy_test.cc +++ b/runtime/proxy_test.cc @@ -44,9 +44,9 @@ TEST_F(ProxyTest, ProxyClassHelper) { ASSERT_TRUE(I != nullptr); ASSERT_TRUE(J != nullptr); - std::vector<mirror::Class*> interfaces; - interfaces.push_back(I.Get()); - interfaces.push_back(J.Get()); + std::vector<Handle<mirror::Class>> interfaces; + interfaces.push_back(I); + interfaces.push_back(J); Handle<mirror::Class> proxy_class(hs.NewHandle( GenerateProxyClass(soa, jclass_loader, class_linker_, "$Proxy1234", interfaces))); interfaces.clear(); // Don't least possibly stale objects in the array as good practice. @@ -80,9 +80,9 @@ TEST_F(ProxyTest, ProxyFieldHelper) { Handle<mirror::Class> proxyClass; { - std::vector<mirror::Class*> interfaces; - interfaces.push_back(I.Get()); - interfaces.push_back(J.Get()); + std::vector<Handle<mirror::Class>> interfaces; + interfaces.push_back(I); + interfaces.push_back(J); proxyClass = hs.NewHandle( GenerateProxyClass(soa, jclass_loader, class_linker_, "$Proxy1234", interfaces)); } @@ -131,7 +131,7 @@ TEST_F(ProxyTest, CheckArtMirrorFieldsOfProxyStaticFields) { Handle<mirror::Class> proxyClass0; Handle<mirror::Class> proxyClass1; { - std::vector<mirror::Class*> interfaces; + std::vector<Handle<mirror::Class>> interfaces; proxyClass0 = hs.NewHandle( GenerateProxyClass(soa, jclass_loader, class_linker_, "$Proxy0", interfaces)); proxyClass1 = hs.NewHandle( diff --git a/runtime/proxy_test.h b/runtime/proxy_test.h index fa5a449e31..860d96c116 100644 --- a/runtime/proxy_test.h +++ b/runtime/proxy_test.h @@ -25,6 +25,7 @@ #include "class_root.h" #include "mirror/class-inl.h" #include "mirror/method.h" +#include "obj_ptr-inl.h" namespace art { namespace proxy_test { @@ -32,11 +33,11 @@ namespace proxy_test { // Generate a proxy class with the given name and interfaces. This is a simplification from what // libcore does to fit to our test needs. We do not check for duplicated interfaces or methods and // we do not declare exceptions. -mirror::Class* GenerateProxyClass(ScopedObjectAccess& soa, - jobject jclass_loader, - ClassLinker* class_linker, - const char* className, - const std::vector<mirror::Class*>& interfaces) +ObjPtr<mirror::Class> GenerateProxyClass(ScopedObjectAccess& soa, + jobject jclass_loader, + ClassLinker* class_linker, + const char* className, + const std::vector<Handle<mirror::Class>>& interfaces) REQUIRES_SHARED(Locks::mutator_lock_) { StackHandleScope<1> hs(soa.Self()); Handle<mirror::Class> javaLangObject = hs.NewHandle( @@ -46,21 +47,23 @@ mirror::Class* GenerateProxyClass(ScopedObjectAccess& soa, jclass javaLangClass = soa.AddLocalReference<jclass>(mirror::Class::GetJavaLangClass()); // Builds the interfaces array. - jobjectArray proxyClassInterfaces = soa.Env()->NewObjectArray(interfaces.size(), javaLangClass, - nullptr); + jobjectArray proxyClassInterfaces = + soa.Env()->NewObjectArray(interfaces.size(), javaLangClass, /* initialElement */ nullptr); soa.Self()->AssertNoPendingException(); for (size_t i = 0; i < interfaces.size(); ++i) { soa.Env()->SetObjectArrayElement(proxyClassInterfaces, i, - soa.AddLocalReference<jclass>(interfaces[i])); + soa.AddLocalReference<jclass>(interfaces[i].Get())); } // Builds the method array. jsize methods_count = 3; // Object.equals, Object.hashCode and Object.toString. - for (mirror::Class* interface : interfaces) { + for (Handle<mirror::Class> interface : interfaces) { methods_count += interface->NumVirtualMethods(); } jobjectArray proxyClassMethods = soa.Env()->NewObjectArray( - methods_count, soa.AddLocalReference<jclass>(GetClassRoot<mirror::Method>()), nullptr); + methods_count, + soa.AddLocalReference<jclass>(GetClassRoot<mirror::Method>()), + /* initialElement */ nullptr); soa.Self()->AssertNoPendingException(); jsize array_index = 0; @@ -91,7 +94,7 @@ mirror::Class* GenerateProxyClass(ScopedObjectAccess& soa, proxyClassMethods, array_index++, soa.AddLocalReference<jobject>( mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), method))); // Now adds all interfaces virtual methods. - for (mirror::Class* interface : interfaces) { + for (Handle<mirror::Class> interface : interfaces) { for (auto& m : interface->GetDeclaredVirtualMethods(kRuntimePointerSize)) { soa.Env()->SetObjectArrayElement( proxyClassMethods, array_index++, soa.AddLocalReference<jobject>( @@ -104,9 +107,13 @@ mirror::Class* GenerateProxyClass(ScopedObjectAccess& soa, jobjectArray proxyClassThrows = soa.Env()->NewObjectArray(0, javaLangClass, nullptr); soa.Self()->AssertNoPendingException(); - mirror::Class* proxyClass = class_linker->CreateProxyClass( - soa, soa.Env()->NewStringUTF(className), proxyClassInterfaces, jclass_loader, - proxyClassMethods, proxyClassThrows); + ObjPtr<mirror::Class> proxyClass = class_linker->CreateProxyClass( + soa, + soa.Env()->NewStringUTF(className), + proxyClassInterfaces, + jclass_loader, + proxyClassMethods, + proxyClassThrows); soa.Self()->AssertNoPendingException(); return proxyClass; } diff --git a/runtime/reflection_test.cc b/runtime/reflection_test.cc index d2d720f722..424ee0681a 100644 --- a/runtime/reflection_test.cc +++ b/runtime/reflection_test.cc @@ -80,7 +80,7 @@ class ReflectionTest : public CommonCompilerTest { jclass GetPrimitiveClass(char descriptor) { ScopedObjectAccess soa(env_); - mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor); + ObjPtr<mirror::Class> c = class_linker_->FindPrimitiveClass(descriptor); CHECK(c != nullptr); return soa.AddLocalReference<jclass>(c); } @@ -518,7 +518,7 @@ TEST_F(ReflectionTest, StaticMainMethod) { hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V"); - mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader); + ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader); ASSERT_TRUE(klass != nullptr); ArtMethod* method = klass->FindClassMethod("main", diff --git a/runtime/thread.cc b/runtime/thread.cc index ab1a4bba6c..b59606a06b 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -2862,27 +2862,18 @@ jobjectArray Thread::CreateAnnotatedStackTrace(const ScopedObjectAccessAlreadyRu ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); StackHandleScope<6> hs(soa.Self()); - mirror::Class* aste_array_class = class_linker->FindClass( + Handle<mirror::Class> h_aste_array_class = hs.NewHandle(class_linker->FindSystemClass( soa.Self(), - "[Ldalvik/system/AnnotatedStackTraceElement;", - ScopedNullHandle<mirror::ClassLoader>()); - if (aste_array_class == nullptr) { + "[Ldalvik/system/AnnotatedStackTraceElement;")); + if (h_aste_array_class == nullptr) { return nullptr; } - Handle<mirror::Class> h_aste_array_class(hs.NewHandle<mirror::Class>(aste_array_class)); + Handle<mirror::Class> h_aste_class = hs.NewHandle(h_aste_array_class->GetComponentType()); - mirror::Class* o_array_class = class_linker->FindClass(soa.Self(), - "[Ljava/lang/Object;", - ScopedNullHandle<mirror::ClassLoader>()); - if (o_array_class == nullptr) { - // This should not fail in a healthy runtime. - soa.Self()->AssertPendingException(); - return nullptr; - } - Handle<mirror::Class> h_o_array_class(hs.NewHandle<mirror::Class>(o_array_class)); + Handle<mirror::Class> h_o_array_class = + hs.NewHandle(GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker)); + DCHECK(h_o_array_class != nullptr); // Class roots must be already initialized. - Handle<mirror::Class> h_aste_class(hs.NewHandle<mirror::Class>( - h_aste_array_class->GetComponentType())); // Make sure the AnnotatedStackTraceElement.class is initialized, b/76208924 . class_linker->EnsureInitialized(soa.Self(), @@ -2906,7 +2897,7 @@ jobjectArray Thread::CreateAnnotatedStackTrace(const ScopedObjectAccessAlreadyRu size_t length = dumper.stack_trace_elements_.size(); ObjPtr<mirror::ObjectArray<mirror::Object>> array = - mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), aste_array_class, length); + mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), h_aste_array_class.Get(), length); if (array == nullptr) { soa.Self()->AssertPendingOOMException(); return nullptr; diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index cc71dc5f84..2e3a6590e4 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -144,7 +144,7 @@ static void SafelyMarkAllRegistersAsConflicts(MethodVerifier* verifier, Register } FailureKind MethodVerifier::VerifyClass(Thread* self, - mirror::Class* klass, + ObjPtr<mirror::Class> klass, CompilerCallbacks* callbacks, bool allow_soft_failures, HardFailLogMode log_level, diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index b2adc62a97..ae7481c6b1 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -96,7 +96,7 @@ class MethodVerifier { public: // Verify a class. Returns "kNoFailure" on success. static FailureKind VerifyClass(Thread* self, - mirror::Class* klass, + ObjPtr<mirror::Class> klass, CompilerCallbacks* callbacks, bool allow_soft_failures, HardFailLogMode log_level, diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc index db3f093905..d1be9fa6f8 100644 --- a/runtime/verifier/method_verifier_test.cc +++ b/runtime/verifier/method_verifier_test.cc @@ -37,7 +37,7 @@ class MethodVerifierTest : public CommonRuntimeTest { REQUIRES_SHARED(Locks::mutator_lock_) { ASSERT_TRUE(descriptor != nullptr); Thread* self = Thread::Current(); - mirror::Class* klass = class_linker_->FindSystemClass(self, descriptor.c_str()); + ObjPtr<mirror::Class> klass = class_linker_->FindSystemClass(self, descriptor.c_str()); // Verify the class std::string error_msg; |