diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-05-22 22:06:51 +0000 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2014-05-22 22:06:51 +0000 |
commit | 3bdb873122964da7937eb070cbcf2ef638a8e459 (patch) | |
tree | 3d29123f33853e11adb67bdd6ac56f19ee798a1f | |
parent | e09ae0920be57760fb390b6944bce420fa0b5582 (diff) | |
download | android_art-3bdb873122964da7937eb070cbcf2ef638a8e459.tar.gz android_art-3bdb873122964da7937eb070cbcf2ef638a8e459.tar.bz2 android_art-3bdb873122964da7937eb070cbcf2ef638a8e459.zip |
Revert "Fix an outstanding compaction bug in interpreter."
This reverts commit e09ae0920be57760fb390b6944bce420fa0b5582.
Change-Id: I48036306130d5ccfec683d0dc3e9a642a02ee9c1
38 files changed, 306 insertions, 339 deletions
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h index 5050d4eb78..fb6c625926 100644 --- a/compiler/common_compiler_test.h +++ b/compiler/common_compiler_test.h @@ -377,7 +377,7 @@ class CommonCompilerTest : public CommonRuntimeTest { timings.EndSplit(); } - void CompileDirectMethod(Handle<mirror::ClassLoader> class_loader, const char* class_name, + void CompileDirectMethod(Handle<mirror::ClassLoader>& class_loader, const char* class_name, const char* method_name, const char* signature) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { std::string class_descriptor(DotToDescriptor(class_name)); @@ -390,7 +390,7 @@ class CommonCompilerTest : public CommonRuntimeTest { CompileMethod(method); } - void CompileVirtualMethod(Handle<mirror::ClassLoader> class_loader, const char* class_name, + void CompileVirtualMethod(Handle<mirror::ClassLoader>& class_loader, const char* class_name, const char* method_name, const char* signature) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { std::string class_descriptor(DotToDescriptor(class_name)); diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index 45abfcc895..08fd386226 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -42,8 +42,8 @@ inline mirror::ClassLoader* CompilerDriver::GetClassLoader(ScopedObjectAccess& s } inline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass( - ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) { + ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); const DexFile::MethodId& referrer_method_id = @@ -59,8 +59,8 @@ inline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass( } inline mirror::ArtField* CompilerDriver::ResolveField( - ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, uint32_t field_idx, bool is_static) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); @@ -165,14 +165,13 @@ inline std::pair<bool, bool> CompilerDriver::IsFastStaticField( } inline mirror::ArtMethod* CompilerDriver::ResolveMethod( - ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, uint32_t method_idx, InvokeType invoke_type) { - DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); - DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); + DCHECK(dex_cache->GetDexFile() == mUnit->GetDexFile()); + DCHECK(class_loader.Get() == soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); mirror::ArtMethod* resolved_method = mUnit->GetClassLinker()->ResolveMethod( - *mUnit->GetDexFile(), method_idx, dex_cache, class_loader, NullHandle<mirror::ArtMethod>(), - invoke_type); + *mUnit->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type); DCHECK_EQ(resolved_method == nullptr, soa.Self()->IsExceptionPending()); if (UNLIKELY(resolved_method == nullptr)) { // Clean up any exception left by type resolution. @@ -207,8 +206,8 @@ inline uint16_t CompilerDriver::GetResolvedMethodVTableIndex( } inline int CompilerDriver::IsFastInvoke( - ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, mirror::Class* referrer_class, mirror::ArtMethod* resolved_method, InvokeType* invoke_type, MethodReference* target_method, const MethodReference* devirt_target, uintptr_t* direct_code, uintptr_t* direct_method) { @@ -257,17 +256,15 @@ inline int CompilerDriver::IsFastInvoke( ClassLinker* class_linker = mUnit->GetClassLinker(); if (LIKELY(devirt_target->dex_file == mUnit->GetDexFile())) { called_method = class_linker->ResolveMethod(*devirt_target->dex_file, - devirt_target->dex_method_index, dex_cache, - class_loader, NullHandle<mirror::ArtMethod>(), - kVirtual); + devirt_target->dex_method_index, + dex_cache, class_loader, NULL, kVirtual); } else { StackHandleScope<1> hs(soa.Self()); Handle<mirror::DexCache> target_dex_cache( hs.NewHandle(class_linker->FindDexCache(*devirt_target->dex_file))); called_method = class_linker->ResolveMethod(*devirt_target->dex_file, devirt_target->dex_method_index, - target_dex_cache, class_loader, - NullHandle<mirror::ArtMethod>(), kVirtual); + target_dex_cache, class_loader, NULL, kVirtual); } CHECK(called_method != NULL); CHECK(!called_method->IsAbstract()); diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 330456180b..0f41d2b2f6 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -511,7 +511,7 @@ void CompilerDriver::CompileAll(jobject class_loader, } static DexToDexCompilationLevel GetDexToDexCompilationlevel( - Thread* self, Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file, + Thread* self, Handle<mirror::ClassLoader>& class_loader, const DexFile& dex_file, const DexFile::ClassDef& class_def) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { const char* descriptor = dex_file.GetClassDescriptor(class_def); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); @@ -731,11 +731,11 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings) for (const std::pair<uint16_t, const DexFile*>& exception_type : unresolved_exception_types) { uint16_t exception_type_idx = exception_type.first; const DexFile* dex_file = exception_type.second; - StackHandleScope<2> hs(self); + StackHandleScope<3> hs(self); Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(*dex_file))); + auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); Handle<mirror::Class> klass(hs.NewHandle( - class_linker->ResolveType(*dex_file, exception_type_idx, dex_cache, - NullHandle<mirror::ClassLoader>()))); + class_linker->ResolveType(*dex_file, exception_type_idx, dex_cache, class_loader))); if (klass.Get() == NULL) { const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx); const char* descriptor = dex_file->GetTypeDescriptor(type_id); @@ -1541,8 +1541,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag if (resolve_fields_and_methods) { while (it.HasNextDirectMethod()) { mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), - dex_cache, class_loader, - NullHandle<mirror::ArtMethod>(), + dex_cache, class_loader, NULL, it.GetMethodInvokeType(class_def)); if (method == NULL) { CHECK(soa.Self()->IsExceptionPending()); @@ -1552,8 +1551,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag } while (it.HasNextVirtualMethod()) { mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), - dex_cache, class_loader, - NullHandle<mirror::ArtMethod>(), + dex_cache, class_loader, NULL, it.GetMethodInvokeType(class_def)); if (method == NULL) { CHECK(soa.Self()->IsExceptionPending()); diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 14ccb5047b..abca659cce 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -221,15 +221,15 @@ class CompilerDriver { // Resolve compiling method's class. Returns nullptr on failure. mirror::Class* ResolveCompilingMethodsClass( - ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) + ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Resolve a field. Returns nullptr on failure, including incompatible class change. // NOTE: Unlike ClassLinker's ResolveField(), this method enforces is_static. mirror::ArtField* ResolveField( - ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, uint32_t field_idx, bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -258,8 +258,8 @@ class CompilerDriver { // Resolve a method. Returns nullptr on failure, including incompatible class change. mirror::ArtMethod* ResolveMethod( - ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, uint32_t method_idx, InvokeType invoke_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -277,8 +277,8 @@ class CompilerDriver { // Can we fast-path an INVOKE? If no, returns 0. If yes, returns a non-zero opaque flags value // for ProcessedInvoke() and computes the necessary lowering info. int IsFastInvoke( - ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, mirror::Class* referrer_class, mirror::ArtMethod* resolved_method, InvokeType* invoke_type, MethodReference* target_method, const MethodReference* devirt_target, uintptr_t* direct_code, uintptr_t* direct_method) diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc index 964dfeb5b1..4efd27d476 100644 --- a/compiler/driver/compiler_driver_test.cc +++ b/compiler/driver/compiler_driver_test.cc @@ -152,9 +152,10 @@ TEST_F(CompilerDriverTest, AbstractMethodErrorStub) { jobject class_loader; { ScopedObjectAccess soa(Thread::Current()); - CompileVirtualMethod(NullHandle<mirror::ClassLoader>(), "java.lang.Class", "isFinalizable", - "()Z"); - CompileDirectMethod(NullHandle<mirror::ClassLoader>(), "java.lang.Object", "<init>", "()V"); + StackHandleScope<1> hs(soa.Self()); + auto null_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); + CompileVirtualMethod(null_loader, "java.lang.Class", "isFinalizable", "()Z"); + CompileDirectMethod(null_loader, "java.lang.Object", "<init>", "()V"); class_loader = LoadDex("AbstractMethod"); } ASSERT_TRUE(class_loader != NULL); diff --git a/compiler/elf_writer_mclinker.cc b/compiler/elf_writer_mclinker.cc index 3dba426242..0e2721014a 100644 --- a/compiler/elf_writer_mclinker.cc +++ b/compiler/elf_writer_mclinker.cc @@ -361,11 +361,10 @@ void ElfWriterMclinker::FixupOatMethodOffsets(const std::vector<const DexFile*>& ClassLinker* linker = Runtime::Current()->GetClassLinker(); // Unchecked as we hold mutator_lock_ on entry. ScopedObjectAccessUnchecked soa(Thread::Current()); - StackHandleScope<1> hs(soa.Self()); + StackHandleScope<2> hs(soa.Self()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(linker->FindDexCache(dex_file))); - method = linker->ResolveMethod(dex_file, method_idx, dex_cache, - NullHandle<mirror::ClassLoader>(), - NullHandle<mirror::ArtMethod>(), invoke_type); + auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); + method = linker->ResolveMethod(dex_file, method_idx, dex_cache, class_loader, NULL, invoke_type); CHECK(method != NULL); } const CompiledMethod* compiled_method = diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index be53926ac8..70144c80fc 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -695,14 +695,15 @@ void ImageWriter::FixupMethod(ArtMethod* orig, ArtMethod* copy) { static ArtMethod* GetTargetMethod(const CompilerDriver::CallPatchInformation* patch) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - StackHandleScope<1> hs(Thread::Current()); + StackHandleScope<2> hs(Thread::Current()); Handle<mirror::DexCache> dex_cache( hs.NewHandle(class_linker->FindDexCache(*patch->GetTargetDexFile()))); + auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); ArtMethod* method = class_linker->ResolveMethod(*patch->GetTargetDexFile(), patch->GetTargetMethodIdx(), dex_cache, - NullHandle<mirror::ClassLoader>(), - NullHandle<mirror::ArtMethod>(), + class_loader, + NULL, patch->GetTargetInvokeType()); CHECK(method != NULL) << patch->GetTargetDexFile()->GetLocation() << " " << patch->GetTargetMethodIdx(); @@ -720,8 +721,11 @@ static Class* GetTargetType(const CompilerDriver::TypePatchInformation* patch) ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); StackHandleScope<2> hs(Thread::Current()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(patch->GetDexFile()))); - Class* klass = class_linker->ResolveType(patch->GetDexFile(), patch->GetTargetTypeIdx(), - dex_cache, NullHandle<mirror::ClassLoader>()); + auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); + Class* klass = class_linker->ResolveType(patch->GetDexFile(), + patch->GetTargetTypeIdx(), + dex_cache, + class_loader); CHECK(klass != NULL) << patch->GetDexFile().GetLocation() << " " << patch->GetTargetTypeIdx(); CHECK(dex_cache->GetResolvedTypes()->Get(patch->GetTargetTypeIdx()) == klass) diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index 6812f3c9df..a7ee82edd3 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -154,8 +154,8 @@ TEST_F(OatTest, WriteRead) { } const char* descriptor = dex_file->GetClassDescriptor(class_def); StackHandleScope<1> hs(soa.Self()); - mirror::Class* klass = class_linker->FindClass(soa.Self(), descriptor, - NullHandle<mirror::ClassLoader>()); + auto loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); + mirror::Class* klass = class_linker->FindClass(soa.Self(), descriptor, loader); const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(i); CHECK_EQ(mirror::Class::Status::kStatusNotReady, oat_class.GetStatus()) << descriptor; diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 5d532abdd6..bace25c84e 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -513,10 +513,9 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { ScopedObjectAccessUnchecked soa(Thread::Current()); StackHandleScope<2> hs(soa.Self()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(linker->FindDexCache(*dex_file_))); + auto class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr); mirror::ArtMethod* method = linker->ResolveMethod(*dex_file_, it.GetMemberIndex(), dex_cache, - NullHandle<mirror::ClassLoader>(), - NullHandle<mirror::ArtMethod>(), - invoke_type); + class_loader, nullptr, invoke_type); CHECK(method != NULL); // Portable code offsets are set by ElfWriterMclinker::FixupCompiledCodeOffset after linking. method->SetQuickOatCodeOffset(offsets.code_offset_); diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 8fd6b6d02f..dcae50284a 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -417,10 +417,10 @@ class OatDumper { Runtime* runtime = Runtime::Current(); if (runtime != nullptr) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<1> hs(soa.Self()); + StackHandleScope<2> hs(soa.Self()); Handle<mirror::DexCache> dex_cache( hs.NewHandle(runtime->GetClassLinker()->FindDexCache(dex_file))); - NullHandle<mirror::ClassLoader> class_loader; + auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); verifier::MethodVerifier verifier(&dex_file, &dex_cache, &class_loader, &class_def, code_item, dex_method_idx, nullptr, method_access_flags, true, true); diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index 84afb2d3f6..ac86014545 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -34,7 +34,9 @@ inline bool ClassLinker::IsInBootClassPath(const char* descriptor) { } inline mirror::Class* ClassLinker::FindSystemClass(Thread* self, const char* descriptor) { - return FindClass(self, descriptor, NullHandle<mirror::ClassLoader>()); + StackHandleScope<1> hs(self); + auto class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr); + return FindClass(self, descriptor, class_loader); } inline mirror::Class* ClassLinker::FindArrayClass(Thread* self, mirror::Class* element_class) { @@ -108,47 +110,31 @@ inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, mirror::ArtFie return resolved_type; } -inline mirror::ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx, - mirror::ArtMethod* referrer, - InvokeType type) { +inline mirror::ArtMethod* ClassLinker::ResolveMethod(uint32_t method_idx, + mirror::ArtMethod* referrer, + InvokeType type) { mirror::ArtMethod* resolved_method = referrer->GetDexCacheResolvedMethods()->Get(method_idx); - if (resolved_method == nullptr || resolved_method->IsRuntimeMethod()) { - return nullptr; - } - return resolved_method; -} - -inline mirror::ArtMethod* ClassLinker::ResolveMethod(Thread* self, uint32_t method_idx, - mirror::ArtMethod** referrer, - InvokeType type) { - mirror::ArtMethod* resolved_method = GetResolvedMethod(method_idx, *referrer, type); - if (LIKELY(resolved_method != nullptr)) { - return resolved_method; - } - mirror::Class* declaring_class = (*referrer)->GetDeclaringClass(); - StackHandleScope<3> hs(self); - Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(declaring_class->GetDexCache())); - Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader())); - HandleWrapper<mirror::ArtMethod> h_referrer(hs.NewHandleWrapper(referrer)); - const DexFile* dex_file = h_dex_cache->GetDexFile(); - resolved_method = ResolveMethod(*dex_file, method_idx, h_dex_cache, h_class_loader, h_referrer, - type); - if (resolved_method != nullptr) { - DCHECK_EQ(h_dex_cache->GetResolvedMethod(method_idx), resolved_method); + if (UNLIKELY(resolved_method == NULL || resolved_method->IsRuntimeMethod())) { + mirror::Class* declaring_class = referrer->GetDeclaringClass(); + StackHandleScope<2> hs(Thread::Current()); + Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache())); + Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader())); + const DexFile& dex_file = *dex_cache->GetDexFile(); + resolved_method = ResolveMethod(dex_file, method_idx, dex_cache, class_loader, referrer, type); + if (resolved_method != nullptr) { + DCHECK_EQ(dex_cache->GetResolvedMethod(method_idx), resolved_method); + } } return resolved_method; } -inline mirror::ArtField* ClassLinker::GetResolvedField(uint32_t field_idx, - mirror::Class* field_declaring_class) { - return field_declaring_class->GetDexCache()->GetResolvedField(field_idx); -} - -inline mirror::ArtField* ClassLinker::ResolveField(uint32_t field_idx, mirror::ArtMethod* referrer, +inline mirror::ArtField* ClassLinker::ResolveField(uint32_t field_idx, + mirror::ArtMethod* referrer, bool is_static) { mirror::Class* declaring_class = referrer->GetDeclaringClass(); - mirror::ArtField* resolved_field = GetResolvedField(field_idx, declaring_class); + mirror::ArtField* resolved_field = + declaring_class->GetDexCache()->GetResolvedField(field_idx); if (UNLIKELY(resolved_field == NULL)) { StackHandleScope<2> hs(Thread::Current()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache())); diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index afff7a2e7b..c7302b5a73 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1369,7 +1369,7 @@ static mirror::Class* EnsureResolved(Thread* self, mirror::Class* klass) } mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, - Handle<mirror::ClassLoader> class_loader) { + const Handle<mirror::ClassLoader>& class_loader) { DCHECK_NE(*descriptor, '\0') << "descriptor is empty string"; DCHECK(self != nullptr); self->AssertNoPendingException(); @@ -1390,7 +1390,8 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, DexFile::ClassPathEntry pair = DexFile::FindInClassPath(descriptor, boot_class_path_); if (pair.second != NULL) { StackHandleScope<1> hs(self); - return DefineClass(descriptor, NullHandle<mirror::ClassLoader>(), *pair.first, *pair.second); + auto class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr); + return DefineClass(descriptor, class_loader, *pair.first, *pair.second); } } else if (Runtime::Current()->UseCompileTimeClassPath()) { // First try the boot class path, we check the descriptor first to avoid an unnecessary @@ -1451,7 +1452,7 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, } mirror::Class* ClassLinker::DefineClass(const char* descriptor, - Handle<mirror::ClassLoader> class_loader, + const Handle<mirror::ClassLoader>& class_loader, const DexFile& dex_file, const DexFile::ClassDef& dex_class_def) { Thread* self = Thread::Current(); @@ -1795,9 +1796,10 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { // Ignore virtual methods on the iterator. } -void ClassLinker::LinkCode(Handle<mirror::ArtMethod> method, const OatFile::OatClass* oat_class, +void ClassLinker::LinkCode(const Handle<mirror::ArtMethod>& method, + const OatFile::OatClass* oat_class, const DexFile& dex_file, uint32_t dex_method_index, - uint32_t method_index) { + uint32_t method_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { // Method shouldn't have already been linked. DCHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr); DCHECK(method->GetEntryPointFromPortableCompiledCode() == nullptr); @@ -1869,7 +1871,7 @@ void ClassLinker::LinkCode(Handle<mirror::ArtMethod> method, const OatFile::OatC void ClassLinker::LoadClass(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, - Handle<mirror::Class> klass, + const Handle<mirror::Class>& klass, mirror::ClassLoader* class_loader) { CHECK(klass.Get() != NULL); CHECK(klass->GetDexCache() != NULL); @@ -1907,7 +1909,7 @@ void ClassLinker::LoadClass(const DexFile& dex_file, void ClassLinker::LoadClassMembers(const DexFile& dex_file, const byte* class_data, - Handle<mirror::Class> klass, + const Handle<mirror::Class>& klass, mirror::ClassLoader* class_loader, const OatFile::OatClass* oat_class) { // Load fields. @@ -2005,7 +2007,8 @@ void ClassLinker::LoadClassMembers(const DexFile& dex_file, } void ClassLinker::LoadField(const DexFile& /*dex_file*/, const ClassDataItemIterator& it, - Handle<mirror::Class> klass, Handle<mirror::ArtField> dst) { + const Handle<mirror::Class>& klass, + const Handle<mirror::ArtField>& dst) { uint32_t field_idx = it.GetMemberIndex(); dst->SetDexFieldIndex(field_idx); dst->SetDeclaringClass(klass.Get()); @@ -2014,7 +2017,7 @@ void ClassLinker::LoadField(const DexFile& /*dex_file*/, const ClassDataItemIter mirror::ArtMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file, const ClassDataItemIterator& it, - Handle<mirror::Class> klass) { + const Handle<mirror::Class>& klass) { uint32_t dex_method_idx = it.GetMemberIndex(); const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx); const char* method_name = dex_file.StringDataByIdx(method_id.name_idx_); @@ -2085,7 +2088,7 @@ void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) { } void ClassLinker::AppendToBootClassPath(const DexFile& dex_file, - Handle<mirror::DexCache> dex_cache) { + const Handle<mirror::DexCache>& dex_cache) { CHECK(dex_cache.Get() != NULL) << dex_file.GetLocation(); boot_class_path_.push_back(&dex_file); RegisterDexFile(dex_file, dex_cache); @@ -2107,7 +2110,7 @@ bool ClassLinker::IsDexFileRegistered(const DexFile& dex_file) const { } void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, - Handle<mirror::DexCache> dex_cache) { + const Handle<mirror::DexCache>& dex_cache) { dex_lock_.AssertExclusiveHeld(Thread::Current()); CHECK(dex_cache.Get() != NULL) << dex_file.GetLocation(); CHECK(dex_cache->GetLocation()->Equals(dex_file.GetLocation())) @@ -2144,7 +2147,7 @@ void ClassLinker::RegisterDexFile(const DexFile& dex_file) { } void ClassLinker::RegisterDexFile(const DexFile& dex_file, - Handle<mirror::DexCache> dex_cache) { + const Handle<mirror::DexCache>& dex_cache) { WriterMutexLock mu(Thread::Current(), dex_lock_); RegisterDexFileLocked(dex_file, dex_cache); } @@ -2221,7 +2224,7 @@ mirror::Class* ClassLinker::InitializePrimitiveClass(mirror::Class* primitive_cl // // Returns NULL with an exception raised on failure. mirror::Class* ClassLinker::CreateArrayClass(Thread* self, const char* descriptor, - Handle<mirror::ClassLoader> class_loader) { + const Handle<mirror::ClassLoader>& class_loader) { // Identify the underlying component type CHECK_EQ('[', descriptor[0]); StackHandleScope<2> hs(self); @@ -2413,7 +2416,7 @@ bool ClassLinker::RemoveClass(const char* descriptor, const mirror::ClassLoader* it != end && it->first == hash; ++it) { mirror::Class* klass = it->second; - if (klass->GetClassLoader() == class_loader && klass->DescriptorEquals(descriptor)) { + if (klass->GetClassLoader() == class_loader && descriptor == klass->GetDescriptor()) { class_table_.erase(it); return true; } @@ -2457,13 +2460,13 @@ mirror::Class* ClassLinker::LookupClassFromTableLocked(const char* descriptor, auto end = class_table_.end(); for (auto it = class_table_.lower_bound(hash); it != end && it->first == hash; ++it) { mirror::Class* klass = it->second; - if (klass->GetClassLoader() == class_loader && klass->DescriptorEquals(descriptor)) { + if (klass->GetClassLoader() == class_loader && descriptor == klass->GetDescriptor()) { if (kIsDebugBuild) { // Check for duplicates in the table. for (++it; it != end && it->first == hash; ++it) { mirror::Class* klass2 = it->second; - CHECK(!(klass2->GetClassLoader() == class_loader && - klass2->DescriptorEquals(descriptor))) + CHECK(!((klass2->GetClassLoader() == class_loader) && + descriptor == klass2->GetDescriptor())) << PrettyClass(klass) << " " << klass << " " << klass->GetClassLoader() << " " << PrettyClass(klass2) << " " << klass2 << " " << klass2->GetClassLoader(); } @@ -2554,13 +2557,13 @@ void ClassLinker::LookupClasses(const char* descriptor, std::vector<mirror::Clas for (auto it = class_table_.lower_bound(hash), end = class_table_.end(); it != end && it->first == hash; ++it) { mirror::Class* klass = it->second; - if (klass->DescriptorEquals(descriptor)) { + if (descriptor == klass->GetDescriptor()) { result.push_back(klass); } } } -void ClassLinker::VerifyClass(Handle<mirror::Class> klass) { +void ClassLinker::VerifyClass(const Handle<mirror::Class>& klass) { // TODO: assert that the monitor on the Class is held Thread* self = Thread::Current(); ObjectLock<mirror::Class> lock(self, klass); @@ -2773,7 +2776,7 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class } void ClassLinker::ResolveClassExceptionHandlerTypes(const DexFile& dex_file, - Handle<mirror::Class> klass) { + const Handle<mirror::Class>& klass) { for (size_t i = 0; i < klass->NumDirectMethods(); i++) { ResolveMethodExceptionHandlerTypes(dex_file, klass->GetDirectMethod(i)); } @@ -2814,7 +2817,7 @@ void ClassLinker::ResolveMethodExceptionHandlerTypes(const DexFile& dex_file, static void CheckProxyConstructor(mirror::ArtMethod* constructor); static void CheckProxyMethod(mirror::ArtMethod* method, - Handle<mirror::ArtMethod> prototype); + Handle<mirror::ArtMethod>& prototype); mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& soa, jstring name, jobjectArray interfaces, jobject loader, @@ -2996,7 +2999,7 @@ mirror::ArtMethod* ClassLinker::FindMethodForProxy(mirror::Class* proxy_class, mirror::ArtMethod* ClassLinker::CreateProxyConstructor(Thread* self, - Handle<mirror::Class> klass, + const Handle<mirror::Class>& klass, mirror::Class* proxy_class) { // Create constructor for Proxy that must initialize h mirror::ObjectArray<mirror::ArtMethod>* proxy_direct_methods = @@ -3027,8 +3030,8 @@ static void CheckProxyConstructor(mirror::ArtMethod* constructor) } mirror::ArtMethod* ClassLinker::CreateProxyMethod(Thread* self, - Handle<mirror::Class> klass, - Handle<mirror::ArtMethod> prototype) { + const Handle<mirror::Class>& klass, + const Handle<mirror::ArtMethod>& prototype) { // Ensure prototype is in dex cache so that we can use the dex cache to look up the overridden // prototype method prototype->GetDeclaringClass()->GetDexCache()->SetResolvedMethod(prototype->GetDexMethodIndex(), @@ -3055,7 +3058,8 @@ mirror::ArtMethod* ClassLinker::CreateProxyMethod(Thread* self, return method; } -static void CheckProxyMethod(mirror::ArtMethod* method, Handle<mirror::ArtMethod> prototype) +static void CheckProxyMethod(mirror::ArtMethod* method, + Handle<mirror::ArtMethod>& prototype) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { // Basic sanity CHECK(!prototype->IsFinal()); @@ -3115,7 +3119,7 @@ bool ClassLinker::IsInitialized() const { return init_done_; } -bool ClassLinker::InitializeClass(Handle<mirror::Class> klass, bool can_init_statics, +bool ClassLinker::InitializeClass(const Handle<mirror::Class>& klass, bool can_init_statics, bool can_init_parents) { // see JLS 3rd edition, 12.4.2 "Detailed Initialization Procedure" for the locking protocol @@ -3282,7 +3286,7 @@ bool ClassLinker::InitializeClass(Handle<mirror::Class> klass, bool can_init_sta return success; } -bool ClassLinker::WaitForInitializeClass(Handle<mirror::Class> klass, Thread* self, +bool ClassLinker::WaitForInitializeClass(const Handle<mirror::Class>& klass, Thread* self, ObjectLock<mirror::Class>& lock) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { while (true) { @@ -3322,7 +3326,7 @@ bool ClassLinker::WaitForInitializeClass(Handle<mirror::Class> klass, Thread* se LOG(FATAL) << "Not Reached" << PrettyClass(klass.Get()); } -bool ClassLinker::ValidateSuperClassDescriptors(Handle<mirror::Class> klass) { +bool ClassLinker::ValidateSuperClassDescriptors(const Handle<mirror::Class>& klass) { if (klass->IsInterface()) { return true; } @@ -3364,12 +3368,18 @@ bool ClassLinker::ValidateSuperClassDescriptors(Handle<mirror::Class> klass) { return true; } -bool ClassLinker::EnsureInitialized(Handle<mirror::Class> c, bool can_init_fields, +bool ClassLinker::EnsureInitialized(const Handle<mirror::Class>& c, bool can_init_fields, bool can_init_parents) { - DCHECK(c.Get() != nullptr); - const bool success = c->IsInitialized() || InitializeClass(c, can_init_fields, can_init_parents); - if (!success && can_init_fields && can_init_parents) { - CHECK(Thread::Current()->IsExceptionPending()) << PrettyClass(c.Get()); + DCHECK(c.Get() != NULL); + if (c->IsInitialized()) { + return true; + } + + bool success = InitializeClass(c, can_init_fields, can_init_parents); + if (!success) { + if (can_init_fields && can_init_parents) { + CHECK(Thread::Current()->IsExceptionPending()) << PrettyClass(c.Get()); + } } return success; } @@ -3388,8 +3398,8 @@ void ClassLinker::ConstructFieldMap(const DexFile& dex_file, const DexFile::Clas } } -bool ClassLinker::LinkClass(Thread* self, Handle<mirror::Class> klass, - Handle<mirror::ObjectArray<mirror::Class>> interfaces) { +bool ClassLinker::LinkClass(Thread* self, const Handle<mirror::Class>& klass, + const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) { CHECK_EQ(mirror::Class::kStatusLoaded, klass->GetStatus()); if (!LinkSuperClass(klass)) { return false; @@ -3410,7 +3420,8 @@ bool ClassLinker::LinkClass(Thread* self, Handle<mirror::Class> klass, return true; } -bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexFile& dex_file) { +bool ClassLinker::LoadSuperAndInterfaces(const Handle<mirror::Class>& klass, + const DexFile& dex_file) { CHECK_EQ(mirror::Class::kStatusIdx, klass->GetStatus()); const DexFile::ClassDef& class_def = dex_file.GetClassDef(klass->GetDexClassDefIndex()); uint16_t super_class_idx = class_def.superclass_idx_; @@ -3453,7 +3464,7 @@ bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexF return true; } -bool ClassLinker::LinkSuperClass(Handle<mirror::Class> klass) { +bool ClassLinker::LinkSuperClass(const Handle<mirror::Class>& klass) { CHECK(!klass->IsPrimitive()); mirror::Class* super = klass->GetSuperClass(); if (klass.Get() == GetClassRoot(kJavaLangObject)) { @@ -3513,8 +3524,8 @@ bool ClassLinker::LinkSuperClass(Handle<mirror::Class> klass) { } // Populate the class vtable and itable. Compute return type indices. -bool ClassLinker::LinkMethods(Handle<mirror::Class> klass, - Handle<mirror::ObjectArray<mirror::Class>> interfaces) { +bool ClassLinker::LinkMethods(const Handle<mirror::Class>& klass, + const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) { if (klass->IsInterface()) { // No vtable. size_t count = klass->NumVirtualMethods(); @@ -3534,7 +3545,7 @@ bool ClassLinker::LinkMethods(Handle<mirror::Class> klass, return true; } -bool ClassLinker::LinkVirtualMethods(Handle<mirror::Class> klass) { +bool ClassLinker::LinkVirtualMethods(const Handle<mirror::Class>& klass) { Thread* self = Thread::Current(); if (klass->HasSuperClass()) { uint32_t max_count = (klass->NumVirtualMethods() + @@ -3621,8 +3632,9 @@ bool ClassLinker::LinkVirtualMethods(Handle<mirror::Class> klass) { return true; } -bool ClassLinker::LinkInterfaceMethods(Handle<mirror::Class> klass, - Handle<mirror::ObjectArray<mirror::Class>> interfaces) { +bool ClassLinker::LinkInterfaceMethods( + const Handle<mirror::Class>& klass, + const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) { Thread* const self = Thread::Current(); // Set the imt table to be all conflicts by default. klass->SetImTable(Runtime::Current()->GetDefaultImt()); @@ -3877,12 +3889,12 @@ bool ClassLinker::LinkInterfaceMethods(Handle<mirror::Class> klass, return true; } -bool ClassLinker::LinkInstanceFields(Handle<mirror::Class> klass) { +bool ClassLinker::LinkInstanceFields(const Handle<mirror::Class>& klass) { CHECK(klass.Get() != NULL); return LinkFields(klass, false); } -bool ClassLinker::LinkStaticFields(Handle<mirror::Class> klass) { +bool ClassLinker::LinkStaticFields(const Handle<mirror::Class>& klass) { CHECK(klass.Get() != NULL); size_t allocated_class_size = klass->GetClassSize(); bool success = LinkFields(klass, true); @@ -3921,7 +3933,7 @@ struct LinkFieldsComparator { } }; -bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) { +bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static) { size_t num_fields = is_static ? klass->NumStaticFields() : klass->NumInstanceFields(); @@ -4017,7 +4029,7 @@ bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) { } // We lie to the GC about the java.lang.ref.Reference.referent field, so it doesn't scan it. - if (!is_static && klass->DescriptorEquals("Ljava/lang/ref/Reference;")) { + if (!is_static && "Ljava/lang/ref/Reference;" == klass->GetDescriptor()) { // We know there are no non-reference fields in the Reference classes, and we know // that 'referent' is alphabetically last, so this is easy... CHECK_EQ(num_reference_fields, num_fields) << PrettyClass(klass.Get()); @@ -4042,7 +4054,7 @@ bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) { FieldHelper fh(field); Primitive::Type type = fh.GetTypeAsPrimitiveType(); bool is_primitive = type != Primitive::kPrimNot; - if (klass->DescriptorEquals("Ljava/lang/ref/Reference;") && + if ("Ljava/lang/ref/Reference;" == klass->GetDescriptor() && strcmp("referent", fh.GetName()) == 0) { is_primitive = true; // We lied above, so we have to expect a lie here. } @@ -4081,7 +4093,7 @@ bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) { // Set the bitmap of reference offsets, refOffsets, from the ifields // list. -void ClassLinker::CreateReferenceInstanceOffsets(Handle<mirror::Class> klass) { +void ClassLinker::CreateReferenceInstanceOffsets(const Handle<mirror::Class>& klass) { uint32_t reference_offsets = 0; mirror::Class* super_class = klass->GetSuperClass(); if (super_class != NULL) { @@ -4095,11 +4107,11 @@ void ClassLinker::CreateReferenceInstanceOffsets(Handle<mirror::Class> klass) { CreateReferenceOffsets(klass, false, reference_offsets); } -void ClassLinker::CreateReferenceStaticOffsets(Handle<mirror::Class> klass) { +void ClassLinker::CreateReferenceStaticOffsets(const Handle<mirror::Class>& klass) { CreateReferenceOffsets(klass, true, 0); } -void ClassLinker::CreateReferenceOffsets(Handle<mirror::Class> klass, bool is_static, +void ClassLinker::CreateReferenceOffsets(const Handle<mirror::Class>& klass, bool is_static, uint32_t reference_offsets) { size_t num_reference_fields = is_static ? klass->NumReferenceStaticFieldsDuringLinking() @@ -4132,7 +4144,7 @@ void ClassLinker::CreateReferenceOffsets(Handle<mirror::Class> klass, bool is_st } mirror::String* ClassLinker::ResolveString(const DexFile& dex_file, uint32_t string_idx, - Handle<mirror::DexCache> dex_cache) { + const Handle<mirror::DexCache>& dex_cache) { DCHECK(dex_cache.Get() != nullptr); mirror::String* resolved = dex_cache->GetResolvedString(string_idx); if (resolved != NULL) { @@ -4154,8 +4166,8 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, uint16_t type_i } mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, uint16_t type_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader) { + const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader) { DCHECK(dex_cache.Get() != NULL); mirror::Class* resolved = dex_cache->GetResolvedType(type_idx); if (resolved == NULL) { @@ -4186,15 +4198,16 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file, uint16_t type_i return resolved; } -mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, uint32_t method_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, - Handle<mirror::ArtMethod> referrer, +mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, + uint32_t method_idx, + const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, + mirror::ArtMethod* referrer, InvokeType type) { DCHECK(dex_cache.Get() != NULL); // Check for hit in the dex cache. mirror::ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx); - if (resolved != nullptr && !resolved->IsRuntimeMethod()) { + if (resolved != NULL && !resolved->IsRuntimeMethod()) { return resolved; } // Fail, get the declaring class. @@ -4269,7 +4282,7 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, uint32_t } // If we found something, check that it can be accessed by the referrer. - if (resolved != NULL && referrer.Get() != NULL) { + if (resolved != NULL && referrer != NULL) { mirror::Class* methods_class = resolved->GetDeclaringClass(); mirror::Class* referring_class = referrer->GetDeclaringClass(); if (!referring_class->CanAccess(methods_class)) { @@ -4289,11 +4302,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, uint32_t case kDirect: case kStatic: if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer.Get()); + ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer); } else { resolved = klass->FindInterfaceMethod(name, signature); if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer.Get()); + ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer); } else { ThrowNoSuchMethodError(type, klass, name, signature); } @@ -4301,11 +4314,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, uint32_t break; case kInterface: if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer.Get()); + ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer); } else { resolved = klass->FindVirtualMethod(name, signature); if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer.Get()); + ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer); } else { ThrowNoSuchMethodError(type, klass, name, signature); } @@ -4316,11 +4329,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, uint32_t break; case kVirtual: if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer.Get()); + ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer); } else { resolved = klass->FindInterfaceMethod(name, signature); if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer.Get()); + ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer); } else { ThrowNoSuchMethodError(type, klass, name, signature); } @@ -4333,8 +4346,8 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, uint32_t } mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t field_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, + const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, bool is_static) { DCHECK(dex_cache.Get() != nullptr); mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx); @@ -4376,8 +4389,8 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t fi mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file, uint32_t field_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader) { + const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader) { DCHECK(dex_cache.Get() != nullptr); mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx); if (resolved != NULL) { diff --git a/runtime/class_linker.h b/runtime/class_linker.h index a8271eda9a..54805be42e 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -75,7 +75,7 @@ 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) + const Handle<mirror::ClassLoader>& class_loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Finds a class by its descriptor using the "system" class loader, ie by searching the @@ -92,7 +92,7 @@ class ClassLinker { // Define a new a class based on a ClassDef from a DexFile mirror::Class* DefineClass(const char* descriptor, - Handle<mirror::ClassLoader> class_loader, + const Handle<mirror::ClassLoader>& class_loader, const DexFile& dex_file, const DexFile::ClassDef& dex_class_def) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -136,7 +136,7 @@ class ClassLinker { // Resolve a String with the given index from the DexFile, storing the // result in the DexCache. mirror::String* ResolveString(const DexFile& dex_file, uint32_t string_idx, - Handle<mirror::DexCache> dex_cache) + const Handle<mirror::DexCache>& dex_cache) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Resolve a Type with the given index from the DexFile, storing the @@ -159,8 +159,8 @@ class ClassLinker { // type, since it may be referenced from but not contained within // the given DexFile. mirror::Class* ResolveType(const DexFile& dex_file, uint16_t type_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader) + const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Resolve a method with a given ID from the DexFile, storing the @@ -170,21 +170,16 @@ class ClassLinker { // virtual method. mirror::ArtMethod* ResolveMethod(const DexFile& dex_file, uint32_t method_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, - Handle<mirror::ArtMethod> referrer, + const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, + mirror::ArtMethod* referrer, InvokeType type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - mirror::ArtMethod* GetResolvedMethod(uint32_t method_idx, mirror::ArtMethod* referrer, - InvokeType type) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - mirror::ArtMethod* ResolveMethod(Thread* self, uint32_t method_idx, mirror::ArtMethod** referrer, + mirror::ArtMethod* ResolveMethod(uint32_t method_idx, mirror::ArtMethod* referrer, InvokeType type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - mirror::ArtField* GetResolvedField(uint32_t field_idx, mirror::Class* field_declaring_class) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); mirror::ArtField* ResolveField(uint32_t field_idx, mirror::ArtMethod* referrer, bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -196,8 +191,8 @@ class ClassLinker { // field. mirror::ArtField* ResolveField(const DexFile& dex_file, uint32_t field_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, + const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader, bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -205,9 +200,10 @@ class ClassLinker { // result in DexCache. The ClassLinker and ClassLoader are used as // in ResolveType. No is_static argument is provided so that Java // field resolution semantics are followed. - mirror::ArtField* ResolveFieldJLS(const DexFile& dex_file, uint32_t field_idx, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader) + mirror::ArtField* ResolveFieldJLS(const DexFile& dex_file, + uint32_t field_idx, + const Handle<mirror::DexCache>& dex_cache, + const Handle<mirror::ClassLoader>& class_loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Get shorty from method index without resolution. Used to do handlerization. @@ -217,7 +213,8 @@ class ClassLinker { // Returns true on success, false if there's an exception pending. // can_run_clinit=false allows the compiler to attempt to init a class, // given the restriction that no <clinit> execution is possible. - bool EnsureInitialized(Handle<mirror::Class> c, bool can_init_fields, bool can_init_parents) + bool EnsureInitialized(const Handle<mirror::Class>& c, + bool can_init_fields, bool can_init_parents) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Initializes classes that have instances in the image but that have @@ -227,7 +224,7 @@ class ClassLinker { void RegisterDexFile(const DexFile& dex_file) LOCKS_EXCLUDED(dex_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void RegisterDexFile(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) + void RegisterDexFile(const DexFile& dex_file, const Handle<mirror::DexCache>& dex_cache) LOCKS_EXCLUDED(dex_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -319,12 +316,12 @@ class ClassLinker { size_t length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void VerifyClass(Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void VerifyClass(const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class* klass, mirror::Class::Status& oat_file_class_status) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void ResolveClassExceptionHandlerTypes(const DexFile& dex_file, - Handle<mirror::Class> klass) + const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void ResolveMethodExceptionHandlerTypes(const DexFile& dex_file, mirror::ArtMethod* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -423,12 +420,12 @@ class ClassLinker { mirror::Class* CreateArrayClass(Thread* self, const char* descriptor, - Handle<mirror::ClassLoader> class_loader) + const Handle<mirror::ClassLoader>& class_loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void AppendToBootClassPath(const DexFile& dex_file) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void AppendToBootClassPath(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) + void AppendToBootClassPath(const DexFile& dex_file, const Handle<mirror::DexCache>& dex_cache) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, @@ -440,23 +437,23 @@ class ClassLinker { void LoadClass(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, - Handle<mirror::Class> klass, + const Handle<mirror::Class>& klass, mirror::ClassLoader* class_loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void LoadClassMembers(const DexFile& dex_file, const byte* class_data, - Handle<mirror::Class> klass, + const Handle<mirror::Class>& klass, mirror::ClassLoader* class_loader, const OatFile::OatClass* oat_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void LoadField(const DexFile& dex_file, const ClassDataItemIterator& it, - Handle<mirror::Class> klass, Handle<mirror::ArtField> dst) + const Handle<mirror::Class>& klass, const Handle<mirror::ArtField>& dst) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); mirror::ArtMethod* LoadMethod(Thread* self, const DexFile& dex_file, const ClassDataItemIterator& dex_method, - Handle<mirror::Class> klass) + const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void FixupStaticTrampolines(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -465,23 +462,23 @@ class ClassLinker { OatFile::OatClass GetOatClass(const DexFile& dex_file, uint16_t class_def_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void RegisterDexFileLocked(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) + void RegisterDexFileLocked(const DexFile& dex_file, const Handle<mirror::DexCache>& dex_cache) EXCLUSIVE_LOCKS_REQUIRED(dex_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool IsDexFileRegisteredLocked(const DexFile& dex_file) const SHARED_LOCKS_REQUIRED(dex_lock_, Locks::mutator_lock_); - bool InitializeClass(Handle<mirror::Class> klass, bool can_run_clinit, + bool InitializeClass(const Handle<mirror::Class>& klass, bool can_run_clinit, bool can_init_parents) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool WaitForInitializeClass(Handle<mirror::Class> klass, Thread* self, + bool WaitForInitializeClass(const Handle<mirror::Class>& klass, Thread* self, ObjectLock<mirror::Class>& lock); - bool ValidateSuperClassDescriptors(Handle<mirror::Class> klass) + bool ValidateSuperClassDescriptors(const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool IsSameDescriptorInDifferentClassContexts(Thread* self, const char* descriptor, - Handle<mirror::ClassLoader> class_loader1, - Handle<mirror::ClassLoader> class_loader2) + Handle<mirror::ClassLoader>& class_loader1, + Handle<mirror::ClassLoader>& class_loader2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool IsSameMethodSignatureInDifferentClassContexts(Thread* self, mirror::ArtMethod* method, @@ -489,43 +486,43 @@ class ClassLinker { mirror::Class* klass2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkClass(Thread* self, Handle<mirror::Class> klass, - Handle<mirror::ObjectArray<mirror::Class>> interfaces) + bool LinkClass(Thread* self, const Handle<mirror::Class>& klass, + const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkSuperClass(Handle<mirror::Class> klass) + bool LinkSuperClass(const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexFile& dex_file) + bool LoadSuperAndInterfaces(const Handle<mirror::Class>& klass, const DexFile& dex_file) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkMethods(Handle<mirror::Class> klass, - Handle<mirror::ObjectArray<mirror::Class>> interfaces) + bool LinkMethods(const Handle<mirror::Class>& klass, + const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkVirtualMethods(Handle<mirror::Class> klass) + bool LinkVirtualMethods(const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkInterfaceMethods(Handle<mirror::Class> klass, - Handle<mirror::ObjectArray<mirror::Class>> interfaces) + bool LinkInterfaceMethods(const Handle<mirror::Class>& klass, + const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkStaticFields(Handle<mirror::Class> klass) + bool LinkStaticFields(const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkInstanceFields(Handle<mirror::Class> klass) + bool LinkInstanceFields(const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkFields(Handle<mirror::Class> klass, bool is_static) + bool LinkFields(const Handle<mirror::Class>& klass, bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void LinkCode(Handle<mirror::ArtMethod> method, const OatFile::OatClass* oat_class, + void LinkCode(const Handle<mirror::ArtMethod>& method, const OatFile::OatClass* oat_class, const DexFile& dex_file, uint32_t dex_method_index, uint32_t method_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void CreateReferenceInstanceOffsets(Handle<mirror::Class> klass) + void CreateReferenceInstanceOffsets(const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void CreateReferenceStaticOffsets(Handle<mirror::Class> klass) + void CreateReferenceStaticOffsets(const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void CreateReferenceOffsets(Handle<mirror::Class> klass, bool is_static, + void CreateReferenceOffsets(const Handle<mirror::Class>& klass, bool is_static, uint32_t reference_offsets) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -554,11 +551,11 @@ class ClassLinker { bool* open_failed) LOCKS_EXCLUDED(dex_lock_); - mirror::ArtMethod* CreateProxyConstructor(Thread* self, Handle<mirror::Class> klass, + mirror::ArtMethod* CreateProxyConstructor(Thread* self, const Handle<mirror::Class>& klass, mirror::Class* proxy_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - mirror::ArtMethod* CreateProxyMethod(Thread* self, Handle<mirror::Class> klass, - Handle<mirror::ArtMethod> prototype) + mirror::ArtMethod* CreateProxyMethod(Thread* self, const Handle<mirror::Class>& klass, + const Handle<mirror::ArtMethod>& prototype) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); std::vector<const DexFile*> boot_class_path_; diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index c11aeccee4..d04f02ba3a 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -108,7 +108,7 @@ class ClassLinkerTest : public CommonRuntimeTest { AssertArrayClass(array_descriptor, array); } - void AssertArrayClass(const std::string& array_descriptor, Handle<mirror::Class> array) + void AssertArrayClass(const std::string& array_descriptor, const Handle<mirror::Class>& array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { ASSERT_TRUE(array.Get() != NULL); ASSERT_TRUE(array->GetClass() != NULL); @@ -178,7 +178,7 @@ class ClassLinkerTest : public CommonRuntimeTest { EXPECT_TRUE(fh.GetType() != NULL); } - void AssertClass(const std::string& descriptor, Handle<mirror::Class> klass) + void AssertClass(const std::string& descriptor, const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { EXPECT_STREQ(descriptor.c_str(), klass->GetDescriptor().c_str()); if (descriptor == "Ljava/lang/Object;") { @@ -846,7 +846,8 @@ TEST_F(ClassLinkerTest, ValidateBoxedTypes) { // Validate that the "value" field is always the 0th field in each of java.lang's box classes. // This lets UnboxPrimitive avoid searching for the field by name at runtime. ScopedObjectAccess soa(Thread::Current()); - NullHandle<mirror::ClassLoader> class_loader; + StackHandleScope<1> hs(soa.Self()); + auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); mirror::Class* c; c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Boolean;", class_loader); FieldHelper fh(c->GetIFields()->Get(0)); diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index 58b4286c30..f1795a5a63 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -385,36 +385,31 @@ EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticPrimitiveWrite); template<InvokeType type, bool access_check> static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, - mirror::Object** this_object, - mirror::ArtMethod** referrer, Thread* self) { - ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); - mirror::ArtMethod* resolved_method = class_linker->GetResolvedMethod(method_idx, *referrer, type); - if (resolved_method == nullptr) { - StackHandleScope<1> hs(self); - mirror::Object* null_this = nullptr; - HandleWrapper<mirror::Object> h_this( - hs.NewHandleWrapper(type == kStatic ? &null_this : this_object)); - resolved_method = class_linker->ResolveMethod(self, method_idx, referrer, type); - } + mirror::Object* this_object, + mirror::ArtMethod* referrer, Thread* self) { + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + StackHandleScope<1> hs(self); + Handle<mirror::Object> handle_scope_this(hs.NewHandle(type == kStatic ? nullptr : this_object)); + mirror::ArtMethod* resolved_method = class_linker->ResolveMethod(method_idx, referrer, type); if (UNLIKELY(resolved_method == nullptr)) { DCHECK(self->IsExceptionPending()); // Throw exception and unwind. return nullptr; // Failure. - } else if (UNLIKELY(*this_object == nullptr && type != kStatic)) { + } else if (UNLIKELY(handle_scope_this.Get() == nullptr && type != kStatic)) { // Maintain interpreter-like semantics where NullPointerException is thrown // after potential NoSuchMethodError from class linker. ThrowLocation throw_location = self->GetCurrentLocationForThrow(); - DCHECK_EQ(*referrer, throw_location.GetMethod()); + DCHECK(referrer == throw_location.GetMethod()); ThrowNullPointerExceptionForMethodAccess(throw_location, method_idx, type); return nullptr; // Failure. } else if (access_check) { // Incompatible class change should have been handled in resolve method. if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) { ThrowIncompatibleClassChangeError(type, resolved_method->GetInvokeType(), resolved_method, - *referrer); + referrer); return nullptr; // Failure. } mirror::Class* methods_class = resolved_method->GetDeclaringClass(); - mirror::Class* referring_class = (*referrer)->GetDeclaringClass(); + mirror::Class* referring_class = referrer->GetDeclaringClass(); bool can_access_resolved_method = referring_class->CheckResolvedMethodAccess<type>(methods_class, resolved_method, method_idx); @@ -428,7 +423,7 @@ static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, case kDirect: return resolved_method; case kVirtual: { - mirror::ObjectArray<mirror::ArtMethod>* vtable = (*this_object)->GetClass()->GetVTable(); + mirror::ObjectArray<mirror::ArtMethod>* vtable = handle_scope_this->GetClass()->GetVTable(); uint16_t vtable_index = resolved_method->GetMethodIndex(); if (access_check && (vtable == nullptr || vtable_index >= static_cast<uint32_t>(vtable->GetLength()))) { @@ -442,7 +437,7 @@ static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, return vtable->GetWithoutChecks(vtable_index); } case kSuper: { - mirror::Class* super_class = (*referrer)->GetDeclaringClass()->GetSuperClass(); + mirror::Class* super_class = referrer->GetDeclaringClass()->GetSuperClass(); uint16_t vtable_index = resolved_method->GetMethodIndex(); mirror::ObjectArray<mirror::ArtMethod>* vtable; if (access_check) { @@ -465,19 +460,20 @@ static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, } case kInterface: { uint32_t imt_index = resolved_method->GetDexMethodIndex() % ClassLinker::kImtSize; - mirror::ObjectArray<mirror::ArtMethod>* imt_table = (*this_object)->GetClass()->GetImTable(); + mirror::ObjectArray<mirror::ArtMethod>* imt_table = handle_scope_this->GetClass()->GetImTable(); mirror::ArtMethod* imt_method = imt_table->Get(imt_index); if (!imt_method->IsImtConflictMethod()) { return imt_method; } else { mirror::ArtMethod* interface_method = - (*this_object)->GetClass()->FindVirtualMethodForInterface(resolved_method); + handle_scope_this->GetClass()->FindVirtualMethodForInterface(resolved_method); if (UNLIKELY(interface_method == nullptr)) { ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, - *this_object, *referrer); + handle_scope_this.Get(), referrer); return nullptr; // Failure. + } else { + return interface_method; } - return interface_method; } } default: @@ -490,8 +486,8 @@ static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, #define EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, _access_check) \ template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE \ mirror::ArtMethod* FindMethodFromCode<_type, _access_check>(uint32_t method_idx, \ - mirror::Object** this_object, \ - mirror::ArtMethod** referrer, \ + mirror::Object* this_object, \ + mirror::ArtMethod* referrer, \ Thread* self) #define EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(_type) \ EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, false); \ diff --git a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc index f2e2bf7aa9..3f02ec7f73 100644 --- a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc +++ b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc @@ -25,7 +25,6 @@ namespace art { -// TODO: Make the MethodHelper here be compaction safe. extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame, JValue* result) { @@ -44,8 +43,6 @@ extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper& m } self->PopShadowFrame(); CHECK(h_class->IsInitializing()); - // Reload from shadow frame in case the method moved, this is faster than adding a handle. - method = shadow_frame->GetMethod(); } } uint16_t arg_offset = (code_item == NULL) ? 0 : code_item->registers_size_ - code_item->ins_size_; diff --git a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc index 3a898e8ed5..d34b09737f 100644 --- a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc +++ b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc @@ -23,20 +23,17 @@ namespace art { template<InvokeType type, bool access_check> mirror::ArtMethod* FindMethodHelper(uint32_t method_idx, mirror::Object* this_object, - mirror::ArtMethod* caller_method, Thread* self) { + mirror::ArtMethod* caller_method, Thread* thread) { mirror::ArtMethod* method = FindMethodFast(method_idx, this_object, caller_method, access_check, type); if (UNLIKELY(method == NULL)) { - // Note: This can cause thread suspension. - self->AssertThreadSuspensionIsAllowable(); - method = FindMethodFromCode<type, access_check>(method_idx, &this_object, &caller_method, - self); + method = FindMethodFromCode<type, access_check>(method_idx, this_object, caller_method, thread); if (UNLIKELY(method == NULL)) { - CHECK(self->IsExceptionPending()); + CHECK(thread->IsExceptionPending()); return 0; // failure } } - DCHECK(!self->IsExceptionPending()); + DCHECK(!thread->IsExceptionPending()); const void* code = method->GetEntryPointFromPortableCompiledCode(); // When we return, the caller will branch to this address, so it had better not be 0! diff --git a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc index 3756f47311..17c3222ff1 100644 --- a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc +++ b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc @@ -317,11 +317,11 @@ extern "C" uint64_t artPortableProxyInvokeHandler(mirror::ArtMethod* proxy_metho // Lazily resolve a method for portable. Called by stub code. extern "C" const void* artPortableResolutionTrampoline(mirror::ArtMethod* called, mirror::Object* receiver, - Thread* self, + Thread* thread, mirror::ArtMethod** called_addr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { uint32_t dex_pc; - mirror::ArtMethod* caller = self->GetCurrentMethod(&dex_pc); + mirror::ArtMethod* caller = thread->GetCurrentMethod(&dex_pc); ClassLinker* linker = Runtime::Current()->GetClassLinker(); InvokeType invoke_type; @@ -379,7 +379,7 @@ extern "C" const void* artPortableResolutionTrampoline(mirror::ArtMethod* called is_range = true; } uint32_t dex_method_idx = (is_range) ? instr->VRegB_3rc() : instr->VRegB_35c(); - called = linker->ResolveMethod(Thread::Current(), dex_method_idx, &caller, invoke_type); + called = linker->ResolveMethod(dex_method_idx, caller, invoke_type); // Incompatible class change should have been handled in resolve method. CHECK(!called->CheckIncompatibleClassChange(invoke_type)); // Refine called method based on receiver. @@ -395,9 +395,9 @@ extern "C" const void* artPortableResolutionTrampoline(mirror::ArtMethod* called CHECK(!called->CheckIncompatibleClassChange(invoke_type)); } const void* code = nullptr; - if (LIKELY(!self->IsExceptionPending())) { + if (LIKELY(!thread->IsExceptionPending())) { // Ensure that the called method's class is initialized. - StackHandleScope<1> hs(self); + StackHandleScope<1> hs(Thread::Current()); Handle<mirror::Class> called_class(hs.NewHandle(called->GetDeclaringClass())); linker->EnsureInitialized(called_class, true, true); if (LIKELY(called_class->IsInitialized())) { diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 2c920decb9..ee276c1670 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -755,12 +755,11 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called, self->EndAssertNoThreadSuspension(old_cause); bool virtual_or_interface = invoke_type == kVirtual || invoke_type == kInterface; // Resolve method filling in dex cache. - if (UNLIKELY(called->IsRuntimeMethod())) { + if (called->IsRuntimeMethod()) { StackHandleScope<1> hs(self); - mirror::Object* dummy = nullptr; - HandleWrapper<mirror::Object> h_receiver( - hs.NewHandleWrapper(virtual_or_interface ? &receiver : &dummy)); - called = linker->ResolveMethod(self, dex_method_idx, &caller, invoke_type); + Handle<mirror::Object> handle_scope_receiver(hs.NewHandle(virtual_or_interface ? receiver : nullptr)); + called = linker->ResolveMethod(dex_method_idx, caller, invoke_type); + receiver = handle_scope_receiver.Get(); } const void* code = NULL; if (LIKELY(!self->IsExceptionPending())) { @@ -1682,8 +1681,7 @@ static MethodAndCode artInvokeCommon(uint32_t method_idx, mirror::Object* this_o ScopedObjectAccessUnchecked soa(self->GetJniEnv()); RememberForGcArgumentVisitor visitor(sp, type == kStatic, shorty, shorty_len, &soa); visitor.VisitArguments(); - method = FindMethodFromCode<type, access_check>(method_idx, &this_object, &caller_method, - self); + method = FindMethodFromCode<type, access_check>(method_idx, this_object, caller_method, self); visitor.FixupReferences(); } @@ -1873,7 +1871,7 @@ extern "C" MethodAndCode artInvokeInterfaceTrampoline(mirror::ArtMethod* interfa ScopedObjectAccessUnchecked soa(self->GetJniEnv()); RememberForGcArgumentVisitor visitor(sp, false, shorty, shorty_len, &soa); visitor.VisitArguments(); - method = FindMethodFromCode<kInterface, false>(dex_method_idx, &this_object, &caller_method, + method = FindMethodFromCode<kInterface, false>(dex_method_idx, this_object, caller_method, self); visitor.FixupReferences(); } diff --git a/runtime/handle.h b/runtime/handle.h index c4e92851e2..3127864e19 100644 --- a/runtime/handle.h +++ b/runtime/handle.h @@ -53,43 +53,29 @@ class Handle { reference_->Assign(reference); return old; } - jobject ToJObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE { - if (UNLIKELY(reference_->AsMirrorPtr() == nullptr)) { - // Special case so that we work with NullHandles. - return nullptr; - } + jobject ToJObject() const ALWAYS_INLINE { return reinterpret_cast<jobject>(reference_); } - protected: + private: StackReference<T>* reference_; template<typename S> explicit Handle(StackReference<S>* reference) : reference_(reinterpret_cast<StackReference<T>*>(reference)) { } + template<typename S> explicit Handle(const Handle<S>& handle) : reference_(reinterpret_cast<StackReference<T>*>(handle.reference_)) { } - private: template<class S> friend class Handle; friend class HandleScope; template<class S> friend class HandleWrapper; template<size_t kNumReferences> friend class StackHandleScope; }; -template<class T> -class NullHandle : public Handle<T> { - public: - NullHandle() : Handle<T>(&null_ref_) { - } - - private: - StackReference<T> null_ref_; -}; - } // namespace art #endif // ART_RUNTIME_HANDLE_H_ diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index f77a0f6d35..478c74cd25 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -524,17 +524,16 @@ extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh ArtMethod* method = shadow_frame->GetMethod(); // Ensure static methods are initialized. if (method->IsStatic()) { - mirror::Class* declaring_class = method->GetDeclaringClass(); - if (UNLIKELY(!declaring_class->IsInitializing())) { - StackHandleScope<1> hs(self); - HandleWrapper<Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class)); - if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized( - h_declaring_class, true, true))) { - DCHECK(self->IsExceptionPending()); + StackHandleScope<1> hs(self); + Handle<Class> declaringClass(hs.NewHandle(method->GetDeclaringClass())); + if (UNLIKELY(!declaringClass->IsInitializing())) { + if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(declaringClass, true, + true))) { + DCHECK(Thread::Current()->IsExceptionPending()); self->PopShadowFrame(); return; } - CHECK(h_declaring_class->IsInitializing()); + CHECK(declaringClass->IsInitializing()); } } diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 63ae6fdf18..418aff51dc 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -296,9 +296,11 @@ static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh, // other variants that take more arguments should also be added. std::string descriptor(DotToDescriptor(shadow_frame->GetVRegReference(arg_offset)->AsString()->ToModifiedUtf8().c_str())); + StackHandleScope<1> hs(self); // shadow_frame.GetMethod()->GetDeclaringClass()->GetClassLoader(); - Class* found = Runtime::Current()->GetClassLinker()->FindClass( - self, descriptor.c_str(), NullHandle<mirror::ClassLoader>()); + auto class_loader = hs.NewHandle<ClassLoader>(nullptr); + Class* found = Runtime::Current()->GetClassLinker()->FindClass(self, descriptor.c_str(), + class_loader); CHECK(found != NULL) << "Class.forName failed in un-started runtime for class: " << PrettyDescriptor(descriptor); result->SetL(found); diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index cfc90a6618..b42af11986 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -29,7 +29,6 @@ #include "dex_instruction.h" #include "entrypoints/entrypoint_utils.h" #include "gc/accounting/card_table-inl.h" -#include "handle_scope-inl.h" #include "nth_caller_visitor.h" #include "mirror/art_field-inl.h" #include "mirror/art_method.h" @@ -113,10 +112,9 @@ static inline bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instr const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); Object* receiver = (type == kStatic) ? nullptr : shadow_frame.GetVRegReference(vregC); - mirror::ArtMethod* sf_method = shadow_frame.GetMethod(); - ArtMethod* const method = FindMethodFromCode<type, do_access_check>( - method_idx, &receiver, &sf_method, self); - // The shadow frame should already be pushed, so we don't need to update it. + ArtMethod* const method = FindMethodFromCode<type, do_access_check>(method_idx, receiver, + shadow_frame.GetMethod(), + self); if (UNLIKELY(method == nullptr)) { CHECK(self->IsExceptionPending()); result->SetJ(0); @@ -350,10 +348,6 @@ static SOMETIMES_INLINE_KEYWORD bool DoFieldPut(Thread* self, const ShadowFrame& case Primitive::kPrimNot: { Object* reg = shadow_frame.GetVRegReference(vregA); if (do_assignability_check && reg != nullptr) { - // FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the - // object in the destructor. - StackHandleScope<1> hs(self); - HandleWrapper<mirror::Object> wrapper(hs.NewHandleWrapper(&obj)); Class* field_class = FieldHelper(f).GetType(); if (!reg->VerifierInstanceOf(field_class)) { // This should never happen. @@ -378,8 +372,7 @@ static SOMETIMES_INLINE_KEYWORD bool DoFieldPut(Thread* self, const ShadowFrame& // Handles iput-quick, iput-wide-quick and iput-object-quick instructions. // Returns true on success, otherwise throws an exception and returns false. template<Primitive::Type field_type, bool transaction_active> -static SOMETIMES_INLINE_KEYWORD bool DoIPutQuick(const ShadowFrame& shadow_frame, - const Instruction* inst, uint16_t inst_data) { +static SOMETIMES_INLINE_KEYWORD bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) { Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); if (UNLIKELY(obj == nullptr)) { // We lost the reference to the field index so we cannot get a more diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index b51e1d586c..6f3317da6b 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -3138,7 +3138,7 @@ void JavaVMExt::DumpReferenceTables(std::ostream& os) { } bool JavaVMExt::LoadNativeLibrary(const std::string& path, - Handle<mirror::ClassLoader> class_loader, + const Handle<mirror::ClassLoader>& class_loader, std::string* detail) { detail->clear(); diff --git a/runtime/jni_internal.h b/runtime/jni_internal.h index 7e76e11c71..37195eb34a 100644 --- a/runtime/jni_internal.h +++ b/runtime/jni_internal.h @@ -67,7 +67,7 @@ class JavaVMExt : public JavaVM { * Returns 'true' on success. On failure, sets 'detail' to a * human-readable description of the error. */ - bool LoadNativeLibrary(const std::string& path, Handle<mirror::ClassLoader> class_loader, + bool LoadNativeLibrary(const std::string& path, const Handle<mirror::ClassLoader>& class_loader, std::string* detail) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); diff --git a/runtime/mirror/array.cc b/runtime/mirror/array.cc index 107664381a..552652cd24 100644 --- a/runtime/mirror/array.cc +++ b/runtime/mirror/array.cc @@ -42,8 +42,8 @@ namespace mirror { // Recursively create an array with multiple dimensions. Elements may be // Objects or primitive types. static Array* RecursiveCreateMultiArray(Thread* self, - Handle<Class> array_class, int current_dimension, - Handle<mirror::IntArray> dimensions) + const Handle<Class>& array_class, int current_dimension, + const Handle<mirror::IntArray>& dimensions) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { int32_t array_length = dimensions->Get(current_dimension); StackHandleScope<1> hs(self); @@ -73,8 +73,8 @@ static Array* RecursiveCreateMultiArray(Thread* self, return new_array.Get(); } -Array* Array::CreateMultiArray(Thread* self, Handle<Class> element_class, - Handle<IntArray> dimensions) { +Array* Array::CreateMultiArray(Thread* self, const Handle<Class>& element_class, + const Handle<IntArray>& dimensions) { // Verify dimensions. // // The caller is responsible for verifying that "dimArray" is non-null diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h index 64e2317cfb..1b8106e05f 100644 --- a/runtime/mirror/array.h +++ b/runtime/mirror/array.h @@ -38,8 +38,8 @@ class MANAGED Array : public Object { bool fill_usable = false) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - static Array* CreateMultiArray(Thread* self, Handle<Class> element_class, - Handle<IntArray> dimensions) + static Array* CreateMultiArray(Thread* self, const Handle<Class>& element_class, + const Handle<IntArray>& dimensions) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc index e2d3f41603..af544fdf72 100644 --- a/runtime/mirror/art_method.cc +++ b/runtime/mirror/art_method.cc @@ -229,7 +229,7 @@ uintptr_t ArtMethod::ToNativePc(const uint32_t dex_pc) { return 0; } -uint32_t ArtMethod::FindCatchBlock(Handle<Class> exception_type, uint32_t dex_pc, +uint32_t ArtMethod::FindCatchBlock(Handle<Class>& exception_type, uint32_t dex_pc, bool* has_no_move_exception, bool* exc_changed) { MethodHelper mh(this); const DexFile::CodeItem* code_item = mh.GetCodeItem(); diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h index 2e8253fad7..34fe0bf530 100644 --- a/runtime/mirror/art_method.h +++ b/runtime/mirror/art_method.h @@ -401,7 +401,7 @@ class MANAGED ArtMethod : public Object { // In the process of finding a catch block we might trigger resolution errors. This is flagged // by exc_changed, which indicates that a different exception is now stored in the thread and // should be reloaded. - uint32_t FindCatchBlock(Handle<Class> exception_type, uint32_t dex_pc, + uint32_t FindCatchBlock(Handle<Class>& exception_type, uint32_t dex_pc, bool* has_no_move_exception, bool* exc_changed) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); diff --git a/runtime/mirror/stack_trace_element.cc b/runtime/mirror/stack_trace_element.cc index b1de2b6f7d..d8591cca7a 100644 --- a/runtime/mirror/stack_trace_element.cc +++ b/runtime/mirror/stack_trace_element.cc @@ -39,8 +39,10 @@ void StackTraceElement::ResetClass() { java_lang_StackTraceElement_ = NULL; } -StackTraceElement* StackTraceElement::Alloc(Thread* self, Handle<String> declaring_class, - Handle<String> method_name, Handle<String> file_name, +StackTraceElement* StackTraceElement::Alloc(Thread* self, + Handle<String>& declaring_class, + Handle<String>& method_name, + Handle<String>& file_name, int32_t line_number) { StackTraceElement* trace = down_cast<StackTraceElement*>(GetStackTraceElement()->AllocObject(self)); @@ -55,8 +57,8 @@ StackTraceElement* StackTraceElement::Alloc(Thread* self, Handle<String> declari } template<bool kTransactionActive> -void StackTraceElement::Init(Handle<String> declaring_class, Handle<String> method_name, - Handle<String> file_name, int32_t line_number) { +void StackTraceElement::Init(Handle<String>& declaring_class, Handle<String>& method_name, + Handle<String>& file_name, int32_t line_number) { SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, declaring_class_), declaring_class.Get()); SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, method_name_), diff --git a/runtime/mirror/stack_trace_element.h b/runtime/mirror/stack_trace_element.h index e094e8bc85..22d9b71410 100644 --- a/runtime/mirror/stack_trace_element.h +++ b/runtime/mirror/stack_trace_element.h @@ -46,8 +46,10 @@ class MANAGED StackTraceElement : public Object { return GetField32(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_)); } - static StackTraceElement* Alloc(Thread* self, Handle<String> declaring_class, - Handle<String> method_name, Handle<String> file_name, + static StackTraceElement* Alloc(Thread* self, + Handle<String>& declaring_class, + Handle<String>& method_name, + Handle<String>& file_name, int32_t line_number) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -68,8 +70,8 @@ class MANAGED StackTraceElement : public Object { int32_t line_number_; template<bool kTransactionActive> - void Init(Handle<String> declaring_class, Handle<String> method_name, Handle<String> file_name, - int32_t line_number) + void Init(Handle<String>& declaring_class, Handle<String>& method_name, + Handle<String>& file_name, int32_t line_number) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static Class* java_lang_StackTraceElement_; diff --git a/runtime/mirror/string.cc b/runtime/mirror/string.cc index 1d79106a44..ee719b477b 100644 --- a/runtime/mirror/string.cc +++ b/runtime/mirror/string.cc @@ -131,7 +131,7 @@ String* String::Alloc(Thread* self, int32_t utf16_length) { return Alloc(self, array); } -String* String::Alloc(Thread* self, Handle<CharArray> array) { +String* String::Alloc(Thread* self, const Handle<CharArray>& array) { // Hold reference in case AllocObject causes GC. String* string = down_cast<String*>(GetJavaLangString()->AllocObject(self)); if (LIKELY(string != nullptr)) { diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h index 6c3015f4d0..169b671574 100644 --- a/runtime/mirror/string.h +++ b/runtime/mirror/string.h @@ -137,7 +137,7 @@ class MANAGED String : public Object { static String* Alloc(Thread* self, int32_t utf16_length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - static String* Alloc(Thread* self, Handle<CharArray> array) + static String* Alloc(Thread* self, const Handle<CharArray>& array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); diff --git a/runtime/monitor.cc b/runtime/monitor.cc index fe1ef6cba0..f783edbfc3 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -637,7 +637,7 @@ void Monitor::Inflate(Thread* self, Thread* owner, mirror::Object* obj, int32_t } } -void Monitor::InflateThinLocked(Thread* self, Handle<mirror::Object> obj, LockWord lock_word, +void Monitor::InflateThinLocked(Thread* self, Handle<mirror::Object>& obj, LockWord lock_word, uint32_t hash_code) { DCHECK_EQ(lock_word.GetState(), LockWord::kThinLocked); uint32_t owner_thread_id = lock_word.ThinLockOwner(); diff --git a/runtime/monitor.h b/runtime/monitor.h index 007f54d9b1..bc1b2ed4eb 100644 --- a/runtime/monitor.h +++ b/runtime/monitor.h @@ -114,7 +114,7 @@ class Monitor { return monitor_id_; } - static void InflateThinLocked(Thread* self, Handle<mirror::Object> obj, LockWord lock_word, + static void InflateThinLocked(Thread* self, Handle<mirror::Object>& obj, LockWord lock_word, uint32_t hash_code) NO_THREAD_SAFETY_ANALYSIS; static bool Deflate(Thread* self, mirror::Object* obj) diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc index d55b5450c3..d9c9b5937d 100644 --- a/runtime/native/dalvik_system_VMRuntime.cc +++ b/runtime/native/dalvik_system_VMRuntime.cc @@ -221,7 +221,7 @@ static void PreloadDexCachesStringsCallback(mirror::Object** root, void* arg, } // Based on ClassLinker::ResolveString. -static void PreloadDexCachesResolveString(Handle<mirror::DexCache> dex_cache, uint32_t string_idx, +static void PreloadDexCachesResolveString(Handle<mirror::DexCache>& dex_cache, uint32_t string_idx, StringTable& strings) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { mirror::String* string = dex_cache->GetResolvedString(string_idx); @@ -267,7 +267,8 @@ static void PreloadDexCachesResolveType(mirror::DexCache* dex_cache, uint32_t ty } // Based on ClassLinker::ResolveField. -static void PreloadDexCachesResolveField(Handle<mirror::DexCache> dex_cache, uint32_t field_idx, +static void PreloadDexCachesResolveField(Handle<mirror::DexCache>& dex_cache, + uint32_t field_idx, bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { mirror::ArtField* field = dex_cache->GetResolvedField(field_idx); @@ -295,7 +296,8 @@ static void PreloadDexCachesResolveField(Handle<mirror::DexCache> dex_cache, uin } // Based on ClassLinker::ResolveMethod. -static void PreloadDexCachesResolveMethod(Handle<mirror::DexCache> dex_cache, uint32_t method_idx, +static void PreloadDexCachesResolveMethod(Handle<mirror::DexCache>& dex_cache, + uint32_t method_idx, InvokeType invoke_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { mirror::ArtMethod* method = dex_cache->GetResolvedMethod(method_idx); diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 2293ad7c08..4863b8367b 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -121,8 +121,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(mirror::Class* klass, } MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, + Handle<mirror::DexCache>& dex_cache, + Handle<mirror::ClassLoader>& class_loader, const DexFile::ClassDef* class_def, bool allow_soft_failures, std::string* error) { @@ -151,8 +151,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file, previous_direct_method_idx = method_idx; InvokeType type = it.GetMethodInvokeType(*class_def); mirror::ArtMethod* method = - linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, - NullHandle<mirror::ArtMethod>(), type); + linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type); if (method == NULL) { DCHECK(Thread::Current()->IsExceptionPending()); // We couldn't resolve the method, but continue regardless. @@ -194,8 +193,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file, previous_virtual_method_idx = method_idx; InvokeType type = it.GetMethodInvokeType(*class_def); mirror::ArtMethod* method = - linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, - NullHandle<mirror::ArtMethod>(), type); + linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type); if (method == NULL) { DCHECK(Thread::Current()->IsExceptionPending()); // We couldn't resolve the method, but continue regardless. @@ -234,8 +232,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file, MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx, const DexFile* dex_file, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, + Handle<mirror::DexCache>& dex_cache, + Handle<mirror::ClassLoader>& class_loader, const DexFile::ClassDef* class_def, const DexFile::CodeItem* code_item, mirror::ArtMethod* method, @@ -279,8 +277,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx, void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_idx, const DexFile* dex_file, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, + Handle<mirror::DexCache>& dex_cache, + Handle<mirror::ClassLoader>& class_loader, const DexFile::ClassDef* class_def, const DexFile::CodeItem* code_item, mirror::ArtMethod* method, diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index f614425a91..495d3c5353 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -142,15 +142,15 @@ class MethodVerifier { /* Verify a class. Returns "kNoFailure" on success. */ static FailureKind VerifyClass(mirror::Class* klass, bool allow_soft_failures, std::string* error) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - static FailureKind VerifyClass(const DexFile* dex_file, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, + static FailureKind VerifyClass(const DexFile* dex_file, Handle<mirror::DexCache>& dex_cache, + Handle<mirror::ClassLoader>& class_loader, const DexFile::ClassDef* class_def, bool allow_soft_failures, std::string* error) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static void VerifyMethodAndDump(std::ostream& os, uint32_t method_idx, const DexFile* dex_file, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, + Handle<mirror::DexCache>& dex_cache, + Handle<mirror::ClassLoader>& class_loader, const DexFile::ClassDef* class_def, const DexFile::CodeItem* code_item, mirror::ArtMethod* method, uint32_t method_access_flags) @@ -255,8 +255,8 @@ class MethodVerifier { * for code flow problems. */ static FailureKind VerifyMethod(uint32_t method_idx, const DexFile* dex_file, - Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, + Handle<mirror::DexCache>& dex_cache, + Handle<mirror::ClassLoader>& class_loader, const DexFile::ClassDef* class_def_idx, const DexFile::CodeItem* code_item, mirror::ArtMethod* method, uint32_t method_access_flags, |