Move DexFiles to be allocated on the heap

Removed pointer from DexFile to RawDexfile to allow heap allocation of
DexFile. DexFile is now an ObjectArray of ObjectArrays. Removing the
pointer from DexFile to RawDexfile meant adding arguments to pass the
RawDexfile along to ClassLinker::LoadClass, LoadInterfaces, LoadField,
LoadMethod, LinkClass, LinkInterfaces, ResolveClass to avoid the need
to look a RawDexfile up from a DexFile. ClassLinker::CreateArrayClass
now takes the raw_dex_file to assist in looking up the component class
from the proper source. Moved Method::HasSame* methods to ClassLinker
since for access to the RawDexfile (and tests of HasSame from
ObjectTest to ClassLinkerTest.

	src/dex_file.cc
	src/dex_file.h
	src/class_linker.cc
	src/class_linker.h
	src/object.h

RunTime::Create/RunTime::Init/ClassLinker::Create/ClassLinker::Init
now take the boot class path. A boot class path with
Ljava/lang/Object; must be provided to initalize [Ljava/lang/Object;
during startup in order to heap allocate DexFiles.

	src/class_linker.cc
	src/class_linker.h
	src/runtime.cc
	src/runtime.h

Restored FindClass to load from a specific dex file. This is for use
by class loaders, otherwise it is assumed the caller wants to use the
boot classpath. We now distinguish and track the boot classpath as
separate from other dex files known to the class linker. Renamed
AppendToClassPath to AppendToBootClassPath and FindInClassPath to
FindInBootClassPath to clarify.

	src/class_linker.cc
	src/class_linker.h

Cleaned up AllocCharArray to generic AllocArray and added
AllocObjectArray. Added a functional ObjectArray implementation and a
ObjectTest to cover it.

	src/heap.h
	src/object.h
	src/object_test.cc

Switched more Object* downcasting to down_cast

	src/class_linker.cc

Switched order of arguments for DexFile::SetResolved to follow more
conventional collection ordering ( "(index, value)" vs "(value, index)" )

	src/dex_file.h
	src/class_linker.cc
	src/class_linker.h

Added class_linker_ and java_lang_raw_dex_file_ to RuntimeTest as
convenience to test subclasses. ClassLinkerTest now can use these to
simplify its ::Assert* methods. JniCompilerTest now uses it for
setting up its boot class path. Removed now unneeded
OpenDexFileBase64.

	src/common_test.h
	src/class_linker_test.cc
	src/jni_compiler_test.cc

Add external/gtest/include to non-test include path so FRIEND_TEST can be used.
Add src to include path to remove the need of using in in art/src files.

	build/Android.libart.host.mk
	build/Android.libart.mk
	src/assembler.cc
	src/assembler.h
	src/assembler_arm.cc
	src/assembler_arm.h
	src/assembler_x86.cc
	src/assembler_x86.h
	src/assembler_x86_test.cc
	src/base64.cc
	src/base64.h
	src/calling_convention.cc
	src/calling_convention.h
	src/calling_convention_arm.cc
	src/calling_convention_x86.cc
	src/casts.h
	src/class_linker.h
	src/class_linker_test.cc
	src/common_test.h
	src/constants.h
	src/constants_arm.h
	src/constants_x86.h
	src/dex_file.cc
	src/dex_file.h
	src/dex_file_test.cc
	src/dex_instruction.cc
	src/dex_instruction.h
	src/dex_instruction_visitor.h
	src/dex_instruction_visitor_test.cc
	src/dex_verifier.cc
	src/dex_verifier.h
	src/heap.cc
	src/heap.h
	src/jni_compiler.cc
	src/jni_compiler_test.cc
	src/jni_internal.cc
	src/jni_internal.h
	src/leb128.h
	src/managed_register.h
	src/managed_register_arm.cc
	src/managed_register_arm.h
	src/managed_register_arm_test.cc
	src/managed_register_x86.cc
	src/managed_register_x86.h
	src/managed_register_x86_test.cc
	src/mark_stack.cc
	src/mark_stack.h
	src/mark_sweep.cc
	src/mark_sweep.h
	src/memory_region.cc
	src/memory_region.h
	src/monitor.h
	src/object.cc
	src/object.h
	src/object_bitmap.cc
	src/object_bitmap.h
	src/object_test.cc
	src/offsets.cc
	src/offsets.h
	src/raw_dex_file.cc
	src/raw_dex_file.h
	src/raw_dex_file_test.cc
	src/runtime.cc
	src/runtime.h
	src/scoped_ptr.h
	src/space.cc
	src/space.h
	src/space_test.cc
	src/stringpiece.cc
	src/thread.cc
	src/thread.h
	src/thread_arm.cc
	src/thread_x86.cc
	src/utils.h

Change-Id: Ib633cea878c36921e9037b0464cb903aec318c3e
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 6fac610..20960d2 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1,32 +1,39 @@
 // Copyright 2011 Google Inc. All Rights Reserved.
 // Author: cshapiro@google.com (Carl Shapiro)
 
-#include "src/class_linker.h"
+#include "class_linker.h"
 
 #include <vector>
 #include <utility>
 
-#include "src/casts.h"
-#include "src/dex_verifier.h"
-#include "src/heap.h"
-#include "src/logging.h"
-#include "src/monitor.h"
-#include "src/object.h"
-#include "src/raw_dex_file.h"
-#include "src/scoped_ptr.h"
-#include "src/thread.h"
-#include "src/utils.h"
+#include "casts.h"
+#include "dex_file.h"
+#include "dex_verifier.h"
+#include "heap.h"
+#include "logging.h"
+#include "monitor.h"
+#include "object.h"
+#include "raw_dex_file.h"
+#include "scoped_ptr.h"
+#include "thread.h"
+#include "utils.h"
 
 namespace art {
 
-ClassLinker* ClassLinker::Create() {
+ClassLinker* ClassLinker::Create(std::vector<RawDexFile*> boot_class_path) {
   scoped_ptr<ClassLinker> class_linker(new ClassLinker);
-  class_linker->Init();
+  class_linker->Init(boot_class_path);
   // TODO: check for failure during initialization
   return class_linker.release();
 }
 
-void ClassLinker::Init() {
+void ClassLinker::Init(std::vector<RawDexFile*> boot_class_path) {
+
+  // setup boot_class_path_ so that object_array_class_ can be properly initialized
+  for (size_t i = 0; i != boot_class_path.size(); ++i) {
+    AppendToBootClassPath(boot_class_path[i]);
+  }
+
   // Allocate and partially initialize the Class, Object, Field, Method classes.
   // Initialization will be completed when the definitions are loaded.
   java_lang_Class_ = down_cast<Class*>(Heap::AllocObject(NULL, sizeof(Class)));
@@ -74,10 +81,17 @@
 
   char_array_class_ = FindSystemClass("[C");
   CHECK(char_array_class_ != NULL);
+
+  object_array_class_ = FindSystemClass("[Ljava/lang/Object;");
+  CHECK(object_array_class_ != NULL);
+}
+
+DexFile* ClassLinker::AllocDexFile() {
+  return down_cast<DexFile*>(Heap::AllocObjectArray(object_array_class_, DexFile::kMax));
 }
 
 Class* ClassLinker::AllocClass(DexFile* dex_file) {
-  Class* klass = reinterpret_cast<Class*>(Heap::AllocObject(java_lang_Class_));
+  Class* klass = down_cast<Class*>(Heap::AllocObject(java_lang_Class_));
   klass->dex_file_ = dex_file;
   return klass;
 }
@@ -97,8 +111,13 @@
                                               sizeof(Method)));
 }
 
+ObjectArray* ClassLinker::AllocObjectArray(size_t length) {
+    return Heap::AllocObjectArray(object_array_class_, length);
+}
+
 Class* ClassLinker::FindClass(const StringPiece& descriptor,
-                              Object* class_loader) {
+                              Object* class_loader,
+                              const RawDexFile* raw_dex_file) {
   Thread* self = Thread::Current();
   DCHECK(self != NULL);
   CHECK(!self->IsExceptionPending());
@@ -107,15 +126,22 @@
   if (klass == NULL) {
     // Class is not yet loaded.
     if (descriptor[0] == '[') {
-      return CreateArrayClass(descriptor, class_loader);
+      return CreateArrayClass(descriptor, class_loader, raw_dex_file);
     }
-    ClassPathEntry pair = FindInClassPath(descriptor);
-    if (pair.first == NULL) {
+    ClassPathEntry pair;
+    if (raw_dex_file == NULL) {
+      pair = FindInBootClassPath(descriptor);
+    } else {
+      pair.first = raw_dex_file;
+      pair.second = raw_dex_file->FindClassDef(descriptor);
+    }
+    if (pair.second == NULL) {
       LG << "Class " << descriptor << " not found";  // TODO: NoClassDefFoundError
       return NULL;
     }
-    DexFile* dex_file = pair.first;
+    const RawDexFile* raw_dex_file = pair.first;
     const RawDexFile::ClassDef* class_def = pair.second;
+    DexFile* dex_file = FindDexFile(raw_dex_file);
     // Load the class from the dex file.
     if (descriptor == "Ljava/lang/Object;") {
       klass = java_lang_Object_;
@@ -147,7 +173,7 @@
     } else {
       klass = AllocClass(dex_file);
     }
-    LoadClass(*class_def, klass);
+    LoadClass(*raw_dex_file, *class_def, klass);
     // Check for a pending exception during load
     if (self->IsExceptionPending()) {
       // TODO: free native allocations in klass
@@ -166,7 +192,7 @@
         CHECK(klass != NULL);
       } else {
         // Link the class.
-        if (!LinkClass(klass)) {
+        if (!LinkClass(klass, raw_dex_file)) {
           // Linking failed.
           // TODO: CHECK(self->IsExceptionPending());
           lock.NotifyAll();
@@ -197,14 +223,15 @@
   return klass;
 }
 
-void ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) {
+void ClassLinker::LoadClass(const RawDexFile& raw_dex_file,
+                            const RawDexFile::ClassDef& class_def,
+                            Class* klass) {
   CHECK(klass != NULL);
   CHECK(klass->dex_file_ != NULL);
-  const RawDexFile* raw = klass->GetDexFile()->GetRaw();
-  const byte* class_data = raw->GetClassData(class_def);
-  RawDexFile::ClassDataHeader header = raw->ReadClassDataHeader(&class_data);
+  const byte* class_data = raw_dex_file.GetClassData(class_def);
+  RawDexFile::ClassDataHeader header = raw_dex_file.ReadClassDataHeader(&class_data);
 
-  const char* descriptor = raw->GetClassDescriptor(class_def);
+  const char* descriptor = raw_dex_file.GetClassDescriptor(class_def);
   CHECK(descriptor != NULL);
 
   klass->klass_ = java_lang_Class_;
@@ -223,10 +250,10 @@
   klass->num_direct_methods_ = header.direct_methods_size_;
   klass->num_virtual_methods_ = header.virtual_methods_size_;
 
-  klass->source_file_ = raw->dexGetSourceFile(class_def);
+  klass->source_file_ = raw_dex_file.dexGetSourceFile(class_def);
 
   // Load class interfaces.
-  LoadInterfaces(class_def, klass);
+  LoadInterfaces(raw_dex_file, class_def, klass);
 
   // Load static fields.
   if (klass->NumStaticFields() != 0) {
@@ -235,10 +262,10 @@
     uint32_t last_idx = 0;
     for (size_t i = 0; i < klass->NumStaticFields(); ++i) {
       RawDexFile::Field raw_field;
-      raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
+      raw_dex_file.dexReadClassDataField(&class_data, &raw_field, &last_idx);
       StaticField* sfield = AllocStaticField();
       klass->sfields_[i] = sfield;
-      LoadField(klass, raw_field, sfield);
+      LoadField(raw_dex_file, raw_field, klass, sfield);
     }
   }
 
@@ -249,10 +276,10 @@
     uint32_t last_idx = 0;
     for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
       RawDexFile::Field raw_field;
-      raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
+      raw_dex_file.dexReadClassDataField(&class_data, &raw_field, &last_idx);
       InstanceField* ifield = AllocInstanceField();
       klass->ifields_[i] = ifield;
-      LoadField(klass, raw_field, ifield);
+      LoadField(raw_dex_file, raw_field, klass, ifield);
     }
   }
 
@@ -263,10 +290,10 @@
     uint32_t last_idx = 0;
     for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
       RawDexFile::Method raw_method;
-      raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
+      raw_dex_file.dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
       Method* meth = AllocMethod();
       klass->direct_methods_[i] = meth;
-      LoadMethod(klass, raw_method, meth);
+      LoadMethod(raw_dex_file, raw_method, klass, meth);
       // TODO: register maps
     }
   }
@@ -278,19 +305,19 @@
     uint32_t last_idx = 0;
     for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
       RawDexFile::Method raw_method;
-      raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
+      raw_dex_file.dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
       Method* meth = AllocMethod();
       klass->virtual_methods_[i] = meth;
-      LoadMethod(klass, raw_method, meth);
+      LoadMethod(raw_dex_file, raw_method, klass, meth);
       // TODO: register maps
     }
   }
 }
 
-void ClassLinker::LoadInterfaces(const RawDexFile::ClassDef& class_def,
+void ClassLinker::LoadInterfaces(const RawDexFile& raw_dex_file,
+                                 const RawDexFile::ClassDef& class_def,
                                  Class* klass) {
-  const RawDexFile* raw = klass->GetDexFile()->GetRaw();
-  const RawDexFile::TypeList* list = raw->GetInterfacesList(class_def);
+  const RawDexFile::TypeList* list = raw_dex_file.GetInterfacesList(class_def);
   if (list != NULL) {
     klass->interface_count_ = list->Size();
     // TODO: allocate the interfaces array on the object heap.
@@ -302,29 +329,31 @@
   }
 }
 
-void ClassLinker::LoadField(Class* klass, const RawDexFile::Field& src,
+void ClassLinker::LoadField(const RawDexFile& raw_dex_file,
+                            const RawDexFile::Field& src,
+                            Class* klass,
                             Field* dst) {
-  const RawDexFile* raw = klass->GetDexFile()->GetRaw();
-  const RawDexFile::FieldId& field_id = raw->GetFieldId(src.field_idx_);
+  const RawDexFile::FieldId& field_id = raw_dex_file.GetFieldId(src.field_idx_);
   dst->klass_ = klass;
-  dst->name_ = raw->dexStringById(field_id.name_idx_);
-  dst->signature_ = raw->dexStringByTypeIdx(field_id.type_idx_);
+  dst->name_ = raw_dex_file.dexStringById(field_id.name_idx_);
+  dst->signature_ = raw_dex_file.dexStringByTypeIdx(field_id.type_idx_);
   dst->access_flags_ = src.access_flags_;
 }
 
-void ClassLinker::LoadMethod(Class* klass, const RawDexFile::Method& src,
+void ClassLinker::LoadMethod(const RawDexFile& raw_dex_file,
+                             const RawDexFile::Method& src,
+                             Class* klass,
                              Method* dst) {
-  const RawDexFile* raw = klass->GetDexFile()->GetRaw();
-  const RawDexFile::MethodId& method_id = raw->GetMethodId(src.method_idx_);
+  const RawDexFile::MethodId& method_id = raw_dex_file.GetMethodId(src.method_idx_);
   dst->klass_ = klass;
-  dst->name_.set(raw->dexStringById(method_id.name_idx_));
+  dst->name_.set(raw_dex_file.dexStringById(method_id.name_idx_));
   dst->proto_idx_ = method_id.proto_idx_;
-  dst->shorty_.set(raw->GetShorty(method_id.proto_idx_));
+  dst->shorty_.set(raw_dex_file.GetShorty(method_id.proto_idx_));
   dst->access_flags_ = src.access_flags_;
 
   // TODO: check for finalize method
 
-  const RawDexFile::CodeItem* code_item = raw->GetCodeItem(src);
+  const RawDexFile::CodeItem* code_item = raw_dex_file.GetCodeItem(src);
   if (code_item != NULL) {
     dst->num_registers_ = code_item->registers_size_;
     dst->num_ins_ = code_item->ins_size_;
@@ -340,19 +369,53 @@
   }
 }
 
-ClassLinker::ClassPathEntry ClassLinker::FindInClassPath(const StringPiece& descriptor) {
-  for (size_t i = 0; i != class_path_.size(); ++i) {
-    DexFile* dex_file = class_path_[i];
-    const RawDexFile::ClassDef* class_def = dex_file->GetRaw()->FindClassDef(descriptor);
+ClassLinker::ClassPathEntry ClassLinker::FindInBootClassPath(const StringPiece& descriptor) {
+  for (size_t i = 0; i != boot_class_path_.size(); ++i) {
+    RawDexFile* raw_dex_file = boot_class_path_[i];
+    const RawDexFile::ClassDef* class_def = raw_dex_file->FindClassDef(descriptor);
     if (class_def != NULL) {
-      return ClassPathEntry(dex_file, class_def);
+      return ClassPathEntry(raw_dex_file, class_def);
     }
   }
   return ClassPathEntry(NULL, NULL);
 }
 
-void ClassLinker::AppendToClassPath(DexFile* dex_file) {
-  class_path_.push_back(dex_file);
+void ClassLinker::AppendToBootClassPath(RawDexFile* raw_dex_file) {
+  boot_class_path_.push_back(raw_dex_file);
+  RegisterDexFile(raw_dex_file);
+}
+
+void ClassLinker::RegisterDexFile(RawDexFile* raw_dex_file) {
+  raw_dex_files_.push_back(raw_dex_file);
+  DexFile* dex_file = AllocDexFile();
+  CHECK(dex_file != NULL);
+  dex_file->Init(AllocObjectArray(raw_dex_file->NumStringIds()),
+                 AllocObjectArray(raw_dex_file->NumTypeIds()),
+                 AllocObjectArray(raw_dex_file->NumMethodIds()),
+                 AllocObjectArray(raw_dex_file->NumFieldIds()));
+  dex_files_.push_back(dex_file);
+}
+
+const RawDexFile* ClassLinker::FindRawDexFile(const DexFile* dex_file) const {
+  CHECK(dex_file != NULL);
+  for (size_t i = 0; i != dex_files_.size(); ++i) {
+    if (dex_files_[i] == dex_file) {
+        return raw_dex_files_[i];
+    }
+  }
+  CHECK(false) << "Could not find RawDexFile";
+  return NULL;
+}
+
+DexFile* ClassLinker::FindDexFile(const RawDexFile* raw_dex_file) const {
+  CHECK(raw_dex_file != NULL);
+  for (size_t i = 0; i != raw_dex_files_.size(); ++i) {
+    if (raw_dex_files_[i] == raw_dex_file) {
+        return dex_files_[i];
+    }
+  }
+  CHECK(false) << "Could not find DexFile";
+  return NULL;
 }
 
 Class* ClassLinker::CreatePrimitiveClass(const StringPiece& descriptor) {
@@ -381,7 +444,9 @@
 // always comes from the base element class.
 //
 // Returns NULL with an exception raised on failure.
-Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor, Object* class_loader)
+Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor,
+                                     Object* class_loader,
+                                     const RawDexFile* raw_dex_file)
 {
     CHECK(descriptor[0] == '[');
     DCHECK(java_lang_Class_ != NULL);
@@ -392,7 +457,7 @@
     int array_rank;
     if (descriptor[1] == '[') {
         // array of arrays; keep descriptor and grab stuff from parent
-        Class* outer = FindClass(descriptor.substr(1), class_loader);
+        Class* outer = FindClass(descriptor.substr(1), class_loader, raw_dex_file);
         if (outer != NULL) {
             // want the base class, not "outer", in our component_type_
             component_type_ = outer->component_type_;
@@ -405,8 +470,7 @@
         if (descriptor[1] == 'L') {
             // array of objects; strip off "[" and look up descriptor.
             const StringPiece subDescriptor = descriptor.substr(1);
-            LG << "searching for element class '" << subDescriptor << "'";
-            component_type_ = FindClass(subDescriptor, class_loader);  // TODO FindClassNoInit
+            component_type_ = FindClass(subDescriptor, class_loader, raw_dex_file);
         } else {
             // array of a primitive type
             component_type_ = FindPrimitiveClass(descriptor[1]);
@@ -474,7 +538,7 @@
     // interfaces.  We need to set that up here, so that stuff like
     // "instanceof" works right.
     //
-    // Note: The GC could run during the call to FindSystemClassNoInit(),
+    // Note: The GC could run during the call to FindSystemClass,
     // so we need to make sure the class object is GC-valid while we're in
     // there.  Do this by clearing the interface list so the GC will just
     // think that the entries are null.
@@ -735,7 +799,7 @@
 bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
                                                  const Class* klass1,
                                                  const Class* klass2) {
-  const RawDexFile* raw = method->GetClass()->GetDexFile()->GetRaw();
+  const RawDexFile* raw = FindRawDexFile(method->GetClass()->GetDexFile());
   const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_);
   RawDexFile::ParameterIterator *it;
   for (it = raw->GetParameterIterator(proto_id); it->HasNext(); it->Next()) {
@@ -769,9 +833,9 @@
   CHECK(klass1 != NULL);
   CHECK(klass2 != NULL);
 #if 0
-  Class* found1 = FindClassNoInit(descriptor, klass1->GetClassLoader());
+  Class* found1 = FindClass(descriptor, klass1->GetClassLoader());
   // TODO: found1 == NULL
-  Class* found2 = FindClassNoInit(descriptor, klass2->GetClassLoader());
+  Class* found2 = FindClass(descriptor, klass2->GetClassLoader());
   // TODO: found2 == NULL
   // TODO: lookup found1 in initiating loader list
   if (found1 == NULL || found2 == NULL) {
@@ -786,6 +850,44 @@
   return true;
 }
 
+bool ClassLinker::HasSameArgumentTypes(const Method* m1, const Method* m2) const {
+  const RawDexFile* raw1 = FindRawDexFile(m1->GetClass()->GetDexFile());
+  const RawDexFile* raw2 = FindRawDexFile(m2->GetClass()->GetDexFile());
+  const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(m1->proto_idx_);
+  const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(m2->proto_idx_);
+
+  // TODO: compare ProtoId objects for equality and exit early
+  const RawDexFile::TypeList* type_list1 = raw1->GetProtoParameters(proto1);
+  const RawDexFile::TypeList* type_list2 = raw2->GetProtoParameters(proto2);
+  size_t arity1 = (type_list1 == NULL) ? 0 : type_list1->Size();
+  size_t arity2 = (type_list2 == NULL) ? 0 : type_list2->Size();
+  if (arity1 != arity2) {
+    return false;
+  }
+
+  for (size_t i = 0; i < arity1; ++i) {
+    uint32_t type_idx1 = type_list1->GetTypeItem(i).type_idx_;
+    uint32_t type_idx2 = type_list2->GetTypeItem(i).type_idx_;
+    const char* type1 = raw1->dexStringByTypeIdx(type_idx1);
+    const char* type2 = raw2->dexStringByTypeIdx(type_idx2);
+    if (strcmp(type1, type2) != 0) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool ClassLinker::HasSameReturnType(const Method* m1, const Method* m2) const {
+  const RawDexFile* raw1 = FindRawDexFile(m1->GetClass()->GetDexFile());
+  const RawDexFile* raw2 = FindRawDexFile(m2->GetClass()->GetDexFile());
+  const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(m1->proto_idx_);
+  const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(m2->proto_idx_);
+  const char* type1 = raw1->dexStringByTypeIdx(proto1.return_type_idx_);
+  const char* type2 = raw2->dexStringByTypeIdx(proto2.return_type_idx_);
+  return (strcmp(type1, type2) == 0);
+}
+
 bool ClassLinker::InitializeSuperClass(Class* klass) {
   CHECK(klass != NULL);
   // TODO: assert klass lock is acquired
@@ -817,7 +919,7 @@
     return;
   }
   const StringPiece& descriptor = klass->GetDescriptor();
-  const RawDexFile* raw = dex_file->GetRaw();
+  const RawDexFile* raw = FindRawDexFile(dex_file);
   const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
   CHECK(class_def != NULL);
   const byte* addr = raw->GetEncodedArray(*class_def);
@@ -866,11 +968,11 @@
   }
 }
 
-bool ClassLinker::LinkClass(Class* klass) {
+bool ClassLinker::LinkClass(Class* klass, const RawDexFile* raw_dex_file) {
   CHECK(klass->status_ == Class::kStatusIdx ||
         klass->status_ == Class::kStatusLoaded);
   if (klass->status_ == Class::kStatusIdx) {
-    if (!LinkInterfaces(klass)) {
+    if (!LinkInterfaces(klass, raw_dex_file)) {
       return false;
     }
   }
@@ -889,7 +991,7 @@
   return true;
 }
 
-bool ClassLinker::LinkInterfaces(Class* klass) {
+bool ClassLinker::LinkInterfaces(Class* klass, const RawDexFile* raw_dex_file) {
   scoped_array<uint32_t> interfaces_idx;
   // TODO: store interfaces_idx in the Class object
   // TODO: move this outside of link interfaces
@@ -902,7 +1004,7 @@
   // Mark the class as loaded.
   klass->status_ = Class::kStatusLoaded;
   if (klass->super_class_idx_ != RawDexFile::kDexNoIndex) {
-    Class* super_class = ResolveClass(klass, klass->super_class_idx_);
+    Class* super_class = ResolveClass(klass, klass->super_class_idx_, raw_dex_file);
     if (super_class == NULL) {
       LG << "Failed to resolve superclass";
       return false;
@@ -912,7 +1014,7 @@
   if (klass->interface_count_ > 0) {
     for (size_t i = 0; i < klass->interface_count_; ++i) {
       uint32_t idx = interfaces_idx[i];
-      klass->interfaces_[i] = ResolveClass(klass, idx);
+      klass->interfaces_[i] = ResolveClass(klass, idx, raw_dex_file);
       if (klass->interfaces_[i] == NULL) {
         LG << "Failed to resolve interface";
         return false;
@@ -1004,7 +1106,7 @@
       size_t j = 0;
       for (; j < klass->GetSuperClass()->vtable_count_; ++j) {
         const Method* super_method = klass->vtable_[j];
-        if (local_method->HasSameNameAndPrototype(super_method)) {
+        if (HasSameNameAndPrototype(local_method, super_method)) {
           // Verify
           if (super_method->IsFinal()) {
             LG << "Method overrides final method";  // TODO: VirtualMachineError
@@ -1115,7 +1217,7 @@
       Method* interface_method = interface->GetVirtualMethod(j);
       int k;  // must be signed
       for (k = klass->vtable_count_ - 1; k >= 0; --k) {
-        if (interface_method->HasSameNameAndPrototype(klass->vtable_[k])) {
+        if (HasSameNameAndPrototype(interface_method, klass->vtable_[k])) {
           if (!klass->vtable_[k]->IsPublic()) {
             LG << "Implementation not public";
             return false;
@@ -1135,7 +1237,7 @@
         }
         int mir;
         for (mir = 0; mir < miranda_count; mir++) {
-          if (miranda_list[mir]->HasSameNameAndPrototype(interface_method)) {
+          if (HasSameNameAndPrototype(miranda_list[mir], interface_method)) {
             break;
           }
         }
@@ -1349,17 +1451,19 @@
   }
 }
 
-Class* ClassLinker::ResolveClass(const Class* referrer, uint32_t class_idx) {
+Class* ClassLinker::ResolveClass(const Class* referrer,
+                                 uint32_t class_idx,
+                                 const RawDexFile* raw_dex_file) {
   DexFile* dex_file = referrer->GetDexFile();
   Class* resolved = dex_file->GetResolvedClass(class_idx);
   if (resolved != NULL) {
     return resolved;
   }
-  const char* descriptor = dex_file->GetRaw()->dexStringByTypeIdx(class_idx);
+  const char* descriptor = raw_dex_file->dexStringByTypeIdx(class_idx);
   if (descriptor[0] != '\0' && descriptor[1] == '\0') {
     resolved = FindPrimitiveClass(descriptor[0]);
   } else {
-    resolved = FindClass(descriptor, referrer->GetClassLoader());
+    resolved = FindClass(descriptor, referrer->GetClassLoader(), raw_dex_file);
   }
   if (resolved != NULL) {
     Class* check = resolved->IsArray() ? resolved->component_type_ : resolved;
@@ -1369,7 +1473,7 @@
         return NULL;
       }
     }
-    dex_file->SetResolvedClass(resolved, class_idx);
+    dex_file->SetResolvedClass(class_idx, resolved);
   } else {
     DCHECK(Thread::Current()->IsExceptionPending());
   }
@@ -1384,14 +1488,14 @@
 
 String* ClassLinker::ResolveString(const Class* referring,
                                    uint32_t string_idx) {
-  const RawDexFile* raw = referring->GetDexFile()->GetRaw();
+  const RawDexFile* raw = FindRawDexFile(referring->GetDexFile());
   const RawDexFile::StringId& string_id = raw->GetStringId(string_idx);
   const char* string_data = raw->GetStringData(string_id);
   String* new_string = Heap::AllocStringFromModifiedUtf8(java_lang_String_,
                                                          char_array_class_,
                                                          string_data);
   // TODO: intern the new string
-  referring->GetDexFile()->SetResolvedString(new_string, string_idx);
+  referring->GetDexFile()->SetResolvedString(string_idx, new_string);
   return new_string;
 }