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/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)