Merge "Revert "Remove dexCacheResolvedMethods from Method/Constructor"" into dalvik-dev
diff --git a/src/class_linker.cc b/src/class_linker.cc
index bfdc3b1..62d3df7 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1517,6 +1517,7 @@
 
   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());
 }
@@ -2167,8 +2168,7 @@
 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
-  klass->GetDexCache()->SetResolvedMethod(prototype->GetDexMethodIndex(),
-                                          prototype.get());
+  prototype->GetDexCacheResolvedMethods()->Set(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());
diff --git a/src/class_linker.h b/src/class_linker.h
index 297cee7..0b16533 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) {
-    Class* declaring_class = referrer->GetDeclaringClass();
-    DexCache* dex_cache = declaring_class->GetDexCache();
-    Method* resolved_method = dex_cache->GetResolvedMethod(method_idx);
+    Method* resolved_method = referrer->GetDexCacheResolvedMethods()->Get(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);
@@ -170,10 +170,11 @@
   }
 
   Field* ResolveField(uint32_t field_idx, const Method* referrer, bool is_static) {
-    Class* declaring_class = referrer->GetDeclaringClass();
-    DexCache* dex_cache = declaring_class->GetDexCache();
-    Field* resolved_field = dex_cache->GetResolvedField(field_idx);
+    Field* resolved_field =
+        referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx);
     if (UNLIKELY(resolved_field == 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_field = ResolveField(dex_file, field_idx, dex_cache, class_loader, is_static);
@@ -193,10 +194,11 @@
                       bool is_static);
 
   Field* ResolveFieldJLS(uint32_t field_idx, const Method* referrer) {
-    Class* declaring_class = referrer->GetDeclaringClass();
-    DexCache* dex_cache = declaring_class->GetDexCache();
-    Field* resolved_field = dex_cache->GetResolvedField(field_idx);
+    Field* resolved_field =
+        referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx);
     if (UNLIKELY(resolved_field == 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_field = ResolveFieldJLS(dex_file, field_idx, dex_cache, class_loader);
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 9f63c5e..e9a94a9 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -139,12 +139,15 @@
 
     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(),
@@ -443,6 +446,7 @@
     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/compiler_test.cc b/src/compiler_test.cc
index 2257f87..76a39a4 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -139,7 +139,6 @@
 }
 
 TEST_F(CompilerTest, AbstractMethodErrorStub) {
-  CompileVirtualMethod(NULL, "java.lang.Class", "isFinalizable", "()Z");
   CompileDirectMethod(NULL, "java.lang.Object", "<init>", "()V");
 
   SirtRef<ClassLoader> class_loader(LoadDex("AbstractMethod"));
diff --git a/src/object.cc b/src/object.cc
index a8493ef..bb87698 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -355,6 +355,16 @@
                  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_),
diff --git a/src/object.h b/src/object.h
index 6092ce4..738d2b0 100644
--- a/src/object.h
+++ b/src/object.h
@@ -604,6 +604,9 @@
   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);
 
@@ -789,6 +792,10 @@
     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_);
   }
@@ -861,6 +868,9 @@
   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 2286f7f..e2d9b88 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 = klass->GetDexCache()->GetResolvedMethod(method->GetDexMethodIndex());
+        method = method->GetDexCacheResolvedMethods()->Get(method->GetDexMethodIndex());
         CHECK(method != NULL);
       }
     }
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index 889414f..14b14e0 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -1037,7 +1037,7 @@
     FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
     Method* method = class_linker->ResolveMethod(method_idx, referrer, is_direct);
-    referrer->GetDeclaringClass()->GetDexCache()->SetResolvedMethod(method_idx, method);
+    referrer->GetDexCacheResolvedMethods()->Set(method_idx, method);
     return method;
 }