diff options
| author | 2012-02-14 12:29:06 -0800 | |
|---|---|---|
| committer | 2012-02-14 14:39:26 -0800 | |
| commit | 16f93671923979733cb46fc6f053c8f65754d5eb (patch) | |
| tree | 1bcb06e29786c5c93e0dc588b4ad6e8e94de0034 | |
| parent | b305770f45e9cec66c3bdf792c4e7fa9cff5ec6e (diff) | |
Remove dexCacheResolvedMethods, address Proxy issue
Change-Id: Iab8c7edb954d241bd5a92260db07696b9559155f
| -rw-r--r-- | src/class_linker.cc | 27 | ||||
| -rw-r--r-- | src/class_linker.h | 7 | ||||
| -rw-r--r-- | src/class_linker_test.cc | 4 | ||||
| -rw-r--r-- | src/java_lang_reflect_Method.cc | 6 | ||||
| -rw-r--r-- | src/object.cc | 38 | ||||
| -rw-r--r-- | src/object.h | 10 | ||||
| -rw-r--r-- | src/object_utils.h | 2 | ||||
| -rw-r--r-- | src/runtime_support.cc | 1 |
8 files changed, 52 insertions, 43 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index bc8e333f43..60bd6147f9 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -1515,7 +1515,6 @@ void ClassLinker::LoadMethod(const DexFile& dex_file, const ClassDataItemIterato dst->SetDexCacheStrings(klass->GetDexCache()->GetStrings()); dst->SetDexCacheResolvedTypes(klass->GetDexCache()->GetResolvedTypes()); - dst->SetDexCacheResolvedMethods(klass->GetDexCache()->GetResolvedMethods()); dst->SetDexCacheCodeAndDirectMethods(klass->GetDexCache()->GetCodeAndDirectMethods()); dst->SetDexCacheInitializedStaticStorage(klass->GetDexCache()->GetInitializedStaticStorage()); } @@ -2140,6 +2139,28 @@ std::string ClassLinker::GetDescriptorForProxy(const Class* proxy_class) { return DotToDescriptor(name->ToModifiedUtf8().c_str()); } +Method* ClassLinker::FindMethodForProxy(const Class* proxy_class, const Method* proxy_method) { + DCHECK(proxy_class->IsProxyClass()); + DCHECK(proxy_method->IsProxyMethod()); + // Locate the dex cache of the original interface/Object + DexCache* dex_cache = NULL; + { + ObjectArray<Class>* resolved_types = proxy_method->GetDexCacheResolvedTypes(); + MutexLock mu(dex_lock_); + for (size_t i = 0; i != dex_caches_.size(); ++i) { + if (dex_caches_[i]->GetResolvedTypes() == resolved_types) { + dex_cache = dex_caches_[i]; + break; + } + } + } + CHECK(dex_cache != NULL); + uint32_t method_idx = proxy_method->GetDexMethodIndex(); + Method* resolved_method = dex_cache->GetResolvedMethod(method_idx); + CHECK(resolved_method != NULL); + return resolved_method; +} + Method* ClassLinker::CreateProxyConstructor(SirtRef<Class>& klass, Class* proxy_class) { // Create constructor for Proxy that must initialize h @@ -2166,7 +2187,8 @@ static void CheckProxyConstructor(Method* constructor) { Method* ClassLinker::CreateProxyMethod(SirtRef<Class>& klass, SirtRef<Method>& prototype) { // Ensure prototype is in dex cache so that we can use the dex cache to look up the overridden // prototype method - prototype->GetDexCacheResolvedMethods()->Set(prototype->GetDexMethodIndex(), prototype.get()); + prototype->GetDeclaringClass()->GetDexCache()->SetResolvedMethod(prototype->GetDexMethodIndex(), + prototype.get()); // We steal everything from the prototype (such as DexCache, invoke stub, etc.) then specialize // as necessary Method* method = down_cast<Method*>(prototype->Clone()); @@ -2183,6 +2205,7 @@ Method* ClassLinker::CreateProxyMethod(SirtRef<Class>& klass, SirtRef<Method>& p method->SetFpSpillMask(refs_and_args->GetFpSpillMask()); method->SetFrameSizeInBytes(refs_and_args->GetFrameSizeInBytes()); method->SetCode(reinterpret_cast<void*>(art_proxy_invoke_handler)); + return method; } diff --git a/src/class_linker.h b/src/class_linker.h index 0b165334cf..f6b7c159fc 100644 --- a/src/class_linker.h +++ b/src/class_linker.h @@ -158,10 +158,10 @@ class ClassLinker { bool is_direct); Method* ResolveMethod(uint32_t method_idx, const Method* referrer, bool is_direct) { - Method* resolved_method = referrer->GetDexCacheResolvedMethods()->Get(method_idx); + Class* declaring_class = referrer->GetDeclaringClass(); + DexCache* dex_cache = declaring_class->GetDexCache(); + Method* resolved_method = dex_cache->GetResolvedMethod(method_idx); if (UNLIKELY(resolved_method == NULL)) { - Class* declaring_class = referrer->GetDeclaringClass(); - DexCache* dex_cache = declaring_class->GetDexCache(); const ClassLoader* class_loader = declaring_class->GetClassLoader(); const DexFile& dex_file = FindDexFile(dex_cache); resolved_method = ResolveMethod(dex_file, method_idx, dex_cache, class_loader, is_direct); @@ -282,6 +282,7 @@ class ClassLinker { Class* CreateProxyClass(String* name, ObjectArray<Class>* interfaces, ClassLoader* loader, ObjectArray<Method>* methods, ObjectArray<ObjectArray<Class> >* throws); std::string GetDescriptorForProxy(const Class* proxy_class); + Method* FindMethodForProxy(const Class* proxy_class, const Method* proxy_method); pid_t GetClassesLockOwner(); // For SignalCatcher. pid_t GetDexLockOwner(); // For SignalCatcher. diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc index e9a94a9bba..9f63c5e3f2 100644 --- a/src/class_linker_test.cc +++ b/src/class_linker_test.cc @@ -139,15 +139,12 @@ class ClassLinkerTest : public CommonTest { EXPECT_TRUE(method->GetDexCacheStrings() != NULL); EXPECT_TRUE(method->GetDexCacheResolvedTypes() != NULL); - EXPECT_TRUE(method->GetDexCacheResolvedMethods() != NULL); EXPECT_TRUE(method->GetDexCacheCodeAndDirectMethods() != NULL); EXPECT_TRUE(method->GetDexCacheInitializedStaticStorage() != NULL); EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetStrings(), method->GetDexCacheStrings()); EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetResolvedTypes(), method->GetDexCacheResolvedTypes()); - EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetResolvedMethods(), - method->GetDexCacheResolvedMethods()); EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetCodeAndDirectMethods(), method->GetDexCacheCodeAndDirectMethods()); EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetInitializedStaticStorage(), @@ -446,7 +443,6 @@ struct MethodOffsets : public CheckOffsets<Method> { offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, declaring_class_), "declaringClass")); offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_code_and_direct_methods_), "dexCacheCodeAndDirectMethods")); offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_initialized_static_storage_), "dexCacheInitializedStaticStorage")); - offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_resolved_methods_), "dexCacheResolvedMethods")); offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_resolved_types_), "dexCacheResolvedTypes")); offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_strings_), "dexCacheStrings")); diff --git a/src/java_lang_reflect_Method.cc b/src/java_lang_reflect_Method.cc index 3be13ca3a3..b32f815b20 100644 --- a/src/java_lang_reflect_Method.cc +++ b/src/java_lang_reflect_Method.cc @@ -50,9 +50,15 @@ jobject Method_getExceptionTypesNative(JNIEnv* env, jobject javaMethod) { return AddLocalReference<jobject>(env, declared_exceptions->Clone()); } +jobject Method_findOverriddenMethod(JNIEnv* env, jobject javaMethod) { + Method* method = Decode<Object*>(env, javaMethod)->AsMethod(); + return AddLocalReference<jobject>(env, method->FindOverriddenMethod()); +} + static JNINativeMethod gMethods[] = { NATIVE_METHOD(Method, invoke, "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"), NATIVE_METHOD(Method, getExceptionTypesNative, "()[Ljava/lang/Class;"), + NATIVE_METHOD(Method, findOverriddenMethod, "()Ljava/lang/reflect/Method;"), }; } // namespace diff --git a/src/object.cc b/src/object.cc index bb87698aa4..22ee74297e 100644 --- a/src/object.cc +++ b/src/object.cc @@ -355,16 +355,6 @@ void Method::SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_classes) new_dex_cache_classes, false); } -ObjectArray<Method>* Method::GetDexCacheResolvedMethods() const { - return GetFieldObject<ObjectArray<Method>*>( - OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_methods_), false); -} - -void Method::SetDexCacheResolvedMethods(ObjectArray<Method>* new_dex_cache_methods) { - SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_methods_), - new_dex_cache_methods, false); -} - CodeAndDirectMethods* Method::GetDexCacheCodeAndDirectMethods() const { return GetFieldPtr<CodeAndDirectMethods*>( OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_code_and_direct_methods_), @@ -421,18 +411,22 @@ Method* Method::FindOverriddenMethod() const { result = super_class_vtable->Get(method_index); } else { // Method didn't override superclass method so search interfaces - MethodHelper mh(this); - MethodHelper interface_mh; - ObjectArray<InterfaceEntry>* iftable = GetDeclaringClass()->GetIfTable(); - for (int32_t i = 0; i < iftable->GetLength() && result == NULL; i++) { - InterfaceEntry* entry = iftable->Get(i); - Class* interface = entry->GetInterface(); - for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) { - Method* interface_method = interface->GetVirtualMethod(j); - interface_mh.ChangeMethod(interface_method); - if (mh.HasSameNameAndSignature(&interface_mh)) { - result = interface_method; - break; + if (IsProxyMethod()) { + result = Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this); + } else { + MethodHelper mh(this); + MethodHelper interface_mh; + ObjectArray<InterfaceEntry>* iftable = GetDeclaringClass()->GetIfTable(); + for (int32_t i = 0; i < iftable->GetLength() && result == NULL; i++) { + InterfaceEntry* entry = iftable->Get(i); + Class* interface = entry->GetInterface(); + for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) { + Method* interface_method = interface->GetVirtualMethod(j); + interface_mh.ChangeMethod(interface_method); + if (mh.HasSameNameAndSignature(&interface_mh)) { + result = interface_method; + break; + } } } } diff --git a/src/object.h b/src/object.h index 738d2b04c2..6092ce4a88 100644 --- a/src/object.h +++ b/src/object.h @@ -604,9 +604,6 @@ class MANAGED Method : public Object { ObjectArray<Class>* GetDexCacheResolvedTypes() const; void SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_types); - ObjectArray<Method>* GetDexCacheResolvedMethods() const; - void SetDexCacheResolvedMethods(ObjectArray<Method>* new_dex_cache_methods); - CodeAndDirectMethods* GetDexCacheCodeAndDirectMethods() const; void SetDexCacheCodeAndDirectMethods(CodeAndDirectMethods* new_value); @@ -792,10 +789,6 @@ class MANAGED Method : public Object { return OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_code_and_direct_methods_); } - static MemberOffset GetDexCacheResolvedMethodsOffset() { - return OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_methods_); - } - static MemberOffset GetMethodIndexOffset() { return OFFSET_OF_OBJECT_MEMBER(Method, method_index_); } @@ -868,9 +861,6 @@ class MANAGED Method : public Object { ObjectArray<StaticStorageBase>* dex_cache_initialized_static_storage_; // short cuts to declaring_class_->dex_cache_ member for fast compiled code access - ObjectArray<Method>* dex_cache_resolved_methods_; - - // short cuts to declaring_class_->dex_cache_ member for fast compiled code access ObjectArray<Class>* dex_cache_resolved_types_; // short cuts to declaring_class_->dex_cache_ member for fast compiled code access diff --git a/src/object_utils.h b/src/object_utils.h index e2d9b88604..28b5ef6724 100644 --- a/src/object_utils.h +++ b/src/object_utils.h @@ -561,7 +561,7 @@ class MethodHelper { if (method != NULL) { Class* klass = method->GetDeclaringClass(); if (klass->IsProxyClass()) { - method = method->GetDexCacheResolvedMethods()->Get(method->GetDexMethodIndex()); + method = GetClassLinker()->FindMethodForProxy(klass, method); CHECK(method != NULL); } } diff --git a/src/runtime_support.cc b/src/runtime_support.cc index 14b14e0b49..eb06df5ef8 100644 --- a/src/runtime_support.cc +++ b/src/runtime_support.cc @@ -1037,7 +1037,6 @@ extern "C" Method* artResolveMethodFromCode(Method* referrer, FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); Method* method = class_linker->ResolveMethod(method_idx, referrer, is_direct); - referrer->GetDexCacheResolvedMethods()->Set(method_idx, method); return method; } |