Revert "Combine direct_methods_ and virtual_methods_ fields of mirror::Class"

This reverts commit 6286a97bea0f584342803a215550038852b24776.

Change-Id: I5b00f6d1350e9c587acd4b185367dc815ea707de
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index c7c1907..638b897 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -142,7 +142,10 @@
   mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), loader);
   CHECK(klass != nullptr) << "Class not found " << class_name;
   size_t pointer_size = class_linker_->GetImagePointerSize();
-  for (auto& m : klass->GetMethods(pointer_size)) {
+  for (auto& m : klass->GetDirectMethods(pointer_size)) {
+    MakeExecutable(&m);
+  }
+  for (auto& m : klass->GetVirtualMethods(pointer_size)) {
     MakeExecutable(&m);
   }
 }
@@ -256,7 +259,10 @@
   mirror::Class* klass = class_linker_->FindClass(self, class_descriptor.c_str(), loader);
   CHECK(klass != nullptr) << "Class not found " << class_name;
   auto pointer_size = class_linker_->GetImagePointerSize();
-  for (auto& m : klass->GetMethods(pointer_size)) {
+  for (auto& m : klass->GetDirectMethods(pointer_size)) {
+    CompileMethod(&m);
+  }
+  for (auto& m : klass->GetVirtualMethods(pointer_size)) {
     CompileMethod(&m);
   }
 }
diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h
index 7a93613..15a4ba0 100644
--- a/compiler/compiled_method.h
+++ b/compiler/compiled_method.h
@@ -23,7 +23,7 @@
 
 #include "arch/instruction_set.h"
 #include "base/bit_utils.h"
-#include "base/length_prefixed_array.h"
+#include "length_prefixed_array.h"
 #include "method_reference.h"
 #include "utils/array_ref.h"
 
diff --git a/compiler/driver/compiled_method_storage.h b/compiler/driver/compiled_method_storage.h
index d6961a0..ef10b67 100644
--- a/compiler/driver/compiled_method_storage.h
+++ b/compiler/driver/compiled_method_storage.h
@@ -20,8 +20,8 @@
 #include <iosfwd>
 #include <memory>
 
-#include "base/length_prefixed_array.h"
 #include "base/macros.h"
+#include "length_prefixed_array.h"
 #include "utils/array_ref.h"
 #include "utils/dedupe_set.h"
 #include "utils/swap_space.h"
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 56839f8..ba8f1d0 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -790,7 +790,10 @@
 
   virtual bool Visit(mirror::Class* c) OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
     const auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
-    for (auto& m : c->GetMethods(pointer_size)) {
+    for (auto& m : c->GetVirtualMethods(pointer_size)) {
+      ResolveExceptionsForMethod(&m, pointer_size);
+    }
+    for (auto& m : c->GetDirectMethods(pointer_size)) {
       ResolveExceptionsForMethod(&m, pointer_size);
     }
     return true;
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 86f8b82..f8de9fa 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -86,7 +86,10 @@
       mirror::Class* c = class_linker->FindClass(soa.Self(), descriptor, loader);
       CHECK(c != nullptr);
       const auto pointer_size = class_linker->GetImagePointerSize();
-      for (auto& m : c->GetMethods(pointer_size)) {
+      for (auto& m : c->GetDirectMethods(pointer_size)) {
+        MakeExecutable(&m);
+      }
+      for (auto& m : c->GetVirtualMethods(pointer_size)) {
         MakeExecutable(&m);
       }
     }
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index b9ec47d..fce08ea 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -1030,42 +1030,44 @@
         }
       }
       // Visit and assign offsets for methods.
-      size_t num_methods = as_klass->NumMethods();
-      if (num_methods != 0) {
+      LengthPrefixedArray<ArtMethod>* method_arrays[] = {
+          as_klass->GetDirectMethodsPtr(), as_klass->GetVirtualMethodsPtr(),
+      };
+      for (LengthPrefixedArray<ArtMethod>* array : method_arrays) {
+        if (array == nullptr) {
+          continue;
+        }
         bool any_dirty = false;
-        for (auto& m : as_klass->GetMethods(target_ptr_size_)) {
-          if (WillMethodBeDirty(&m)) {
-            any_dirty = true;
-            break;
-          }
+        size_t count = 0;
+        const size_t method_alignment = ArtMethod::Alignment(target_ptr_size_);
+        const size_t method_size = ArtMethod::Size(target_ptr_size_);
+        auto iteration_range =
+            MakeIterationRangeFromLengthPrefixedArray(array, method_size, method_alignment);
+        for (auto& m : iteration_range) {
+          any_dirty = any_dirty || WillMethodBeDirty(&m);
+          ++count;
         }
         NativeObjectRelocationType type = any_dirty
             ? kNativeObjectRelocationTypeArtMethodDirty
             : kNativeObjectRelocationTypeArtMethodClean;
         Bin bin_type = BinTypeForNativeRelocationType(type);
         // Forward the entire array at once, but header first.
-        const size_t method_alignment = ArtMethod::Alignment(target_ptr_size_);
-        const size_t method_size = ArtMethod::Size(target_ptr_size_);
         const size_t header_size = LengthPrefixedArray<ArtMethod>::ComputeSize(0,
                                                                                method_size,
                                                                                method_alignment);
-        LengthPrefixedArray<ArtMethod>* array = as_klass->GetMethodsPtr();
         auto it = native_object_relocations_.find(array);
-        CHECK(it == native_object_relocations_.end())
-            << "Method array " << array << " already forwarded";
+        CHECK(it == native_object_relocations_.end()) << "Method array " << array
+            << " already forwarded";
         size_t& offset = bin_slot_sizes_[bin_type];
         DCHECK(!IsInBootImage(array));
-        native_object_relocations_.emplace(
-            array, NativeObjectRelocation {
-              offset,
-              any_dirty ? kNativeObjectRelocationTypeArtMethodArrayDirty
-                        : kNativeObjectRelocationTypeArtMethodArrayClean
-            });
+        native_object_relocations_.emplace(array, NativeObjectRelocation { offset,
+            any_dirty ? kNativeObjectRelocationTypeArtMethodArrayDirty :
+                kNativeObjectRelocationTypeArtMethodArrayClean });
         offset += header_size;
-        for (auto& m : as_klass->GetMethods(target_ptr_size_)) {
+        for (auto& m : iteration_range) {
           AssignMethodOffset(&m, type);
         }
-        (any_dirty ? dirty_methods_ : clean_methods_) += num_methods;
+        (any_dirty ? dirty_methods_ : clean_methods_) += count;
       }
     } else if (h_obj->IsObjectArray()) {
       // Walk elements of an object array.
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index f1b2965..8e930f0 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -27,11 +27,11 @@
 #include <ostream>
 
 #include "base/bit_utils.h"
-#include "base/length_prefixed_array.h"
 #include "base/macros.h"
 #include "driver/compiler_driver.h"
 #include "gc/space/space.h"
 #include "image.h"
+#include "length_prefixed_array.h"
 #include "lock_word.h"
 #include "mem_map.h"
 #include "oat_file.h"
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index b849b12..a2b29a3 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -238,12 +238,12 @@
       ++method_index;
     }
     size_t visited_virtuals = 0;
-    // TODO We should also check copied methods in this test.
-    for (auto& m : klass->GetDeclaredVirtualMethods(pointer_size)) {
-      EXPECT_FALSE(m.IsMiranda());
-      CheckMethod(&m, oat_class.GetOatMethod(method_index), dex_file);
-      ++method_index;
-      ++visited_virtuals;
+    for (auto& m : klass->GetVirtualMethods(pointer_size)) {
+      if (!m.IsMiranda()) {
+        CheckMethod(&m, oat_class.GetOatMethod(method_index), dex_file);
+        ++method_index;
+        ++visited_virtuals;
+      }
     }
     EXPECT_EQ(visited_virtuals, num_virtual_methods);
   }