From 302f69cf7172d057c3ad9a8d4125a38e9dab8a71 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Tue, 25 Jul 2017 15:27:15 +0100 Subject: Fix race in artInvokeInterfaceTrampoline(). When artInvokeInterfaceTrampoline() didn't get a resolved interface method, it was calling FindMethodFromCode<>() where the interface method was resolved and then a virtual method for it was looked up. It then tried to retrieve the interface method from the DexCache where it would usualy be found as it was just stored there by the method resolution. However, another thread could have just evicted that entry. Instead of adding another call to LookupResolvedMethod(), use the fact that artInvokeInterfaceTrampoline() already explicitly inlines all the FindMethodFromCode<>() except for the interface method resolution, so we can simply do the resolution and then take the existing path for the rest of the work. Test: m test-art-host-gtest Test: testrunner.py --host Bug: 30627598 Change-Id: I62ca9c4e108ab6a3ee700b55d3b19c8f0f63f1d2 --- runtime/entrypoints/entrypoint_utils-inl.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'runtime/entrypoints/entrypoint_utils-inl.h') diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index a6c5d6c7aa..be3e4f811a 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -476,7 +476,7 @@ inline ArtMethod* FindMethodFromCode(uint32_t method_idx, case kDirect: return resolved_method; case kVirtual: { - mirror::Class* klass = (*this_object)->GetClass(); + ObjPtr klass = (*this_object)->GetClass(); uint16_t vtable_index = resolved_method->GetMethodIndex(); if (access_check && (!klass->HasVTable() || @@ -509,7 +509,7 @@ inline ArtMethod* FindMethodFromCode(uint32_t method_idx, // It is not an interface. If the referring class is in the class hierarchy of the // referenced class in the bytecode, we use its super class. Otherwise, we throw // a NoSuchMethodError. - mirror::Class* super_class = nullptr; + ObjPtr super_class = nullptr; if (method_reference_class->IsAssignableFrom(h_referring_class.Get())) { super_class = h_referring_class->GetSuperClass(); } @@ -554,11 +554,10 @@ inline ArtMethod* FindMethodFromCode(uint32_t method_idx, case kInterface: { uint32_t imt_index = ImTable::GetImtIndex(resolved_method); PointerSize pointer_size = class_linker->GetImagePointerSize(); - ArtMethod* imt_method = (*this_object)->GetClass()->GetImt(pointer_size)-> - Get(imt_index, pointer_size); + ObjPtr klass = (*this_object)->GetClass(); + ArtMethod* imt_method = klass->GetImt(pointer_size)->Get(imt_index, pointer_size); if (!imt_method->IsRuntimeMethod()) { if (kIsDebugBuild) { - mirror::Class* klass = (*this_object)->GetClass(); ArtMethod* method = klass->FindVirtualMethodForInterface( resolved_method, class_linker->GetImagePointerSize()); CHECK_EQ(imt_method, method) << ArtMethod::PrettyMethod(resolved_method) << " / " @@ -568,7 +567,7 @@ inline ArtMethod* FindMethodFromCode(uint32_t method_idx, } return imt_method; } else { - ArtMethod* interface_method = (*this_object)->GetClass()->FindVirtualMethodForInterface( + ArtMethod* interface_method = klass->FindVirtualMethodForInterface( resolved_method, class_linker->GetImagePointerSize()); if (UNLIKELY(interface_method == nullptr)) { ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, -- cgit v1.2.3-59-g8ed1b