diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-05-15 12:39:19 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2014-05-22 10:47:44 -0700 |
commit | e09ae0920be57760fb390b6944bce420fa0b5582 (patch) | |
tree | acc40266093df4289ffb6728c979cafd6b5114d2 | |
parent | b8033db2a8dc6f7c7e29b1552177542964f56e44 (diff) | |
download | art-e09ae0920be57760fb390b6944bce420fa0b5582.zip art-e09ae0920be57760fb390b6944bce420fa0b5582.tar.gz art-e09ae0920be57760fb390b6944bce420fa0b5582.tar.bz2 |
Fix an outstanding compaction bug in interpreter.
Fixed a bug in DoFieldPut where the FieldHelper GetType could cause
thread suspension which would result in a stale obj.
Added more handles in the class linker to facilitate moving fiels
and methods in the future.
Removed un-necessarly passing handle references since these are value
types and don't need to be passed by reference.
Added a special NullHandle type which allows null handles without a
handle scope.
Change-Id: I1b51723920a2e4f4f8b2907066f578a3e879fd5b
38 files changed, 339 insertions, 306 deletions
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h index fb6c625..5050d4e 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 08fd386..45abfcc 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, const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit) { + ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, + 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, const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, + 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,13 +165,14 @@ inline std::pair<bool, bool> CompilerDriver::IsFastStaticField( } inline mirror::ArtMethod* CompilerDriver::ResolveMethod( - ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, uint32_t method_idx, InvokeType invoke_type) { - DCHECK(dex_cache->GetDexFile() == mUnit->GetDexFile()); - DCHECK(class_loader.Get() == soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); + DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); + DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); mirror::ArtMethod* resolved_method = mUnit->GetClassLinker()->ResolveMethod( - *mUnit->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type); + *mUnit->GetDexFile(), method_idx, dex_cache, class_loader, NullHandle<mirror::ArtMethod>(), + invoke_type); DCHECK_EQ(resolved_method == nullptr, soa.Self()->IsExceptionPending()); if (UNLIKELY(resolved_method == nullptr)) { // Clean up any exception left by type resolution. @@ -206,8 +207,8 @@ inline uint16_t CompilerDriver::GetResolvedMethodVTableIndex( } inline int CompilerDriver::IsFastInvoke( - ScopedObjectAccess& soa, const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, + 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) { @@ -256,15 +257,17 @@ 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, NULL, kVirtual); + devirt_target->dex_method_index, dex_cache, + class_loader, NullHandle<mirror::ArtMethod>(), + 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, NULL, kVirtual); + target_dex_cache, class_loader, + NullHandle<mirror::ArtMethod>(), kVirtual); } CHECK(called_method != NULL); CHECK(!called_method->IsAbstract()); diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 0f41d2b..3304561 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<3> hs(self); + StackHandleScope<2> 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, class_loader))); + class_linker->ResolveType(*dex_file, exception_type_idx, dex_cache, + NullHandle<mirror::ClassLoader>()))); if (klass.Get() == NULL) { const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx); const char* descriptor = dex_file->GetTypeDescriptor(type_id); @@ -1541,7 +1541,8 @@ 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, NULL, + dex_cache, class_loader, + NullHandle<mirror::ArtMethod>(), it.GetMethodInvokeType(class_def)); if (method == NULL) { CHECK(soa.Self()->IsExceptionPending()); @@ -1551,7 +1552,8 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag } while (it.HasNextVirtualMethod()) { mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), - dex_cache, class_loader, NULL, + dex_cache, class_loader, + NullHandle<mirror::ArtMethod>(), 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 abca659..14ccb50 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, const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit) + ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, + 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, const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, + 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, const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, + 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, const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, + ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, + 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 4efd27d..964dfeb 100644 --- a/compiler/driver/compiler_driver_test.cc +++ b/compiler/driver/compiler_driver_test.cc @@ -152,10 +152,9 @@ TEST_F(CompilerDriverTest, AbstractMethodErrorStub) { jobject class_loader; { ScopedObjectAccess soa(Thread::Current()); - 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"); + CompileVirtualMethod(NullHandle<mirror::ClassLoader>(), "java.lang.Class", "isFinalizable", + "()Z"); + CompileDirectMethod(NullHandle<mirror::ClassLoader>(), "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 0e27210..3dba426 100644 --- a/compiler/elf_writer_mclinker.cc +++ b/compiler/elf_writer_mclinker.cc @@ -361,10 +361,11 @@ 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<2> hs(soa.Self()); + StackHandleScope<1> hs(soa.Self()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(linker->FindDexCache(dex_file))); - auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); - method = linker->ResolveMethod(dex_file, method_idx, dex_cache, class_loader, NULL, invoke_type); + method = linker->ResolveMethod(dex_file, method_idx, dex_cache, + NullHandle<mirror::ClassLoader>(), + NullHandle<mirror::ArtMethod>(), invoke_type); CHECK(method != NULL); } const CompiledMethod* compiled_method = diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index 70144c8..be53926 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -695,15 +695,14 @@ 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<2> hs(Thread::Current()); + StackHandleScope<1> 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, - class_loader, - NULL, + NullHandle<mirror::ClassLoader>(), + NullHandle<mirror::ArtMethod>(), patch->GetTargetInvokeType()); CHECK(method != NULL) << patch->GetTargetDexFile()->GetLocation() << " " << patch->GetTargetMethodIdx(); @@ -721,11 +720,8 @@ 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()))); - auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); - Class* klass = class_linker->ResolveType(patch->GetDexFile(), - patch->GetTargetTypeIdx(), - dex_cache, - class_loader); + Class* klass = class_linker->ResolveType(patch->GetDexFile(), patch->GetTargetTypeIdx(), + dex_cache, NullHandle<mirror::ClassLoader>()); 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 a7ee82e..6812f3c 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()); - auto loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); - mirror::Class* klass = class_linker->FindClass(soa.Self(), descriptor, loader); + mirror::Class* klass = class_linker->FindClass(soa.Self(), descriptor, + NullHandle<mirror::ClassLoader>()); 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 bace25c..5d532ab 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -513,9 +513,10 @@ 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, - class_loader, nullptr, invoke_type); + NullHandle<mirror::ClassLoader>(), + NullHandle<mirror::ArtMethod>(), + 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 dcae502..8fd6b6d 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<2> hs(soa.Self()); + StackHandleScope<1> hs(soa.Self()); Handle<mirror::DexCache> dex_cache( hs.NewHandle(runtime->GetClassLinker()->FindDexCache(dex_file))); - auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); + NullHandle<mirror::ClassLoader> class_loader; 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 ac86014..84afb2d 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -34,9 +34,7 @@ inline bool ClassLinker::IsInBootClassPath(const char* descriptor) { } inline mirror::Class* ClassLinker::FindSystemClass(Thread* self, const char* descriptor) { - StackHandleScope<1> hs(self); - auto class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr); - return FindClass(self, descriptor, class_loader); + return FindClass(self, descriptor, NullHandle<mirror::ClassLoader>()); } inline mirror::Class* ClassLinker::FindArrayClass(Thread* self, mirror::Class* element_class) { @@ -110,31 +108,47 @@ inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, mirror::ArtFie return resolved_type; } -inline mirror::ArtMethod* ClassLinker::ResolveMethod(uint32_t method_idx, - mirror::ArtMethod* referrer, - InvokeType type) { +inline mirror::ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx, + mirror::ArtMethod* referrer, + InvokeType type) { mirror::ArtMethod* resolved_method = referrer->GetDexCacheResolvedMethods()->Get(method_idx); - 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); - } + if (resolved_method == nullptr || resolved_method->IsRuntimeMethod()) { + return nullptr; } return resolved_method; } -inline mirror::ArtField* ClassLinker::ResolveField(uint32_t field_idx, - mirror::ArtMethod* referrer, +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); + } + 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, bool is_static) { mirror::Class* declaring_class = referrer->GetDeclaringClass(); - mirror::ArtField* resolved_field = - declaring_class->GetDexCache()->GetResolvedField(field_idx); + mirror::ArtField* resolved_field = GetResolvedField(field_idx, declaring_class); 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 c7302b5..afff7a2 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, - const Handle<mirror::ClassLoader>& class_loader) { + Handle<mirror::ClassLoader> class_loader) { DCHECK_NE(*descriptor, '\0') << "descriptor is empty string"; DCHECK(self != nullptr); self->AssertNoPendingException(); @@ -1390,8 +1390,7 @@ 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); - auto class_loader = hs.NewHandle<mirror::ClassLoader>(nullptr); - return DefineClass(descriptor, class_loader, *pair.first, *pair.second); + return DefineClass(descriptor, NullHandle<mirror::ClassLoader>(), *pair.first, *pair.second); } } else if (Runtime::Current()->UseCompileTimeClassPath()) { // First try the boot class path, we check the descriptor first to avoid an unnecessary @@ -1452,7 +1451,7 @@ mirror::Class* ClassLinker::FindClass(Thread* self, const char* descriptor, } mirror::Class* ClassLinker::DefineClass(const char* descriptor, - const Handle<mirror::ClassLoader>& class_loader, + Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file, const DexFile::ClassDef& dex_class_def) { Thread* self = Thread::Current(); @@ -1796,10 +1795,9 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { // Ignore virtual methods on the iterator. } -void ClassLinker::LinkCode(const Handle<mirror::ArtMethod>& method, - const OatFile::OatClass* oat_class, +void ClassLinker::LinkCode(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_) { + uint32_t method_index) { // Method shouldn't have already been linked. DCHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr); DCHECK(method->GetEntryPointFromPortableCompiledCode() == nullptr); @@ -1871,7 +1869,7 @@ void ClassLinker::LinkCode(const Handle<mirror::ArtMethod>& method, void ClassLinker::LoadClass(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, - const Handle<mirror::Class>& klass, + Handle<mirror::Class> klass, mirror::ClassLoader* class_loader) { CHECK(klass.Get() != NULL); CHECK(klass->GetDexCache() != NULL); @@ -1909,7 +1907,7 @@ void ClassLinker::LoadClass(const DexFile& dex_file, void ClassLinker::LoadClassMembers(const DexFile& dex_file, const byte* class_data, - const Handle<mirror::Class>& klass, + Handle<mirror::Class> klass, mirror::ClassLoader* class_loader, const OatFile::OatClass* oat_class) { // Load fields. @@ -2007,8 +2005,7 @@ void ClassLinker::LoadClassMembers(const DexFile& dex_file, } void ClassLinker::LoadField(const DexFile& /*dex_file*/, const ClassDataItemIterator& it, - const Handle<mirror::Class>& klass, - const Handle<mirror::ArtField>& dst) { + Handle<mirror::Class> klass, Handle<mirror::ArtField> dst) { uint32_t field_idx = it.GetMemberIndex(); dst->SetDexFieldIndex(field_idx); dst->SetDeclaringClass(klass.Get()); @@ -2017,7 +2014,7 @@ void ClassLinker::LoadField(const DexFile& /*dex_file*/, const ClassDataItemIter mirror::ArtMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file, const ClassDataItemIterator& it, - const Handle<mirror::Class>& klass) { + 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_); @@ -2088,7 +2085,7 @@ void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) { } void ClassLinker::AppendToBootClassPath(const DexFile& dex_file, - const Handle<mirror::DexCache>& dex_cache) { + 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); @@ -2110,7 +2107,7 @@ bool ClassLinker::IsDexFileRegistered(const DexFile& dex_file) const { } void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, - const Handle<mirror::DexCache>& dex_cache) { + 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())) @@ -2147,7 +2144,7 @@ void ClassLinker::RegisterDexFile(const DexFile& dex_file) { } void ClassLinker::RegisterDexFile(const DexFile& dex_file, - const Handle<mirror::DexCache>& dex_cache) { + Handle<mirror::DexCache> dex_cache) { WriterMutexLock mu(Thread::Current(), dex_lock_); RegisterDexFileLocked(dex_file, dex_cache); } @@ -2224,7 +2221,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, - const Handle<mirror::ClassLoader>& class_loader) { + Handle<mirror::ClassLoader> class_loader) { // Identify the underlying component type CHECK_EQ('[', descriptor[0]); StackHandleScope<2> hs(self); @@ -2416,7 +2413,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 && descriptor == klass->GetDescriptor()) { + if (klass->GetClassLoader() == class_loader && klass->DescriptorEquals(descriptor)) { class_table_.erase(it); return true; } @@ -2460,13 +2457,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 && descriptor == klass->GetDescriptor()) { + if (klass->GetClassLoader() == class_loader && klass->DescriptorEquals(descriptor)) { 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) && - descriptor == klass2->GetDescriptor())) + CHECK(!(klass2->GetClassLoader() == class_loader && + klass2->DescriptorEquals(descriptor))) << PrettyClass(klass) << " " << klass << " " << klass->GetClassLoader() << " " << PrettyClass(klass2) << " " << klass2 << " " << klass2->GetClassLoader(); } @@ -2557,13 +2554,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 (descriptor == klass->GetDescriptor()) { + if (klass->DescriptorEquals(descriptor)) { result.push_back(klass); } } } -void ClassLinker::VerifyClass(const Handle<mirror::Class>& klass) { +void ClassLinker::VerifyClass(Handle<mirror::Class> klass) { // TODO: assert that the monitor on the Class is held Thread* self = Thread::Current(); ObjectLock<mirror::Class> lock(self, klass); @@ -2776,7 +2773,7 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class } void ClassLinker::ResolveClassExceptionHandlerTypes(const DexFile& dex_file, - const Handle<mirror::Class>& klass) { + Handle<mirror::Class> klass) { for (size_t i = 0; i < klass->NumDirectMethods(); i++) { ResolveMethodExceptionHandlerTypes(dex_file, klass->GetDirectMethod(i)); } @@ -2817,7 +2814,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, @@ -2999,7 +2996,7 @@ mirror::ArtMethod* ClassLinker::FindMethodForProxy(mirror::Class* proxy_class, mirror::ArtMethod* ClassLinker::CreateProxyConstructor(Thread* self, - const Handle<mirror::Class>& klass, + Handle<mirror::Class> klass, mirror::Class* proxy_class) { // Create constructor for Proxy that must initialize h mirror::ObjectArray<mirror::ArtMethod>* proxy_direct_methods = @@ -3030,8 +3027,8 @@ static void CheckProxyConstructor(mirror::ArtMethod* constructor) } mirror::ArtMethod* ClassLinker::CreateProxyMethod(Thread* self, - const Handle<mirror::Class>& klass, - const Handle<mirror::ArtMethod>& prototype) { + Handle<mirror::Class> klass, + 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(), @@ -3058,8 +3055,7 @@ 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()); @@ -3119,7 +3115,7 @@ bool ClassLinker::IsInitialized() const { return init_done_; } -bool ClassLinker::InitializeClass(const Handle<mirror::Class>& klass, bool can_init_statics, +bool ClassLinker::InitializeClass(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 @@ -3286,7 +3282,7 @@ bool ClassLinker::InitializeClass(const Handle<mirror::Class>& klass, bool can_i return success; } -bool ClassLinker::WaitForInitializeClass(const Handle<mirror::Class>& klass, Thread* self, +bool ClassLinker::WaitForInitializeClass(Handle<mirror::Class> klass, Thread* self, ObjectLock<mirror::Class>& lock) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { while (true) { @@ -3326,7 +3322,7 @@ bool ClassLinker::WaitForInitializeClass(const Handle<mirror::Class>& klass, Thr LOG(FATAL) << "Not Reached" << PrettyClass(klass.Get()); } -bool ClassLinker::ValidateSuperClassDescriptors(const Handle<mirror::Class>& klass) { +bool ClassLinker::ValidateSuperClassDescriptors(Handle<mirror::Class> klass) { if (klass->IsInterface()) { return true; } @@ -3368,18 +3364,12 @@ bool ClassLinker::ValidateSuperClassDescriptors(const Handle<mirror::Class>& kla return true; } -bool ClassLinker::EnsureInitialized(const Handle<mirror::Class>& c, bool can_init_fields, +bool ClassLinker::EnsureInitialized(Handle<mirror::Class> c, bool can_init_fields, bool can_init_parents) { - 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()); - } + 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()); } return success; } @@ -3398,8 +3388,8 @@ void ClassLinker::ConstructFieldMap(const DexFile& dex_file, const DexFile::Clas } } -bool ClassLinker::LinkClass(Thread* self, const Handle<mirror::Class>& klass, - const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) { +bool ClassLinker::LinkClass(Thread* self, Handle<mirror::Class> klass, + Handle<mirror::ObjectArray<mirror::Class>> interfaces) { CHECK_EQ(mirror::Class::kStatusLoaded, klass->GetStatus()); if (!LinkSuperClass(klass)) { return false; @@ -3420,8 +3410,7 @@ bool ClassLinker::LinkClass(Thread* self, const Handle<mirror::Class>& klass, return true; } -bool ClassLinker::LoadSuperAndInterfaces(const Handle<mirror::Class>& klass, - const DexFile& dex_file) { +bool ClassLinker::LoadSuperAndInterfaces(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_; @@ -3464,7 +3453,7 @@ bool ClassLinker::LoadSuperAndInterfaces(const Handle<mirror::Class>& klass, return true; } -bool ClassLinker::LinkSuperClass(const Handle<mirror::Class>& klass) { +bool ClassLinker::LinkSuperClass(Handle<mirror::Class> klass) { CHECK(!klass->IsPrimitive()); mirror::Class* super = klass->GetSuperClass(); if (klass.Get() == GetClassRoot(kJavaLangObject)) { @@ -3524,8 +3513,8 @@ bool ClassLinker::LinkSuperClass(const Handle<mirror::Class>& klass) { } // Populate the class vtable and itable. Compute return type indices. -bool ClassLinker::LinkMethods(const Handle<mirror::Class>& klass, - const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) { +bool ClassLinker::LinkMethods(Handle<mirror::Class> klass, + Handle<mirror::ObjectArray<mirror::Class>> interfaces) { if (klass->IsInterface()) { // No vtable. size_t count = klass->NumVirtualMethods(); @@ -3545,7 +3534,7 @@ bool ClassLinker::LinkMethods(const Handle<mirror::Class>& klass, return true; } -bool ClassLinker::LinkVirtualMethods(const Handle<mirror::Class>& klass) { +bool ClassLinker::LinkVirtualMethods(Handle<mirror::Class> klass) { Thread* self = Thread::Current(); if (klass->HasSuperClass()) { uint32_t max_count = (klass->NumVirtualMethods() + @@ -3632,9 +3621,8 @@ bool ClassLinker::LinkVirtualMethods(const Handle<mirror::Class>& klass) { return true; } -bool ClassLinker::LinkInterfaceMethods( - const Handle<mirror::Class>& klass, - const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) { +bool ClassLinker::LinkInterfaceMethods(Handle<mirror::Class> klass, + 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()); @@ -3889,12 +3877,12 @@ bool ClassLinker::LinkInterfaceMethods( return true; } -bool ClassLinker::LinkInstanceFields(const Handle<mirror::Class>& klass) { +bool ClassLinker::LinkInstanceFields(Handle<mirror::Class> klass) { CHECK(klass.Get() != NULL); return LinkFields(klass, false); } -bool ClassLinker::LinkStaticFields(const Handle<mirror::Class>& klass) { +bool ClassLinker::LinkStaticFields(Handle<mirror::Class> klass) { CHECK(klass.Get() != NULL); size_t allocated_class_size = klass->GetClassSize(); bool success = LinkFields(klass, true); @@ -3933,7 +3921,7 @@ struct LinkFieldsComparator { } }; -bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static) { +bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) { size_t num_fields = is_static ? klass->NumStaticFields() : klass->NumInstanceFields(); @@ -4029,7 +4017,7 @@ bool ClassLinker::LinkFields(const 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 && "Ljava/lang/ref/Reference;" == klass->GetDescriptor()) { + if (!is_static && klass->DescriptorEquals("Ljava/lang/ref/Reference;")) { // 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()); @@ -4054,7 +4042,7 @@ bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static) FieldHelper fh(field); Primitive::Type type = fh.GetTypeAsPrimitiveType(); bool is_primitive = type != Primitive::kPrimNot; - if ("Ljava/lang/ref/Reference;" == klass->GetDescriptor() && + if (klass->DescriptorEquals("Ljava/lang/ref/Reference;") && strcmp("referent", fh.GetName()) == 0) { is_primitive = true; // We lied above, so we have to expect a lie here. } @@ -4093,7 +4081,7 @@ bool ClassLinker::LinkFields(const Handle<mirror::Class>& klass, bool is_static) // Set the bitmap of reference offsets, refOffsets, from the ifields // list. -void ClassLinker::CreateReferenceInstanceOffsets(const Handle<mirror::Class>& klass) { +void ClassLinker::CreateReferenceInstanceOffsets(Handle<mirror::Class> klass) { uint32_t reference_offsets = 0; mirror::Class* super_class = klass->GetSuperClass(); if (super_class != NULL) { @@ -4107,11 +4095,11 @@ void ClassLinker::CreateReferenceInstanceOffsets(const Handle<mirror::Class>& kl CreateReferenceOffsets(klass, false, reference_offsets); } -void ClassLinker::CreateReferenceStaticOffsets(const Handle<mirror::Class>& klass) { +void ClassLinker::CreateReferenceStaticOffsets(Handle<mirror::Class> klass) { CreateReferenceOffsets(klass, true, 0); } -void ClassLinker::CreateReferenceOffsets(const Handle<mirror::Class>& klass, bool is_static, +void ClassLinker::CreateReferenceOffsets(Handle<mirror::Class> klass, bool is_static, uint32_t reference_offsets) { size_t num_reference_fields = is_static ? klass->NumReferenceStaticFieldsDuringLinking() @@ -4144,7 +4132,7 @@ void ClassLinker::CreateReferenceOffsets(const Handle<mirror::Class>& klass, boo } mirror::String* ClassLinker::ResolveString(const DexFile& dex_file, uint32_t string_idx, - const Handle<mirror::DexCache>& dex_cache) { + Handle<mirror::DexCache> dex_cache) { DCHECK(dex_cache.Get() != nullptr); mirror::String* resolved = dex_cache->GetResolvedString(string_idx); if (resolved != NULL) { @@ -4166,8 +4154,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, - const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader) { + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader) { DCHECK(dex_cache.Get() != NULL); mirror::Class* resolved = dex_cache->GetResolvedType(type_idx); if (resolved == NULL) { @@ -4198,16 +4186,15 @@ 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, - const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, - mirror::ArtMethod* referrer, +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, InvokeType type) { DCHECK(dex_cache.Get() != NULL); // Check for hit in the dex cache. mirror::ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx); - if (resolved != NULL && !resolved->IsRuntimeMethod()) { + if (resolved != nullptr && !resolved->IsRuntimeMethod()) { return resolved; } // Fail, get the declaring class. @@ -4282,7 +4269,7 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, } // If we found something, check that it can be accessed by the referrer. - if (resolved != NULL && referrer != NULL) { + if (resolved != NULL && referrer.Get() != NULL) { mirror::Class* methods_class = resolved->GetDeclaringClass(); mirror::Class* referring_class = referrer->GetDeclaringClass(); if (!referring_class->CanAccess(methods_class)) { @@ -4302,11 +4289,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, case kDirect: case kStatic: if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer); + ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer.Get()); } else { resolved = klass->FindInterfaceMethod(name, signature); if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer); + ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer.Get()); } else { ThrowNoSuchMethodError(type, klass, name, signature); } @@ -4314,11 +4301,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, break; case kInterface: if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer); + ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer.Get()); } else { resolved = klass->FindVirtualMethod(name, signature); if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer); + ThrowIncompatibleClassChangeError(type, kVirtual, resolved, referrer.Get()); } else { ThrowNoSuchMethodError(type, klass, name, signature); } @@ -4329,11 +4316,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, break; case kVirtual: if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer); + ThrowIncompatibleClassChangeError(type, kDirect, resolved, referrer.Get()); } else { resolved = klass->FindInterfaceMethod(name, signature); if (resolved != NULL) { - ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer); + ThrowIncompatibleClassChangeError(type, kInterface, resolved, referrer.Get()); } else { ThrowNoSuchMethodError(type, klass, name, signature); } @@ -4346,8 +4333,8 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, } mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t field_idx, - const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader, bool is_static) { DCHECK(dex_cache.Get() != nullptr); mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx); @@ -4389,8 +4376,8 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t fi mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file, uint32_t field_idx, - const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader) { + Handle<mirror::DexCache> dex_cache, + 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 54805be..a8271ed 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, - const Handle<mirror::ClassLoader>& class_loader) + 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, - const Handle<mirror::ClassLoader>& class_loader, + 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, - const Handle<mirror::DexCache>& dex_cache) + 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, - const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader) + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Resolve a method with a given ID from the DexFile, storing the @@ -170,16 +170,21 @@ class ClassLinker { // virtual method. mirror::ArtMethod* ResolveMethod(const DexFile& dex_file, uint32_t method_idx, - const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, - mirror::ArtMethod* referrer, + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader, + Handle<mirror::ArtMethod> referrer, InvokeType type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - mirror::ArtMethod* ResolveMethod(uint32_t method_idx, mirror::ArtMethod* referrer, + 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, 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_); @@ -191,8 +196,8 @@ class ClassLinker { // field. mirror::ArtField* ResolveField(const DexFile& dex_file, uint32_t field_idx, - const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader, + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader, bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -200,10 +205,9 @@ 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, - const Handle<mirror::DexCache>& dex_cache, - const Handle<mirror::ClassLoader>& class_loader) + mirror::ArtField* ResolveFieldJLS(const DexFile& dex_file, uint32_t field_idx, + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Get shorty from method index without resolution. Used to do handlerization. @@ -213,8 +217,7 @@ 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(const Handle<mirror::Class>& c, - bool can_init_fields, bool can_init_parents) + bool EnsureInitialized(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 @@ -224,7 +227,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, const Handle<mirror::DexCache>& dex_cache) + void RegisterDexFile(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) LOCKS_EXCLUDED(dex_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -316,12 +319,12 @@ class ClassLinker { size_t length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void VerifyClass(const Handle<mirror::Class>& klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void VerifyClass(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, - const Handle<mirror::Class>& klass) + 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_); @@ -420,12 +423,12 @@ class ClassLinker { mirror::Class* CreateArrayClass(Thread* self, const char* descriptor, - const Handle<mirror::ClassLoader>& class_loader) + 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, const Handle<mirror::DexCache>& dex_cache) + void AppendToBootClassPath(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, @@ -437,23 +440,23 @@ class ClassLinker { void LoadClass(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def, - const Handle<mirror::Class>& klass, + Handle<mirror::Class> klass, mirror::ClassLoader* class_loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void LoadClassMembers(const DexFile& dex_file, const byte* class_data, - const Handle<mirror::Class>& klass, + 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, - const Handle<mirror::Class>& klass, const Handle<mirror::ArtField>& dst) + Handle<mirror::Class> klass, Handle<mirror::ArtField> dst) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); mirror::ArtMethod* LoadMethod(Thread* self, const DexFile& dex_file, const ClassDataItemIterator& dex_method, - const Handle<mirror::Class>& klass) + Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void FixupStaticTrampolines(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -462,23 +465,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, const Handle<mirror::DexCache>& dex_cache) + void RegisterDexFileLocked(const DexFile& dex_file, 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(const Handle<mirror::Class>& klass, bool can_run_clinit, + bool InitializeClass(Handle<mirror::Class> klass, bool can_run_clinit, bool can_init_parents) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool WaitForInitializeClass(const Handle<mirror::Class>& klass, Thread* self, + bool WaitForInitializeClass(Handle<mirror::Class> klass, Thread* self, ObjectLock<mirror::Class>& lock); - bool ValidateSuperClassDescriptors(const Handle<mirror::Class>& klass) + bool ValidateSuperClassDescriptors(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, @@ -486,43 +489,43 @@ class ClassLinker { mirror::Class* klass2) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkClass(Thread* self, const Handle<mirror::Class>& klass, - const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) + bool LinkClass(Thread* self, Handle<mirror::Class> klass, + Handle<mirror::ObjectArray<mirror::Class>> interfaces) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkSuperClass(const Handle<mirror::Class>& klass) + bool LinkSuperClass(Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LoadSuperAndInterfaces(const Handle<mirror::Class>& klass, const DexFile& dex_file) + bool LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexFile& dex_file) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkMethods(const Handle<mirror::Class>& klass, - const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) + bool LinkMethods(Handle<mirror::Class> klass, + Handle<mirror::ObjectArray<mirror::Class>> interfaces) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkVirtualMethods(const Handle<mirror::Class>& klass) + bool LinkVirtualMethods(Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkInterfaceMethods(const Handle<mirror::Class>& klass, - const Handle<mirror::ObjectArray<mirror::Class>>& interfaces) + bool LinkInterfaceMethods(Handle<mirror::Class> klass, + Handle<mirror::ObjectArray<mirror::Class>> interfaces) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkStaticFields(const Handle<mirror::Class>& klass) + bool LinkStaticFields(Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkInstanceFields(const Handle<mirror::Class>& klass) + bool LinkInstanceFields(Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - bool LinkFields(const Handle<mirror::Class>& klass, bool is_static) + bool LinkFields(Handle<mirror::Class> klass, bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void LinkCode(const Handle<mirror::ArtMethod>& method, const OatFile::OatClass* oat_class, + void LinkCode(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(const Handle<mirror::Class>& klass) + void CreateReferenceInstanceOffsets(Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void CreateReferenceStaticOffsets(const Handle<mirror::Class>& klass) + void CreateReferenceStaticOffsets(Handle<mirror::Class> klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void CreateReferenceOffsets(const Handle<mirror::Class>& klass, bool is_static, + void CreateReferenceOffsets(Handle<mirror::Class> klass, bool is_static, uint32_t reference_offsets) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -551,11 +554,11 @@ class ClassLinker { bool* open_failed) LOCKS_EXCLUDED(dex_lock_); - mirror::ArtMethod* CreateProxyConstructor(Thread* self, const Handle<mirror::Class>& klass, + mirror::ArtMethod* CreateProxyConstructor(Thread* self, Handle<mirror::Class> klass, mirror::Class* proxy_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - mirror::ArtMethod* CreateProxyMethod(Thread* self, const Handle<mirror::Class>& klass, - const Handle<mirror::ArtMethod>& prototype) + mirror::ArtMethod* CreateProxyMethod(Thread* self, Handle<mirror::Class> klass, + 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 d04f02b..c11aecc 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, const Handle<mirror::Class>& array) + void AssertArrayClass(const std::string& array_descriptor, 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, const Handle<mirror::Class>& klass) + void AssertClass(const std::string& descriptor, 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,8 +846,7 @@ 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()); - StackHandleScope<1> hs(soa.Self()); - auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); + NullHandle<mirror::ClassLoader> class_loader; 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 f1795a5..58b4286 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -385,31 +385,36 @@ 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* 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); + 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); + } if (UNLIKELY(resolved_method == nullptr)) { DCHECK(self->IsExceptionPending()); // Throw exception and unwind. return nullptr; // Failure. - } else if (UNLIKELY(handle_scope_this.Get() == nullptr && type != kStatic)) { + } else if (UNLIKELY(*this_object == nullptr && type != kStatic)) { // Maintain interpreter-like semantics where NullPointerException is thrown // after potential NoSuchMethodError from class linker. ThrowLocation throw_location = self->GetCurrentLocationForThrow(); - DCHECK(referrer == throw_location.GetMethod()); + DCHECK_EQ(*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); @@ -423,7 +428,7 @@ static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, case kDirect: return resolved_method; case kVirtual: { - mirror::ObjectArray<mirror::ArtMethod>* vtable = handle_scope_this->GetClass()->GetVTable(); + mirror::ObjectArray<mirror::ArtMethod>* vtable = (*this_object)->GetClass()->GetVTable(); uint16_t vtable_index = resolved_method->GetMethodIndex(); if (access_check && (vtable == nullptr || vtable_index >= static_cast<uint32_t>(vtable->GetLength()))) { @@ -437,7 +442,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) { @@ -460,20 +465,19 @@ 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 = handle_scope_this->GetClass()->GetImTable(); + mirror::ObjectArray<mirror::ArtMethod>* imt_table = (*this_object)->GetClass()->GetImTable(); mirror::ArtMethod* imt_method = imt_table->Get(imt_index); if (!imt_method->IsImtConflictMethod()) { return imt_method; } else { mirror::ArtMethod* interface_method = - handle_scope_this->GetClass()->FindVirtualMethodForInterface(resolved_method); + (*this_object)->GetClass()->FindVirtualMethodForInterface(resolved_method); if (UNLIKELY(interface_method == nullptr)) { ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, - handle_scope_this.Get(), referrer); + *this_object, *referrer); return nullptr; // Failure. - } else { - return interface_method; } + return interface_method; } } default: @@ -486,8 +490,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 3f02ec7..f2e2bf7 100644 --- a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc +++ b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc @@ -25,6 +25,7 @@ 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) { @@ -43,6 +44,8 @@ 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 d34b097..3a898e8 100644 --- a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc +++ b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc @@ -23,17 +23,20 @@ namespace art { template<InvokeType type, bool access_check> mirror::ArtMethod* FindMethodHelper(uint32_t method_idx, mirror::Object* this_object, - mirror::ArtMethod* caller_method, Thread* thread) { + mirror::ArtMethod* caller_method, Thread* self) { mirror::ArtMethod* method = FindMethodFast(method_idx, this_object, caller_method, access_check, type); if (UNLIKELY(method == NULL)) { - method = FindMethodFromCode<type, access_check>(method_idx, this_object, caller_method, thread); + // Note: This can cause thread suspension. + self->AssertThreadSuspensionIsAllowable(); + method = FindMethodFromCode<type, access_check>(method_idx, &this_object, &caller_method, + self); if (UNLIKELY(method == NULL)) { - CHECK(thread->IsExceptionPending()); + CHECK(self->IsExceptionPending()); return 0; // failure } } - DCHECK(!thread->IsExceptionPending()); + DCHECK(!self->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 17c3222..3756f47 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* thread, + Thread* self, mirror::ArtMethod** called_addr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { uint32_t dex_pc; - mirror::ArtMethod* caller = thread->GetCurrentMethod(&dex_pc); + mirror::ArtMethod* caller = self->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(dex_method_idx, caller, invoke_type); + called = linker->ResolveMethod(Thread::Current(), 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(!thread->IsExceptionPending())) { + if (LIKELY(!self->IsExceptionPending())) { // Ensure that the called method's class is initialized. - StackHandleScope<1> hs(Thread::Current()); + StackHandleScope<1> hs(self); 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 ee276c1..2c920de 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -755,11 +755,12 @@ 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 (called->IsRuntimeMethod()) { + if (UNLIKELY(called->IsRuntimeMethod())) { StackHandleScope<1> hs(self); - 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(); + 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); } const void* code = NULL; if (LIKELY(!self->IsExceptionPending())) { @@ -1681,7 +1682,8 @@ 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(); } @@ -1871,7 +1873,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 3127864..c4e9285 100644 --- a/runtime/handle.h +++ b/runtime/handle.h @@ -53,29 +53,43 @@ class Handle { reference_->Assign(reference); return old; } - jobject ToJObject() const ALWAYS_INLINE { + 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; + } return reinterpret_cast<jobject>(reference_); } - private: + protected: 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 478c74c..f77a0f6 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -524,16 +524,17 @@ extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh ArtMethod* method = shadow_frame->GetMethod(); // Ensure static methods are initialized. if (method->IsStatic()) { - 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()); + 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()); self->PopShadowFrame(); return; } - CHECK(declaringClass->IsInitializing()); + CHECK(h_declaring_class->IsInitializing()); } } diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 418aff5..63ae6fd 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -296,11 +296,9 @@ 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(); - auto class_loader = hs.NewHandle<ClassLoader>(nullptr); - Class* found = Runtime::Current()->GetClassLinker()->FindClass(self, descriptor.c_str(), - class_loader); + Class* found = Runtime::Current()->GetClassLinker()->FindClass( + self, descriptor.c_str(), NullHandle<mirror::ClassLoader>()); 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 b42af11..cfc90a6 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -29,6 +29,7 @@ #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" @@ -112,9 +113,10 @@ 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); - ArtMethod* const method = FindMethodFromCode<type, do_access_check>(method_idx, receiver, - shadow_frame.GetMethod(), - self); + 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. if (UNLIKELY(method == nullptr)) { CHECK(self->IsExceptionPending()); result->SetJ(0); @@ -348,6 +350,10 @@ 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. @@ -372,7 +378,8 @@ 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 6f3317d..b51e1d5 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, - const Handle<mirror::ClassLoader>& class_loader, + Handle<mirror::ClassLoader> class_loader, std::string* detail) { detail->clear(); diff --git a/runtime/jni_internal.h b/runtime/jni_internal.h index 37195eb..7e76e11 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, const Handle<mirror::ClassLoader>& class_loader, + bool LoadNativeLibrary(const std::string& path, 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 552652c..1076643 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, - const Handle<Class>& array_class, int current_dimension, - const Handle<mirror::IntArray>& dimensions) + Handle<Class> array_class, int current_dimension, + 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, const Handle<Class>& element_class, - const Handle<IntArray>& dimensions) { +Array* Array::CreateMultiArray(Thread* self, Handle<Class> element_class, + 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 1b8106e..64e2317 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, const Handle<Class>& element_class, - const Handle<IntArray>& dimensions) + static Array* CreateMultiArray(Thread* self, Handle<Class> element_class, + 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 af544fd..e2d3f41 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 34fe0bf..2e8253f 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 d8591cc..b1de2b6 100644 --- a/runtime/mirror/stack_trace_element.cc +++ b/runtime/mirror/stack_trace_element.cc @@ -39,10 +39,8 @@ 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)); @@ -57,8 +55,8 @@ StackTraceElement* StackTraceElement::Alloc(Thread* self, } 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 22d9b71..e094e8b 100644 --- a/runtime/mirror/stack_trace_element.h +++ b/runtime/mirror/stack_trace_element.h @@ -46,10 +46,8 @@ 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_); @@ -70,8 +68,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 ee719b4..1d79106 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, const Handle<CharArray>& array) { +String* String::Alloc(Thread* self, 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 169b671..6c3015f 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, const Handle<CharArray>& array) + static String* Alloc(Thread* self, 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 f783edb..fe1ef6c 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 bc1b2ed4..007f54d 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 d9c9b59..d55b545 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,8 +267,7 @@ 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); @@ -296,8 +295,7 @@ static void PreloadDexCachesResolveField(Handle<mirror::DexCache>& dex_cache, } // 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 4863b83..2293ad7 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,7 +151,8 @@ 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, NULL, type); + linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, + NullHandle<mirror::ArtMethod>(), type); if (method == NULL) { DCHECK(Thread::Current()->IsExceptionPending()); // We couldn't resolve the method, but continue regardless. @@ -193,7 +194,8 @@ 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, NULL, type); + linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, + NullHandle<mirror::ArtMethod>(), type); if (method == NULL) { DCHECK(Thread::Current()->IsExceptionPending()); // We couldn't resolve the method, but continue regardless. @@ -232,8 +234,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, @@ -277,8 +279,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 495d3c5..f614425 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, |