diff options
author | 2023-01-06 12:06:13 +0000 | |
---|---|---|
committer | 2023-01-16 12:14:00 +0000 | |
commit | ae12f96965dd1fb1cf5fefb0188b749e921ba88b (patch) | |
tree | 802eb68fb823189f39cb1d7e57ed9e035568f4b9 | |
parent | e52e4fb74e9f13009af4ffbfb2e5103ce035a94b (diff) |
Refactor code aroud method resolution.
- Make unresolved AOT entrypoints use the tls cache
- Remove duplicate code
- Inline method access checks logic in its only use.
- Fix in ClassLinker::ResolveMethodWithoutInvokeType() by calling shared
helper.
Test: test.py
Change-Id: I1f42b5d0ac1dcd9c5eb483db9c5c5eefc9b2f4d1
-rw-r--r-- | runtime/class_linker-inl.h | 182 | ||||
-rw-r--r-- | runtime/class_linker.cc | 14 | ||||
-rw-r--r-- | runtime/class_linker.h | 5 | ||||
-rw-r--r-- | runtime/entrypoints/entrypoint_utils-inl.h | 4 | ||||
-rw-r--r-- | runtime/entrypoints/entrypoint_utils.h | 1 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 87 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.h | 3 | ||||
-rw-r--r-- | runtime/mirror/class-inl.h | 57 | ||||
-rw-r--r-- | runtime/mirror/class.h | 23 |
9 files changed, 74 insertions, 302 deletions
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index 8f3692dd39..8b6d45da39 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -305,129 +305,32 @@ inline ArtMethod* ClassLinker::LookupResolvedMethod(uint32_t method_idx, return resolved; } -template <InvokeType type, ClassLinker::ResolveMode kResolveMode> -inline ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx, ArtMethod* referrer) { - DCHECK(referrer != nullptr); - // Note: The referrer can be a Proxy constructor. In that case, we need to do the - // lookup in the context of the original method from where it steals the code. - // However, we delay the GetInterfaceMethodIfProxy() until needed. - DCHECK_IMPLIES(referrer->IsProxyMethod(), referrer->IsConstructor()); - // We do not need the read barrier for getting the DexCache for the initial resolved method - // lookup as both from-space and to-space copies point to the same native resolved methods array. - ArtMethod* resolved_method = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedMethod( - method_idx); - if (resolved_method == nullptr) { - return nullptr; - } - DCHECK(!resolved_method->IsRuntimeMethod()); - if (kResolveMode == ResolveMode::kCheckICCEAndIAE) { - referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_); - // Check if the invoke type matches the class type. - ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache(); - ObjPtr<mirror::ClassLoader> class_loader = referrer->GetClassLoader(); - const dex::MethodId& method_id = referrer->GetDexFile()->GetMethodId(method_idx); - ObjPtr<mirror::Class> cls = LookupResolvedType(method_id.class_idx_, dex_cache, class_loader); - if (cls == nullptr) { - // The verifier breaks the invariant that a resolved method must have its - // class in the class table. Because this method should only lookup and not - // resolve class, return null. The caller is responsible for calling - // `ResolveMethod` afterwards. - // b/73760543 - return nullptr; - } - if (CheckInvokeClassMismatch</* kThrow= */ false>(dex_cache, type, method_idx, class_loader)) { - return nullptr; - } - // Check access. - ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass(); - if (!referring_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(), - resolved_method, - dex_cache, - method_idx)) { - return nullptr; - } - // Check if the invoke type matches the method type. - if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) { - return nullptr; - } - } - return resolved_method; -} - template <ClassLinker::ResolveMode kResolveMode> inline ArtMethod* ClassLinker::ResolveMethod(Thread* self, uint32_t method_idx, ArtMethod* referrer, InvokeType type) { DCHECK(referrer != nullptr); - // Note: The referrer can be a Proxy constructor. In that case, we need to do the - // lookup in the context of the original method from where it steals the code. - // However, we delay the GetInterfaceMethodIfProxy() until needed. DCHECK_IMPLIES(referrer->IsProxyMethod(), referrer->IsConstructor()); + Thread::PoisonObjectPointersIfDebug(); - // We do not need the read barrier for getting the DexCache for the initial resolved method - // lookup as both from-space and to-space copies point to the same native resolved methods array. - ArtMethod* resolved_method = referrer->GetDexCache<kWithoutReadBarrier>()->GetResolvedMethod( - method_idx); - DCHECK(resolved_method == nullptr || !resolved_method->IsRuntimeMethod()); - if (UNLIKELY(resolved_method == nullptr)) { - referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_); - ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass(); - StackHandleScope<2> hs(self); - Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer->GetDexCache())); - Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader())); - resolved_method = ResolveMethod<kResolveMode>(method_idx, - h_dex_cache, - h_class_loader, - referrer, - type); - } else if (kResolveMode == ResolveMode::kCheckICCEAndIAE) { - referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_); - const dex::MethodId& method_id = referrer->GetDexFile()->GetMethodId(method_idx); - ObjPtr<mirror::Class> cls = - LookupResolvedType(method_id.class_idx_, - referrer->GetDexCache(), - referrer->GetClassLoader()); - if (cls == nullptr) { - // The verifier breaks the invariant that a resolved method must have its - // class in the class table, so resolve the type in case we haven't found it. - // b/73760543 - StackHandleScope<2> hs(Thread::Current()); - Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer->GetDexCache())); - Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(referrer->GetClassLoader())); - cls = ResolveType(method_id.class_idx_, h_dex_cache, h_class_loader); - if (hs.Self()->IsExceptionPending()) { - return nullptr; - } - } - // Check if the invoke type matches the class type. - if (CheckInvokeClassMismatch</* kThrow= */ true>( - referrer->GetDexCache(), type, [cls]() { return cls; })) { - DCHECK(Thread::Current()->IsExceptionPending()); - return nullptr; - } - // Check access. - ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass(); - if (!referring_class->CheckResolvedMethodAccess(resolved_method->GetDeclaringClass(), - resolved_method, - referrer->GetDexCache(), - method_idx, - type)) { - DCHECK(Thread::Current()->IsExceptionPending()); - return nullptr; - } - // Check if the invoke type matches the method type. - if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) { - ThrowIncompatibleClassChangeError(type, - resolved_method->GetInvokeType(), - resolved_method, - referrer); - return nullptr; + // Fast path: no checks and in the dex cache. + if (kResolveMode == ResolveMode::kNoChecks) { + ArtMethod* resolved_method = referrer->GetDexCache()->GetResolvedMethod(method_idx); + if (resolved_method != nullptr) { + DCHECK(!resolved_method->IsRuntimeMethod()); + return resolved_method; } } - // Note: We cannot check here to see whether we added the method to the cache. It - // might be an erroneous class, which results in it being hidden from us. - return resolved_method; + + // For a Proxy constructor, we need to do the lookup in the context of the original method + // from where it steals the code. + referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_); + StackHandleScope<2> hs(self); + Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache())); + Handle<mirror::ClassLoader> class_loader( + hs.NewHandle(referrer->GetDeclaringClass()->GetClassLoader())); + return ResolveMethod<kResolveMode>(method_idx, dex_cache, class_loader, referrer, type); } template <ClassLinker::ResolveMode kResolveMode> @@ -436,10 +339,11 @@ inline ArtMethod* ClassLinker::ResolveMethod(uint32_t method_idx, Handle<mirror::ClassLoader> class_loader, ArtMethod* referrer, InvokeType type) { + DCHECK(dex_cache != nullptr); DCHECK(dex_cache->GetClassLoader() == class_loader.Get()); DCHECK(!Thread::Current()->IsExceptionPending()) << Thread::Current()->GetException()->Dump(); - DCHECK(dex_cache != nullptr); DCHECK(referrer == nullptr || !referrer->IsProxyMethod()); + // Check for hit in the dex cache. ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx); Thread::PoisonObjectPointersIfDebug(); @@ -499,12 +403,20 @@ inline ArtMethod* ClassLinker::ResolveMethod(uint32_t method_idx, if (kResolveMode == ResolveMode::kCheckICCEAndIAE && resolved != nullptr && referrer != nullptr) { ObjPtr<mirror::Class> methods_class = resolved->GetDeclaringClass(); ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass(); - if (!referring_class->CheckResolvedMethodAccess(methods_class, - resolved, - dex_cache.Get(), - method_idx, - type)) { - DCHECK(Thread::Current()->IsExceptionPending()); + if (UNLIKELY(!referring_class->CanAccess(methods_class))) { + // The referrer class can't access the method's declaring class but may still be able + // to access the method if the MethodId specifies an accessible subclass of the declaring + // class rather than the declaring class itself. + if (UNLIKELY(!referring_class->CanAccess(klass))) { + ThrowIllegalAccessErrorClassForMethodDispatch(referring_class, + klass, + resolved, + type); + return nullptr; + } + } + if (UNLIKELY(!referring_class->CanAccessMember(methods_class, resolved->GetAccessFlags()))) { + ThrowIllegalAccessErrorMethod(referring_class, resolved); return nullptr; } } @@ -514,23 +426,23 @@ inline ArtMethod* ClassLinker::ResolveMethod(uint32_t method_idx, LIKELY(kResolveMode == ResolveMode::kNoChecks || !resolved->CheckIncompatibleClassChange(type))) { return resolved; + } + + // If we had a method, or if we can find one with another lookup type, + // it's an incompatible-class-change error. + if (resolved == nullptr) { + resolved = FindIncompatibleMethod(klass, dex_cache.Get(), class_loader.Get(), method_idx); + } + if (resolved != nullptr) { + ThrowIncompatibleClassChangeError(type, resolved->GetInvokeType(), resolved, referrer); } else { - // If we had a method, or if we can find one with another lookup type, - // it's an incompatible-class-change error. - if (resolved == nullptr) { - resolved = FindIncompatibleMethod(klass, dex_cache.Get(), class_loader.Get(), method_idx); - } - if (resolved != nullptr) { - ThrowIncompatibleClassChangeError(type, resolved->GetInvokeType(), resolved, referrer); - } else { - // We failed to find the method (using all lookup types), so throw a NoSuchMethodError. - const char* name = dex_file.StringDataByIdx(method_id.name_idx_); - const Signature signature = dex_file.GetMethodSignature(method_id); - ThrowNoSuchMethodError(type, klass, name, signature); - } - Thread::Current()->AssertPendingException(); - return nullptr; + // We failed to find the method (using all lookup types), so throw a NoSuchMethodError. + const char* name = dex_file.StringDataByIdx(method_id.name_idx_); + const Signature signature = dex_file.GetMethodSignature(method_id); + ThrowNoSuchMethodError(type, klass, name, signature); } + Thread::Current()->AssertPendingException(); + return nullptr; } inline ArtField* ClassLinker::LookupResolvedField(uint32_t field_idx, diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index e109a505b6..8082d46e25 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -9471,19 +9471,7 @@ ArtMethod* ClassLinker::ResolveMethodWithoutInvokeType(uint32_t method_idx, Thread::Current()->AssertPendingException(); return nullptr; } - if (klass->IsInterface()) { - resolved = klass->FindInterfaceMethod(dex_cache.Get(), method_idx, image_pointer_size_); - } else { - resolved = klass->FindClassMethod(dex_cache.Get(), method_idx, image_pointer_size_); - } - if (resolved != nullptr && - hiddenapi::ShouldDenyAccessToMember( - resolved, - hiddenapi::AccessContext(class_loader.Get(), dex_cache.Get()), - hiddenapi::AccessMethod::kLinking)) { - resolved = nullptr; - } - return resolved; + return FindResolvedMethod(klass, dex_cache.Get(), class_loader.Get(), method_idx); } ArtField* ClassLinker::LookupResolvedField(uint32_t field_idx, diff --git a/runtime/class_linker.h b/runtime/class_linker.h index b7a05ee404..9a57bd4658 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -367,14 +367,11 @@ class ClassLinker { REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); - template <InvokeType type, ResolveMode kResolveMode> - ArtMethod* GetResolvedMethod(uint32_t method_idx, ArtMethod* referrer) - REQUIRES_SHARED(Locks::mutator_lock_); - template <ResolveMode kResolveMode> ArtMethod* ResolveMethod(Thread* self, uint32_t method_idx, ArtMethod* referrer, InvokeType type) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_); + ArtMethod* ResolveMethodWithoutInvokeType(uint32_t method_idx, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader) diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 91163f4139..cbe754337c 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -519,6 +519,7 @@ ArtMethod* FindMethodToCall(Thread* self, ArtMethod* caller, ObjPtr<mirror::Object>* this_object, const Instruction& inst, + bool only_lookup_tls_cache, /*out*/ bool* string_init) REQUIRES_SHARED(Locks::mutator_lock_) { PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); @@ -526,6 +527,9 @@ ArtMethod* FindMethodToCall(Thread* self, // Try to find the method in thread-local cache. size_t tls_value = 0u; if (!self->GetInterpreterCache()->Get(self, &inst, &tls_value)) { + if (only_lookup_tls_cache) { + return nullptr; + } DCHECK(!self->IsExceptionPending()); // NterpGetMethod can suspend, so save this_object. StackHandleScope<1> hs(self); diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index 777fd9880d..a69b055c1f 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -148,6 +148,7 @@ inline ArtMethod* FindMethodToCall(Thread* self, ArtMethod* referrer, ObjPtr<mirror::Object>* this_object, const Instruction& inst, + bool only_lookup_tls_cache, /*out*/ bool* string_init) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 559662cf9a..4960f387b1 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -2079,68 +2079,6 @@ extern "C" uint64_t artQuickGenericJniEndTrampoline(Thread* self, return GenericJniMethodEnd(self, cookie, result, result_f, called); } -// Fast path method resolution that can't throw exceptions. -template <InvokeType type> -inline ArtMethod* FindMethodFast(uint32_t method_idx, - ObjPtr<mirror::Object> this_object, - ArtMethod* referrer) - REQUIRES_SHARED(Locks::mutator_lock_) - REQUIRES(!Roles::uninterruptible_) { - ScopedAssertNoThreadSuspension ants(__FUNCTION__); - if (UNLIKELY(this_object == nullptr && type != kStatic)) { - return nullptr; - } - ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass(); - ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache(); - constexpr ClassLinker::ResolveMode resolve_mode = ClassLinker::ResolveMode::kCheckICCEAndIAE; - ClassLinker* linker = Runtime::Current()->GetClassLinker(); - ArtMethod* resolved_method = linker->GetResolvedMethod<type, resolve_mode>(method_idx, referrer); - if (UNLIKELY(resolved_method == nullptr)) { - return nullptr; - } - if (type == kInterface) { // Most common form of slow path dispatch. - return this_object->GetClass()->FindVirtualMethodForInterface(resolved_method, - kRuntimePointerSize); - } - if (type == kStatic || type == kDirect) { - return resolved_method; - } - - if (type == kSuper) { - // TODO This lookup is rather slow. - dex::TypeIndex method_type_idx = dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_; - ObjPtr<mirror::Class> method_reference_class = linker->LookupResolvedType( - method_type_idx, dex_cache, referrer->GetClassLoader()); - if (method_reference_class == nullptr) { - // Need to do full type resolution... - return nullptr; - } - - // If the referring class is in the class hierarchy of the - // referenced class in the bytecode, we use its super class. Otherwise, we cannot - // resolve the method. - if (!method_reference_class->IsAssignableFrom(referring_class)) { - return nullptr; - } - - if (method_reference_class->IsInterface()) { - return method_reference_class->FindVirtualMethodForInterfaceSuper( - resolved_method, kRuntimePointerSize); - } - - ObjPtr<mirror::Class> super_class = referring_class->GetSuperClass(); - if (resolved_method->GetMethodIndex() >= super_class->GetVTableLength()) { - // The super class does not have the method. - return nullptr; - } - return super_class->GetVTableEntry(resolved_method->GetMethodIndex(), kRuntimePointerSize); - } - - DCHECK(type == kVirtual); - return this_object->GetClass()->GetVTableEntry( - resolved_method->GetMethodIndex(), kRuntimePointerSize); -} - // We use TwoWordReturn to optimize scalar returns. We use the hi value for code, and the lo value // for the method pointer. // @@ -2155,8 +2093,19 @@ static TwoWordReturn artInvokeCommon(uint32_t method_idx, ScopedQuickEntrypointChecks sqec(self); DCHECK_EQ(*sp, Runtime::Current()->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs)); ArtMethod* caller_method = QuickArgumentVisitor::GetCallingMethod(sp); - ArtMethod* method = FindMethodFast<type>(method_idx, this_object, caller_method); + uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp); + CodeItemInstructionAccessor accessor(caller_method->DexInstructions()); + DCHECK_LT(dex_pc, accessor.InsnsSizeInCodeUnits()); + const Instruction& instr = accessor.InstructionAt(dex_pc); + bool string_init = false; + ArtMethod* method = FindMethodToCall<type>( + self, caller_method, &this_object, instr, /* only_lookup_tls_cache= */ true, &string_init); + if (UNLIKELY(method == nullptr)) { + if (self->IsExceptionPending()) { + // Return a failure if the first lookup threw an exception. + return GetTwoWordFailureValue(); // Failure. + } const DexFile* dex_file = caller_method->GetDexFile(); uint32_t shorty_len; const char* shorty = dex_file->GetMethodShorty(dex_file->GetMethodId(method_idx), &shorty_len); @@ -2166,12 +2115,12 @@ static TwoWordReturn artInvokeCommon(uint32_t method_idx, RememberForGcArgumentVisitor visitor(sp, type == kStatic, shorty, shorty_len, &soa); visitor.VisitArguments(); - uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp); - CodeItemInstructionAccessor accessor(caller_method->DexInstructions()); - CHECK_LT(dex_pc, accessor.InsnsSizeInCodeUnits()); - const Instruction& instr = accessor.InstructionAt(dex_pc); - bool string_init = false; - method = FindMethodToCall<type>(self, caller_method, &this_object, instr, &string_init); + method = FindMethodToCall<type>(self, + caller_method, + &this_object, + instr, + /* only_lookup_tls_cache= */ false, + &string_init); visitor.FixupReferences(); } diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 64d4d719e8..35e329c7e9 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -239,7 +239,8 @@ static ALWAYS_INLINE bool DoInvoke(Thread* self, ObjPtr<mirror::Object> obj = type == kStatic ? nullptr : shadow_frame.GetVRegReference(vregC); ArtMethod* sf_method = shadow_frame.GetMethod(); bool string_init = false; - ArtMethod* called_method = FindMethodToCall<type>(self, sf_method, &obj, *inst, &string_init); + ArtMethod* called_method = FindMethodToCall<type>( + self, sf_method, &obj, *inst, /* only_lookup_tls_cache= */ false, &string_init); if (called_method == nullptr) { DCHECK(self->IsExceptionPending()); result->SetJ(0); diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index 77f78c5156..b6b1415b09 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -498,47 +498,6 @@ inline bool Class::ResolvedFieldAccessTest(ObjPtr<Class> access_to, return false; } -template <bool throw_on_failure> -inline bool Class::ResolvedMethodAccessTest(ObjPtr<Class> access_to, - ArtMethod* method, - ObjPtr<DexCache> dex_cache, - uint32_t method_idx, - InvokeType throw_invoke_type) { - DCHECK(throw_on_failure || throw_invoke_type == kStatic); - DCHECK(dex_cache != nullptr); - if (UNLIKELY(!this->CanAccess(access_to))) { - // The referrer class can't access the method's declaring class but may still be able - // to access the method if the MethodId specifies an accessible subclass of the declaring - // class rather than the declaring class itself. - dex::TypeIndex class_idx = dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_; - // The referenced class has already been resolved with the method, but may not be in the dex - // cache. - ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType( - class_idx, - dex_cache, - GetClassLoader()); - DCHECK(dex_access_to != nullptr) - << " Could not resolve " << dex_cache->GetDexFile()->StringByTypeIdx(class_idx) - << " when checking access to " << method->PrettyMethod() << " from " << PrettyDescriptor(); - if (UNLIKELY(!this->CanAccess(dex_access_to))) { - if (throw_on_failure) { - ThrowIllegalAccessErrorClassForMethodDispatch(this, - dex_access_to, - method, - throw_invoke_type); - } - return false; - } - } - if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) { - return true; - } - if (throw_on_failure) { - ThrowIllegalAccessErrorMethod(this, method); - } - return false; -} - inline bool Class::CanAccessResolvedField(ObjPtr<Class> access_to, ArtField* field, ObjPtr<DexCache> dex_cache, @@ -553,22 +512,6 @@ inline bool Class::CheckResolvedFieldAccess(ObjPtr<Class> access_to, return ResolvedFieldAccessTest<true>(access_to, field, dex_cache, field_idx); } -inline bool Class::CanAccessResolvedMethod(ObjPtr<Class> access_to, - ArtMethod* method, - ObjPtr<DexCache> dex_cache, - uint32_t method_idx) { - return ResolvedMethodAccessTest<false>(access_to, method, dex_cache, method_idx, kStatic); -} - -inline bool Class::CheckResolvedMethodAccess(ObjPtr<Class> access_to, - ArtMethod* method, - ObjPtr<DexCache> dex_cache, - uint32_t method_idx, - InvokeType throw_invoke_type) { - return ResolvedMethodAccessTest<true>( - access_to, method, dex_cache, method_idx, throw_invoke_type); -} - inline bool Class::IsObsoleteVersionOf(ObjPtr<Class> klass) { DCHECK(!klass->IsObsoleteObject()) << klass->PrettyClass() << " is obsolete!"; if (LIKELY(!IsObsoleteObject())) { diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index 67b95596b2..ca13462da8 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -638,21 +638,6 @@ class MANAGED Class final : public Object { uint32_t field_idx) REQUIRES_SHARED(Locks::mutator_lock_); - // Can this class access a resolved method? - // Note that access to methods's class is checked and this may require looking up the class - // referenced by the MethodId in the DexFile in case the declaring class is inaccessible. - bool CanAccessResolvedMethod(ObjPtr<Class> access_to, - ArtMethod* resolved_method, - ObjPtr<DexCache> dex_cache, - uint32_t method_idx) - REQUIRES_SHARED(Locks::mutator_lock_); - bool CheckResolvedMethodAccess(ObjPtr<Class> access_to, - ArtMethod* resolved_method, - ObjPtr<DexCache> dex_cache, - uint32_t method_idx, - InvokeType throw_invoke_type) - REQUIRES_SHARED(Locks::mutator_lock_); - bool IsSubClass(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); // Can src be assigned to this class? For example, String can be assigned to Object (by an @@ -1391,14 +1376,6 @@ class MANAGED Class final : public Object { uint32_t field_idx) REQUIRES_SHARED(Locks::mutator_lock_); - template <bool throw_on_failure> - bool ResolvedMethodAccessTest(ObjPtr<Class> access_to, - ArtMethod* resolved_method, - ObjPtr<DexCache> dex_cache, - uint32_t method_idx, - InvokeType throw_invoke_type) - REQUIRES_SHARED(Locks::mutator_lock_); - bool IsArrayAssignableFromArray(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); bool IsAssignableFromArray(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); |