Change dex cache to be java object instead of array, add pointer to dex file in dex cache.

Generic clean up to facilitate having GDB macros for Pretty* helper functions.

Improved cleanliness of DexCache since having it as an object array was not the best solution.

Fixed a bug in InOrderWalk caused by ResolveType sometimes allocating classes.

Rename C++ Method to AbstractMethod and add two new classes Constructor, Method which both inherit from AbstractMethod.

Rename done to have the C++ code be closer to the java code.

Change-Id: I4995b4c5e47a3822192b08afa24a639d3b1f4da9
diff --git a/src/class_linker.cc b/src/class_linker.cc
index f9fbc58..c7c3a33 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -166,11 +166,16 @@
   "[Ljava/lang/Class;",
   "[Ljava/lang/Object;",
   "Ljava/lang/String;",
+  "Ljava/lang/DexCache;",
   "Ljava/lang/ref/Reference;",
   "Ljava/lang/reflect/Constructor;",
   "Ljava/lang/reflect/Field;",
+  "Ljava/lang/reflect/AbstractMethod;",
   "Ljava/lang/reflect/Method;",
   "Ljava/lang/reflect/Proxy;",
+  "[Ljava/lang/String;",
+  "[Ljava/lang/reflect/Field;",
+  "[Ljava/lang/reflect/AbstractMethod;",
   "Ljava/lang/ClassLoader;",
   "Ljava/lang/Throwable;",
   "Ljava/lang/ClassNotFoundException;",
@@ -294,19 +299,17 @@
 
   // now that these are registered, we can use AllocClass() and AllocObjectArray
 
-  // setup boot_class_path_ and register class_path now that we can
-  // use AllocObjectArray to create DexCache instances
-  CHECK_NE(0U, boot_class_path.size());
-  for (size_t i = 0; i != boot_class_path.size(); ++i) {
-    const DexFile* dex_file = boot_class_path[i];
-    CHECK(dex_file != NULL);
-    AppendToBootClassPath(*dex_file);
-  }
+  // Setup DexCache. This can not be done later since AppendToBootClassPath calls AllocDexCache.
+  SirtRef<Class> java_lang_DexCache(AllocClass(java_lang_Class.get(), sizeof(DexCacheClass)));
+  SetClassRoot(kJavaLangDexCache, java_lang_DexCache.get());
+  java_lang_DexCache->SetObjectSize(sizeof(DexCacheClass));
+  java_lang_DexCache->SetStatus(Class::kStatusResolved);
 
-  // Constructor, Field, and Method are necessary so that FindClass can link members
-  SirtRef<Class> java_lang_reflect_Constructor(AllocClass(java_lang_Class.get(), sizeof(MethodClass)));
+  // Constructor, Field, Method, and AbstractMethod are necessary so that FindClass can link members.
+  SirtRef<Class> java_lang_reflect_Constructor(AllocClass(java_lang_Class.get(),
+                                                          sizeof(MethodClass)));
   CHECK(java_lang_reflect_Constructor.get() != NULL);
-  java_lang_reflect_Constructor->SetObjectSize(sizeof(Method));
+  java_lang_reflect_Constructor->SetObjectSize(sizeof(Constructor));
   SetClassRoot(kJavaLangReflectConstructor, java_lang_reflect_Constructor.get());
   java_lang_reflect_Constructor->SetStatus(Class::kStatusResolved);
 
@@ -322,7 +325,37 @@
   java_lang_reflect_Method->SetObjectSize(sizeof(Method));
   SetClassRoot(kJavaLangReflectMethod, java_lang_reflect_Method.get());
   java_lang_reflect_Method->SetStatus(Class::kStatusResolved);
-  Method::SetClasses(java_lang_reflect_Constructor.get(), java_lang_reflect_Method.get());
+
+  SirtRef<Class> java_lang_reflect_AbstractMethod(AllocClass(java_lang_Class.get(),
+                                                             sizeof(MethodClass)));
+  CHECK(java_lang_reflect_AbstractMethod.get() != NULL);
+  java_lang_reflect_AbstractMethod->SetObjectSize(sizeof(AbstractMethod));
+  SetClassRoot(kJavaLangReflectAbstractMethod, java_lang_reflect_AbstractMethod.get());
+  java_lang_reflect_AbstractMethod->SetStatus(Class::kStatusResolved);
+  AbstractMethod::SetClasses(java_lang_reflect_Constructor.get(), java_lang_reflect_Method.get());
+
+  // Set up array classes for string, field, method
+  SirtRef<Class> object_array_string(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  object_array_string->SetComponentType(java_lang_String.get());
+  SetClassRoot(kJavaLangStringArrayClass, object_array_string.get());
+
+  SirtRef<Class> object_array_field(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  object_array_field->SetComponentType(java_lang_reflect_Field.get());
+  SetClassRoot(kJavaLangReflectFieldArrayClass, object_array_field.get());
+
+  SirtRef<Class> object_array_abstract_method(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  object_array_abstract_method->SetComponentType(java_lang_reflect_AbstractMethod.get());
+  SetClassRoot(kJavaLangReflectAbstractMethodArrayClass, object_array_abstract_method.get());
+
+  // setup boot_class_path_ and register class_path now that we can
+  // use AllocObjectArray to create DexCache instances
+  // Needs to be after String, Field, Method arrays since AllocDexCache uses these roots.
+  CHECK_NE(0U, boot_class_path.size());
+  for (size_t i = 0; i != boot_class_path.size(); ++i) {
+    const DexFile* dex_file = boot_class_path[i];
+    CHECK(dex_file != NULL);
+    AppendToBootClassPath(*dex_file);
+  }
 
   // now we can use FindSystemClass
 
@@ -330,7 +363,7 @@
   InitializePrimitiveClass(char_class.get(), Primitive::kPrimChar);
   SetClassRoot(kPrimitiveChar, char_class.get());  // needs descriptor
 
-  // Object and String need to be rerun through FindSystemClass to finish init
+  // Object, String and DexCache need to be rerun through FindSystemClass to finish init
   java_lang_Object->SetStatus(Class::kStatusNotReady);
   Class* Object_class = FindSystemClass("Ljava/lang/Object;");
   CHECK_EQ(java_lang_Object.get(), Object_class);
@@ -339,6 +372,11 @@
   Class* String_class = FindSystemClass("Ljava/lang/String;");
   CHECK_EQ(java_lang_String.get(), String_class);
   CHECK_EQ(java_lang_String->GetObjectSize(), sizeof(String));
+  java_lang_DexCache->SetStatus(Class::kStatusNotReady);
+  Class* DexCache_class = FindSystemClass("Ljava/lang/DexCache;");
+  CHECK_EQ(java_lang_String.get(), String_class);
+  CHECK_EQ(java_lang_DexCache.get(), DexCache_class);
+  CHECK_EQ(java_lang_DexCache->GetObjectSize(), sizeof(DexCache));
 
   // Setup the primitive array type classes - can't be done until Object has a vtable
   SetClassRoot(kBooleanArrayClass, FindSystemClass("[Z"));
@@ -394,6 +432,16 @@
   Class* Class_class = FindSystemClass("Ljava/lang/Class;");
   CHECK_EQ(java_lang_Class.get(), Class_class);
 
+  java_lang_reflect_AbstractMethod->SetStatus(Class::kStatusNotReady);
+  Class* Abstract_method_class = FindSystemClass("Ljava/lang/reflect/AbstractMethod;");
+  CHECK_EQ(java_lang_reflect_AbstractMethod.get(), Abstract_method_class);
+
+  // Method extends AbstractMethod so must reset after.
+  java_lang_reflect_Method->SetStatus(Class::kStatusNotReady);
+  Class* Method_class = FindSystemClass("Ljava/lang/reflect/Method;");
+  CHECK_EQ(java_lang_reflect_Method.get(), Method_class);
+
+  // Constructor extends AbstractMethod so must reset after.
   java_lang_reflect_Constructor->SetStatus(Class::kStatusNotReady);
   Class* Constructor_class = FindSystemClass("Ljava/lang/reflect/Constructor;");
   CHECK_EQ(java_lang_reflect_Constructor.get(), Constructor_class);
@@ -402,9 +450,15 @@
   Class* Field_class = FindSystemClass("Ljava/lang/reflect/Field;");
   CHECK_EQ(java_lang_reflect_Field.get(), Field_class);
 
-  java_lang_reflect_Method->SetStatus(Class::kStatusNotReady);
-  Class* Method_class = FindSystemClass("Ljava/lang/reflect/Method;");
-  CHECK_EQ(java_lang_reflect_Method.get(), Method_class);
+  Class* String_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangStringArrayClass]);
+  CHECK_EQ(object_array_string.get(), String_array_class);
+
+  Class* Field_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangReflectFieldArrayClass]);
+  CHECK_EQ(object_array_field.get(), Field_array_class);
+
+  Class* Abstract_method_array_class =
+      FindSystemClass(class_roots_descriptors_[kJavaLangReflectAbstractMethodArrayClass]);
+  CHECK_EQ(object_array_abstract_method.get(), Abstract_method_array_class);
 
   // End of special init trickery, subsequent classes may be loaded via FindSystemClass
 
@@ -935,7 +989,8 @@
   DCHECK(array_iftable_ == GetClassRoot(kBooleanArrayClass)->GetIfTable());
   // String class root was set above
   Field::SetClass(GetClassRoot(kJavaLangReflectField));
-  Method::SetClasses(GetClassRoot(kJavaLangReflectConstructor), GetClassRoot(kJavaLangReflectMethod));
+  AbstractMethod::SetClasses(GetClassRoot(kJavaLangReflectConstructor),
+                             GetClassRoot(kJavaLangReflectMethod));
   BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
   ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
   CharArray::SetArrayClass(GetClassRoot(kCharArrayClass));
@@ -1034,7 +1089,7 @@
 ClassLinker::~ClassLinker() {
   String::ResetClass();
   Field::ResetClass();
-  Method::ResetClasses();
+  AbstractMethod::ResetClasses();
   BooleanArray::ResetArrayClass();
   ByteArray::ResetArrayClass();
   CharArray::ResetArrayClass();
@@ -1050,7 +1105,10 @@
 }
 
 DexCache* ClassLinker::AllocDexCache(const DexFile& dex_file) {
-  SirtRef<DexCache> dex_cache(down_cast<DexCache*>(AllocObjectArray<Object>(DexCache::LengthAsArray())));
+  Heap* heap = Runtime::Current()->GetHeap();
+  Class* dex_cache_class = GetClassRoot(kJavaLangDexCache);
+  SirtRef<DexCache> dex_cache(
+      down_cast<DexCache*>(heap->AllocObject(dex_cache_class, dex_cache_class->GetObjectSize())));
   if (dex_cache.get() == NULL) {
     return NULL;
   }
@@ -1058,7 +1116,7 @@
   if (location.get() == NULL) {
     return NULL;
   }
-  SirtRef<ObjectArray<String> > strings(AllocObjectArray<String>(dex_file.NumStringIds()));
+  SirtRef<ObjectArray<String> > strings(AllocStringArray(dex_file.NumStringIds()));
   if (strings.get() == NULL) {
     return NULL;
   }
@@ -1066,11 +1124,11 @@
   if (types.get() == NULL) {
     return NULL;
   }
-  SirtRef<ObjectArray<Method> > methods(AllocObjectArray<Method>(dex_file.NumMethodIds()));
+  SirtRef<ObjectArray<AbstractMethod> > methods(AllocMethodArray(dex_file.NumMethodIds()));
   if (methods.get() == NULL) {
     return NULL;
   }
-  SirtRef<ObjectArray<Field> > fields(AllocObjectArray<Field>(dex_file.NumFieldIds()));
+  SirtRef<ObjectArray<Field> > fields(AllocFieldArray(dex_file.NumFieldIds()));
   if (fields.get() == NULL) {
     return NULL;
   }
@@ -1079,7 +1137,8 @@
     return NULL;
   }
 
-  dex_cache->Init(location.get(),
+  dex_cache->Init(&dex_file,
+                  location.get(),
                   strings.get(),
                   types.get(),
                   methods.get(),
@@ -1117,6 +1176,10 @@
   return down_cast<Method*>(GetClassRoot(kJavaLangReflectMethod)->AllocObject());
 }
 
+Constructor* ClassLinker::AllocConstructor() {
+  return down_cast<Constructor*>(GetClassRoot(kJavaLangReflectConstructor)->AllocObject());
+}
+
 ObjectArray<StackTraceElement>* ClassLinker::AllocStackTraceElementArray(size_t length) {
   return ObjectArray<StackTraceElement>::Alloc(
       GetClassRoot(kJavaLangStackTraceElementArrayClass),
@@ -1255,10 +1318,14 @@
       klass.reset(GetClassRoot(kJavaLangClass));
     } else if (descriptor == "Ljava/lang/String;") {
       klass.reset(GetClassRoot(kJavaLangString));
-    } else if (descriptor == "Ljava/lang/reflect/Constructor;") {
-      klass.reset(GetClassRoot(kJavaLangReflectConstructor));
+    } else if (descriptor == "Ljava/lang/DexCache;") {
+      klass.reset(GetClassRoot(kJavaLangDexCache));
     } else if (descriptor == "Ljava/lang/reflect/Field;") {
       klass.reset(GetClassRoot(kJavaLangReflectField));
+    } else if (descriptor == "Ljava/lang/reflect/AbstractMethod;") {
+      klass.reset(GetClassRoot(kJavaLangReflectAbstractMethod));
+    } else if (descriptor == "Ljava/lang/reflect/Constructor;") {
+      klass.reset(GetClassRoot(kJavaLangReflectConstructor));
     } else if (descriptor == "Ljava/lang/reflect/Method;") {
       klass.reset(GetClassRoot(kJavaLangReflectMethod));
     } else {
@@ -1373,7 +1440,7 @@
   return oat_class;
 }
 
-const OatFile::OatMethod ClassLinker::GetOatMethodFor(const Method* method) {
+const OatFile::OatMethod ClassLinker::GetOatMethodFor(const AbstractMethod* method) {
   // Although we overwrite the trampoline of non-static methods, we may get here via the resolution
   // method for direct methods (or virtual methods made direct).
   Class* declaring_class = method->GetDeclaringClass();
@@ -1403,7 +1470,7 @@
 }
 
 // Special case to get oat code without overwriting a trampoline.
-const void* ClassLinker::GetOatCodeFor(const Method* method) {
+const void* ClassLinker::GetOatCodeFor(const AbstractMethod* method) {
   CHECK(Runtime::Current()->IsCompiler() || method->GetDeclaringClass()->IsInitializing());
   return GetOatMethodFor(method).GetCode();
 }
@@ -1435,7 +1502,7 @@
   // Link the code of methods skipped by LinkCode
   const void* trampoline = Runtime::Current()->GetResolutionStubArray(Runtime::kStaticMethod)->GetData();
   for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) {
-    Method* method = klass->GetDirectMethod(i);
+    AbstractMethod* method = klass->GetDirectMethod(i);
     if (Runtime::Current()->IsMethodTracingActive()) {
       Trace* tracer = Runtime::Current()->GetTracer();
       if (tracer->GetSavedCodeFromMap(method) == trampoline) {
@@ -1454,7 +1521,7 @@
   }
 }
 
-static void LinkCode(SirtRef<Method>& method, const OatFile::OatClass* oat_class,
+static void LinkCode(SirtRef<AbstractMethod>& method, const OatFile::OatClass* oat_class,
                      uint32_t method_index)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   // Every kind of method should at least get an invoke stub from the oat_method.
@@ -1535,17 +1602,16 @@
   // Load methods.
   if (it.NumDirectMethods() != 0) {
     // TODO: append direct methods to class object
-    klass->SetDirectMethods(AllocObjectArray<Method>(it.NumDirectMethods()));
+    klass->SetDirectMethods(AllocObjectArray<AbstractMethod>(it.NumDirectMethods()));
   }
   if (it.NumVirtualMethods() != 0) {
     // TODO: append direct methods to class object
-    klass->SetVirtualMethods(AllocObjectArray<Method>(it.NumVirtualMethods()));
+    klass->SetVirtualMethods(AllocObjectArray<AbstractMethod>(it.NumVirtualMethods()));
   }
   size_t class_def_method_index = 0;
   for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) {
-    SirtRef<Method> method(AllocMethod());
+    SirtRef<AbstractMethod> method(LoadMethod(dex_file, it, klass));
     klass->SetDirectMethod(i, method.get());
-    LoadMethod(dex_file, it, klass, method);
     if (oat_class.get() != NULL) {
       LinkCode(method, oat_class.get(), class_def_method_index);
     }
@@ -1553,9 +1619,8 @@
     class_def_method_index++;
   }
   for (size_t i = 0; it.HasNextVirtualMethod(); i++, it.Next()) {
-    SirtRef<Method> method(AllocMethod());
+    SirtRef<AbstractMethod> method(LoadMethod(dex_file, it, klass));
     klass->SetVirtualMethod(i, method.get());
-    LoadMethod(dex_file, it, klass, method);
     DCHECK_EQ(class_def_method_index, it.NumDirectMethods() + i);
     if (oat_class.get() != NULL) {
       LinkCode(method, oat_class.get(), class_def_method_index);
@@ -1573,18 +1638,23 @@
   dst->SetAccessFlags(it.GetMemberAccessFlags());
 }
 
-void ClassLinker::LoadMethod(const DexFile& dex_file, const ClassDataItemIterator& it,
-                             SirtRef<Class>& klass, SirtRef<Method>& dst) {
+AbstractMethod* ClassLinker::LoadMethod(const DexFile& dex_file, const ClassDataItemIterator& it,
+                             SirtRef<Class>& klass) {
   uint32_t dex_method_idx = it.GetMemberIndex();
-  dst->SetDexMethodIndex(dex_method_idx);
   const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
-  dst->SetDeclaringClass(klass.get());
-
-
   StringPiece method_name(dex_file.GetMethodName(method_id));
+
+  AbstractMethod* dst = NULL;
   if (method_name == "<init>") {
-    dst->SetClass(GetClassRoot(kJavaLangReflectConstructor));
+    dst = AllocConstructor();
+  } else {
+    dst = AllocMethod();
   }
+  DCHECK(dst->IsMethod()) << PrettyDescriptor(dst->GetClass());
+
+  const char* old_cause = Thread::Current()->StartAssertNoThreadSuspension("LoadMethod");
+  dst->SetDexMethodIndex(dex_method_idx);
+  dst->SetDeclaringClass(klass.get());
 
   if (method_name == "finalize") {
     // Create the prototype for a signature of "()V"
@@ -1623,6 +1693,11 @@
   dst->SetDexCacheResolvedMethods(klass->GetDexCache()->GetResolvedMethods());
   dst->SetDexCacheResolvedTypes(klass->GetDexCache()->GetResolvedTypes());
   dst->SetDexCacheInitializedStaticStorage(klass->GetDexCache()->GetInitializedStaticStorage());
+
+  CHECK(dst->IsMethod());
+
+  Thread::Current()->EndAssertNoThreadSuspension(old_cause);
+  return dst;
 }
 
 void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) {
@@ -1638,8 +1713,8 @@
 
 bool ClassLinker::IsDexFileRegisteredLocked(const DexFile& dex_file) const {
   dex_lock_.AssertHeld();
-  for (size_t i = 0; i != dex_files_.size(); ++i) {
-    if (dex_files_[i] == &dex_file) {
+  for (size_t i = 0; i != dex_caches_.size(); ++i) {
+    if (dex_caches_[i]->GetDexFile() == &dex_file) {
       return true;
     }
   }
@@ -1655,8 +1730,8 @@
   dex_lock_.AssertHeld();
   CHECK(dex_cache.get() != NULL) << dex_file.GetLocation();
   CHECK(dex_cache->GetLocation()->Equals(dex_file.GetLocation()));
-  dex_files_.push_back(&dex_file);
   dex_caches_.push_back(dex_cache.get());
+  dex_cache->SetDexFile(&dex_file);
 }
 
 void ClassLinker::RegisterDexFile(const DexFile& dex_file) {
@@ -1684,30 +1759,29 @@
   RegisterDexFileLocked(dex_file, dex_cache);
 }
 
+// TODO: Remove.
 const DexFile& ClassLinker::FindDexFile(const DexCache* dex_cache) const {
   CHECK(dex_cache != NULL);
-  MutexLock mu(dex_lock_);
-  for (size_t i = 0; i != dex_caches_.size(); ++i) {
-    if (dex_caches_[i] == dex_cache) {
-      return *dex_files_[i];
-    }
+  const DexFile* dex_file = dex_cache->GetDexFile();
+  if (dex_file == NULL) {
+    LOG(FATAL) << "DexCache has no DexFile " << dex_cache->GetLocation()->ToModifiedUtf8();
   }
-  LOG(FATAL) << "Failed to find DexFile for DexCache " << dex_cache->GetLocation()->ToModifiedUtf8();
-  return *dex_files_[-1];
+  return *dex_file;
 }
 
 DexCache* ClassLinker::FindDexCache(const DexFile& dex_file) const {
   MutexLock mu(dex_lock_);
-  for (size_t i = 0; i != dex_files_.size(); ++i) {
-    if (dex_files_[i] == &dex_file) {
-      return dex_caches_[i];
+  for (size_t i = 0; i != dex_caches_.size(); ++i) {
+    DexCache* dex_cache = dex_caches_[i];
+    if (dex_cache->GetDexFile() == &dex_file) {
+      return dex_cache;
     }
   }
   LOG(FATAL) << "Failed to find DexCache for DexFile " << dex_file.GetLocation();
   return NULL;
 }
 
-void ClassLinker::FixupDexCaches(Method* resolution_method) const {
+void ClassLinker::FixupDexCaches(AbstractMethod* resolution_method) const {
   MutexLock mu(dex_lock_);
   for (size_t i = 0; i != dex_caches_.size(); ++i) {
     dex_caches_[i]->Fixup(resolution_method);
@@ -1788,6 +1862,12 @@
       new_class.reset(GetClassRoot(kClassArrayClass));
     } else if (descriptor == "[Ljava/lang/Object;") {
       new_class.reset(GetClassRoot(kObjectArrayClass));
+    } else if (descriptor == class_roots_descriptors_[kJavaLangStringArrayClass]) {
+      new_class.reset(GetClassRoot(kJavaLangStringArrayClass));
+    } else if (descriptor == class_roots_descriptors_[kJavaLangReflectFieldArrayClass]) {
+      new_class.reset(GetClassRoot(kJavaLangReflectFieldArrayClass));
+    } else if (descriptor == class_roots_descriptors_[kJavaLangReflectAbstractMethodArrayClass]) {
+      new_class.reset(GetClassRoot(kJavaLangReflectAbstractMethodArrayClass));
     } else if (descriptor == "[C") {
       new_class.reset(GetClassRoot(kCharArrayClass));
     } else if (descriptor == "[I") {
@@ -2164,7 +2244,7 @@
   }
 }
 
-void ClassLinker::ResolveMethodExceptionHandlerTypes(const DexFile& dex_file, Method* method) {
+void ClassLinker::ResolveMethodExceptionHandlerTypes(const DexFile& dex_file, AbstractMethod* method) {
   // similar to DexVerifier::ScanTryCatchBlocks and dex2oat's ResolveExceptionsForMethod.
   const DexFile::CodeItem* code_item = dex_file.GetCodeItem(method->GetCodeItemOffset());
   if (code_item == NULL) {
@@ -2193,11 +2273,11 @@
   }
 }
 
-static void CheckProxyConstructor(Method* constructor);
-static void CheckProxyMethod(Method* method, SirtRef<Method>& prototype);
+static void CheckProxyConstructor(AbstractMethod* constructor);
+static void CheckProxyMethod(AbstractMethod* method, SirtRef<AbstractMethod>& prototype);
 
 Class* ClassLinker::CreateProxyClass(String* name, ObjectArray<Class>* interfaces,
-                                     ClassLoader* loader, ObjectArray<Method>* methods,
+                                     ClassLoader* loader, ObjectArray<AbstractMethod>* methods,
                                      ObjectArray<ObjectArray<Class> >* throws) {
   SirtRef<Class> klass(AllocClass(GetClassRoot(kJavaLangClass), sizeof(SynthesizedProxyClass)));
   CHECK(klass.get() != NULL);
@@ -2231,14 +2311,14 @@
   throws_sfield->SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
 
   // Proxies have 1 direct method, the constructor
-  klass->SetDirectMethods(AllocObjectArray<Method>(1));
+  klass->SetDirectMethods(AllocObjectArray<AbstractMethod>(1));
   klass->SetDirectMethod(0, CreateProxyConstructor(klass, proxy_class));
 
   // Create virtual method using specified prototypes
   size_t num_virtual_methods = methods->GetLength();
-  klass->SetVirtualMethods(AllocObjectArray<Method>(num_virtual_methods));
+  klass->SetVirtualMethods(AllocObjectArray<AbstractMethod>(num_virtual_methods));
   for (size_t i = 0; i < num_virtual_methods; ++i) {
-    SirtRef<Method> prototype(methods->Get(i));
+    SirtRef<AbstractMethod> prototype(methods->Get(i));
     klass->SetVirtualMethod(i, CreateProxyMethod(klass, prototype));
   }
 
@@ -2263,7 +2343,7 @@
     CHECK(klass->GetIFields() == NULL);
     CheckProxyConstructor(klass->GetDirectMethod(0));
     for (size_t i = 0; i < num_virtual_methods; ++i) {
-      SirtRef<Method> prototype(methods->Get(i));
+      SirtRef<AbstractMethod> prototype(methods->Get(i));
       CheckProxyMethod(klass->GetVirtualMethod(i), prototype);
     }
 
@@ -2289,7 +2369,7 @@
   return DotToDescriptor(name->ToModifiedUtf8().c_str());
 }
 
-Method* ClassLinker::FindMethodForProxy(const Class* proxy_class, const Method* proxy_method) {
+AbstractMethod* ClassLinker::FindMethodForProxy(const Class* proxy_class, const AbstractMethod* proxy_method) {
   DCHECK(proxy_class->IsProxyClass());
   DCHECK(proxy_method->IsProxyMethod());
   // Locate the dex cache of the original interface/Object
@@ -2306,27 +2386,27 @@
   }
   CHECK(dex_cache != NULL);
   uint32_t method_idx = proxy_method->GetDexMethodIndex();
-  Method* resolved_method = dex_cache->GetResolvedMethod(method_idx);
+  AbstractMethod* resolved_method = dex_cache->GetResolvedMethod(method_idx);
   CHECK(resolved_method != NULL);
   return resolved_method;
 }
 
 
-Method* ClassLinker::CreateProxyConstructor(SirtRef<Class>& klass, Class* proxy_class) {
+AbstractMethod* ClassLinker::CreateProxyConstructor(SirtRef<Class>& klass, Class* proxy_class) {
   // Create constructor for Proxy that must initialize h
-  ObjectArray<Method>* proxy_direct_methods = proxy_class->GetDirectMethods();
+  ObjectArray<AbstractMethod>* proxy_direct_methods = proxy_class->GetDirectMethods();
   CHECK_EQ(proxy_direct_methods->GetLength(), 15);
-  Method* proxy_constructor = proxy_direct_methods->Get(2);
+  AbstractMethod* proxy_constructor = proxy_direct_methods->Get(2);
   // Clone the existing constructor of Proxy (our constructor would just invoke it so steal its
   // code_ too)
-  Method* constructor = down_cast<Method*>(proxy_constructor->Clone());
+  AbstractMethod* constructor = down_cast<AbstractMethod*>(proxy_constructor->Clone());
   // Make this constructor public and fix the class to be our Proxy version
   constructor->SetAccessFlags((constructor->GetAccessFlags() & ~kAccProtected) | kAccPublic);
   constructor->SetDeclaringClass(klass.get());
   return constructor;
 }
 
-static void CheckProxyConstructor(Method* constructor)
+static void CheckProxyConstructor(AbstractMethod* constructor)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   CHECK(constructor->IsConstructor());
   MethodHelper mh(constructor);
@@ -2335,14 +2415,14 @@
   DCHECK(constructor->IsPublic());
 }
 
-Method* ClassLinker::CreateProxyMethod(SirtRef<Class>& klass, SirtRef<Method>& prototype) {
+AbstractMethod* ClassLinker::CreateProxyMethod(SirtRef<Class>& klass, SirtRef<AbstractMethod>& prototype) {
   // Ensure prototype is in dex cache so that we can use the dex cache to look up the overridden
   // prototype method
   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());
+  AbstractMethod* method = down_cast<AbstractMethod*>(prototype->Clone());
 
   // Set class to be the concrete proxy class and clear the abstract flag, modify exceptions to
   // the intersection of throw exceptions as defined in Proxy
@@ -2351,7 +2431,7 @@
 
   // At runtime the method looks like a reference and argument saving method, clone the code
   // related parameters from this method.
-  Method* refs_and_args = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs);
+  AbstractMethod* refs_and_args = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs);
   method->SetCoreSpillMask(refs_and_args->GetCoreSpillMask());
   method->SetFpSpillMask(refs_and_args->GetFpSpillMask());
   method->SetFrameSizeInBytes(refs_and_args->GetFrameSizeInBytes());
@@ -2365,7 +2445,7 @@
   return method;
 }
 
-static void CheckProxyMethod(Method* method, SirtRef<Method>& prototype)
+static void CheckProxyMethod(AbstractMethod* method, SirtRef<AbstractMethod>& prototype)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   // Basic sanity
   CHECK(!prototype->IsFinal());
@@ -2395,7 +2475,7 @@
 
   Thread* self = Thread::Current();
 
-  Method* clinit = NULL;
+  AbstractMethod* clinit = NULL;
   {
     // see JLS 3rd edition, 12.4.2 "Detailed Initialization Procedure" for the locking protocol
     ObjectLock lock(klass);
@@ -2555,7 +2635,7 @@
       klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
     const Class* super = klass->GetSuperClass();
     for (int i = super->GetVTable()->GetLength() - 1; i >= 0; --i) {
-      const Method* method = klass->GetVTable()->Get(i);
+      const AbstractMethod* method = klass->GetVTable()->Get(i);
       if (method != super->GetVTable()->Get(i) &&
           !IsSameMethodSignatureInDifferentClassContexts(method, super, klass)) {
         ThrowLinkageError("Class %s method %s resolves differently in superclass %s",
@@ -2570,7 +2650,7 @@
     Class* interface = interface_entry->GetInterface();
     if (klass->GetClassLoader() != interface->GetClassLoader()) {
       for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
-        const Method* method = interface_entry->GetMethodArray()->Get(j);
+        const AbstractMethod* method = interface_entry->GetMethodArray()->Get(j);
         if (!IsSameMethodSignatureInDifferentClassContexts(method, interface,
                                                            method->GetDeclaringClass())) {
           ThrowLinkageError("Class %s method %s resolves differently in interface %s",
@@ -2587,7 +2667,7 @@
 
 // Returns true if classes referenced by the signature of the method are the
 // same classes in klass1 as they are in klass2.
-bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(const Method* method,
+bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(const AbstractMethod* method,
                                                                 const Class* klass1,
                                                                 const Class* klass2) {
   if (klass1 == klass2) {
@@ -2872,16 +2952,16 @@
     size_t actual_count = klass->GetSuperClass()->GetVTable()->GetLength();
     CHECK_LE(actual_count, max_count);
     // TODO: do not assign to the vtable field until it is fully constructed.
-    SirtRef<ObjectArray<Method> > vtable(klass->GetSuperClass()->GetVTable()->CopyOf(max_count));
+    SirtRef<ObjectArray<AbstractMethod> > vtable(klass->GetSuperClass()->GetVTable()->CopyOf(max_count));
     // See if any of our virtual methods override the superclass.
     MethodHelper local_mh(NULL, this);
     MethodHelper super_mh(NULL, this);
     for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
-      Method* local_method = klass->GetVirtualMethodDuringLinking(i);
+      AbstractMethod* local_method = klass->GetVirtualMethodDuringLinking(i);
       local_mh.ChangeMethod(local_method);
       size_t j = 0;
       for (; j < actual_count; ++j) {
-        Method* super_method = vtable->Get(j);
+        AbstractMethod* super_method = vtable->Get(j);
         super_mh.ChangeMethod(super_method);
         if (local_mh.HasSameNameAndSignature(&super_mh)) {
           if (klass->CanAccessMember(super_method->GetDeclaringClass(), super_method->GetAccessFlags())) {
@@ -2925,9 +3005,9 @@
       ThrowClassFormatError("Too many methods: %d", num_virtual_methods);
       return false;
     }
-    SirtRef<ObjectArray<Method> > vtable(AllocObjectArray<Method>(num_virtual_methods));
+    SirtRef<ObjectArray<AbstractMethod> > vtable(AllocObjectArray<AbstractMethod>(num_virtual_methods));
     for (size_t i = 0; i < num_virtual_methods; ++i) {
-      Method* virtual_method = klass->GetVirtualMethodDuringLinking(i);
+      AbstractMethod* virtual_method = klass->GetVirtualMethodDuringLinking(i);
       vtable->Set(i, virtual_method);
       virtual_method->SetMethodIndex(i & 0xFFFF);
     }
@@ -3021,17 +3101,17 @@
   if (klass->IsInterface() /*|| super_ifcount == ifcount*/) {
     return true;
   }
-  std::vector<Method*> miranda_list;
+  std::vector<AbstractMethod*> miranda_list;
   MethodHelper vtable_mh(NULL, this);
   MethodHelper interface_mh(NULL, this);
   for (size_t i = 0; i < ifcount; ++i) {
     InterfaceEntry* interface_entry = iftable->Get(i);
     Class* interface = interface_entry->GetInterface();
-    ObjectArray<Method>* method_array = AllocObjectArray<Method>(interface->NumVirtualMethods());
+    ObjectArray<AbstractMethod>* method_array = AllocObjectArray<AbstractMethod>(interface->NumVirtualMethods());
     interface_entry->SetMethodArray(method_array);
-    ObjectArray<Method>* vtable = klass->GetVTableDuringLinking();
+    ObjectArray<AbstractMethod>* vtable = klass->GetVTableDuringLinking();
     for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
-      Method* interface_method = interface->GetVirtualMethod(j);
+      AbstractMethod* interface_method = interface->GetVirtualMethod(j);
       interface_mh.ChangeMethod(interface_method);
       int32_t k;
       // For each method listed in the interface's method list, find the
@@ -3043,7 +3123,7 @@
       // those don't end up in the virtual method table, so it shouldn't
       // matter which direction we go.  We walk it backward anyway.)
       for (k = vtable->GetLength() - 1; k >= 0; --k) {
-        Method* vtable_method = vtable->Get(k);
+        AbstractMethod* vtable_method = vtable->Get(k);
         vtable_mh.ChangeMethod(vtable_method);
         if (interface_mh.HasSameNameAndSignature(&vtable_mh)) {
           if (!vtable_method->IsPublic()) {
@@ -3056,9 +3136,9 @@
         }
       }
       if (k < 0) {
-        SirtRef<Method> miranda_method(NULL);
+        SirtRef<AbstractMethod> miranda_method(NULL);
         for (size_t mir = 0; mir < miranda_list.size(); mir++) {
-          Method* mir_method = miranda_list[mir];
+          AbstractMethod* mir_method = miranda_list[mir];
           vtable_mh.ChangeMethod(mir_method);
           if (interface_mh.HasSameNameAndSignature(&vtable_mh)) {
             miranda_method.reset(miranda_list[mir]);
@@ -3067,7 +3147,7 @@
         }
         if (miranda_method.get() == NULL) {
           // point the interface table at a phantom slot
-          miranda_method.reset(down_cast<Method*>(interface_method->Clone()));
+          miranda_method.reset(down_cast<AbstractMethod*>(interface_method->Clone()));
           miranda_list.push_back(miranda_method.get());
         }
         method_array->Set(j, miranda_method.get());
@@ -3078,16 +3158,16 @@
     int old_method_count = klass->NumVirtualMethods();
     int new_method_count = old_method_count + miranda_list.size();
     klass->SetVirtualMethods((old_method_count == 0)
-                             ? AllocObjectArray<Method>(new_method_count)
+                             ? AllocObjectArray<AbstractMethod>(new_method_count)
                              : klass->GetVirtualMethods()->CopyOf(new_method_count));
 
-    SirtRef<ObjectArray<Method> > vtable(klass->GetVTableDuringLinking());
+    SirtRef<ObjectArray<AbstractMethod> > vtable(klass->GetVTableDuringLinking());
     CHECK(vtable.get() != NULL);
     int old_vtable_count = vtable->GetLength();
     int new_vtable_count = old_vtable_count + miranda_list.size();
     vtable.reset(vtable->CopyOf(new_vtable_count));
     for (size_t i = 0; i < miranda_list.size(); ++i) {
-      Method* method = miranda_list[i];
+      AbstractMethod* method = miranda_list[i];
       // Leave the declaring class alone as type indices are relative to it
       method->SetAccessFlags(method->GetAccessFlags() | kAccMiranda);
       method->SetMethodIndex(0xFFFF & (old_vtable_count + i));
@@ -3098,7 +3178,7 @@
     klass->SetVTable(vtable.get());
   }
 
-  ObjectArray<Method>* vtable = klass->GetVTableDuringLinking();
+  ObjectArray<AbstractMethod>* vtable = klass->GetVTableDuringLinking();
   for (int i = 0; i < vtable->GetLength(); ++i) {
     CHECK(vtable->Get(i) != NULL);
   }
@@ -3396,15 +3476,15 @@
   return resolved;
 }
 
-Method* ClassLinker::ResolveMethod(const DexFile& dex_file,
+AbstractMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
                                    uint32_t method_idx,
                                    DexCache* dex_cache,
                                    ClassLoader* class_loader,
-                                   const Method* referrer,
+                                   const AbstractMethod* referrer,
                                    InvokeType type) {
   DCHECK(dex_cache != NULL);
   // Check for hit in the dex cache.
-  Method* resolved = dex_cache->GetResolvedMethod(method_idx);
+  AbstractMethod* resolved = dex_cache->GetResolvedMethod(method_idx);
   if (resolved != NULL) {
     return resolved;
   }
@@ -3608,7 +3688,7 @@
   return resolved;
 }
 
-const char* ClassLinker::MethodShorty(uint32_t method_idx, Method* referrer, uint32_t* length) {
+const char* ClassLinker::MethodShorty(uint32_t method_idx, AbstractMethod* referrer, uint32_t* length) {
   Class* declaring_class = referrer->GetDeclaringClass();
   DexCache* dex_cache = declaring_class->GetDexCache();
   const DexFile& dex_file = FindDexFile(dex_cache);