Remove dexCacheResolvedMethods, address Proxy issue
Change-Id: Iab8c7edb954d241bd5a92260db07696b9559155f
diff --git a/src/class_linker.cc b/src/class_linker.cc
index bc8e333..60bd614 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1515,7 +1515,6 @@
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 @@
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 @@
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->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 0b16533..f6b7c15 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -158,10 +158,10 @@
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* 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 e9a94a9..9f63c5e 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -139,15 +139,12 @@
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 @@
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 3be13ca..b32f815 100644
--- a/src/java_lang_reflect_Method.cc
+++ b/src/java_lang_reflect_Method.cc
@@ -50,9 +50,15 @@
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 bb87698..22ee742 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -355,16 +355,6 @@
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 @@
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 738d2b0..6092ce4 100644
--- a/src/object.h
+++ b/src/object.h
@@ -604,9 +604,6 @@
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 @@
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 @@
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 e2d9b88..28b5ef6 100644
--- a/src/object_utils.h
+++ b/src/object_utils.h
@@ -561,7 +561,7 @@
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 14b14e0..eb06df5 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -1037,7 +1037,6 @@
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;
}