Use class def index from java.lang.Class.

Bug: 10244719
This removes the computation of the dex file index, when necessary this is
computed by searching the dex file. Its only necessary in
dalvik.system.DexFile.defineClassNative and DexFile::FindInClassPath, the
latter not showing up significantly in profiling with this change.

(cherry-picked from 8b2c0b9abc3f520495f4387ea040132ba85cae69)
Change-Id: I20c73a3b17d86286428ab0fd21bc13f51f36c85c
diff --git a/runtime/Android.mk b/runtime/Android.mk
index a8d505e..a0ae4bf 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -92,6 +92,7 @@
 	native/dalvik_system_VMStack.cc \
 	native/dalvik_system_Zygote.cc \
 	native/java_lang_Class.cc \
+	native/java_lang_DexCache.cc \
 	native/java_lang_Object.cc \
 	native/java_lang_Runtime.cc \
 	native/java_lang_String.cc \
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 0773a8d..4043f8b 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -475,40 +475,33 @@
   // as the types of the field can't be resolved prior to the runtime being
   // fully initialized
   mirror::Class* java_lang_ref_Reference = GetClassRoot(kJavaLangRefReference);
-  mirror::Class* java_lang_ref_ReferenceQueue = FindSystemClass("Ljava/lang/ref/ReferenceQueue;");
-  mirror::Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;");
-
-  const DexFile& java_lang_dex = *java_lang_ref_Reference->GetDexCache()->GetDexFile();
+  mirror::Class* java_lang_ref_FinalizerReference =
+      FindSystemClass("Ljava/lang/ref/FinalizerReference;");
 
   mirror::ArtField* pendingNext = java_lang_ref_Reference->GetInstanceField(0);
   FieldHelper fh(pendingNext, this);
   CHECK_STREQ(fh.GetName(), "pendingNext");
-  CHECK_EQ(java_lang_dex.GetFieldId(pendingNext->GetDexFieldIndex()).type_idx_,
-           java_lang_ref_Reference->GetDexTypeIndex());
+  CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/Reference;");
 
   mirror::ArtField* queue = java_lang_ref_Reference->GetInstanceField(1);
   fh.ChangeField(queue);
   CHECK_STREQ(fh.GetName(), "queue");
-  CHECK_EQ(java_lang_dex.GetFieldId(queue->GetDexFieldIndex()).type_idx_,
-           java_lang_ref_ReferenceQueue->GetDexTypeIndex());
+  CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/ReferenceQueue;");
 
   mirror::ArtField* queueNext = java_lang_ref_Reference->GetInstanceField(2);
   fh.ChangeField(queueNext);
   CHECK_STREQ(fh.GetName(), "queueNext");
-  CHECK_EQ(java_lang_dex.GetFieldId(queueNext->GetDexFieldIndex()).type_idx_,
-           java_lang_ref_Reference->GetDexTypeIndex());
+  CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/Reference;");
 
   mirror::ArtField* referent = java_lang_ref_Reference->GetInstanceField(3);
   fh.ChangeField(referent);
   CHECK_STREQ(fh.GetName(), "referent");
-  CHECK_EQ(java_lang_dex.GetFieldId(referent->GetDexFieldIndex()).type_idx_,
-           GetClassRoot(kJavaLangObject)->GetDexTypeIndex());
+  CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/Object;");
 
   mirror::ArtField* zombie = java_lang_ref_FinalizerReference->GetInstanceField(2);
   fh.ChangeField(zombie);
   CHECK_STREQ(fh.GetName(), "zombie");
-  CHECK_EQ(java_lang_dex.GetFieldId(zombie->GetDexFieldIndex()).type_idx_,
-           GetClassRoot(kJavaLangObject)->GetDexTypeIndex());
+  CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/Object;");
 
   gc::Heap* heap = Runtime::Current()->GetHeap();
   heap->SetReferenceOffsets(referent->GetOffset(),
@@ -1231,8 +1224,10 @@
     return NULL;
   }
   mirror::Class* klass = k->AsClass();
-  klass->SetPrimitiveType(Primitive::kPrimNot);  // default to not being primitive
+  klass->SetPrimitiveType(Primitive::kPrimNot);  // Default to not being primitive.
   klass->SetClassSize(class_size);
+  klass->SetDexClassDefIndex(DexFile::kDexNoIndex16);  // Default to no valid class def index.
+  klass->SetDexTypeIndex(DexFile::kDexNoIndex16);  // Default to no valid type index.
   return klass;
 }
 
@@ -1496,26 +1491,21 @@
   return size;
 }
 
-const OatFile::OatClass* ClassLinker::GetOatClass(const DexFile& dex_file, const char* descriptor) {
-  DCHECK(descriptor != NULL);
+const OatFile::OatClass* ClassLinker::GetOatClass(const DexFile& dex_file, uint16_t class_def_idx) {
+  DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
   const OatFile* oat_file = FindOpenedOatFileForDexFile(dex_file);
-  CHECK(oat_file != NULL) << dex_file.GetLocation() << " " << descriptor;
+  CHECK(oat_file != NULL) << dex_file.GetLocation();
   const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
-  CHECK(oat_dex_file != NULL) << dex_file.GetLocation() << " " << descriptor;
-  uint32_t class_def_index;
-  bool found = dex_file.FindClassDefIndex(descriptor, class_def_index);
-  CHECK(found) << dex_file.GetLocation() << " " << descriptor;
-  const OatFile::OatClass* oat_class = oat_dex_file->GetOatClass(class_def_index);
-  CHECK(oat_class != NULL) << dex_file.GetLocation() << " " << descriptor;
+  CHECK(oat_dex_file != NULL) << dex_file.GetLocation();
+  const OatFile::OatClass* oat_class = oat_dex_file->GetOatClass(class_def_idx);
+  CHECK(oat_class != NULL) << dex_file.GetLocation() << " " << class_def_idx;
   return oat_class;
 }
 
-static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file, uint32_t method_idx) {
-  const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
-  const DexFile::TypeId& type_id = dex_file.GetTypeId(method_id.class_idx_);
-  const DexFile::ClassDef* class_def = dex_file.FindClassDef(dex_file.GetTypeDescriptor(type_id));
-  CHECK(class_def != NULL);
-  const byte* class_data = dex_file.GetClassData(*class_def);
+static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file, uint16_t class_def_idx,
+                                                 uint32_t method_idx) {
+  const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_idx);
+  const byte* class_data = dex_file.GetClassData(class_def);
   CHECK(class_data != NULL);
   ClassDataItemIterator it(dex_file, class_data);
   // Skip fields
@@ -1569,11 +1559,13 @@
     }
     CHECK(found) << "Didn't find oat method index for virtual method: " << PrettyMethod(method);
   }
-  ClassHelper kh(declaring_class);
-  UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(kh.GetDexFile(), kh.GetDescriptor()));
+  UniquePtr<const OatFile::OatClass>
+      oat_class(GetOatClass(*declaring_class->GetDexCache()->GetDexFile(),
+                            declaring_class->GetDexClassDefIndex()));
   CHECK(oat_class.get() != NULL);
   DCHECK_EQ(oat_method_index,
             GetOatMethodIndexFromMethodIndex(*declaring_class->GetDexCache()->GetDexFile(),
+                                             method->GetDeclaringClass()->GetDexClassDefIndex(),
                                              method->GetDexMethodIndex()));
 
   return oat_class->GetOatMethod(oat_method_index);
@@ -1597,12 +1589,11 @@
   return result;
 }
 
-const void* ClassLinker::GetOatCodeFor(const DexFile& dex_file, uint32_t method_idx) {
-  const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
-  const char* descriptor = dex_file.GetTypeDescriptor(dex_file.GetTypeId(method_id.class_idx_));
-  uint32_t oat_method_idx = GetOatMethodIndexFromMethodIndex(dex_file, method_idx);
-  UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, descriptor));
-  CHECK(oat_class.get() != NULL);
+const void* ClassLinker::GetOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx,
+                                       uint32_t method_idx) {
+  UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, class_def_idx));
+  CHECK(oat_class.get() != nullptr);
+  uint32_t oat_method_idx = GetOatMethodIndexFromMethodIndex(dex_file, class_def_idx, method_idx);
   return oat_class->GetOatMethod(oat_method_idx).GetCode();
 }
 
@@ -1639,7 +1630,7 @@
     // OAT file unavailable
     return;
   }
-  UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, kh.GetDescriptor()));
+  UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, klass->GetDexClassDefIndex()));
   CHECK(oat_class.get() != NULL);
   ClassDataItemIterator it(dex_file, class_data);
   // Skip fields
@@ -1731,6 +1722,7 @@
   DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
   klass->SetStatus(mirror::Class::kStatusIdx, NULL);
 
+  klass->SetDexClassDefIndex(dex_file.GetIndexForClassDef(dex_class_def));
   klass->SetDexTypeIndex(dex_class_def.class_idx_);
 
   // Load fields fields.
@@ -1778,7 +1770,7 @@
 
   UniquePtr<const OatFile::OatClass> oat_class;
   if (Runtime::Current()->IsStarted() && !Runtime::Current()->UseCompileTimeClassPath()) {
-    oat_class.reset(GetOatClass(dex_file, descriptor));
+    oat_class.reset(GetOatClass(dex_file, klass->GetDexClassDefIndex()));
   }
 
   // Load methods.
@@ -1873,7 +1865,8 @@
           if (klass->GetClassLoader() != NULL) {  // All non-boot finalizer methods are flagged
             klass->SetFinalizable();
           } else {
-            StringPiece klass_descriptor(dex_file.StringByTypeIdx(klass->GetDexTypeIndex()));
+            ClassHelper kh(klass.get());
+            StringPiece klass_descriptor(kh.GetDescriptor());
             // The Enum class declares a "final" finalize() method to prevent subclasses from
             // introducing a finalizer. We don't want to set the finalizable flag for Enum or its
             // subclasses, so we exclude it here.
@@ -2339,12 +2332,16 @@
     const DexFile* dex_file = dex_cache->GetDexFile();
     // First search using the class def map, but don't bother for non-class types.
     if (descriptor[0] == 'L') {
-      const DexFile::ClassDef* class_def = dex_file->FindClassDef(descriptor);
-      if (class_def != NULL) {
-        mirror::Class* klass = dex_cache->GetResolvedType(class_def->class_idx_);
-        if (klass != NULL) {
-          self->EndAssertNoThreadSuspension(old_no_suspend_cause);
-          return klass;
+      const DexFile::StringId* descriptor_string_id = dex_file->FindStringId(descriptor);
+      if (descriptor_string_id != NULL) {
+        const DexFile::TypeId* type_id =
+            dex_file->FindTypeId(dex_file->GetIndexForStringId(*descriptor_string_id));
+        if (type_id != NULL) {
+          mirror::Class* klass = dex_cache->GetResolvedType(dex_file->GetIndexForTypeId(*type_id));
+          if (klass != NULL) {
+            self->EndAssertNoThreadSuspension(old_no_suspend_cause);
+            return klass;
+          }
         }
       }
     }
@@ -2455,8 +2452,9 @@
   verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure;
   std::string error_msg;
   if (!preverified) {
-    verifier_failure = verifier::MethodVerifier::VerifyClass(klass, error_msg,
-                                                             Runtime::Current()->IsCompiler());
+    verifier_failure = verifier::MethodVerifier::VerifyClass(klass,
+                                                             Runtime::Current()->IsCompiler(),
+                                                             &error_msg);
   }
   if (preverified || verifier_failure != verifier::MethodVerifier::kHardFailure) {
     if (!preverified && verifier_failure != verifier::MethodVerifier::kNoFailure) {
@@ -2527,7 +2525,6 @@
     }
   }
 
-
   const OatFile* oat_file = FindOpenedOatFileForDexFile(dex_file);
   // Make this work with gtests, which do not set up the image properly.
   // TODO: we should clean up gtests to set up the image path properly.
@@ -2539,9 +2536,7 @@
   const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
   CHECK(oat_dex_file != NULL) << dex_file.GetLocation() << " " << PrettyClass(klass);
   const char* descriptor = ClassHelper(klass).GetDescriptor();
-  uint32_t class_def_index;
-  bool found = dex_file.FindClassDefIndex(descriptor, class_def_index);
-  CHECK(found) << dex_file.GetLocation() << " " << PrettyClass(klass) << " " << descriptor;
+  uint16_t class_def_index = klass->GetDexClassDefIndex();
   UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file->GetOatClass(class_def_index));
   CHECK(oat_class.get() != NULL)
           << dex_file.GetLocation() << " " << PrettyClass(klass) << " " << descriptor;
@@ -2654,8 +2649,6 @@
 
   klass->SetStatus(mirror::Class::kStatusIdx, self);
 
-  klass->SetDexTypeIndex(DexFile::kDexNoIndex16);
-
   // Instance fields are inherited, but we add a couple of static fields...
   {
     mirror::ObjectArray<mirror::ArtField>* sfields = AllocArtFieldArray(self, 2);
@@ -3262,10 +3255,8 @@
 
 bool ClassLinker::LoadSuperAndInterfaces(SirtRef<mirror::Class>& klass, const DexFile& dex_file) {
   CHECK_EQ(mirror::Class::kStatusIdx, klass->GetStatus());
-  StringPiece descriptor(dex_file.StringByTypeIdx(klass->GetDexTypeIndex()));
-  const DexFile::ClassDef* class_def = dex_file.FindClassDef(descriptor);
-  CHECK(class_def != NULL);
-  uint16_t super_class_idx = class_def->superclass_idx_;
+  const DexFile::ClassDef& class_def = dex_file.GetClassDef(klass->GetDexClassDefIndex());
+  uint16_t super_class_idx = class_def.superclass_idx_;
   if (super_class_idx != DexFile::kDexNoIndex16) {
     mirror::Class* super_class = ResolveType(dex_file, super_class_idx, klass.get());
     if (super_class == NULL) {
@@ -3281,7 +3272,7 @@
     }
     klass->SetSuperClass(super_class);
   }
-  const DexFile::TypeList* interfaces = dex_file.GetInterfacesList(*class_def);
+  const DexFile::TypeList* interfaces = dex_file.GetInterfacesList(class_def);
   if (interfaces != NULL) {
     for (size_t i = 0; i < interfaces->Size(); i++) {
       uint16_t idx = interfaces->GetTypeItem(i).type_idx_;
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 20efbb4..3ffcf14 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -329,7 +329,7 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Get the oat code for a method from a method index.
-  const void* GetOatCodeFor(const DexFile& dex_file, uint32_t method_idx)
+  const void* GetOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx, uint32_t method_idx)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   pid_t GetClassesLockOwner();  // For SignalCatcher.
@@ -424,7 +424,7 @@
   void FixupStaticTrampolines(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Finds the associated oat class for a dex_file and descriptor
-  const OatFile::OatClass* GetOatClass(const DexFile& dex_file, const char* descriptor)
+  const OatFile::OatClass* GetOatClass(const DexFile& dex_file, uint16_t class_def_idx)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   void RegisterDexFileLocked(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache)
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 995434c..bbc2877 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -507,6 +507,7 @@
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, access_flags_),                  "accessFlags"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, class_size_),                    "classSize"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, clinit_thread_id_),              "clinitThreadId"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, dex_class_def_idx_),             "dexClassDefIndex"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, dex_type_idx_),                  "dexTypeIndex"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, num_reference_instance_fields_), "numReferenceInstanceFields"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, num_reference_static_fields_),   "numReferenceStaticFields"));
@@ -569,10 +570,6 @@
 
 struct ClassClassOffsets : public CheckOffsets<mirror::ClassClass> {
   ClassClassOffsets() : CheckOffsets<mirror::ClassClass>(true, "Ljava/lang/Class;") {
-    // padding 32-bit
-    CHECK_EQ(OFFSETOF_MEMBER(mirror::ClassClass, padding_) + 4,
-             OFFSETOF_MEMBER(mirror::ClassClass, serialVersionUID_));
-
     // alphabetical 64-bit
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ClassClass, serialVersionUID_), "serialVersionUID"));
   };
@@ -584,11 +581,11 @@
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, ASCII_),                  "ASCII"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, CASE_INSENSITIVE_ORDER_), "CASE_INSENSITIVE_ORDER"));
 
-    // padding 32-bit
-    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, REPLACEMENT_CHAR_),       "REPLACEMENT_CHAR"));
-
     // alphabetical 64-bit
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, serialVersionUID_),       "serialVersionUID"));
+
+    // alphabetical 32-bit
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, REPLACEMENT_CHAR_),       "REPLACEMENT_CHAR"));
   };
 };
 
@@ -605,6 +602,7 @@
 struct DexCacheOffsets : public CheckOffsets<mirror::DexCache> {
   DexCacheOffsets() : CheckOffsets<mirror::DexCache>(false, "Ljava/lang/DexCache;") {
     // alphabetical references
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, dex_),                        "dex"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, initialized_static_storage_), "initializedStaticStorage"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, location_),                   "location"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_fields_),            "resolvedFields"));
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 4fd9a60..e81c456 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -48,7 +48,7 @@
 const byte DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
 const byte DexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' };
 
-DexFile::ClassPathEntry DexFile::FindInClassPath(const StringPiece& descriptor,
+DexFile::ClassPathEntry DexFile::FindInClassPath(const char* descriptor,
                                                  const ClassPath& class_path) {
   for (size_t i = 0; i != class_path.size(); ++i) {
     const DexFile* dex_file = class_path[i];
@@ -251,56 +251,11 @@
   // the global reference table is otherwise empty!
 }
 
-class ScopedJniMonitorLock {
- public:
-  ScopedJniMonitorLock(JNIEnv* env, jobject locked) : env_(env), locked_(locked) {
-    env->MonitorEnter(locked_);
-  }
-  ~ScopedJniMonitorLock() {
-    env_->MonitorExit(locked_);
-  }
- private:
-  JNIEnv* const env_;
-  const jobject locked_;
-};
-
-jobject DexFile::GetDexObject(JNIEnv* env) const {
-  {
-    ScopedJniMonitorLock lock(env, WellKnownClasses::com_android_dex_Dex);
-    if (dex_object_ != NULL) {
-      return dex_object_;
-    }
-  }
-  void* address = const_cast<void*>(reinterpret_cast<const void*>(begin_));
-  jobject byte_buffer = env->NewDirectByteBuffer(address, size_);
-  if (byte_buffer == NULL) {
-    return NULL;
-  }
-
-  ScopedJniMonitorLock lock(env, WellKnownClasses::com_android_dex_Dex);
-  // Re-test to see if someone beat us to the creation when we had the lock released.
-  if (dex_object_ != NULL) {
-    return dex_object_;
-  }
-  jvalue args[1];
-  args[0].l = byte_buffer;
-  jobject local = env->CallStaticObjectMethodA(WellKnownClasses::com_android_dex_Dex,
-                                               WellKnownClasses::com_android_dex_Dex_create,
-                                               args);
-  if (local == NULL) {
-    return NULL;
-  }
-
-  dex_object_ = env->NewGlobalRef(local);
-  return dex_object_;
-}
-
 bool DexFile::Init() {
   InitMembers();
   if (!CheckMagicAndVersion()) {
     return false;
   }
-  InitIndex();
   return true;
 }
 
@@ -351,28 +306,36 @@
   return atoi(version);
 }
 
-void DexFile::InitIndex() {
-  CHECK_EQ(index_.size(), 0U) << GetLocation();
-  for (size_t i = 0; i < NumClassDefs(); ++i) {
+const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor) const {
+  size_t num_class_defs = NumClassDefs();
+  if (num_class_defs == 0) {
+    return NULL;
+  }
+  const StringId* string_id = FindStringId(descriptor);
+  if (string_id == NULL) {
+    return NULL;
+  }
+  const TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id));
+  if (type_id == NULL) {
+    return NULL;
+  }
+  uint16_t type_idx = GetIndexForTypeId(*type_id);
+  for (size_t i = 0; i < num_class_defs; ++i) {
     const ClassDef& class_def = GetClassDef(i);
-    const char* descriptor = GetClassDescriptor(class_def);
-    index_.Put(descriptor, i);
+    if (class_def.class_idx_ == type_idx) {
+      return &class_def;
+    }
   }
+  return NULL;
 }
 
-bool DexFile::FindClassDefIndex(const StringPiece& descriptor, uint32_t& idx) const {
-  Index::const_iterator it = index_.find(descriptor);
-  if (it == index_.end()) {
-    return false;
-  }
-  idx = it->second;
-  return true;
-}
-
-const DexFile::ClassDef* DexFile::FindClassDef(const StringPiece& descriptor) const {
-  uint32_t idx;
-  if (FindClassDefIndex(descriptor, idx)) {
-    return &GetClassDef(idx);
+const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const {
+  size_t num_class_defs = NumClassDefs();
+  for (size_t i = 0; i < num_class_defs; ++i) {
+    const ClassDef& class_def = GetClassDef(i);
+    if (class_def.class_idx_ == type_idx) {
+      return &class_def;
+    }
   }
   return NULL;
 }
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 26635ae..7be5cb8 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -339,7 +339,7 @@
   typedef std::vector<const DexFile*> ClassPath;
 
   // Search a collection of DexFiles for a descriptor
-  static ClassPathEntry FindInClassPath(const StringPiece& descriptor,
+  static ClassPathEntry FindInClassPath(const char* descriptor,
                                         const ClassPath& class_path);
 
   // Returns the checksum of a file for comparison with GetLocationChecksum().
@@ -376,10 +376,6 @@
     return location_checksum_;
   }
 
-  // Returns a com.android.dex.Dex object corresponding to the mapped-in dex file.
-  // Used by managed code to implement annotations.
-  jobject GetDexObject(JNIEnv* env) const;
-
   const Header& GetHeader() const {
     DCHECK(header_ != NULL) << GetLocation();
     return *header_;
@@ -584,12 +580,12 @@
   }
 
   // Returns the ClassDef at the specified index.
-  const ClassDef& GetClassDef(uint32_t idx) const {
+  const ClassDef& GetClassDef(uint16_t idx) const {
     DCHECK_LT(idx, NumClassDefs()) << GetLocation();
     return class_defs_[idx];
   }
 
-  uint32_t GetIndexForClassDef(const ClassDef& class_def) const {
+  uint16_t GetIndexForClassDef(const ClassDef& class_def) const {
     CHECK_GE(&class_def, class_defs_) << GetLocation();
     CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
     return &class_def - class_defs_;
@@ -601,10 +597,10 @@
   }
 
   // Looks up a class definition by its class descriptor.
-  const ClassDef* FindClassDef(const StringPiece& descriptor) const;
+  const ClassDef* FindClassDef(const char* descriptor) const;
 
-  // Looks up a class definition index by its class descriptor.
-  bool FindClassDefIndex(const StringPiece& descriptor, uint32_t& idx) const;
+  // Looks up a class definition by its type index.
+  const ClassDef* FindClassDef(uint16_t type_idx) const;
 
   const TypeList* GetInterfacesList(const ClassDef& class_def) const {
     if (class_def.interfaces_off_ == 0) {
@@ -809,6 +805,14 @@
 
   bool DisableWrite() const;
 
+  const byte* Begin() const {
+    return begin_;
+  }
+
+  size_t Size() const {
+    return size_;
+  }
+
  private:
   // Opens a .dex file
   static const DexFile* OpenFile(const std::string& filename,
@@ -840,7 +844,6 @@
         location_(location),
         location_checksum_(location_checksum),
         mem_map_(mem_map),
-        dex_object_(NULL),
         modification_lock("DEX modification lock"),
         header_(0),
         string_ids_(0),
@@ -853,23 +856,12 @@
     CHECK_GT(size_, 0U) << GetLocation();
   }
 
-  const byte* Begin() const {
-    return begin_;
-  }
-
-  size_t Size() const {
-    return size_;
-  }
-
   // Top-level initializer that calls other Init methods.
   bool Init();
 
   // Caches pointers into to the various file sections.
   void InitMembers();
 
-  // Builds the index of descriptors to class definitions.
-  void InitIndex();
-
   // Returns true if the header magic and version numbers are of the expected values.
   bool CheckMagicAndVersion() const;
 
@@ -877,10 +869,6 @@
       DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
       void* context, const byte* stream, LocalInfo* local_in_reg) const;
 
-  // The index of descriptors to class definition indexes (as opposed to type id indexes)
-  typedef SafeMap<const StringPiece, uint32_t> Index;
-  Index index_;
-
   // The base address of the memory mapping.
   const byte* const begin_;
 
@@ -898,10 +886,6 @@
   // Manages the underlying memory allocation.
   UniquePtr<MemMap> mem_map_;
 
-  // A cached com.android.dex.Dex instance, possibly NULL. Use GetDexObject.
-  // TODO: this is mutable as it shouldn't be here. We should move it to the dex cache or similar.
-  mutable jobject dex_object_;
-
   // The DEX-to-DEX compiler uses this lock to ensure thread safety when
   // enabling write access to a read-only DEX file.
   // TODO: move to Locks::dex_file_modification_lock.
diff --git a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
index 1d8022f..07c1c01 100644
--- a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
@@ -32,7 +32,7 @@
                                                  Thread* self, mirror::ArtMethod** sp)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   mirror::ArtMethod* method;
-  if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex16)) {
+  if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex)) {
     method = this_object->GetClass()->FindVirtualMethodForInterface(interface_method);
     if (UNLIKELY(method == NULL)) {
       FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 224b2ba..ccf3e59 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -178,7 +178,7 @@
 }
 
 inline bool ArtMethod::IsRuntimeMethod() const {
-  return GetDexMethodIndex() == DexFile::kDexNoIndex16;
+  return GetDexMethodIndex() == DexFile::kDexNoIndex;
 }
 
 inline bool ArtMethod::IsCalleeSaveMethod() const {
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 5e8b827..add7e1b 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -128,7 +128,10 @@
 }
 
 void Class::SetClassSize(size_t new_class_size) {
-  DCHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this);
+  if (kIsDebugBuild && (new_class_size < GetClassSize())) {
+    DumpClass(LOG(ERROR), kDumpClassFullDetail);
+    CHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this);
+  }
   SetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size, false);
 }
 
@@ -300,22 +303,8 @@
     return true;
   }
   // Compare the package part of the descriptor string.
-  if (LIKELY(!klass1->IsProxyClass() && !klass2->IsProxyClass())) {
-    ClassHelper kh(klass1);
-    const DexFile* dex_file1 = &kh.GetDexFile();
-    const DexFile::TypeId* type_id1 = &dex_file1->GetTypeId(klass1->GetDexTypeIndex());
-    const char* descriptor1 = dex_file1->GetTypeDescriptor(*type_id1);
-    kh.ChangeClass(klass2);
-    const DexFile* dex_file2 = &kh.GetDexFile();
-    const DexFile::TypeId* type_id2 = &dex_file2->GetTypeId(klass2->GetDexTypeIndex());
-    const char* descriptor2 = dex_file2->GetTypeDescriptor(*type_id2);
-    return IsInSamePackage(descriptor1, descriptor2);
-  }
-  ClassHelper kh(klass1);
-  std::string descriptor1(kh.GetDescriptor());
-  kh.ChangeClass(klass2);
-  std::string descriptor2(kh.GetDescriptor());
-  return IsInSamePackage(descriptor1, descriptor2);
+  return IsInSamePackage(ClassHelper(klass1).GetDescriptor(),
+                         ClassHelper(klass2).GetDescriptor());
 }
 
 bool Class::IsClassClass() const {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 99f3850..d97b603 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -726,6 +726,14 @@
     return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), false);
   }
 
+  uint16_t GetDexClassDefIndex() const {
+    return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_class_def_idx_), false);
+  }
+
+  void SetDexClassDefIndex(uint16_t class_def_idx) {
+    SetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_class_def_idx_), class_def_idx, false);
+  }
+
   uint16_t GetDexTypeIndex() const {
     return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), false);
   }
@@ -807,7 +815,7 @@
   // If class verify fails, we must return same error on subsequent tries.
   Class* verify_error_class_;
 
-  // virtual methods defined in this class; invoked through vtable
+  // Virtual methods defined in this class; invoked through vtable.
   ObjectArray<ArtMethod>* virtual_methods_;
 
   // Virtual method table (vtable), for use by "invoke-virtual".  The vtable from the superclass is
@@ -816,24 +824,28 @@
   // virtual_ methods_ for miranda methods.
   ObjectArray<ArtMethod>* vtable_;
 
-  // access flags; low 16 bits are defined by VM spec
+  // Access flags; low 16 bits are defined by VM spec.
   uint32_t access_flags_;
 
   // Total size of the Class instance; used when allocating storage on gc heap.
   // See also object_size_.
   size_t class_size_;
 
-  // tid used to check for recursive <clinit> invocation
+  // Tid used to check for recursive <clinit> invocation.
   pid_t clinit_thread_id_;
 
-  // type index from dex file
+  // ClassDef index in dex file, -1 if no class definition such as an array.
   // TODO: really 16bits
-  uint32_t dex_type_idx_;
+  int32_t dex_class_def_idx_;
 
-  // number of instance fields that are object refs
+  // Type index in dex file.
+  // TODO: really 16bits
+  int32_t dex_type_idx_;
+
+  // Number of instance fields that are object refs.
   size_t num_reference_instance_fields_;
 
-  // number of static fields that are object refs
+  // Number of static fields that are object refs,
   size_t num_reference_static_fields_;
 
   // Total object size; used when allocating storage on gc heap.
@@ -841,7 +853,7 @@
   // See also class_size_.
   size_t object_size_;
 
-  // primitive type value, or Primitive::kPrimNot (0); set for generated prim classes
+  // Primitive type value, or Primitive::kPrimNot (0); set for generated primitive classes.
   Primitive::Type primitive_type_;
 
   // Bitmap of offsets of ifields.
@@ -850,7 +862,7 @@
   // Bitmap of offsets of sfields.
   uint32_t reference_static_offsets_;
 
-  // state of class initialization
+  // State of class initialization.
   Status status_;
 
   // TODO: ?
@@ -873,7 +885,6 @@
 
 class MANAGED ClassClass : public Class {
  private:
-  int32_t padding_;
   int64_t serialVersionUID_;
   friend struct art::ClassClassOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(ClassClass);
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index 6cfab9e..0522f13 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -164,6 +164,7 @@
   }
 
  private:
+  Object* dex_;
   ObjectArray<StaticStorageBase>* initialized_static_storage_;
   String* location_;
   ObjectArray<ArtField>* resolved_fields_;
diff --git a/runtime/mirror/proxy.h b/runtime/mirror/proxy.h
index 7c5bc39..18a84dc 100644
--- a/runtime/mirror/proxy.h
+++ b/runtime/mirror/proxy.h
@@ -25,6 +25,8 @@
 
 namespace mirror {
 
+// All proxy objects have a class which is a synthesized proxy class. The synthesized proxy class
+// has the static fields used to implement reflection on proxy objects.
 class MANAGED SynthesizedProxyClass : public Class {
  public:
   ObjectArray<Class>* GetInterfaces() {
@@ -41,6 +43,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(SynthesizedProxyClass);
 };
 
+// C++ mirror of java.lang.reflect.Proxy.
 class MANAGED Proxy : public Object {
  private:
   Object* h_;
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index bf545ea..81fe42f 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -155,8 +155,8 @@
  private:
   CharArray* ASCII_;
   Object* CASE_INSENSITIVE_ORDER_;
-  uint32_t REPLACEMENT_CHAR_;
   int64_t serialVersionUID_;
+  uint32_t REPLACEMENT_CHAR_;
   friend struct art::StringClassOffsets;  // for verifying offset information
   DISALLOW_IMPLICIT_CONSTRUCTORS(StringClass);
 };
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 2f4e427..d2a6c0e 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -150,7 +150,7 @@
     return NULL;
   }
   const std::string descriptor(DotToDescriptor(class_name.c_str()));
-  const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor);
+  const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor.c_str());
   if (dex_class_def == NULL) {
     VLOG(class_linker) << "Failed to find dex_class_def";
     return NULL;
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index a729699..d3011cb 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -78,35 +78,6 @@
   return soa.AddLocalReference<jclass>(c);
 }
 
-static jint Class_getAnnotationDirectoryOffset(JNIEnv* env, jclass javaClass) {
-  ScopedObjectAccess soa(env);
-  mirror::Class* c = DecodeClass(soa, javaClass);
-  if (c->IsPrimitive() || c->IsArrayClass() || c->IsProxyClass()) {
-    return 0;  // primitive, array and proxy classes don't have class definitions
-  }
-  const DexFile::ClassDef* class_def = ClassHelper(c).GetClassDef();
-  if (class_def == NULL) {
-    return 0;  // not found
-  } else {
-    return class_def->annotations_off_;
-  }
-}
-
-static jobject Class_getDex(JNIEnv* env, jobject javaClass) {
-  ScopedObjectAccess soa(env);
-  mirror::Class* c = DecodeClass(soa, javaClass);
-
-  mirror::DexCache* dex_cache = c->GetDexCache();
-  if (dex_cache == NULL) {
-    return NULL;
-  }
-  const DexFile* dex_file = dex_cache->GetDexFile();
-  if (dex_file == NULL) {
-    return NULL;
-  }
-  return dex_file->GetDexObject(env);
-}
-
 static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
   ScopedObjectAccess soa(env);
   mirror::Class* c = DecodeClass(soa, javaThis);
@@ -122,8 +93,6 @@
 
 static JNINativeMethod gMethods[] = {
   NATIVE_METHOD(Class, classForName, "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"),
-  NATIVE_METHOD(Class, getAnnotationDirectoryOffset, "()I"),
-  NATIVE_METHOD(Class, getDex, "()Lcom/android/dex/Dex;"),
   NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"),
   NATIVE_METHOD(Class, getProxyInterfaces, "()[Ljava/lang/Class;"),
 };
diff --git a/runtime/native/java_lang_DexCache.cc b/runtime/native/java_lang_DexCache.cc
new file mode 100644
index 0000000..f8eeb29
--- /dev/null
+++ b/runtime/native/java_lang_DexCache.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dex_file.h"
+#include "mirror/dex_cache.h"
+#include "mirror/object-inl.h"
+#include "scoped_thread_state_change.h"
+#include "well_known_classes.h"
+
+namespace art {
+
+static jobject DexCache_getDexNative(JNIEnv* env, jobject javaDexCache) {
+  ScopedObjectAccess soa(env);
+  mirror::DexCache* dex_cache = soa.Decode<mirror::DexCache*>(javaDexCache);
+  // Should only be called while holding the lock on the dex cache.
+  DCHECK_EQ(dex_cache->GetThinLockId(), soa.Self()->GetThinLockId());
+  const DexFile* dex_file = dex_cache->GetDexFile();
+  if (dex_file == NULL) {
+    return NULL;
+  }
+  void* address = const_cast<void*>(reinterpret_cast<const void*>(dex_file->Begin()));
+  jobject byte_buffer = env->NewDirectByteBuffer(address, dex_file->Size());
+  if (byte_buffer == NULL) {
+    DCHECK(soa.Self()->IsExceptionPending());
+    return NULL;
+  }
+
+  jvalue args[1];
+  args[0].l = byte_buffer;
+  return env->CallStaticObjectMethodA(WellKnownClasses::com_android_dex_Dex,
+                                      WellKnownClasses::com_android_dex_Dex_create,
+                                      args);
+}
+
+static JNINativeMethod gMethods[] = {
+  NATIVE_METHOD(DexCache, getDexNative, "()Lcom/android/dex/Dex;"),
+};
+
+void register_java_lang_DexCache(JNIEnv* env) {
+  REGISTER_NATIVE_METHODS("java/lang/DexCache");
+}
+
+}  // namespace art
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index afa823d..4c97017 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -365,7 +365,7 @@
                        dex_file_location_checksum_);
 }
 
-const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint32_t class_def_index) const {
+const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint16_t class_def_index) const {
   uint32_t oat_class_offset = oat_class_offsets_pointer_[class_def_index];
 
   const byte* oat_class_pointer = oat_file_->Begin() + oat_class_offset;
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 325ebb2..bbd2615 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -183,7 +183,7 @@
     }
 
     // Returns the OatClass for the class specified by the given DexFile class_def_index.
-    const OatClass* GetOatClass(uint32_t class_def_index) const;
+    const OatClass* GetOatClass(uint16_t class_def_index) const;
 
     ~OatDexFile();
 
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index 2910243..6ee3016 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -68,8 +68,7 @@
  public:
   ClassHelper(const mirror::Class* c = NULL, ClassLinker* l = NULL)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      : class_def_(NULL),
-        class_linker_(l),
+      : class_linker_(l),
         dex_cache_(NULL),
         dex_file_(NULL),
         interface_type_list_(NULL),
@@ -92,7 +91,6 @@
     }
     klass_ = new_c;
     interface_type_list_ = NULL;
-    class_def_ = NULL;
   }
 
   // The returned const char* is only guaranteed to be valid for the lifetime of the ClassHelper.
@@ -108,7 +106,7 @@
       return descriptor_.c_str();
     } else {
       const DexFile& dex_file = GetDexFile();
-      const DexFile::TypeId& type_id = dex_file.GetTypeId(klass_->GetDexTypeIndex());
+      const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
       return dex_file.GetTypeDescriptor(type_id);
     }
   }
@@ -124,14 +122,13 @@
     return descriptor_.c_str();
   }
 
-  const DexFile::ClassDef* GetClassDef()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    const DexFile::ClassDef* result = class_def_;
-    if (result == NULL) {
-      result = GetDexFile().FindClassDef(GetDescriptor());
-      class_def_ = result;
+  const DexFile::ClassDef* GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    DCHECK(klass_ != nullptr);
+    uint16_t class_def_idx = klass_->GetDexClassDefIndex();
+    if (class_def_idx == DexFile::kDexNoIndex16) {
+      return nullptr;
     }
-    return result;
+    return &GetDexFile().GetClassDef(class_def_idx);
   }
 
   uint32_t NumDirectInterfaces() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -187,7 +184,7 @@
   const char* GetSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     std::string descriptor(GetDescriptor());
     const DexFile& dex_file = GetDexFile();
-    const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
+    const DexFile::ClassDef* dex_class_def = GetClassDef();
     CHECK(dex_class_def != NULL);
     return dex_file.GetSourceFile(*dex_class_def);
   }
@@ -242,7 +239,6 @@
     return result;
   }
 
-  const DexFile::ClassDef* class_def_;
   ClassLinker* class_linker_;
   mirror::DexCache* dex_cache_;
   const DexFile* dex_file_;
@@ -327,12 +323,15 @@
   // If you need it longer, copy it into a std::string.
   const char* GetDeclaringClassDescriptor()
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    uint16_t type_idx = field_->GetDeclaringClass()->GetDexTypeIndex();
-    if (type_idx != DexFile::kDexNoIndex16) {
+    uint32_t field_index = field_->GetDexFieldIndex();
+    if (!field_->GetDeclaringClass()->IsProxyClass()) {
       const DexFile& dex_file = GetDexFile();
-      return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
+      const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
+      return dex_file.GetFieldDeclaringClassDescriptor(field_id);
     } else {
-      // Most likely a proxy class.
+      DCHECK(field_->IsStatic());
+      DCHECK_LT(field_index, 2U);
+      // 0 == Class[] interfaces; 1 == Class[][] throws;
       ClassHelper kh(field_->GetDeclaringClass());
       declaring_class_descriptor_ = kh.GetDescriptor();
       return declaring_class_descriptor_.c_str();
@@ -418,7 +417,7 @@
   const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const DexFile& dex_file = GetDexFile();
     uint32_t dex_method_idx = method_->GetDexMethodIndex();
-    if (dex_method_idx != DexFile::kDexNoIndex16) {
+    if (dex_method_idx != DexFile::kDexNoIndex) {
       return dex_file.GetMethodName(dex_file.GetMethodId(dex_method_idx));
     } else {
       Runtime* runtime = Runtime::Current();
@@ -464,21 +463,19 @@
   const std::string GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const DexFile& dex_file = GetDexFile();
     uint32_t dex_method_idx = method_->GetDexMethodIndex();
-    if (dex_method_idx != DexFile::kDexNoIndex16) {
+    if (dex_method_idx != DexFile::kDexNoIndex) {
       return dex_file.GetMethodSignature(dex_file.GetMethodId(dex_method_idx));
     } else {
       return "<no signature>";
     }
   }
 
-  const DexFile::ProtoId& GetPrototype()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const DexFile& dex_file = GetDexFile();
     return dex_file.GetMethodPrototype(dex_file.GetMethodId(method_->GetDexMethodIndex()));
   }
 
-  const DexFile::TypeList* GetParameterTypeList()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const DexFile::ProtoId& proto = GetPrototype();
     return GetDexFile().GetProtoParameters(proto);
   }
@@ -491,8 +488,7 @@
     return GetClassFromTypeIdx(return_type_idx);
   }
 
-  const char* GetReturnTypeDescriptor()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const DexFile& dex_file = GetDexFile();
     const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
     const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
@@ -500,8 +496,7 @@
     return dex_file.GetTypeDescriptor(dex_file.GetTypeId(return_type_idx));
   }
 
-  int32_t GetLineNumFromDexPC(uint32_t dex_pc)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     if (dex_pc == DexFile::kDexNoIndex) {
       return method_->IsNative() ? -2 : -1;
     } else {
@@ -510,35 +505,29 @@
     }
   }
 
-  const char* GetDeclaringClassDescriptor()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    mirror::Class* klass = method_->GetDeclaringClass();
-    DCHECK(!klass->IsProxyClass());
-    uint16_t type_idx = klass->GetDexTypeIndex();
+  const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const DexFile& dex_file = GetDexFile();
-    return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
+    uint32_t dex_method_idx = method_->GetDexMethodIndex();
+    if (dex_method_idx != DexFile::kDexNoIndex) {
+      return dex_file.GetMethodDeclaringClassDescriptor(dex_file.GetMethodId(dex_method_idx));
+    } else {
+      return "<runtime method>";
+    }
   }
 
-  const char* GetDeclaringClassSourceFile()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    const char* descriptor = GetDeclaringClassDescriptor();
-    const DexFile& dex_file = GetDexFile();
-    const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
-    CHECK(dex_class_def != NULL);
-    return dex_file.GetSourceFile(*dex_class_def);
+  const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return ClassHelper(method_->GetDeclaringClass()).GetSourceFile();
   }
 
-  uint32_t GetClassDefIndex()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    const char* descriptor = GetDeclaringClassDescriptor();
-    const DexFile& dex_file = GetDexFile();
-    uint32_t index;
-    CHECK(dex_file.FindClassDefIndex(descriptor, index));
-    return index;
+  uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return method_->GetDeclaringClass()->GetDexClassDefIndex();
   }
 
-  mirror::ClassLoader* GetClassLoader()
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return GetDexFile().GetClassDef(GetClassDefIndex());
+  }
+
+  mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return method_->GetDeclaringClass()->GetClassLoader();
   }
 
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 657735a..09d1447 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1001,6 +1001,7 @@
   REGISTER(register_dalvik_system_VMStack);
   REGISTER(register_dalvik_system_Zygote);
   REGISTER(register_java_lang_Class);
+  REGISTER(register_java_lang_DexCache);
   REGISTER(register_java_lang_Object);
   REGISTER(register_java_lang_Runtime);
   REGISTER(register_java_lang_String);
@@ -1164,7 +1165,7 @@
       method(self, down_cast<mirror::ArtMethod*>(method_class->AllocObject(self)));
   method->SetDeclaringClass(method_class);
   // TODO: use a special method for resolution method saves
-  method->SetDexMethodIndex(DexFile::kDexNoIndex16);
+  method->SetDexMethodIndex(DexFile::kDexNoIndex);
   // When compiling, the code pointer will get set later when the image is loaded.
   Runtime* r = Runtime::Current();
   ClassLinker* cl = r->GetClassLinker();
@@ -1180,7 +1181,7 @@
       method(self, down_cast<mirror::ArtMethod*>(method_class->AllocObject(self)));
   method->SetDeclaringClass(method_class);
   // TODO: use a special method for callee saves
-  method->SetDexMethodIndex(DexFile::kDexNoIndex16);
+  method->SetDexMethodIndex(DexFile::kDexNoIndex);
   method->SetEntryPointFromCompiledCode(NULL);
   if ((instruction_set == kThumb2) || (instruction_set == kArm)) {
     uint32_t ref_spills = (1 << art::arm::R5) | (1 << art::arm::R6)  | (1 << art::arm::R7) |
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 558ceb4..23cafe8 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1807,7 +1807,7 @@
     uint32_t new_dex_pc = dex_pc + inst->SizeInCodeUnits();
     ShadowFrame* new_frame = ShadowFrame::Create(num_regs, NULL, m, new_dex_pc);
     verifier::MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
-                                      mh.GetClassDefIndex(), code_item,
+                                      &mh.GetClassDef(), code_item,
                                       m->GetDexMethodIndex(), m, m->GetAccessFlags(), false, true);
     verifier.Verify();
     std::vector<int32_t> kinds = verifier.DescribeVRegs(dex_pc);
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index fa00c61..9811926 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -74,50 +74,51 @@
 }
 
 MethodVerifier::FailureKind MethodVerifier::VerifyClass(const mirror::Class* klass,
-                                                        std::string& error,
-                                                        bool allow_soft_failures) {
+                                                        bool allow_soft_failures,
+                                                        std::string* error) {
   if (klass->IsVerified()) {
     return kNoFailure;
   }
   mirror::Class* super = klass->GetSuperClass();
   if (super == NULL && StringPiece(ClassHelper(klass).GetDescriptor()) != "Ljava/lang/Object;") {
-    error = "Verifier rejected class ";
-    error += PrettyDescriptor(klass);
-    error += " that has no super class";
+    *error = "Verifier rejected class ";
+    *error += PrettyDescriptor(klass);
+    *error += " that has no super class";
     return kHardFailure;
   }
   if (super != NULL && super->IsFinal()) {
-    error = "Verifier rejected class ";
-    error += PrettyDescriptor(klass);
-    error += " that attempts to sub-class final class ";
-    error += PrettyDescriptor(super);
+    *error = "Verifier rejected class ";
+    *error += PrettyDescriptor(klass);
+    *error += " that attempts to sub-class final class ";
+    *error += PrettyDescriptor(super);
     return kHardFailure;
   }
   ClassHelper kh(klass);
   const DexFile& dex_file = kh.GetDexFile();
-  uint32_t class_def_idx;
-  if (!dex_file.FindClassDefIndex(kh.GetDescriptor(), class_def_idx)) {
-    error = "Verifier rejected class ";
-    error += PrettyDescriptor(klass);
-    error += " that isn't present in dex file ";
-    error += dex_file.GetLocation();
+  const DexFile::ClassDef* class_def = kh.GetClassDef();
+  if (class_def == NULL) {
+    *error = "Verifier rejected class ";
+    *error += PrettyDescriptor(klass);
+    *error += " that isn't present in dex file ";
+    *error += dex_file.GetLocation();
     return kHardFailure;
   }
   return VerifyClass(&dex_file,
                      kh.GetDexCache(),
                      klass->GetClassLoader(),
-                     class_def_idx, error,
-                     allow_soft_failures);
+                     class_def,
+                     allow_soft_failures,
+                     error);
 }
 
 MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
                                                         mirror::DexCache* dex_cache,
                                                         mirror::ClassLoader* class_loader,
-                                                        uint32_t class_def_idx,
-                                                        std::string& error,
-                                                        bool allow_soft_failures) {
-  const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
-  const byte* class_data = dex_file->GetClassData(class_def);
+                                                        const DexFile::ClassDef* class_def,
+                                                        bool allow_soft_failures,
+                                                        std::string* error) {
+  DCHECK(class_def != nullptr);
+  const byte* class_data = dex_file->GetClassData(*class_def);
   if (class_data == NULL) {
     // empty class, probably a marker interface
     return kNoFailure;
@@ -139,7 +140,7 @@
       continue;
     }
     previous_direct_method_idx = method_idx;
-    InvokeType type = it.GetMethodInvokeType(class_def);
+    InvokeType type = it.GetMethodInvokeType(*class_def);
     mirror::ArtMethod* method =
         linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
     if (method == NULL) {
@@ -151,7 +152,7 @@
                                                       dex_file,
                                                       dex_cache,
                                                       class_loader,
-                                                      class_def_idx,
+                                                      class_def,
                                                       it.GetMethodCodeItem(),
                                                       method,
                                                       it.GetMemberAccessFlags(),
@@ -160,12 +161,12 @@
       if (result == kHardFailure) {
         hard_fail = true;
         if (error_count > 0) {
-          error += "\n";
+          *error += "\n";
         }
-        error = "Verifier rejected class ";
-        error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
-        error += " due to bad method ";
-        error += PrettyMethod(method_idx, *dex_file);
+        *error = "Verifier rejected class ";
+        *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
+        *error += " due to bad method ";
+        *error += PrettyMethod(method_idx, *dex_file);
       }
       ++error_count;
     }
@@ -181,7 +182,7 @@
       continue;
     }
     previous_virtual_method_idx = method_idx;
-    InvokeType type = it.GetMethodInvokeType(class_def);
+    InvokeType type = it.GetMethodInvokeType(*class_def);
     mirror::ArtMethod* method =
         linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
     if (method == NULL) {
@@ -193,7 +194,7 @@
                                                       dex_file,
                                                       dex_cache,
                                                       class_loader,
-                                                      class_def_idx,
+                                                      class_def,
                                                       it.GetMethodCodeItem(),
                                                       method,
                                                       it.GetMemberAccessFlags(),
@@ -202,12 +203,12 @@
       if (result == kHardFailure) {
         hard_fail = true;
         if (error_count > 0) {
-          error += "\n";
+          *error += "\n";
         }
-        error = "Verifier rejected class ";
-        error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
-        error += " due to bad method ";
-        error += PrettyMethod(method_idx, *dex_file);
+        *error = "Verifier rejected class ";
+        *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
+        *error += " due to bad method ";
+        *error += PrettyMethod(method_idx, *dex_file);
       }
       ++error_count;
     }
@@ -224,7 +225,7 @@
                                                          const DexFile* dex_file,
                                                          mirror::DexCache* dex_cache,
                                                          mirror::ClassLoader* class_loader,
-                                                         uint32_t class_def_idx,
+                                                         const DexFile::ClassDef* class_def,
                                                          const DexFile::CodeItem* code_item,
                                                          mirror::ArtMethod* method,
                                                          uint32_t method_access_flags,
@@ -232,7 +233,7 @@
   MethodVerifier::FailureKind result = kNoFailure;
   uint64_t start_ns = NanoTime();
 
-  MethodVerifier verifier_(dex_file, dex_cache, class_loader, class_def_idx, code_item, method_idx,
+  MethodVerifier verifier_(dex_file, dex_cache, class_loader, class_def, code_item, method_idx,
                            method, method_access_flags, true, allow_soft_failures);
   if (verifier_.Verify()) {
     // Verification completed, however failures may be pending that didn't cause the verification
@@ -267,11 +268,12 @@
 
 void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_idx,
                                          const DexFile* dex_file, mirror::DexCache* dex_cache,
-                                         mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+                                         mirror::ClassLoader* class_loader,
+                                         const DexFile::ClassDef* class_def,
                                          const DexFile::CodeItem* code_item,
                                          mirror::ArtMethod* method,
                                          uint32_t method_access_flags) {
-  MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def_idx, code_item,
+  MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def, code_item,
                           dex_method_idx, method, method_access_flags, true, true);
   verifier.Verify();
   verifier.DumpFailures(os);
@@ -280,7 +282,8 @@
 }
 
 MethodVerifier::MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache,
-                               mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+                               mirror::ClassLoader* class_loader,
+                               const DexFile::ClassDef* class_def,
                                const DexFile::CodeItem* code_item,
                                uint32_t dex_method_idx, mirror::ArtMethod* method,
                                uint32_t method_access_flags, bool can_load_classes,
@@ -293,7 +296,7 @@
       dex_file_(dex_file),
       dex_cache_(dex_cache),
       class_loader_(class_loader),
-      class_def_idx_(class_def_idx),
+      class_def_(class_def),
       code_item_(code_item),
       declaring_class_(NULL),
       interesting_dex_pc_(-1),
@@ -306,13 +309,14 @@
       allow_soft_failures_(allow_soft_failures),
       has_check_casts_(false),
       has_virtual_or_interface_invokes_(false) {
+  DCHECK(class_def != NULL);
 }
 
 void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc,
                                       std::vector<uint32_t>& monitor_enter_dex_pcs) {
   MethodHelper mh(m);
   MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
-                          mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+                          &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
                           m, m->GetAccessFlags(), false, true);
   verifier.interesting_dex_pc_ = dex_pc;
   verifier.monitor_enter_dex_pcs_ = &monitor_enter_dex_pcs;
@@ -334,7 +338,7 @@
                                                         uint32_t dex_pc) {
   MethodHelper mh(m);
   MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
-                          mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+                          &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
                           m, m->GetAccessFlags(), false, true);
   return verifier.FindAccessedFieldAtDexPc(dex_pc);
 }
@@ -362,7 +366,7 @@
                                                                  uint32_t dex_pc) {
   MethodHelper mh(m);
   MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
-                          mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+                          &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
                           m, m->GetAccessFlags(), false, true);
   return verifier.FindInvokedMethodAtDexPc(dex_pc);
 }
@@ -448,7 +452,7 @@
       // marked as rejected to prevent it from being compiled.
     case VERIFY_ERROR_BAD_CLASS_HARD: {
       if (Runtime::Current()->IsCompiler()) {
-        ClassReference ref(dex_file_, class_def_idx_);
+        ClassReference ref(dex_file_, dex_file_->GetIndexForClassDef(*class_def_));
         AddRejectedClass(ref);
       }
       have_pending_hard_failure_ = true;
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 70442fb..073a2f7 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -145,17 +145,19 @@
   };
 
   /* Verify a class. Returns "kNoFailure" on success. */
-  static FailureKind VerifyClass(const mirror::Class* klass, std::string& error,
-                                 bool allow_soft_failures)
+  static FailureKind VerifyClass(const mirror::Class* klass, bool allow_soft_failures,
+                                 std::string* error)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static FailureKind VerifyClass(const DexFile* dex_file, mirror::DexCache* dex_cache,
-                                 mirror::ClassLoader* class_loader, uint32_t class_def_idx,
-                                 std::string& error, bool allow_soft_failures)
+                                 mirror::ClassLoader* class_loader,
+                                 const DexFile::ClassDef* class_def,
+                                 bool allow_soft_failures, std::string* error)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   static void VerifyMethodAndDump(std::ostream& os, uint32_t method_idx, const DexFile* dex_file,
                                   mirror::DexCache* dex_cache, mirror::ClassLoader* class_loader,
-                                  uint32_t class_def_idx, const DexFile::CodeItem* code_item,
+                                  const DexFile::ClassDef* class_def,
+                                  const DexFile::CodeItem* code_item,
                                   mirror::ArtMethod* method, uint32_t method_access_flags)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
@@ -222,7 +224,7 @@
   }
 
   MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache,
-                 mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+                 mirror::ClassLoader* class_loader, const DexFile::ClassDef* class_def,
                  const DexFile::CodeItem* code_item,
                  uint32_t method_idx, mirror::ArtMethod* method,
                  uint32_t access_flags, bool can_load_classes, bool allow_soft_failures)
@@ -262,7 +264,8 @@
    */
   static FailureKind VerifyMethod(uint32_t method_idx, const DexFile* dex_file,
                                   mirror::DexCache* dex_cache,
-                                  mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+                                  mirror::ClassLoader* class_loader,
+                                  const DexFile::ClassDef* class_def_idx,
                                   const DexFile::CodeItem* code_item,
                                   mirror::ArtMethod* method, uint32_t method_access_flags,
                                   bool allow_soft_failures)
@@ -690,7 +693,7 @@
   mirror::DexCache* dex_cache_ GUARDED_BY(Locks::mutator_lock_);
   // The class loader for the declaring class of the method.
   mirror::ClassLoader* class_loader_ GUARDED_BY(Locks::mutator_lock_);
-  const uint32_t class_def_idx_;  // The class def index of the declaring class of the method.
+  const DexFile::ClassDef* const class_def_;  // The class def of the declaring class of the method.
   const DexFile::CodeItem* const code_item_;  // The code item containing the code for the method.
   const RegType* declaring_class_;  // Lazily computed reg type of the method's declaring class.
   // Instruction widths and flags, one entry per code unit.
diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc
index 611b7c0..a56abba 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -34,7 +34,8 @@
 
     // Verify the class
     std::string error_msg;
-    ASSERT_TRUE(MethodVerifier::VerifyClass(klass, error_msg, true) == MethodVerifier::kNoFailure) << error_msg;
+    ASSERT_TRUE(MethodVerifier::VerifyClass(klass, true, &error_msg) == MethodVerifier::kNoFailure)
+        << error_msg;
   }
 
   void VerifyDexFile(const DexFile* dex)