Use class def index from java.lang.Class.

Bug: 10244719
Depends on:
https://googleplex-android-review.git.corp.google.com/362363
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.

Change-Id: I20c73a3b17d86286428ab0fd21bc13f51f36c85c
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index c19f872..15eab9d 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(),
@@ -1234,8 +1227,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;
 }
 
@@ -1499,26 +1494,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
@@ -1572,11 +1562,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);
@@ -1600,12 +1592,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();
 }
 
@@ -1642,7 +1633,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
@@ -1734,6 +1725,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.
@@ -1781,7 +1773,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.
@@ -1876,7 +1868,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.
@@ -2342,12 +2335,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;
+          }
         }
       }
     }
@@ -2458,8 +2455,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) {
@@ -2530,7 +2528,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.
@@ -2542,9 +2539,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;
@@ -2657,8 +2652,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);
@@ -3265,10 +3258,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) {
@@ -3284,7 +3275,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_;