First pass of compiler wrapping class

Change-Id: I343625310f69cc4de315af91b9cc72bb4da8f59b
diff --git a/build/Android.common.mk b/build/Android.common.mk
index 9e78a96..0011280 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -42,6 +42,7 @@
 	src/assembler.cc \
 	src/calling_convention.cc \
 	src/class_linker.cc \
+	src/compiler.cc \
 	src/dex_cache.cc \
 	src/dex_file.cc \
 	src/dex_instruction.cc \
diff --git a/src/class_linker.cc b/src/class_linker.cc
index c28fc65..f37df3f 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -49,7 +49,7 @@
   "[S",
 };
 
-ClassLinker* ClassLinker::Create(const std::vector<DexFile*>& boot_class_path, Space* space) {
+ClassLinker* ClassLinker::Create(const std::vector<const DexFile*>& boot_class_path, Space* space) {
   scoped_ptr<ClassLinker> class_linker(new ClassLinker);
   if (space == NULL) {
     class_linker->Init(boot_class_path);
@@ -60,8 +60,13 @@
   return class_linker.release();
 }
 
+ClassLinker::ClassLinker()
+    : classes_lock_(Mutex::Create("ClassLinker::Lock")),
+      class_roots_(NULL),
+      init_done_(false) {
+}
 
-void ClassLinker::Init(const std::vector<DexFile*>& boot_class_path) {
+void ClassLinker::Init(const std::vector<const DexFile*>& boot_class_path) {
   CHECK(!init_done_);
 
   // java_lang_Class comes first, its needed for AllocClass
@@ -128,7 +133,9 @@
   // setup boot_class_path_ now that we can use AllocObjectArray to
   // create DexCache instances
   for (size_t i = 0; i != boot_class_path.size(); ++i) {
-    AppendToBootClassPath(boot_class_path[i]);
+    const DexFile* dex_file = boot_class_path[i];
+    CHECK(dex_file != NULL);
+    AppendToBootClassPath(*dex_file);
   }
   // now we can use FindSystemClass, at least for non-arrays classes.
 
@@ -170,6 +177,7 @@
   CHECK(dalvik_system_PathClassLoader != NULL);
   CHECK_EQ(dalvik_system_PathClassLoader->object_size_, sizeof(PathClassLoader));
   SetClassRoot(kDalvikSystemPathClassLoader, dalvik_system_PathClassLoader);
+  PathClassLoader::SetClass(dalvik_system_PathClassLoader);
 
   // Setup a single, global copy of "interfaces" and "iftable" for
   // reuse across array classes
@@ -267,7 +275,7 @@
   Set dex_caches;
 };
 
-void ClassLinker::Init(const std::vector<DexFile*>& boot_class_path, Space* space) {
+void ClassLinker::Init(const std::vector<const DexFile*>& boot_class_path, Space* space) {
   CHECK(!init_done_);
 
   HeapBitmap* heap_bitmap = Heap::GetLiveBits();
@@ -313,9 +321,10 @@
 
   // reinit boot_class_path with DexFile arguments and found DexCaches
   for (size_t i = 0; i != boot_class_path.size(); ++i) {
-    DexFile* dex_file = boot_class_path[i];
+    const DexFile* dex_file = boot_class_path[i];
+    CHECK(dex_file != NULL);
     DexCache* dex_cache = location_to_dex_cache[dex_file->GetLocation()];
-    AppendToBootClassPath(dex_file, dex_cache);
+    AppendToBootClassPath(*dex_file, dex_cache);
   }
 
   String::SetClass(GetClassRoot(kJavaLangString));
@@ -327,6 +336,7 @@
   IntArray::SetArrayClass(GetClassRoot(kIntArrayClass));
   LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
   ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
+  PathClassLoader::SetClass(GetClassRoot(kDalvikSystemPathClassLoader));
 
   FinishInit();
 }
@@ -388,13 +398,27 @@
   root_visitor(array_interfaces_, arg);
 }
 
-DexCache* ClassLinker::AllocDexCache(const DexFile* dex_file) {
+ClassLinker::~ClassLinker() {
+  delete classes_lock_;
+  String::ResetClass();
+  BooleanArray::ResetArrayClass();
+  ByteArray::ResetArrayClass();
+  CharArray::ResetArrayClass();
+  DoubleArray::ResetArrayClass();
+  FloatArray::ResetArrayClass();
+  IntArray::ResetArrayClass();
+  LongArray::ResetArrayClass();
+  ShortArray::ResetArrayClass();
+  PathClassLoader::ResetClass();
+}
+
+DexCache* ClassLinker::AllocDexCache(const DexFile& dex_file) {
   DexCache* dex_cache = down_cast<DexCache*>(AllocObjectArray<Object>(DexCache::kMax));
-  dex_cache->Init(String::AllocFromModifiedUtf8(dex_file->GetLocation().c_str()),
-                  AllocObjectArray<String>(dex_file->NumStringIds()),
-                  AllocObjectArray<Class>(dex_file->NumTypeIds()),
-                  AllocObjectArray<Method>(dex_file->NumMethodIds()),
-                  AllocObjectArray<Field>(dex_file->NumFieldIds()));
+  dex_cache->Init(String::AllocFromModifiedUtf8(dex_file.GetLocation().c_str()),
+                  AllocObjectArray<String>(dex_file.NumStringIds()),
+                  AllocObjectArray<Class>(dex_file.NumTypeIds()),
+                  AllocObjectArray<Method>(dex_file.NumMethodIds()),
+                  AllocObjectArray<Field>(dex_file.NumFieldIds()));
   return dex_cache;
 }
 
@@ -417,15 +441,8 @@
   return down_cast<Method*>(GetClassRoot(kJavaLangReflectMethod)->NewInstance());
 }
 
-// TODO: remove once we can use java.lang.Class.getSystemClassLoader
-PathClassLoader* ClassLinker::AllocPathClassLoader(std::vector<const DexFile*> dex_files) {
-  PathClassLoader* cl = down_cast<PathClassLoader*>(GetClassRoot(kDalvikSystemPathClassLoader)->NewInstance());
-  cl->SetClassPath(dex_files);
-  return cl;
-}
-
 Class* ClassLinker::FindClass(const StringPiece& descriptor,
-                              ClassLoader* class_loader) {
+                              const ClassLoader* class_loader) {
   // TODO: remove this contrived parent class loader check when we have a real ClassLoader.
   if (class_loader != NULL) {
     Class* klass = FindClass(descriptor, NULL);
@@ -445,7 +462,7 @@
     if (descriptor[0] == '[') {
       return CreateArrayClass(descriptor, class_loader);
     }
-    DexFile::ClassPath& class_path = ((class_loader != NULL) ? class_loader->GetClassPath() : boot_class_path_);
+    const DexFile::ClassPath& class_path = ((class_loader != NULL) ? class_loader->GetClassPath() : boot_class_path_);
     DexFile::ClassPathEntry pair = DexFile::FindInClassPath(descriptor, class_path);
     if (pair.second == NULL) {
       std::string name(PrintableString(descriptor));
@@ -455,7 +472,7 @@
     }
     const DexFile& dex_file = *pair.first;
     const DexFile::ClassDef& dex_class_def = *pair.second;
-    DexCache* dex_cache = FindDexCache(pair.first);
+    DexCache* dex_cache = FindDexCache(dex_file);
     // Load the class from the dex file.
     if (!init_done_) {
       // finish up init of hand crafted class_roots_
@@ -586,7 +603,7 @@
 void ClassLinker::LoadClass(const DexFile& dex_file,
                             const DexFile::ClassDef& dex_class_def,
                             Class* klass,
-                            ClassLoader* class_loader) {
+                            const ClassLoader* class_loader) {
   CHECK(klass != NULL);
   CHECK(klass->dex_cache_ != NULL);
   CHECK_EQ(Class::kStatusNotReady, klass->status_);
@@ -604,7 +621,7 @@
   klass->status_ = Class::kStatusIdx;
 
   klass->super_class_ = NULL;
-  klass->super_class_idx_ = dex_class_def.superclass_idx_;
+  klass->super_class_type_idx_ = dex_class_def.superclass_idx_;
 
   size_t num_static_fields = header.static_fields_size_;
   size_t num_instance_fields = header.instance_fields_size_;
@@ -684,11 +701,11 @@
   if (list != NULL) {
     DCHECK(klass->interfaces_ == NULL);
     klass->interfaces_ = AllocObjectArray<Class>(list->Size());
-    DCHECK(klass->interfaces_idx_ == NULL);
-    klass->interfaces_idx_ = new uint32_t[list->Size()];
+    DCHECK(klass->interfaces_type_idx_ == NULL);
+    klass->interfaces_type_idx_ = new uint32_t[list->Size()];
     for (size_t i = 0; i < list->Size(); ++i) {
       const DexFile::TypeItem& type_item = list->GetTypeItem(i);
-      klass->interfaces_idx_[i] = type_item.type_idx_;
+      klass->interfaces_type_idx_[i] = type_item.type_idx_;
     }
   }
 }
@@ -699,7 +716,7 @@
                             Field* dst) {
   const DexFile::FieldId& field_id = dex_file.GetFieldId(src.field_idx_);
   dst->declaring_class_ = klass;
-  dst->name_ = ResolveString(klass, field_id.name_idx_, dex_file);
+  dst->name_ = ResolveString(dex_file, field_id.name_idx_, klass->GetDexCache());
   dst->descriptor_.set(dex_file.dexStringByTypeIdx(field_id.type_idx_));
   // TODO: Assign dst->type_.
   dst->access_flags_ = src.access_flags_;
@@ -711,7 +728,7 @@
                              Method* dst) {
   const DexFile::MethodId& method_id = dex_file.GetMethodId(src.method_idx_);
   dst->declaring_class_ = klass;
-  dst->name_ = ResolveString(klass, method_id.name_idx_, dex_file);
+  dst->name_ = ResolveString(dex_file, method_id.name_idx_, klass->GetDexCache());
   {
     int32_t utf16_length;
     scoped_array<char> utf8(dex_file.CreateMethodDescriptor(method_id.proto_idx_,
@@ -724,7 +741,7 @@
   dst->access_flags_ = src.access_flags_;
 
   dst->dex_cache_strings_ = klass->dex_cache_->GetStrings();
-  dst->dex_cache_classes_ = klass->dex_cache_->GetClasses();
+  dst->dex_cache_types_ = klass->dex_cache_->GetTypes();
   dst->dex_cache_methods_ = klass->dex_cache_->GetMethods();
   dst->dex_cache_fields_ = klass->dex_cache_->GetFields();
 
@@ -745,27 +762,23 @@
   }
 }
 
-void ClassLinker::AppendToBootClassPath(const DexFile* dex_file) {
-  CHECK(dex_file != NULL);
+void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) {
   AppendToBootClassPath(dex_file, AllocDexCache(dex_file));
 }
 
-void ClassLinker::AppendToBootClassPath(const DexFile* dex_file, DexCache* dex_cache) {
-  CHECK(dex_file != NULL);
+void ClassLinker::AppendToBootClassPath(const DexFile& dex_file, DexCache* dex_cache) {
   CHECK(dex_cache != NULL);
-  boot_class_path_.push_back(dex_file);
+  boot_class_path_.push_back(&dex_file);
   RegisterDexFile(dex_file, dex_cache);
 }
 
-void ClassLinker::RegisterDexFile(const DexFile* dex_file) {
-  CHECK(dex_file != NULL);
+void ClassLinker::RegisterDexFile(const DexFile& dex_file) {
   RegisterDexFile(dex_file, AllocDexCache(dex_file));
 }
 
-void ClassLinker::RegisterDexFile(const DexFile* dex_file, DexCache* dex_cache) {
-  CHECK(dex_file != NULL);
+void ClassLinker::RegisterDexFile(const DexFile& dex_file, DexCache* dex_cache) {
   CHECK(dex_cache != NULL);
-  dex_files_.push_back(dex_file);
+  dex_files_.push_back(&dex_file);
   dex_caches_.push_back(dex_cache);
 }
 
@@ -779,9 +792,9 @@
   return *dex_files_[-1];
 }
 
-DexCache* ClassLinker::FindDexCache(const DexFile* dex_file) const {
+DexCache* ClassLinker::FindDexCache(const DexFile& dex_file) const {
   for (size_t i = 0; i != dex_files_.size(); ++i) {
-    if (dex_files_[i] == dex_file) {
+    if (dex_files_[i] == &dex_file) {
         return dex_caches_[i];
     }
   }
@@ -815,7 +828,7 @@
 //
 // Returns NULL with an exception raised on failure.
 Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor,
-                                     ClassLoader* class_loader)
+                                     const ClassLoader* class_loader)
 {
   CHECK(descriptor[0] == '[');
 
@@ -987,7 +1000,7 @@
   return ((*it).second == klass);
 }
 
-Class* ClassLinker::LookupClass(const StringPiece& descriptor, ClassLoader* class_loader) {
+Class* ClassLinker::LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader) {
   size_t hash = StringPieceHash()(descriptor);
   MutexLock mu(classes_lock_);
   typedef Table::const_iterator It; // TODO: C++0x auto
@@ -1281,7 +1294,7 @@
         break;
       case DexFile::kString: {
         uint32_t string_idx = value.i;
-        String* resolved = ResolveString(klass, string_idx, dex_file);
+        String* resolved = ResolveString(dex_file, string_idx, klass->GetDexCache());
         field->SetObject(NULL, resolved);
         break;
       }
@@ -1320,8 +1333,8 @@
 
 bool ClassLinker::LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file) {
   CHECK_EQ(Class::kStatusIdx, klass->status_);
-  if (klass->super_class_idx_ != DexFile::kDexNoIndex) {
-    Class* super_class = ResolveClass(klass, klass->super_class_idx_, dex_file);
+  if (klass->super_class_type_idx_ != DexFile::kDexNoIndex) {
+    Class* super_class = ResolveType(dex_file, klass->super_class_type_idx_, klass);
     if (super_class == NULL) {
       LG << "Failed to resolve superclass";
       return false;
@@ -1330,8 +1343,8 @@
   }
   if (klass->NumInterfaces() > 0) {
     for (size_t i = 0; i < klass->NumInterfaces(); ++i) {
-      uint32_t idx = klass->interfaces_idx_[i];
-      klass->SetInterface(i, ResolveClass(klass, idx, dex_file));
+      uint32_t type_idx = klass->interfaces_type_idx_[i];
+      klass->SetInterface(i, ResolveType(dex_file, type_idx, klass));
       if (klass->GetInterface(i) == NULL) {
         LG << "Failed to resolve interface";
         return false;
@@ -1798,50 +1811,98 @@
   }
 }
 
-Class* ClassLinker::ResolveClass(const Class* referrer,
-                                 uint32_t class_idx,
-                                 const DexFile& dex_file) {
-  DexCache* dex_cache = referrer->GetDexCache();
-  Class* resolved = dex_cache->GetResolvedClass(class_idx);
+String* ClassLinker::ResolveString(const DexFile& dex_file,
+                                   uint32_t string_idx,
+                                   DexCache* dex_cache) {
+  String* resolved = dex_cache->GetResolvedString(string_idx);
   if (resolved != NULL) {
     return resolved;
   }
-  const char* descriptor = dex_file.dexStringByTypeIdx(class_idx);
+  const DexFile::StringId& string_id = dex_file.GetStringId(string_idx);
+  int32_t utf16_length = dex_file.GetStringLength(string_id);
+  const char* utf8_data = dex_file.GetStringData(string_id);
+  String* string = intern_table_.Intern(utf16_length, utf8_data);
+  dex_cache->SetResolvedString(string_idx, string);
+  return string;
+}
+
+Class* ClassLinker::ResolveType(const DexFile& dex_file,
+                                uint32_t type_idx,
+                                DexCache* dex_cache,
+                                const ClassLoader* class_loader) {
+  Class* resolved = dex_cache->GetResolvedType(type_idx);
+  if (resolved != NULL) {
+    return resolved;
+  }
+  const char* descriptor = dex_file.dexStringByTypeIdx(type_idx);
   if (descriptor[0] != '\0' && descriptor[1] == '\0') {
     resolved = FindPrimitiveClass(descriptor[0]);
   } else {
-    resolved = FindClass(descriptor, referrer->GetClassLoader());
+    resolved = FindClass(descriptor, class_loader);
   }
   if (resolved != NULL) {
     Class* check = resolved->IsArray() ? resolved->component_type_ : resolved;
-    if (referrer->GetDexCache() != check->GetDexCache()) {
+    if (dex_cache != check->GetDexCache()) {
       if (check->GetClassLoader() != NULL) {
         LG << "Class resolved by unexpected DEX";  // TODO: IllegalAccessError
         return NULL;
       }
     }
-    dex_cache->SetResolvedClass(class_idx, resolved);
+    dex_cache->SetResolvedType(type_idx, resolved);
   } else {
     DCHECK(Thread::Current()->IsExceptionPending());
   }
   return resolved;
 }
 
-Method* ResolveMethod(const Class* referrer, uint32_t method_idx,
-                      /*MethodType*/ int method_type) {
-  CHECK(false);
-  return NULL;
+Method* ClassLinker::ResolveMethod(const DexFile& dex_file,
+                                   uint32_t method_idx,
+                                   DexCache* dex_cache,
+                                   const ClassLoader* class_loader,
+                                   /*MethodType*/ int method_type) {
+  Method* resolved = dex_cache->GetResolvedMethod(method_idx);
+  if (resolved != NULL) {
+    return resolved;
+  }
+  const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
+  Class* klass = ResolveType(dex_file, method_id.class_idx_, dex_cache, class_loader);
+  if (klass == NULL) {
+    return NULL;
+  }
+
+  // TODO resolve using class, method_id, and method type.
+  // resolved = ...
+  if (resolved != NULL) {
+    dex_cache->SetResolvedMethod(method_idx, resolved);
+  } else {
+    // DCHECK(Thread::Current()->IsExceptionPending());
+  }
+  return resolved;
 }
 
-String* ClassLinker::ResolveString(const Class* referring,
-                                   uint32_t string_idx,
-                                   const DexFile& dex_file) {
-  const DexFile::StringId& string_id = dex_file.GetStringId(string_idx);
-  int32_t utf16_length = dex_file.GetStringLength(string_id);
-  const char* utf8_data = dex_file.GetStringData(string_id);
-  String* string = intern_table_.Intern(utf16_length, utf8_data);
-  referring->GetDexCache()->SetResolvedString(string_idx, string);
-  return string;
+Field* ClassLinker::ResolveField(const DexFile& dex_file,
+                                 uint32_t field_idx,
+                                 DexCache* dex_cache,
+                                 const ClassLoader* class_loader,
+                                 bool is_static) {
+  Field* resolved = dex_cache->GetResolvedField(field_idx);
+  if (resolved != NULL) {
+    return resolved;
+  }
+  const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
+  Class* klass = ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader);
+  if (klass == NULL) {
+    return NULL;
+  }
+
+  // TODO resolve using class, field_id, and is_static.
+  // resolved = ...
+  if (resolved != NULL) {
+    dex_cache->SetResolvedfield(field_idx, resolved);
+  } else {
+    // DCHECK(Thread::Current()->IsExceptionPending());
+  }
+  return resolved;
 }
 
 }  // namespace art
diff --git a/src/class_linker.h b/src/class_linker.h
index 28dfce7..4cf82c6 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -23,25 +23,14 @@
 class ClassLinker {
  public:
   // Initializes the class linker using DexFile and an optional boot Space.
-  static ClassLinker* Create(const std::vector<DexFile*>& boot_class_path, Space* boot_space);
+  static ClassLinker* Create(const std::vector<const DexFile*>& boot_class_path, Space* boot_space);
 
-  ~ClassLinker() {
-    delete classes_lock_;
-    String::ResetClass();
-    BooleanArray::ResetArrayClass();
-    ByteArray::ResetArrayClass();
-    CharArray::ResetArrayClass();
-    DoubleArray::ResetArrayClass();
-    FloatArray::ResetArrayClass();
-    IntArray::ResetArrayClass();
-    LongArray::ResetArrayClass();
-    ShortArray::ResetArrayClass();
-  }
+  ~ClassLinker();
 
   // Finds a class by its descriptor name.
   // If class_loader is null, searches boot_class_path_.
   Class* FindClass(const StringPiece& descriptor,
-                   ClassLoader* class_loader);
+                   const ClassLoader* class_loader);
 
   Class* FindPrimitiveClass(char type);
 
@@ -49,11 +38,60 @@
     return FindClass(descriptor, NULL);
   }
 
+  // Resolve a String with the given ID from the DexFile, storing the
+  // result in the DexCache.
+  String* ResolveString(const DexFile& dex_file,
+                        uint32_t string_idx,
+                        DexCache* dex_cache);
+
+  // Resolve a Type with the given ID from the DexFile, storing the
+  // result in the DexCache. The referrer is used to identity the
+  // target DexCache and ClassLoader to use for resolution.
+  Class* ResolveType(const DexFile& dex_file,
+                     uint32_t type_idx,
+                     const Class* referrer) {
+    return ResolveType(dex_file,
+                       type_idx,
+                       referrer->GetDexCache(),
+                       referrer->GetClassLoader());
+  }
+
+  // Resolve a type with the given ID from the DexFile, storing the
+  // result in DexCache. The ClassLoader is used to search for the
+  // type, since it may be referenced from but not contained within
+  // the given DexFile.
+  Class* ResolveType(const DexFile& dex_file,
+                     uint32_t type_idx,
+                     DexCache* dex_cache,
+                     const ClassLoader* class_loader);
+
+  // Resolve a method with a given ID from the DexFile, storing the
+  // result in DexCache. The ClassLinker and ClassLoader are used as
+  // in ResolveType. What is unique is the method type argument which
+  // is used to determine if this method is a direct, static, or
+  // virtual method.
+  Method* ResolveMethod(const DexFile& dex_file,
+                        uint32_t method_idx,
+                        DexCache* dex_cache,
+                        const ClassLoader* class_loader,
+                        /*MethodType*/ int method_type);
+
+  // Resolve a method with a given ID from the DexFile, storing the
+  // result in DexCache. The ClassLinker and ClassLoader are used as
+  // in ResolveType. What is unique is the is_static argument which is
+  // used to determine if we are resolving a static or non-static
+  // field.
+  Field* ResolveField(const DexFile& dex_file,
+                      uint32_t field_idx,
+                      DexCache* dex_cache,
+                      const ClassLoader* class_loader,
+                      bool is_static);
+
   // Returns true on success, false if there's an exception pending.
   bool EnsureInitialized(Class* c);
 
-  void RegisterDexFile(const DexFile* dex_file);
-  void RegisterDexFile(const DexFile* dex_file, DexCache* dex_cache);
+  void RegisterDexFile(const DexFile& dex_file);
+  void RegisterDexFile(const DexFile& dex_file, DexCache* dex_cache);
 
   const InternTable& GetInternTable() {
     return intern_table_;
@@ -62,19 +100,16 @@
   void VisitRoots(Heap::RootVistor* root_visitor, void* arg) const;
 
   const DexFile& FindDexFile(const DexCache* dex_cache) const;
+  DexCache* FindDexCache(const DexFile& dex_file) const;
 
  private:
-  ClassLinker()
-      : classes_lock_(Mutex::Create("ClassLinker::Lock")),
-        class_roots_(NULL),
-        init_done_(false) {
-  }
+  ClassLinker();
 
   // Initialize class linker from DexFile instances.
-  void Init(const std::vector<DexFile*>& boot_class_path_);
+  void Init(const std::vector<const DexFile*>& boot_class_path_);
 
   // Initialize class linker from pre-initialized space.
-  void Init(const std::vector<DexFile*>& boot_class_path_, Space* space);
+  void Init(const std::vector<const DexFile*>& boot_class_path_, Space* space);
   static void InitCallback(Object* obj, void *arg);
   struct InitCallbackState;
 
@@ -89,24 +124,21 @@
   // values that are known to the ClassLinker such as
   // kObjectArrayClass and kJavaLangString etc.
   Class* AllocClass(size_t class_size);
-  DexCache* AllocDexCache(const DexFile* dex_file);
+  DexCache* AllocDexCache(const DexFile& dex_file);
   Field* AllocField();
   Method* AllocMethod();
   template <class T>
   ObjectArray<T>* AllocObjectArray(size_t length) {
     return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
   }
-  PathClassLoader* AllocPathClassLoader(std::vector<const DexFile*> dex_files);
 
   Class* CreatePrimitiveClass(const char* descriptor);
 
   Class* CreateArrayClass(const StringPiece& descriptor,
-                          ClassLoader* class_loader);
+                          const ClassLoader* class_loader);
 
-  DexCache* FindDexCache(const DexFile* dex_file) const;
-
-  void AppendToBootClassPath(const DexFile* dex_file);
-  void AppendToBootClassPath(const DexFile* dex_file, DexCache* dex_cache);
+  void AppendToBootClassPath(const DexFile& dex_file);
+  void AppendToBootClassPath(const DexFile& dex_file, DexCache* dex_cache);
 
   size_t SizeOfClass(const DexFile& dex_file,
                      const DexFile::ClassDef& dex_class_def);
@@ -114,7 +146,7 @@
   void LoadClass(const DexFile& dex_file,
                  const DexFile::ClassDef& dex_class_def,
                  Class* klass,
-                 ClassLoader* class_loader);
+                 const ClassLoader* class_loader);
 
   void LoadInterfaces(const DexFile& dex_file,
                       const DexFile::ClassDef& dex_class_def,
@@ -130,15 +162,7 @@
                   Class* klass,
                   Method* dst);
 
-  Class* ResolveClass(const Class* referring,
-                      uint32_t class_idx,
-                      const DexFile& dex_file);
-
-  String* ResolveString(const Class* referring,
-                        uint32_t string_idx,
-                        const DexFile& dex_file);
-
-  Class* LookupClass(const StringPiece& descriptor, ClassLoader* class_loader);
+  Class* LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader);
 
   // Inserts a class into the class table.  Returns true if the class
   // was inserted.
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index e2b9a2b..b5c03fb 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -100,11 +100,11 @@
     EXPECT_TRUE(method->GetSignature() != NULL);
 
     EXPECT_TRUE(method->dex_cache_strings_ != NULL);
-    EXPECT_TRUE(method->dex_cache_classes_ != NULL);
+    EXPECT_TRUE(method->dex_cache_types_ != NULL);
     EXPECT_TRUE(method->dex_cache_methods_ != NULL);
     EXPECT_TRUE(method->dex_cache_fields_ != NULL);
     EXPECT_EQ(method->declaring_class_->dex_cache_->GetStrings(), method->dex_cache_strings_);
-    EXPECT_EQ(method->declaring_class_->dex_cache_->GetClasses(), method->dex_cache_classes_);
+    EXPECT_EQ(method->declaring_class_->dex_cache_->GetTypes(), method->dex_cache_types_);
     EXPECT_EQ(method->declaring_class_->dex_cache_->GetMethods(), method->dex_cache_methods_);
     EXPECT_EQ(method->declaring_class_->dex_cache_->GetFields(), method->dex_cache_fields_);
   }
@@ -231,13 +231,14 @@
 
   void AssertDexFile(const DexFile* dex, ClassLoader* class_loader) {
     ASSERT_TRUE(dex != NULL);
+
     // Verify all the classes defined in this file
     for (size_t i = 0; i < dex->NumClassDefs(); i++) {
       const DexFile::ClassDef& class_def = dex->GetClassDef(i);
       const char* descriptor = dex->GetClassDescriptor(class_def);
       AssertDexFileClass(class_loader, descriptor);
     }
-    // Verify all the types referened by this file
+    // Verify all the types referenced by this file
     for (size_t i = 0; i < dex->NumTypeIds(); i++) {
       const DexFile::TypeId& type_id = dex->GetTypeId(i);
       const char* descriptor = dex->GetTypeDescriptor(type_id);
@@ -354,9 +355,7 @@
 }
 
 TEST_F(ClassLinkerTest, LibCore) {
-  scoped_ptr<DexFile> libcore_dex_file(GetLibCoreDex());
-  EXPECT_TRUE(libcore_dex_file.get() != NULL);
-  AssertDexFile(libcore_dex_file.get(), NULL);
+  AssertDexFile(java_lang_dex_file_.get(), NULL);
 }
 
 // C++ fields must exactly match the fields in the Java classes. If this fails,
diff --git a/src/common_test.h b/src/common_test.h
index a405ce5..1b0404e 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -444,10 +444,9 @@
 
     java_lang_dex_file_.reset(GetLibCoreDex());
 
-    std::vector<const DexFile*> boot_class_path;
-    boot_class_path.push_back(java_lang_dex_file_.get());
+    boot_class_path_.push_back(java_lang_dex_file_.get());
 
-    runtime_.reset(Runtime::Create(boot_class_path));
+    runtime_.reset(Runtime::Create(boot_class_path_));
     ASSERT_TRUE(runtime_ != NULL);
     class_linker_ = runtime_->GetClassLinker();
   }
@@ -505,16 +504,18 @@
   }
 
   PathClassLoader* AllocPathClassLoader(const DexFile* dex_file) {
-    class_linker_->RegisterDexFile(dex_file);
+    CHECK(dex_file != NULL);
+    class_linker_->RegisterDexFile(*dex_file);
     std::vector<const DexFile*> dex_files;
     dex_files.push_back(dex_file);
-    return class_linker_->AllocPathClassLoader(dex_files);
+    return PathClassLoader::Alloc(dex_files);
   }
 
   bool is_host_;
   scoped_ptr_malloc<char> android_data_;
   std::string art_cache_;
   scoped_ptr<const DexFile> java_lang_dex_file_;
+  std::vector<const DexFile*> boot_class_path_;
   scoped_ptr<Runtime> runtime_;
   ClassLinker* class_linker_;
 };
diff --git a/src/compiler.cc b/src/compiler.cc
new file mode 100644
index 0000000..8f529ce
--- /dev/null
+++ b/src/compiler.cc
@@ -0,0 +1,83 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "compiler.h"
+
+#include "class_linker.h"
+#include "dex_cache.h"
+
+extern bool oatCompileMethod(art::Method*, art::InstructionSet);
+
+namespace art {
+
+void Compiler::Compile(std::vector<const DexFile*> class_path) {
+  ClassLoader* class_loader = PathClassLoader::Alloc(class_path);
+  Resolve(class_loader);
+  for (size_t i = 0; i != class_path.size(); ++i) {
+    const DexFile* dex_file = class_path[i];
+    CHECK(dex_file != NULL);
+    CompileDexFile(class_loader, *dex_file);
+  }
+}
+
+void Compiler::Resolve(const ClassLoader* class_loader) {
+  const std::vector<const DexFile*>& class_path = class_loader->GetClassPath();
+  for (size_t i = 0; i != class_path.size(); ++i) {
+    const DexFile* dex_file = class_path[i];
+    CHECK(dex_file != NULL);
+    ResolveDexFile(class_loader, *dex_file);
+  }
+}
+
+void Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+
+  // Strings are easy, they always are simply resolved to literals in the same file
+  DexCache* dex_cache = class_linker->FindDexCache(dex_file);
+  for (size_t i = 0; i < dex_cache->NumStrings(); i++) {
+    class_linker->ResolveString(dex_file, i, dex_cache);
+  }
+
+  // Class derived values are more complicated, they require the linker and loader
+  for (size_t i = 0; i < dex_cache->NumTypes(); i++) {
+    class_linker->ResolveType(dex_file, i, dex_cache, class_loader);
+  }
+  for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
+    // TODO: move resolution into compiler proper where we will know method_type
+    int method_type = 0;
+    class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, method_type);
+  }
+  for (size_t i = 0; i < dex_cache->NumFields(); i++) {
+    // TODO: move resolution into compiler proper where we will know is_static
+    bool is_static = false;
+    class_linker->ResolveField(dex_file, i, dex_cache, class_loader, is_static);
+  }
+}
+
+void Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  for (size_t i = 0; i < dex_file.NumClassDefs(); i++) {
+    const DexFile::ClassDef& class_def = dex_file.GetClassDef(i);
+    const char* descriptor = dex_file.GetClassDescriptor(class_def);
+    Class* klass = class_linker->FindClass(descriptor, class_loader);
+    CHECK(klass != NULL);
+    CompileClass(klass);
+  }
+}
+
+void Compiler::CompileClass(Class* klass) {
+  for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
+    CompileMethod(klass->GetDirectMethod(i));
+  }
+  for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
+    CompileMethod(klass->GetVirtualMethod(i));
+  }
+}
+
+void Compiler::CompileMethod(Method* method) {
+// TODO need to compile art/src/compiler for host as well as target
+#ifdef __arm__
+  oatCompileMethod(method, kThumb2);
+#endif
+}
+
+}  // namespace art
diff --git a/src/compiler.h b/src/compiler.h
new file mode 100644
index 0000000..1e5da6b
--- /dev/null
+++ b/src/compiler.h
@@ -0,0 +1,29 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#ifndef ART_SRC_COMPILER_H_
+#define ART_SRC_COMPILER_H_
+
+#include "dex_file.h"
+#include "object.h"
+
+namespace art {
+
+class Compiler {
+ public:
+  void Compile(std::vector<const DexFile*> class_path);
+
+ private:
+  // Attempt to resolve all type, methods, fields, and strings
+  // referenced from code in the dex file following PathClassLoader
+  // ordering semantics.
+  void Resolve(const ClassLoader* class_loader);
+  void ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
+
+  void CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
+  void CompileClass(Class* klass);
+  void CompileMethod(Method* klass);
+};
+
+}  // namespace art
+
+#endif  // ART_SRC_COMPILER_H_
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index 483d7a7..673aaba 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -26,7 +26,7 @@
 {
     oatFlushAllRegs(cUnit);  /* All temps to home location */
     Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
-        GetResolvedClass(mir->dalvikInsn.vC);
+        GetResolvedType(mir->dalvikInsn.vC);
     if (classPtr == NULL) {
          LOG(FATAL) << "Unexpected null classPtr";
     } else {
@@ -62,7 +62,7 @@
     }
     oatFlushAllRegs(cUnit);  /* All temps to home location */
     Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
-        GetResolvedClass(typeIndex);
+        GetResolvedType(typeIndex);
     if (classPtr == NULL) {
          LOG(FATAL) << "Unexpected null classPtr";
     } else {
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 934a303..e06910d 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -521,7 +521,7 @@
                           RegLocation rlDest, RegLocation rlSrc)
 {
     Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
-        GetResolvedClass(mir->dalvikInsn.vB);
+        GetResolvedType(mir->dalvikInsn.vB);
 
     if (classPtr == NULL) {
         LOG(FATAL) << "Unexpected null class pointer";
@@ -554,7 +554,7 @@
                            RegLocation rlDest)
 {
     Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
-        GetResolvedClass(mir->dalvikInsn.vB);
+        GetResolvedType(mir->dalvikInsn.vB);
 
     if (classPtr == NULL) {
         /* Shouldn't happen */
@@ -590,7 +590,7 @@
    // May generate a call - use explicit registers
     RegLocation rlResult;
     Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
-        GetResolvedClass(mir->dalvikInsn.vC);
+        GetResolvedType(mir->dalvikInsn.vC);
     if (classPtr == NULL) {
         /* Shouldn't happen */
         LOG(FATAL) << "Unexpected null class pointer";
@@ -625,7 +625,7 @@
 static void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
 {
     Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
-        GetResolvedClass(mir->dalvikInsn.vB);
+        GetResolvedType(mir->dalvikInsn.vB);
     if (classPtr == NULL) {
         /* Shouldn't happen with our current model */
         LOG(FATAL) << "Unexpected null class pointer";
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index 8e79155..4692f82 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -2,7 +2,9 @@
 
 #include "class_linker.h"
 #include "common_test.h"
+#include "compiler.h"
 #include "compiler_test.h"
+#include "dex_cache.h"
 #include "dex_file.h"
 #include "heap.h"
 #include "object.h"
@@ -17,6 +19,39 @@
 class CompilerTest : public CommonTest {
 };
 
+TEST_F(CompilerTest, CompileLibCore) {
+  Compiler compiler;
+  compiler.Compile(boot_class_path_);
+
+  // All libcore references should resolve
+  const DexFile* dex = java_lang_dex_file_.get();
+  DexCache* dex_cache = class_linker_->FindDexCache(*dex);
+  EXPECT_EQ(dex->NumStringIds(), dex_cache->NumStrings());
+  for (size_t i = 0; i < dex_cache->NumStrings(); i++) {
+    String* string = dex_cache->GetResolvedString(i);
+    EXPECT_TRUE(string != NULL);
+  }
+  EXPECT_EQ(dex->NumTypeIds(), dex_cache->NumTypes());
+  for (size_t i = 0; i < dex_cache->NumTypes(); i++) {
+    Class* type = dex_cache->GetResolvedType(i);
+    EXPECT_TRUE(type != NULL);
+  }
+  EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumMethods());
+  for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
+    // TODO: ClassLinker::ResolveMethod
+    // Method* method = dex_cache->GetResolvedMethod(i);
+    // EXPECT_TRUE(method != NULL);
+  }
+  EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumFields());
+  for (size_t i = 0; i < dex_cache->NumFields(); i++) {
+    // TODO: ClassLinker::ResolveField
+    // Field* field = dex_cache->GetResolvedField(i);
+    // EXPECT_TRUE(field != NULL);
+  }
+
+}
+
+
 #if defined(__arm__)
 TEST_F(CompilerTest, BasicCodegen) {
   scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kFibonacciDex,
diff --git a/src/dex_cache.cc b/src/dex_cache.cc
index 3bd04eb..a012c71 100644
--- a/src/dex_cache.cc
+++ b/src/dex_cache.cc
@@ -1,5 +1,6 @@
 // Copyright 2011 Google Inc. All Rights Reserved.
 
+#include "class_linker.h"
 #include "dex_cache.h"
 #include "heap.h"
 #include "globals.h"
@@ -10,12 +11,12 @@
 
 void DexCache::Init(String* location,
                     ObjectArray<String>* strings,
-                    ObjectArray<Class>* classes,
+                    ObjectArray<Class>* types,
                     ObjectArray<Method>* methods,
                     ObjectArray<Field>* fields) {
   Set(kLocation, location);
   Set(kStrings,  strings);
-  Set(kClasses,  classes);
+  Set(kTypes,    types);
   Set(kMethods,  methods);
   Set(kFields,   fields);
 }
diff --git a/src/dex_cache.h b/src/dex_cache.h
index f34dbe4..13c900e 100644
--- a/src/dex_cache.h
+++ b/src/dex_cache.h
@@ -3,6 +3,7 @@
 #ifndef ART_SRC_DEX_CACHE_H_
 #define ART_SRC_DEX_CACHE_H_
 
+#include "dex_file.h"
 #include "globals.h"
 #include "macros.h"
 #include "object.h"
@@ -21,7 +22,7 @@
   enum ArrayIndex {
     kLocation = 0,
     kStrings  = 1,
-    kClasses  = 2,
+    kTypes    = 2,
     kMethods  = 3,
     kFields   = 4,
     kMax      = 5,
@@ -29,7 +30,7 @@
 
   void Init(String* location,
             ObjectArray<String>* strings,
-            ObjectArray<Class>* classes,
+            ObjectArray<Class>* types,
             ObjectArray<Method>* methods,
             ObjectArray<Field>* fields);
 
@@ -41,8 +42,8 @@
     return GetStrings()->GetLength();
   }
 
-  size_t NumClasses() const {
-    return GetClasses()->GetLength();
+  size_t NumTypes() const {
+    return GetTypes()->GetLength();
   }
 
   size_t NumMethods() const {
@@ -61,12 +62,12 @@
     GetStrings()->Set(string_idx, resolved);
   }
 
-  Class* GetResolvedClass(uint32_t class_idx) const {
-    return GetClasses()->Get(class_idx);
+  Class* GetResolvedType(uint32_t type_idx) const {
+    return GetTypes()->Get(type_idx);
   }
 
-  void SetResolvedClass(uint32_t class_idx, Class* resolved) {
-    GetClasses()->Set(class_idx, resolved);
+  void SetResolvedType(uint32_t type_idx, Class* resolved) {
+    GetTypes()->Set(type_idx, resolved);
   }
 
   Method* GetResolvedMethod(uint32_t method_idx) const {
@@ -88,8 +89,8 @@
   ObjectArray<String>* GetStrings() const {
     return static_cast<ObjectArray<String>*>(GetNonNull(kStrings));
   }
-  ObjectArray<Class>* GetClasses() const {
-    return static_cast<ObjectArray<Class>*>(GetNonNull(kClasses));
+  ObjectArray<Class>* GetTypes() const {
+    return static_cast<ObjectArray<Class>*>(GetNonNull(kTypes));
   }
   ObjectArray<Method>* GetMethods() const {
     return static_cast<ObjectArray<Method>*>(GetNonNull(kMethods));
diff --git a/src/dex_cache_test.cc b/src/dex_cache_test.cc
index 71125cc..6ecaa18 100644
--- a/src/dex_cache_test.cc
+++ b/src/dex_cache_test.cc
@@ -16,23 +16,23 @@
 
 TEST_F(DexCacheTest, Open) {
 
-  DexCache* dex_cache = class_linker_->AllocDexCache(java_lang_dex_file_.get());
+  DexCache* dex_cache = class_linker_->AllocDexCache(*java_lang_dex_file_.get());
   ASSERT_TRUE(dex_cache != NULL);
 
   EXPECT_EQ(java_lang_dex_file_->NumStringIds(), dex_cache->NumStrings());
-  EXPECT_EQ(java_lang_dex_file_->NumTypeIds(),   dex_cache->NumClasses());
+  EXPECT_EQ(java_lang_dex_file_->NumTypeIds(),   dex_cache->NumTypes());
   EXPECT_EQ(java_lang_dex_file_->NumMethodIds(), dex_cache->NumMethods());
   EXPECT_EQ(java_lang_dex_file_->NumFieldIds(),  dex_cache->NumFields());
 
   EXPECT_LE(0, dex_cache->GetStrings()->GetLength());
-  EXPECT_LE(0, dex_cache->GetClasses()->GetLength());
+  EXPECT_LE(0, dex_cache->GetTypes()->GetLength());
   EXPECT_LE(0, dex_cache->GetMethods()->GetLength());
   EXPECT_LE(0, dex_cache->GetFields()->GetLength());
 
   EXPECT_EQ(java_lang_dex_file_->NumStringIds(),
             static_cast<uint32_t>(dex_cache->GetStrings()->GetLength()));
   EXPECT_EQ(java_lang_dex_file_->NumTypeIds(),
-            static_cast<uint32_t>(dex_cache->GetClasses()->GetLength()));
+            static_cast<uint32_t>(dex_cache->GetTypes()->GetLength()));
   EXPECT_EQ(java_lang_dex_file_->NumMethodIds(),
             static_cast<uint32_t>(dex_cache->GetMethods()->GetLength()));
   EXPECT_EQ(java_lang_dex_file_->NumFieldIds(),
diff --git a/src/dex_file.cc b/src/dex_file.cc
index b575bcf..c828df6 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -27,7 +27,7 @@
 const byte DexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' };
 
 DexFile::ClassPathEntry DexFile::FindInClassPath(const StringPiece& descriptor,
-                                                 ClassPath& class_path) {
+                                                 const ClassPath& class_path) {
   for (size_t i = 0; i != class_path.size(); ++i) {
     const DexFile* dex_file = class_path[i];
     const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor);
diff --git a/src/dex_file.h b/src/dex_file.h
index 1431f1e..d1125df 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -309,7 +309,7 @@
 
   // Search a collection of DexFiles for a descriptor
   static ClassPathEntry FindInClassPath(const StringPiece& descriptor,
-                                        ClassPath& class_path);
+                                        const ClassPath& class_path);
 
   // Opens a .dex file from the file system.
   static DexFile* OpenFile(const std::string& filename);
diff --git a/src/object.cc b/src/object.cc
index 20e462a..bb60dc1 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -567,6 +567,26 @@
   java_lang_String_ = NULL;
 }
 
+// TODO: get global references for these
+Class* PathClassLoader::dalvik_system_PathClassLoader_ = NULL;
+
+PathClassLoader* PathClassLoader::Alloc(std::vector<const DexFile*> dex_files) {
+  PathClassLoader* p = down_cast<PathClassLoader*>(dalvik_system_PathClassLoader_->NewInstance());
+  p->SetClassPath(dex_files);
+  return p;
+}
+
+void PathClassLoader::SetClass(Class* dalvik_system_PathClassLoader) {
+  CHECK(dalvik_system_PathClassLoader_ == NULL);
+  CHECK(dalvik_system_PathClassLoader != NULL);
+  dalvik_system_PathClassLoader_ = dalvik_system_PathClassLoader;
+}
+
+void PathClassLoader::ResetClass() {
+  CHECK(dalvik_system_PathClassLoader_ != NULL);
+  dalvik_system_PathClassLoader_ = NULL;
+}
+
 static const char* kClassStatusNames[] = {
   "Error",
   "NotReady",
diff --git a/src/object.h b/src/object.h
index c8b8ec3..f3cd0fd 100644
--- a/src/object.h
+++ b/src/object.h
@@ -715,7 +715,7 @@
   // short cuts to declaring_class_->dex_cache_ members for fast compiled code
   // access
   ObjectArray<String>* dex_cache_strings_;
-  ObjectArray<Class>* dex_cache_classes_;
+  ObjectArray<Class>* dex_cache_types_;
   ObjectArray<Method>* dex_cache_methods_;
   ObjectArray<Field>* dex_cache_fields_;
 
@@ -858,7 +858,7 @@
 // ClassLoader objects.
 class ClassLoader : public Object {
  public:
-  std::vector<const DexFile*>& GetClassPath() {
+  const std::vector<const DexFile*>& GetClassPath() const {
     return class_path_;
   }
   void SetClassPath(std::vector<const DexFile*>& class_path) {
@@ -886,7 +886,12 @@
 };
 
 class PathClassLoader : public BaseDexClassLoader {
+ public:
+  static PathClassLoader* Alloc(std::vector<const DexFile*> dex_files);
+  static void SetClass(Class* dalvik_system_PathClassLoader);
+  static void ResetClass();
  private:
+  static Class* dalvik_system_PathClassLoader_;
   DISALLOW_IMPLICIT_CONSTRUCTORS(PathClassLoader);
 };
 
@@ -905,8 +910,9 @@
   // kStatusIdx: LoadClass populates with Class with information from
   // the DexFile, moving the status to kStatusIdx, indicating that the
   // Class values in super_class_ and interfaces_ have not been
-  // populated based on super_class_idx_ and interfaces_idx_. The new
-  // Class can then be inserted into the classes table.
+  // populated based on super_class_type_idx_ and
+  // interfaces_type_idx_. The new Class can then be inserted into the
+  // classes table.
   //
   // kStatusLoaded: After taking a lock on Class, the ClassLinker will
   // attempt to move a kStatusIdx class forward to kStatusLoaded by
@@ -920,7 +926,7 @@
   enum Status {
     kStatusError = -1,
     kStatusNotReady = 0,
-    kStatusIdx = 1,  // loaded, DEX idx in super_class_idx_ and interfaces_idx_
+    kStatusIdx = 1,  // loaded, DEX idx in super_class_type_idx_ and interfaces_type_idx_
     kStatusLoaded = 2,  // DEX idx values resolved
     kStatusResolved = 3,  // part of linking
     kStatusVerifying = 4,  // in the process of being verified
@@ -934,6 +940,7 @@
   };
 
   Object* NewInstance() {
+    DCHECK(!IsAbstract());
     return Heap::AllocObject(this, this->object_size_);
   }
 
@@ -941,8 +948,8 @@
     return super_class_;
   }
 
-  uint32_t GetSuperClassIdx() const {
-    return super_class_idx_;
+  uint32_t GetSuperClassTypeIdx() const {
+    return super_class_type_idx_;
   }
 
   bool HasSuperClass() const {
@@ -963,7 +970,7 @@
     return klass->IsSubClass(this);
   }
 
-  ClassLoader* GetClassLoader() const {
+  const ClassLoader* GetClassLoader() const {
     return class_loader_;
   }
 
@@ -1090,10 +1097,10 @@
   }
 
   Method* FindDeclaredDirectMethod(const StringPiece& name,
-                                   const StringPiece& descriptor);
+                                   const StringPiece& signature);
 
   Method* FindDirectMethod(const StringPiece& name,
-                           const StringPiece& descriptor);
+                           const StringPiece& signature);
 
   // Returns the number of non-inherited virtual methods.
   size_t NumVirtualMethods() const {
@@ -1257,10 +1264,10 @@
   // The superclass, or NULL if this is java.lang.Object or a
   // primitive type.
   Class* super_class_;  // TODO: make an instance field
-  uint32_t super_class_idx_;
+  uint32_t super_class_type_idx_;
 
   // defining class loader, or NULL for the "bootstrap" system loader
-  ClassLoader* class_loader_;  // TODO: make an instance field
+  const ClassLoader* class_loader_;  // TODO: make an instance field
 
   // initiating class loader list
   // NOTE: for classes with low serialNumber, these are unused, and the
@@ -1269,7 +1276,7 @@
 
   // array of interfaces this class implements directly
   ObjectArray<Class>* interfaces_;
-  uint32_t* interfaces_idx_;
+  uint32_t* interfaces_type_idx_;
 
   // static, private, and <init> methods
   ObjectArray<Method>* direct_methods_;
diff --git a/src/runtime.cc b/src/runtime.cc
index ac0b90b..30395e1 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -176,7 +176,7 @@
 }
 
 void CreateBootClassPath(const char* boot_class_path_cstr,
-                         std::vector<DexFile*>& boot_class_path_vector) {
+                         std::vector<const DexFile*>& boot_class_path_vector) {
   CHECK(boot_class_path_cstr != NULL);
   std::vector<std::string> parsed;
   ParseClassPath(boot_class_path_cstr, parsed);
@@ -213,7 +213,8 @@
       boot_class_path = option.substr(strlen("-Xbootclasspath:")).data();
     } else if (option == "bootclasspath") {
       const void* dex_vector = options[i].second;
-      const std::vector<DexFile*>* v = reinterpret_cast<const std::vector<DexFile*>*>(dex_vector);
+      const std::vector<const DexFile*>* v
+          = reinterpret_cast<const std::vector<const DexFile*>*>(dex_vector);
       if (v == NULL) {
         if (ignore_unrecognized) {
           continue;
diff --git a/src/runtime.h b/src/runtime.h
index 49657c2..323c6c8 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -36,7 +36,7 @@
     // returns null if problem parsing and ignore_unrecognized is false
     static ParsedOptions* Create(const Options& options, bool ignore_unrecognized);
 
-    std::vector<DexFile*> boot_class_path_;
+    std::vector<const DexFile*> boot_class_path_;
     const char* boot_image_;
     bool check_jni_;
     size_t heap_initial_size_;