Move OatWriter to ClassAccessor

Bug: 79758018
Test: test-art-host

Change-Id: I3ceb3d1fc39ef7e3a363618466f6786c2f8d90dc
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index a1a547c..484554e 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -38,6 +38,7 @@
 #include "compiled_method-inl.h"
 #include "debug/method_debug_info.h"
 #include "dex/art_dex_file_loader.h"
+#include "dex/class_accessor-inl.h"
 #include "dex/dex_file-inl.h"
 #include "dex/dex_file_loader.h"
 #include "dex/dex_file_types.h"
@@ -791,7 +792,7 @@
     return true;
   }
 
-  virtual bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it) = 0;
+  virtual bool VisitMethod(size_t class_def_method_index, const ClassAccessor::Method& method) = 0;
 
   virtual bool EndClass() {
     if (kIsDebugBuild) {
@@ -861,10 +862,10 @@
       : DexMethodVisitor(writer, /* offset */ 0u) {}
 
   bool VisitMethod(size_t class_def_method_index ATTRIBUTE_UNUSED,
-                   const ClassDataItemIterator& it) OVERRIDE {
+                   const ClassAccessor::Method& method) OVERRIDE {
     // Look for patches with .bss references and prepare maps with placeholders for their offsets.
     CompiledMethod* compiled_method = writer_->compiler_driver_->GetCompiledMethod(
-        MethodReference(dex_file_, it.GetMemberIndex()));
+        MethodReference(dex_file_, method.GetIndex()));
     if (HasCompiledCode(compiled_method)) {
       for (const LinkerPatch& patch : compiled_method->GetPatches()) {
         if (patch.GetType() == LinkerPatch::Type::kDataBimgRelRo) {
@@ -943,12 +944,12 @@
   }
 
   bool VisitMethod(size_t class_def_method_index ATTRIBUTE_UNUSED,
-                   const ClassDataItemIterator& it) OVERRIDE {
+                   const ClassAccessor::Method& method) OVERRIDE {
     // Fill in the compiled_methods_ array for methods that have a
     // CompiledMethod. We track the number of non-null entries in
     // compiled_methods_with_code_ since we only want to allocate
     // OatMethodOffsets for the compiled methods.
-    uint32_t method_idx = it.GetMemberIndex();
+    uint32_t method_idx = method.GetIndex();
     CompiledMethod* compiled_method =
         writer_->compiler_driver_->GetCompiledMethod(MethodReference(dex_file_, method_idx));
     compiled_methods_.push_back(compiled_method);
@@ -1150,7 +1151,7 @@
   }
 
   bool VisitMethod(size_t class_def_method_index,
-                   const ClassDataItemIterator& it)
+                   const ClassAccessor::Method& method)
       OVERRIDE
       REQUIRES_SHARED(Locks::mutator_lock_)  {
     Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
@@ -1182,7 +1183,7 @@
         }
       }
 
-      MethodReference method_ref(dex_file_, it.GetMemberIndex());
+      MethodReference method_ref(dex_file_, method.GetIndex());
 
       // Lookup method hotness from profile, if available.
       // Otherwise assume a default of none-hotness.
@@ -1199,8 +1200,8 @@
           method_ref,
           method_offsets_index_,
           class_def_index_,
-          it.GetMethodAccessFlags(),
-          it.GetMethodCodeItem(),
+          method.GetAccessFlags(),
+          method.GetCodeItem(),
           debug_info_idx
       };
       ordered_methods_.push_back(method_data);
@@ -1442,7 +1443,8 @@
   InitMapMethodVisitor(OatWriter* writer, size_t offset)
       : OatDexMethodVisitor(writer, offset) {}
 
-  bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it ATTRIBUTE_UNUSED)
+  bool VisitMethod(size_t class_def_method_index,
+                   const ClassAccessor::Method& method ATTRIBUTE_UNUSED)
       OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
     OatClass* oat_class = &writer_->oat_classes_[oat_class_index_];
     CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index);
@@ -1543,7 +1545,7 @@
     return true;
   }
 
-  bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it) OVERRIDE
+  bool VisitMethod(size_t class_def_method_index, const ClassAccessor::Method& method) OVERRIDE
       REQUIRES_SHARED(Locks::mutator_lock_) {
     // Skip methods that are not in the image.
     if (!IsImageClass()) {
@@ -1562,22 +1564,22 @@
 
     Thread* self = Thread::Current();
     ObjPtr<mirror::DexCache> dex_cache = class_linker_->FindDexCache(self, *dex_file_);
-    ArtMethod* method;
+    ArtMethod* resolved_method;
     if (writer_->GetCompilerOptions().IsBootImage()) {
-      const InvokeType invoke_type = it.GetMethodInvokeType(
-          dex_file_->GetClassDef(class_def_index_));
+      const InvokeType invoke_type = method.GetInvokeType(
+          dex_file_->GetClassDef(class_def_index_).access_flags_);
       // Unchecked as we hold mutator_lock_ on entry.
       ScopedObjectAccessUnchecked soa(self);
       StackHandleScope<1> hs(self);
-      method = class_linker_->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
-          it.GetMemberIndex(),
+      resolved_method = class_linker_->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
+          method.GetIndex(),
           hs.NewHandle(dex_cache),
           ScopedNullHandle<mirror::ClassLoader>(),
           /* referrer */ nullptr,
           invoke_type);
-      if (method == nullptr) {
+      if (resolved_method == nullptr) {
         LOG(FATAL_WITHOUT_ABORT) << "Unexpected failure to resolve a method: "
-            << dex_file_->PrettyMethod(it.GetMemberIndex(), true);
+            << dex_file_->PrettyMethod(method.GetIndex(), true);
         self->AssertPendingException();
         mirror::Throwable* exc = self->GetException();
         std::string dump = exc->Dump();
@@ -1588,12 +1590,14 @@
       // Should already have been resolved by the compiler.
       // It may not be resolved if the class failed to verify, in this case, don't set the
       // entrypoint. This is not fatal since we shall use a resolution method.
-      method = class_linker_->LookupResolvedMethod(it.GetMemberIndex(), dex_cache, class_loader_);
+      resolved_method = class_linker_->LookupResolvedMethod(method.GetIndex(),
+                                                            dex_cache,
+                                                            class_loader_);
     }
-    if (method != nullptr &&
+    if (resolved_method != nullptr &&
         compiled_method != nullptr &&
         compiled_method->GetQuickCode().size() != 0) {
-      method->SetEntryPointFromQuickCompiledCodePtrSize(
+      resolved_method->SetEntryPointFromQuickCompiledCodePtrSize(
           reinterpret_cast<void*>(offsets.code_offset_), pointer_size_);
     }
 
@@ -2001,26 +2005,17 @@
 // Visit all methods from all classes in all dex files with the specified visitor.
 bool OatWriter::VisitDexMethods(DexMethodVisitor* visitor) {
   for (const DexFile* dex_file : *dex_files_) {
-    const size_t class_def_count = dex_file->NumClassDefs();
-    for (size_t class_def_index = 0; class_def_index != class_def_count; ++class_def_index) {
-      if (UNLIKELY(!visitor->StartClass(dex_file, class_def_index))) {
+    for (ClassAccessor accessor : dex_file->GetClasses()) {
+      if (UNLIKELY(!visitor->StartClass(dex_file, accessor.GetClassDefIndex()))) {
         return false;
       }
       if (MayHaveCompiledMethods()) {
-        const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
-        const uint8_t* class_data = dex_file->GetClassData(class_def);
-        if (class_data != nullptr) {  // ie not an empty class, such as a marker interface
-          ClassDataItemIterator it(*dex_file, class_data);
-          it.SkipAllFields();
-          size_t class_def_method_index = 0u;
-          while (it.HasNextMethod()) {
-            if (!visitor->VisitMethod(class_def_method_index, it)) {
-              return false;
-            }
-            ++class_def_method_index;
-            it.Next();
+        size_t class_def_method_index = 0u;
+        for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+          if (!visitor->VisitMethod(class_def_method_index, method)) {
+            return false;
           }
-          DCHECK(!it.HasNext());
+          ++class_def_method_index;
         }
       }
       if (UNLIKELY(!visitor->EndClass())) {
diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc
index bb27e8c..d73f10a 100644
--- a/dex2oat/linker/oat_writer_test.cc
+++ b/dex2oat/linker/oat_writer_test.cc
@@ -26,6 +26,7 @@
 #include "compiled_method-inl.h"
 #include "compiler.h"
 #include "debug/method_debug_info.h"
+#include "dex/class_accessor-inl.h"
 #include "dex/dex_file_loader.h"
 #include "dex/quick_compiler_callbacks.h"
 #include "dex/test_dex_file_builder.h"
@@ -428,22 +429,15 @@
   CHECK_EQ(dex_file.GetLocationChecksum(), oat_dex_file->GetDexFileLocationChecksum());
   ScopedObjectAccess soa(Thread::Current());
   auto pointer_size = class_linker->GetImagePointerSize();
-  for (size_t i = 0; i < dex_file.NumClassDefs(); i++) {
-    const DexFile::ClassDef& class_def = dex_file.GetClassDef(i);
-    const uint8_t* class_data = dex_file.GetClassData(class_def);
+  for (ClassAccessor accessor : dex_file.GetClasses()) {
+    size_t num_virtual_methods = accessor.NumVirtualMethods();
 
-    size_t num_virtual_methods = 0;
-    if (class_data != nullptr) {
-      ClassDataItemIterator it(dex_file, class_data);
-      num_virtual_methods = it.NumVirtualMethods();
-    }
-
-    const char* descriptor = dex_file.GetClassDescriptor(class_def);
+    const char* descriptor = accessor.GetDescriptor();
     ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(),
                                                           descriptor,
                                                           ScopedNullHandle<mirror::ClassLoader>());
 
-    const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(i);
+    const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(accessor.GetClassDefIndex());
     CHECK_EQ(ClassStatus::kNotReady, oat_class.GetStatus()) << descriptor;
     CHECK_EQ(kCompile ? OatClassType::kOatClassAllCompiled : OatClassType::kOatClassNoneCompiled,
              oat_class.GetType()) << descriptor;