Remove DexFile direct accesses to CodeItem

Motivation: StandardDexFile and CompactDexFile should be able to a
have different layout for code items.

Also addressed comments from a previous CL.

Bug: 63756964
Test: test-art-host

Change-Id: I5ea7a853b8095f68b4443ded0f599f2ac5efbd3a
diff --git a/compiler/dex/dex_to_dex_decompiler_test.cc b/compiler/dex/dex_to_dex_decompiler_test.cc
index 89a63c0..8bccd3b 100644
--- a/compiler/dex/dex_to_dex_decompiler_test.cc
+++ b/compiler/dex/dex_to_dex_decompiler_test.cc
@@ -99,7 +99,7 @@
         if (compiled_method != nullptr) {
           table = compiled_method->GetVmapTable();
         }
-        optimizer::ArtDecompileDEX(updated_dex_file,
+        optimizer::ArtDecompileDEX(*updated_dex_file,
                                    *it.GetMethodCodeItem(),
                                    table,
                                    /* decompile_return_instruction */ true);
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 5d4ed46..43e0db5 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -702,7 +702,7 @@
 //       stable order.
 
 static void ResolveConstStrings(Handle<mirror::DexCache> dex_cache,
-                                const DexFile* dex_file,
+                                const DexFile& dex_file,
                                 const DexFile::CodeItem* code_item)
       REQUIRES_SHARED(Locks::mutator_lock_) {
   if (code_item == nullptr) {
@@ -711,7 +711,7 @@
   }
 
   ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
-  for (const DexInstructionPcPair& inst : CodeItemInstructionAccessor(dex_file, code_item)) {
+  for (const DexInstructionPcPair& inst : CodeItemInstructionAccessor(&dex_file, code_item)) {
     switch (inst->Opcode()) {
       case Instruction::CONST_STRING:
       case Instruction::CONST_STRING_JUMBO: {
@@ -773,7 +773,7 @@
           continue;
         }
         previous_method_idx = method_idx;
-        ResolveConstStrings(dex_cache, dex_file, it.GetMethodCodeItem());
+        ResolveConstStrings(dex_cache, *dex_file, it.GetMethodCodeItem());
         it.Next();
       }
       DCHECK(!it.HasNext());
diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc
index 157d4ef..d4a7395 100644
--- a/dexlayout/dex_ir.cc
+++ b/dexlayout/dex_ir.cc
@@ -669,7 +669,7 @@
     }
   }
 
-  uint32_t size = DexFile::GetCodeItemSize(disk_code_item);
+  uint32_t size = dex_file.GetCodeItemSize(disk_code_item);
   CodeItem* code_item = new CodeItem(
       registers_size, ins_size, outs_size, debug_info, insns_size, insns, tries, handler_list);
   code_item->SetSize(size);
diff --git a/runtime/cdex/compact_dex_file.cc b/runtime/cdex/compact_dex_file.cc
index a92ab28..8f90e09 100644
--- a/runtime/cdex/compact_dex_file.cc
+++ b/runtime/cdex/compact_dex_file.cc
@@ -16,6 +16,9 @@
 
 #include "compact_dex_file.h"
 
+#include "dex_file-inl.h"
+#include "leb128.h"
+
 namespace art {
 
 constexpr uint8_t CompactDexFile::kDexMagic[kDexMagicSize];
@@ -51,4 +54,37 @@
       static_cast<uint32_t>(FeatureFlags::kDefaultMethods)) != 0;
 }
 
+uint32_t CompactDexFile::GetCodeItemSize(const DexFile::CodeItem& item) const {
+  // TODO: Clean up this temporary code duplication with StandardDexFile. Eventually the
+  // implementations will differ.
+  DCHECK(HasAddress(&item));
+  const CodeItem& code_item = down_cast<const CodeItem&>(item);
+  uintptr_t code_item_start = reinterpret_cast<uintptr_t>(&code_item);
+  uint32_t insns_size = code_item.insns_size_in_code_units_;
+  uint32_t tries_size = code_item.tries_size_;
+  const uint8_t* handler_data = GetCatchHandlerData(
+      DexInstructionIterator(code_item.insns_, code_item.insns_size_in_code_units_),
+      code_item.tries_size_,
+      0);
+
+  if (tries_size == 0 || handler_data == nullptr) {
+    uintptr_t insns_end = reinterpret_cast<uintptr_t>(&code_item.insns_[insns_size]);
+    return insns_end - code_item_start;
+  } else {
+    // Get the start of the handler data.
+    uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data);
+    // Manually read each handler.
+    for (uint32_t i = 0; i < handlers_size; ++i) {
+      int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2;
+      if (uleb128_count <= 0) {
+        uleb128_count = -uleb128_count + 1;
+      }
+      for (int32_t j = 0; j < uleb128_count; ++j) {
+        DecodeUnsignedLeb128(&handler_data);
+      }
+    }
+    return reinterpret_cast<uintptr_t>(handler_data) - code_item_start;
+  }
+}
+
 }  // namespace art
diff --git a/runtime/cdex/compact_dex_file.h b/runtime/cdex/compact_dex_file.h
index e47f97e..4343229 100644
--- a/runtime/cdex/compact_dex_file.h
+++ b/runtime/cdex/compact_dex_file.h
@@ -47,6 +47,7 @@
   struct CodeItem : public DexFile::CodeItem {
    private:
     // TODO: Insert compact dex specific fields here.
+    friend class CompactDexFile;
     DISALLOW_COPY_AND_ASSIGN(CodeItem);
   };
 
@@ -70,6 +71,8 @@
 
   virtual bool SupportsDefaultMethods() const OVERRIDE;
 
+  uint32_t GetCodeItemSize(const DexFile::CodeItem& item) const OVERRIDE;
+
  private:
   // Not supported yet.
   CompactDexFile(const uint8_t* base,
diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h
index 7cc8b87..90b3c8d 100644
--- a/runtime/dex_file-inl.h
+++ b/runtime/dex_file-inl.h
@@ -507,6 +507,15 @@
   return down_cast<const StandardDexFile*>(this);
 }
 
+// Get the base of the encoded data for the given DexCode.
+inline const uint8_t* DexFile::GetCatchHandlerData(const DexInstructionIterator& code_item_end,
+                                                   uint32_t tries_size,
+                                                   uint32_t offset) {
+  const uint8_t* handler_data =
+      reinterpret_cast<const uint8_t*>(GetTryItems(code_item_end, tries_size));
+  return handler_data + offset;
+}
+
 }  // namespace art
 
 #endif  // ART_RUNTIME_DEX_FILE_INL_H_
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index d6469c6..16325b8 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -217,35 +217,6 @@
   UNREACHABLE();
 }
 
-uint32_t DexFile::GetCodeItemSize(const DexFile::CodeItem& code_item) {
-  uintptr_t code_item_start = reinterpret_cast<uintptr_t>(&code_item);
-  uint32_t insns_size = code_item.insns_size_in_code_units_;
-  uint32_t tries_size = code_item.tries_size_;
-  const uint8_t* handler_data = GetCatchHandlerData(
-      DexInstructionIterator(code_item.insns_, code_item.insns_size_in_code_units_),
-      code_item.tries_size_,
-      0);
-
-  if (tries_size == 0 || handler_data == nullptr) {
-    uintptr_t insns_end = reinterpret_cast<uintptr_t>(&code_item.insns_[insns_size]);
-    return insns_end - code_item_start;
-  } else {
-    // Get the start of the handler data.
-    uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data);
-    // Manually read each handler.
-    for (uint32_t i = 0; i < handlers_size; ++i) {
-      int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2;
-      if (uleb128_count <= 0) {
-        uleb128_count = -uleb128_count + 1;
-      }
-      for (int32_t j = 0; j < uleb128_count; ++j) {
-        DecodeUnsignedLeb128(&handler_data);
-      }
-    }
-    return reinterpret_cast<uintptr_t>(handler_data) - code_item_start;
-  }
-}
-
 const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_klass,
                                              const DexFile::StringId& name,
                                              const DexFile::TypeId& type) const {
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index b9bf119..6e11f09 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -308,7 +308,11 @@
       debug_info_off_ = new_offset;
     }
 
-   private:
+    uint32_t GetDebugInfoOffset() const {
+      return debug_info_off_;
+    }
+
+   protected:
     uint16_t registers_size_;            // the number of registers used by this code
                                          //   (locals + parameters)
     uint16_t ins_size_;                  // the number of words of incoming arguments to the method
@@ -333,7 +337,6 @@
     friend class CodeItemDataAccessor;
     friend class CodeItemDebugInfoAccessor;
     friend class CodeItemInstructionAccessor;
-    friend class DexFile;  // TODO: Remove this one when it's cleaned up.
     friend class VdexFile;  // TODO: Remove this one when it's cleaned up.
     DISALLOW_COPY_AND_ASSIGN(CodeItem);
   };
@@ -583,7 +586,7 @@
   uint32_t FindCodeItemOffset(const DexFile::ClassDef& class_def,
                               uint32_t dex_method_idx) const;
 
-  static uint32_t GetCodeItemSize(const DexFile::CodeItem& disk_code_item);
+  virtual uint32_t GetCodeItemSize(const DexFile::CodeItem& disk_code_item) const = 0;
 
   // Returns the declaring class descriptor string of a field id.
   const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const {
@@ -715,7 +718,7 @@
     }
     CHECK(oat_dex_file_ == nullptr)
         << "Should only use GetDebugInfoOffset in a non runtime setup";
-    return code_item->debug_info_off_;
+    return code_item->GetDebugInfoOffset();
   }
 
   const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const;
@@ -778,11 +781,7 @@
   // Get the base of the encoded data for the given DexCode.
   static const uint8_t* GetCatchHandlerData(const DexInstructionIterator& code_item_end,
                                             uint32_t tries_size,
-                                            uint32_t offset) {
-    const uint8_t* handler_data =
-        reinterpret_cast<const uint8_t*>(GetTryItems(code_item_end, tries_size));
-    return handler_data + offset;
-  }
+                                            uint32_t offset);
 
   // Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
   static int32_t FindTryItem(const TryItem* try_items, uint32_t tries_size, uint32_t address);
diff --git a/runtime/dex_file_tracking_registrar.cc b/runtime/dex_file_tracking_registrar.cc
index c157ddc..bffca55 100644
--- a/runtime/dex_file_tracking_registrar.cc
+++ b/runtime/dex_file_tracking_registrar.cc
@@ -164,7 +164,7 @@
         const DexFile::CodeItem* code_item = cdit.GetMethodCodeItem();
         if (code_item != nullptr) {
           const void* code_item_begin = reinterpret_cast<const void*>(code_item);
-          size_t code_item_size = DexFile::GetCodeItemSize(*code_item);
+          size_t code_item_size = dex_file_->GetCodeItemSize(*code_item);
           range_values_.push_back(std::make_tuple(code_item_begin, code_item_size, should_poison));
         }
         cdit.Next();
@@ -233,7 +233,7 @@
         const DexFile::CodeItem* code_item = cdit.GetMethodCodeItem();
         if (code_item != nullptr && strcmp(methodid_name, class_name) == 0) {
           const void* code_item_begin = reinterpret_cast<const void*>(code_item);
-          size_t code_item_size = DexFile::GetCodeItemSize(*code_item);
+          size_t code_item_size = dex_file_->GetCodeItemSize(*code_item);
           range_values_.push_back(std::make_tuple(code_item_begin, code_item_size, should_poison));
         }
         cdit.Next();
diff --git a/runtime/dex_to_dex_decompiler.cc b/runtime/dex_to_dex_decompiler.cc
index dc7e11b..7f36c4e 100644
--- a/runtime/dex_to_dex_decompiler.cc
+++ b/runtime/dex_to_dex_decompiler.cc
@@ -31,11 +31,11 @@
 
 class DexDecompiler {
  public:
-  DexDecompiler(const DexFile* dex_file,
+  DexDecompiler(const DexFile& dex_file,
                 const DexFile::CodeItem& code_item,
                 const ArrayRef<const uint8_t>& quickened_info,
                 bool decompile_return_instruction)
-    : code_item_accessor_(dex_file, &code_item),
+    : code_item_accessor_(&dex_file, &code_item),
       quicken_info_(quickened_info.data()),
       quicken_info_number_of_indices_(QuickenInfoTable::NumberOfIndices(quickened_info.size())),
       decompile_return_instruction_(decompile_return_instruction) {}
@@ -196,7 +196,7 @@
   return true;
 }
 
-bool ArtDecompileDEX(const DexFile* dex_file,
+bool ArtDecompileDEX(const DexFile& dex_file,
                      const DexFile::CodeItem& code_item,
                      const ArrayRef<const uint8_t>& quickened_info,
                      bool decompile_return_instruction) {
diff --git a/runtime/dex_to_dex_decompiler.h b/runtime/dex_to_dex_decompiler.h
index 804b7e8..a2e3f28 100644
--- a/runtime/dex_to_dex_decompiler.h
+++ b/runtime/dex_to_dex_decompiler.h
@@ -29,7 +29,7 @@
 // to non-const has too many repercussions on the code base. We make it
 // consistent with DexToDexCompiler, but we should really change it to
 // DexFile::CodeItem*.
-bool ArtDecompileDEX(const DexFile* dex_file,
+bool ArtDecompileDEX(const DexFile& dex_file,
                      const DexFile::CodeItem& code_item,
                      const ArrayRef<const uint8_t>& quickened_data,
                      bool decompile_return_instruction);
diff --git a/runtime/standard_dex_file.cc b/runtime/standard_dex_file.cc
index b608341..843508d 100644
--- a/runtime/standard_dex_file.cc
+++ b/runtime/standard_dex_file.cc
@@ -16,6 +16,10 @@
 
 #include "standard_dex_file.h"
 
+#include "base/casts.h"
+#include "dex_file-inl.h"
+#include "leb128.h"
+
 namespace art {
 
 const uint8_t StandardDexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
@@ -67,4 +71,35 @@
   return GetDexVersion() >= DexFile::kDefaultMethodsVersion;
 }
 
+uint32_t StandardDexFile::GetCodeItemSize(const DexFile::CodeItem& item) const {
+  DCHECK(HasAddress(&item));
+  const CodeItem& code_item = down_cast<const CodeItem&>(item);
+  uintptr_t code_item_start = reinterpret_cast<uintptr_t>(&code_item);
+  uint32_t insns_size = code_item.insns_size_in_code_units_;
+  uint32_t tries_size = code_item.tries_size_;
+  const uint8_t* handler_data = GetCatchHandlerData(
+      DexInstructionIterator(code_item.insns_, code_item.insns_size_in_code_units_),
+      code_item.tries_size_,
+      0);
+
+  if (tries_size == 0 || handler_data == nullptr) {
+    uintptr_t insns_end = reinterpret_cast<uintptr_t>(&code_item.insns_[insns_size]);
+    return insns_end - code_item_start;
+  } else {
+    // Get the start of the handler data.
+    uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data);
+    // Manually read each handler.
+    for (uint32_t i = 0; i < handlers_size; ++i) {
+      int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2;
+      if (uleb128_count <= 0) {
+        uleb128_count = -uleb128_count + 1;
+      }
+      for (int32_t j = 0; j < uleb128_count; ++j) {
+        DecodeUnsignedLeb128(&handler_data);
+      }
+    }
+    return reinterpret_cast<uintptr_t>(handler_data) - code_item_start;
+  }
+}
+
 }  // namespace art
diff --git a/runtime/standard_dex_file.h b/runtime/standard_dex_file.h
index 80c406e..74749d2 100644
--- a/runtime/standard_dex_file.h
+++ b/runtime/standard_dex_file.h
@@ -35,6 +35,7 @@
   struct CodeItem : public DexFile::CodeItem {
    private:
     // TODO: Insert standard dex specific fields here.
+    friend class StandardDexFile;
     DISALLOW_COPY_AND_ASSIGN(CodeItem);
   };
 
@@ -58,6 +59,8 @@
 
   virtual bool SupportsDefaultMethods() const OVERRIDE;
 
+  uint32_t GetCodeItemSize(const DexFile::CodeItem& item) const OVERRIDE;
+
  private:
   StandardDexFile(const uint8_t* base,
                   size_t size,
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index a9af97d..6d37d06 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -254,7 +254,7 @@
                                            quickening_info));
           }
           optimizer::ArtDecompileDEX(
-              &target_dex_file,
+              target_dex_file,
               *code_item,
               GetQuickeningInfoAt(quickening_info, quickening_offset),
               decompile_return_instruction);