Refactor ClassAccessor to use an index instead of ClassDef pointer

Removes a separate class_def_idx being required for getting the index
of a ClassAccessor foreach loop.

Bug: 79758018
Test: test-art-host-gtest

Change-Id: Ie3010a17669f24cf492c678b55bdddba7ec62ea8
diff --git a/compiler/dex/dex_to_dex_decompiler_test.cc b/compiler/dex/dex_to_dex_decompiler_test.cc
index 1fe42ad..d4a9ba5 100644
--- a/compiler/dex/dex_to_dex_decompiler_test.cc
+++ b/compiler/dex/dex_to_dex_decompiler_test.cc
@@ -82,9 +82,8 @@
     ASSERT_NE(0, cmp);
 
     // Unquicken the dex file.
-    for (uint32_t i = 0; i < updated_dex_file->NumClassDefs(); ++i) {
+    for (ClassAccessor accessor : updated_dex_file->GetClasses()) {
       // Unquicken each method.
-      ClassAccessor accessor(*updated_dex_file, updated_dex_file->GetClassDef(i));
       for (const ClassAccessor::Method& method : accessor.GetMethods()) {
         CompiledMethod* compiled_method = compiler_driver_->GetCompiledMethod(
             method.GetReference());
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 653e9ed..6cb3936 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1685,16 +1685,14 @@
 
 bool CompilerDriver::RequiresConstructorBarrier(const DexFile& dex_file,
                                                 uint16_t class_def_idx) const {
-  ClassAccessor accessor(dex_file, dex_file.GetClassDef(class_def_idx));
-  bool has_is_final = false;
+  ClassAccessor accessor(dex_file, class_def_idx);
   // We require a constructor barrier if there are final instance fields.
-  accessor.VisitFields(/*static*/ VoidFunctor(),
-                       [&](const ClassAccessor::Field& field) {
+  for (const ClassAccessor::Field& field : accessor.GetInstanceFields()) {
     if (field.IsFinal()) {
-      has_is_final = true;
+      return true;
     }
-  });
-  return has_is_final;
+  }
+  return false;
 }
 
 class ResolveClassFieldsAndMethodsVisitor : public CompilationVisitor {
@@ -1744,7 +1742,7 @@
     // fields are assigned within the lock held for class initialization.
     bool requires_constructor_barrier = false;
 
-    ClassAccessor accessor(dex_file, class_def);
+    ClassAccessor accessor(dex_file, class_def_index);
     // Optionally resolve fields and methods and figure out if we need a constructor barrier.
     auto method_visitor = [&](const ClassAccessor::Method& method)
         REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -1926,13 +1924,12 @@
     // Fetch the list of unverified classes.
     const std::set<dex::TypeIndex>& unverified_classes =
         verifier_deps->GetUnverifiedClasses(*dex_file);
-    uint32_t class_def_idx = 0u;
     for (ClassAccessor accessor : dex_file->GetClasses()) {
       if (unverified_classes.find(accessor.GetClassIdx()) == unverified_classes.end()) {
         if (compiler_only_verifies) {
           // Just update the compiled_classes_ map. The compiler doesn't need to resolve
           // the type.
-          ClassReference ref(dex_file, class_def_idx);
+          ClassReference ref(dex_file, accessor.GetClassDefIndex());
           const ClassStatus existing = ClassStatus::kNotReady;
           ClassStateTable::InsertResult result =
              compiled_classes_.Insert(ref, existing, ClassStatus::kVerified);
@@ -1959,7 +1956,6 @@
                             class_loader,
                             soa.Self());
       }
-      ++class_def_idx;
     }
   }
   return true;
@@ -2700,7 +2696,7 @@
     jobject jclass_loader = context.GetClassLoader();
     ClassReference ref(&dex_file, class_def_index);
     const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
-    ClassAccessor accessor(dex_file, class_def);
+    ClassAccessor accessor(dex_file, class_def_index);
     // Skip compiling classes with generic verifier failures since they will still fail at runtime
     if (context.GetCompiler()->GetVerificationResults()->IsClassRejected(ref)) {
       return;
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc
index 85778b6..8261035 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -612,7 +612,7 @@
           pClassDef.class_data_off_, pClassDef.class_data_off_);
 
   // Fields and methods.
-  ClassAccessor accessor(*pDexFile, pClassDef);
+  ClassAccessor accessor(*pDexFile, idx);
   fprintf(gOutFile, "static_fields_size  : %d\n", accessor.NumStaticFields());
   fprintf(gOutFile, "instance_fields_size: %d\n", accessor.NumInstanceFields());
   fprintf(gOutFile, "direct_methods_size : %d\n", accessor.NumDirectMethods());
diff --git a/libdexfile/dex/class_accessor-inl.h b/libdexfile/dex/class_accessor-inl.h
index 3bb9e93..a335f08 100644
--- a/libdexfile/dex/class_accessor-inl.h
+++ b/libdexfile/dex/class_accessor-inl.h
@@ -26,12 +26,15 @@
 namespace art {
 
 inline ClassAccessor::ClassAccessor(const ClassIteratorData& data)
-    : ClassAccessor(data.dex_file_, data.dex_file_.GetClassDef(data.class_def_idx_)) {}
+    : ClassAccessor(data.dex_file_, data.class_def_idx_) {}
 
 inline ClassAccessor::ClassAccessor(const DexFile& dex_file, const DexFile::ClassDef& class_def)
+    : ClassAccessor(dex_file, dex_file.GetIndexForClassDef(class_def)) {}
+
+inline ClassAccessor::ClassAccessor(const DexFile& dex_file, uint32_t class_def_index)
     : dex_file_(dex_file),
-      descriptor_index_(class_def.class_idx_),
-      ptr_pos_(dex_file.GetClassData(class_def)),
+      class_def_index_(class_def_index),
+      ptr_pos_(dex_file.GetClassData(dex_file.GetClassDef(class_def_index))),
       num_static_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
       num_instance_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
       num_direct_methods_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
@@ -108,7 +111,7 @@
 }
 
 inline const char* ClassAccessor::GetDescriptor() const {
-  return dex_file_.StringByTypeIdx(descriptor_index_);
+  return dex_file_.StringByTypeIdx(GetClassIdx());
 }
 
 inline const DexFile::CodeItem* ClassAccessor::Method::GetCodeItem() const {
@@ -175,6 +178,10 @@
   DexFile::UnHideAccessFlags(const_cast<uint8_t*>(ptr_pos_), GetAccessFlags(), /*is_method*/ true);
 }
 
+inline dex::TypeIndex ClassAccessor::GetClassIdx() const {
+  return dex_file_.GetClassDef(class_def_index_).class_idx_;
+}
+
 }  // namespace art
 
 #endif  // ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_INL_H_
diff --git a/libdexfile/dex/class_accessor.h b/libdexfile/dex/class_accessor.h
index 4f0fd32..34c7e07 100644
--- a/libdexfile/dex/class_accessor.h
+++ b/libdexfile/dex/class_accessor.h
@@ -248,6 +248,8 @@
 
   ClassAccessor(const DexFile& dex_file, const DexFile::ClassDef& class_def);
 
+  ClassAccessor(const DexFile& dex_file, uint32_t class_def_index);
+
   // Return the code item for a method.
   const DexFile::CodeItem* GetCodeItem(const Method& method) const;
 
@@ -315,9 +317,7 @@
 
   const char* GetDescriptor() const;
 
-  dex::TypeIndex GetClassIdx() const {
-    return descriptor_index_;
-  }
+  dex::TypeIndex GetClassIdx() const;
 
   const DexFile& GetDexFile() const {
     return dex_file_;
@@ -327,6 +327,10 @@
     return ptr_pos_ != nullptr;
   }
 
+  uint32_t GetClassDefIndex() const {
+    return class_def_index_;
+  }
+
  protected:
   // Template visitor to reduce copy paste for visiting elements.
   // No thread safety analysis since the visitor may require capabilities.
@@ -341,7 +345,7 @@
   IterationRange<DataIterator<Method>> GetMethodsInternal(size_t count) const;
 
   const DexFile& dex_file_;
-  const dex::TypeIndex descriptor_index_ = {};
+  const uint32_t class_def_index_;
   const uint8_t* ptr_pos_ = nullptr;  // Pointer into stream of class_data_item.
   const uint32_t num_static_fields_ = 0u;
   const uint32_t num_instance_fields_ = 0u;
diff --git a/libdexfile/dex/class_accessor_test.cc b/libdexfile/dex/class_accessor_test.cc
index d0533c1..1f30ae5 100644
--- a/libdexfile/dex/class_accessor_test.cc
+++ b/libdexfile/dex/class_accessor_test.cc
@@ -30,8 +30,9 @@
     uint32_t class_def_idx = 0u;
     ASSERT_GT(dex_file->NumClassDefs(), 0u);
     for (ClassAccessor accessor : dex_file->GetClasses()) {
-      const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
+      const DexFile::ClassDef& class_def = dex_file->GetClassDef(accessor.GetClassDefIndex());
       EXPECT_EQ(accessor.GetDescriptor(), dex_file->StringByTypeIdx(class_def.class_idx_));
+      EXPECT_EQ(class_def_idx, accessor.GetClassDefIndex());
       ++class_def_idx;
       // Check iterators against visitors.
       auto methods = accessor.GetMethods();
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 25676f7..5c339b8 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -274,7 +274,7 @@
   void WalkOatClass(const OatFile::OatClass& oat_class,
                     const DexFile& dex_file,
                     uint32_t class_def_index) {
-    ClassAccessor accessor(dex_file, dex_file.GetClassDef(class_def_index));
+    ClassAccessor accessor(dex_file, class_def_index);
     // Note: even if this is an interface or a native class, we still have to walk it, as there
     //       might be a static initializer.
     uint32_t class_method_idx = 0;
@@ -905,15 +905,13 @@
         continue;
       }
       offsets_.insert(reinterpret_cast<uintptr_t>(&dex_file->GetHeader()));
-      uint32_t class_def_index = 0u;
       for (ClassAccessor accessor : dex_file->GetClasses()) {
-        const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(class_def_index);
+        const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(accessor.GetClassDefIndex());
         for (uint32_t class_method_index = 0;
             class_method_index < accessor.NumMethods();
             ++class_method_index) {
           AddOffsets(oat_class.GetOatMethod(class_method_index));
         }
-        ++class_def_index;
       }
     }
 
diff --git a/profman/profman.cc b/profman/profman.cc
index 096e5dc..5fbce66 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -930,7 +930,9 @@
       dex_resolved_classes.first->AddClass(class_ref.TypeIndex());
       std::vector<ProfileMethodInfo> methods;
       if (method_str == kClassAllMethods) {
-        ClassAccessor accessor(*dex_file, *dex_file->FindClassDef(class_ref.TypeIndex()));
+        ClassAccessor accessor(
+            *dex_file,
+            dex_file->GetIndexForClassDef(*dex_file->FindClassDef(class_ref.TypeIndex())));
         for (const ClassAccessor::Method& method : accessor.GetMethods()) {
           if (method.GetCodeItemOffset() != 0) {
             // Add all of the methods that have code to the profile.
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 45bf664..5b4dcb7 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -425,7 +425,7 @@
 static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file,
                                                  uint16_t class_def_idx,
                                                  uint32_t method_idx) {
-  ClassAccessor accessor(dex_file, dex_file.GetClassDef(class_def_idx));
+  ClassAccessor accessor(dex_file, class_def_idx);
   uint32_t class_def_method_index = 0u;
   for (const ClassAccessor::Method& method : accessor.GetMethods()) {
     if (method.GetIndex() == method_idx) {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index be636d8..b1fd5f4 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2863,9 +2863,9 @@
   }
 
   const DexFile& dex_file = klass->GetDexFile();
-  const DexFile::ClassDef* dex_class_def = klass->GetClassDef();
-  CHECK(dex_class_def != nullptr);
-  ClassAccessor accessor(dex_file, *dex_class_def);
+  const uint16_t class_def_idx = klass->GetDexClassDefIndex();
+  CHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
+  ClassAccessor accessor(dex_file, class_def_idx);
   // There should always be class data if there were direct methods.
   CHECK(accessor.HasClassData()) << klass->PrettyDescriptor();
   bool has_oat_class;
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 5961748..a62271d 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -212,8 +212,6 @@
                                         bool allow_soft_failures,
                                         HardFailLogMode log_level,
                                         std::string* error) {
-  SCOPED_TRACE << "VerifyClass " << PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
-
   // A class must not be abstract and final.
   if ((class_def.access_flags_ & (kAccAbstract | kAccFinal)) == (kAccAbstract | kAccFinal)) {
     *error = "Verifier rejected class ";
@@ -223,6 +221,7 @@
   }
 
   ClassAccessor accessor(*dex_file, class_def);
+  SCOPED_TRACE << "VerifyClass " << PrettyDescriptor(accessor.GetDescriptor());
 
   int64_t previous_method_idx[2] = { -1, -1 };
   MethodVerifier::FailureData failure_data;