Add method info to oat files

The method info data is stored separately from the code info to
reduce oat size by improving deduplication of stack maps.

To reduce code size, this moves the invoke info and inline info
method indices to this table.

Oat size for a large app (arm64): 77746816 -> 74023552 (-4.8%)
Average oat size reduction for golem (arm64): 2%

Repurposed unused SrcMapElem deduping to be for MethodInfo.
TODO: Delete SrcMapElem in a follow up CL.

Bug: 36124906

Test: clean-oat-host && test-art-host-run-test

Change-Id: I2241362e728389030b959f42161ce817cf6e2009
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 3bc49b8..ba8cec3 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -43,6 +43,7 @@
 namespace art {
 
 inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method,
+                                    const MethodInfo& method_info,
                                     const InlineInfo& inline_info,
                                     const InlineInfoEncoding& encoding,
                                     uint8_t inlining_depth)
@@ -56,7 +57,7 @@
     return inline_info.GetArtMethodAtDepth(encoding, inlining_depth);
   }
 
-  uint32_t method_index = inline_info.GetMethodIndexAtDepth(encoding, inlining_depth);
+  uint32_t method_index = inline_info.GetMethodIndexAtDepth(encoding, method_info, inlining_depth);
   if (inline_info.GetDexPcAtDepth(encoding, inlining_depth) == static_cast<uint32_t>(-1)) {
     // "charAt" special case. It is the only non-leaf method we inline across dex files.
     ArtMethod* inlined_method = jni::DecodeArtMethod(WellKnownClasses::java_lang_String_charAt);
@@ -68,6 +69,7 @@
   ArtMethod* caller = outer_method;
   if (inlining_depth != 0) {
     caller = GetResolvedMethod(outer_method,
+                               method_info,
                                inline_info,
                                encoding,
                                inlining_depth - 1);
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index 6301362..2b35b46 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -201,12 +201,14 @@
       DCHECK(current_code->IsOptimized());
       uintptr_t native_pc_offset = current_code->NativeQuickPcOffset(caller_pc);
       CodeInfo code_info = current_code->GetOptimizedCodeInfo();
+      MethodInfo method_info = current_code->GetOptimizedMethodInfo();
       CodeInfoEncoding encoding = code_info.ExtractEncoding();
       StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
       DCHECK(stack_map.IsValid());
       if (stack_map.HasInlineInfo(encoding.stack_map.encoding)) {
         InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
         caller = GetResolvedMethod(outer_method,
+                                   method_info,
                                    inline_info,
                                    encoding.inline_info.encoding,
                                    inline_info.GetDepth(encoding.inline_info.encoding) - 1);
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 3fd20a6..25073a8 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -372,10 +372,11 @@
     uintptr_t outer_pc_offset = current_code->NativeQuickPcOffset(outer_pc);
     CodeInfo code_info = current_code->GetOptimizedCodeInfo();
     CodeInfoEncoding encoding = code_info.ExtractEncoding();
+    MethodInfo method_info = current_code->GetOptimizedMethodInfo();
     InvokeInfo invoke(code_info.GetInvokeInfoForNativePcOffset(outer_pc_offset, encoding));
     if (invoke.IsValid()) {
       *invoke_type = static_cast<InvokeType>(invoke.GetInvokeType(encoding.invoke_info.encoding));
-      *dex_method_index = invoke.GetMethodIndex(encoding.invoke_info.encoding);
+      *dex_method_index = invoke.GetMethodIndex(encoding.invoke_info.encoding, method_info);
       return true;
     }
     return false;
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index e7b23dc..fc41f94 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -211,6 +211,7 @@
 uint8_t* JitCodeCache::CommitCode(Thread* self,
                                   ArtMethod* method,
                                   uint8_t* stack_map,
+                                  uint8_t* method_info,
                                   uint8_t* roots_data,
                                   size_t frame_size_in_bytes,
                                   size_t core_spill_mask,
@@ -225,6 +226,7 @@
   uint8_t* result = CommitCodeInternal(self,
                                        method,
                                        stack_map,
+                                       method_info,
                                        roots_data,
                                        frame_size_in_bytes,
                                        core_spill_mask,
@@ -242,6 +244,7 @@
     result = CommitCodeInternal(self,
                                 method,
                                 stack_map,
+                                method_info,
                                 roots_data,
                                 frame_size_in_bytes,
                                 core_spill_mask,
@@ -510,6 +513,7 @@
 uint8_t* JitCodeCache::CommitCodeInternal(Thread* self,
                                           ArtMethod* method,
                                           uint8_t* stack_map,
+                                          uint8_t* method_info,
                                           uint8_t* roots_data,
                                           size_t frame_size_in_bytes,
                                           size_t core_spill_mask,
@@ -547,6 +551,7 @@
       method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
       new (method_header) OatQuickMethodHeader(
           code_ptr - stack_map,
+          code_ptr - method_info,
           frame_size_in_bytes,
           core_spill_mask,
           fp_spill_mask,
@@ -739,12 +744,14 @@
 
 size_t JitCodeCache::ReserveData(Thread* self,
                                  size_t stack_map_size,
+                                 size_t method_info_size,
                                  size_t number_of_roots,
                                  ArtMethod* method,
                                  uint8_t** stack_map_data,
+                                 uint8_t** method_info_data,
                                  uint8_t** roots_data) {
   size_t table_size = ComputeRootTableSize(number_of_roots);
-  size_t size = RoundUp(stack_map_size + table_size, sizeof(void*));
+  size_t size = RoundUp(stack_map_size + method_info_size + table_size, sizeof(void*));
   uint8_t* result = nullptr;
 
   {
@@ -774,11 +781,13 @@
   if (result != nullptr) {
     *roots_data = result;
     *stack_map_data = result + table_size;
+    *method_info_data = *stack_map_data + stack_map_size;
     FillRootTableLength(*roots_data, number_of_roots);
     return size;
   } else {
     *roots_data = nullptr;
     *stack_map_data = nullptr;
+    *method_info_data = nullptr;
     return 0;
   }
 }
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index c970979..db214e7 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -105,6 +105,7 @@
   uint8_t* CommitCode(Thread* self,
                       ArtMethod* method,
                       uint8_t* stack_map,
+                      uint8_t* method_info,
                       uint8_t* roots_data,
                       size_t frame_size_in_bytes,
                       size_t core_spill_mask,
@@ -129,10 +130,12 @@
   // for storing `number_of_roots` roots. Returns null if there is no more room.
   // Return the number of bytes allocated.
   size_t ReserveData(Thread* self,
-                     size_t size,
+                     size_t stack_map_size,
+                     size_t method_info_size,
                      size_t number_of_roots,
                      ArtMethod* method,
                      uint8_t** stack_map_data,
+                     uint8_t** method_info_data,
                      uint8_t** roots_data)
       REQUIRES_SHARED(Locks::mutator_lock_)
       REQUIRES(!lock_);
@@ -249,6 +252,7 @@
   uint8_t* CommitCodeInternal(Thread* self,
                               ArtMethod* method,
                               uint8_t* stack_map,
+                              uint8_t* method_info,
                               uint8_t* roots_data,
                               size_t frame_size_in_bytes,
                               size_t core_spill_mask,
diff --git a/runtime/method_info.h b/runtime/method_info.h
new file mode 100644
index 0000000..5a72125
--- /dev/null
+++ b/runtime/method_info.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_METHOD_INFO_H_
+#define ART_RUNTIME_METHOD_INFO_H_
+
+#include "base/logging.h"
+#include "leb128.h"
+#include "memory_region.h"
+
+namespace art {
+
+// Method info is for not dedupe friendly data of a method. Currently it only holds methods indices.
+// Putting this data in MethodInfo instead of code infos saves ~5% oat size.
+class MethodInfo {
+  using MethodIndexType = uint16_t;
+
+ public:
+  // Reading mode
+  explicit MethodInfo(const uint8_t* ptr) {
+    if (ptr != nullptr) {
+      num_method_indices_ = DecodeUnsignedLeb128(&ptr);
+      region_ = MemoryRegion(const_cast<uint8_t*>(ptr),
+                             num_method_indices_ * sizeof(MethodIndexType));
+    }
+  }
+
+  // Writing mode
+  MethodInfo(uint8_t* ptr, size_t num_method_indices) : num_method_indices_(num_method_indices) {
+    DCHECK(ptr != nullptr);
+    ptr = EncodeUnsignedLeb128(ptr, num_method_indices_);
+    region_ = MemoryRegion(ptr, num_method_indices_ * sizeof(MethodIndexType));
+  }
+
+  static size_t ComputeSize(size_t num_method_indices) {
+    uint8_t temp[8];
+    uint8_t* ptr = temp;
+    ptr = EncodeUnsignedLeb128(ptr, num_method_indices);
+    return (ptr - temp) + num_method_indices * sizeof(MethodIndexType);
+  }
+
+  ALWAYS_INLINE MethodIndexType GetMethodIndex(size_t index) const {
+    // Use bit functions to avoid pesky alignment requirements.
+    return region_.LoadBits(index * BitSizeOf<MethodIndexType>(), BitSizeOf<MethodIndexType>());
+  }
+
+  void SetMethodIndex(size_t index, MethodIndexType method_index) {
+    region_.StoreBits(index * BitSizeOf<MethodIndexType>(),
+                      method_index,
+                      BitSizeOf<MethodIndexType>());
+  }
+
+  size_t NumMethodIndices() const {
+    return num_method_indices_;
+  }
+
+ private:
+  size_t num_method_indices_ = 0u;
+  MemoryRegion region_;
+};
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_METHOD_INFO_H_
diff --git a/runtime/oat.h b/runtime/oat.h
index df43107..7943b0f 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,7 +32,7 @@
 class PACKED(4) OatHeader {
  public:
   static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
-  static constexpr uint8_t kOatVersion[] = { '1', '1', '5', '\0' };  // hash-based DexCache fields
+  static constexpr uint8_t kOatVersion[] = { '1', '1', '6', '\0' };  // Add method infos
 
   static constexpr const char* kImageLocationKey = "image-location";
   static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
diff --git a/runtime/oat_quick_method_header.cc b/runtime/oat_quick_method_header.cc
index b4e4285..8eef586 100644
--- a/runtime/oat_quick_method_header.cc
+++ b/runtime/oat_quick_method_header.cc
@@ -22,13 +22,14 @@
 
 namespace art {
 
-OatQuickMethodHeader::OatQuickMethodHeader(
-    uint32_t vmap_table_offset,
-    uint32_t frame_size_in_bytes,
-    uint32_t core_spill_mask,
-    uint32_t fp_spill_mask,
-    uint32_t code_size)
+OatQuickMethodHeader::OatQuickMethodHeader(uint32_t vmap_table_offset,
+                                           uint32_t method_info_offset,
+                                           uint32_t frame_size_in_bytes,
+                                           uint32_t core_spill_mask,
+                                           uint32_t fp_spill_mask,
+                                           uint32_t code_size)
     : vmap_table_offset_(vmap_table_offset),
+      method_info_offset_(method_info_offset),
       frame_info_(frame_size_in_bytes, core_spill_mask, fp_spill_mask),
       code_size_(code_size) {}
 
diff --git a/runtime/oat_quick_method_header.h b/runtime/oat_quick_method_header.h
index 3cdde5a..07a4a9f 100644
--- a/runtime/oat_quick_method_header.h
+++ b/runtime/oat_quick_method_header.h
@@ -20,6 +20,7 @@
 #include "arch/instruction_set.h"
 #include "base/macros.h"
 #include "quick/quick_method_frame_info.h"
+#include "method_info.h"
 #include "stack_map.h"
 #include "utils.h"
 
@@ -30,11 +31,13 @@
 // OatQuickMethodHeader precedes the raw code chunk generated by the compiler.
 class PACKED(4) OatQuickMethodHeader {
  public:
-  explicit OatQuickMethodHeader(uint32_t vmap_table_offset = 0U,
-                                uint32_t frame_size_in_bytes = 0U,
-                                uint32_t core_spill_mask = 0U,
-                                uint32_t fp_spill_mask = 0U,
-                                uint32_t code_size = 0U);
+  OatQuickMethodHeader() = default;
+  explicit OatQuickMethodHeader(uint32_t vmap_table_offset,
+                                uint32_t method_info_offset,
+                                uint32_t frame_size_in_bytes,
+                                uint32_t core_spill_mask,
+                                uint32_t fp_spill_mask,
+                                uint32_t code_size);
 
   ~OatQuickMethodHeader();
 
@@ -63,8 +66,7 @@
 
   const void* GetOptimizedCodeInfoPtr() const {
     DCHECK(IsOptimized());
-    const void* data = reinterpret_cast<const void*>(code_ - vmap_table_offset_);
-    return data;
+    return reinterpret_cast<const void*>(code_ - vmap_table_offset_);
   }
 
   uint8_t* GetOptimizedCodeInfoPtr() {
@@ -76,6 +78,20 @@
     return CodeInfo(GetOptimizedCodeInfoPtr());
   }
 
+  const void* GetOptimizedMethodInfoPtr() const {
+    DCHECK(IsOptimized());
+    return reinterpret_cast<const void*>(code_ - method_info_offset_);
+  }
+
+  uint8_t* GetOptimizedMethodInfoPtr() {
+    DCHECK(IsOptimized());
+    return code_ - method_info_offset_;
+  }
+
+  MethodInfo GetOptimizedMethodInfo() const {
+    return MethodInfo(reinterpret_cast<const uint8_t*>(GetOptimizedMethodInfoPtr()));
+  }
+
   const uint8_t* GetCode() const {
     return code_;
   }
@@ -100,6 +116,18 @@
     return &vmap_table_offset_;
   }
 
+  uint32_t GetMethodInfoOffset() const {
+    return method_info_offset_;
+  }
+
+  void SetMethodInfoOffset(uint32_t offset) {
+    method_info_offset_ = offset;
+  }
+
+  const uint32_t* GetMethodInfoOffsetAddr() const {
+    return &method_info_offset_;
+  }
+
   const uint8_t* GetVmapTable() const {
     CHECK(!IsOptimized()) << "Unimplemented vmap table for optimizing compiler";
     return (vmap_table_offset_ == 0) ? nullptr : code_ - vmap_table_offset_;
@@ -160,12 +188,18 @@
   static constexpr uint32_t kCodeSizeMask = ~kShouldDeoptimizeMask;
 
   // The offset in bytes from the start of the vmap table to the end of the header.
-  uint32_t vmap_table_offset_;
+  uint32_t vmap_table_offset_ = 0u;
+  // The offset in bytes from the start of the method info to the end of the header.
+  // The method info offset is not in the CodeInfo since CodeInfo has good dedupe properties that
+  // would be lost from doing so. The method info memory region contains method indices since they
+  // are hard to dedupe.
+
+  uint32_t method_info_offset_ = 0u;
   // The stack frame information.
   QuickMethodFrameInfo frame_info_;
   // The code size in bytes. The highest bit is used to signify if the compiled
   // code with the method header has should_deoptimize flag.
-  uint32_t code_size_;
+  uint32_t code_size_ = 0u;
   // The actual code.
   uint8_t code_[0];
 };
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 51a24e4..0628643 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -142,8 +142,10 @@
       InlineInfo inline_info = GetCurrentInlineInfo();
       const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
       CodeInfoEncoding encoding = method_header->GetOptimizedCodeInfo().ExtractEncoding();
+      MethodInfo method_info = method_header->GetOptimizedMethodInfo();
       DCHECK(walk_kind_ != StackWalkKind::kSkipInlinedFrames);
       return GetResolvedMethod(*GetCurrentQuickFrame(),
+                               method_info,
                                inline_info,
                                encoding.inline_info.encoding,
                                depth_in_stack_map);
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index d657311..250ff2a 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -118,7 +118,8 @@
                     uint32_t code_offset,
                     uint16_t number_of_dex_registers,
                     bool dump_stack_maps,
-                    InstructionSet instruction_set) const {
+                    InstructionSet instruction_set,
+                    const MethodInfo& method_info) const {
   CodeInfoEncoding encoding = ExtractEncoding();
   size_t number_of_stack_maps = GetNumberOfStackMaps(encoding);
   vios->Stream()
@@ -139,6 +140,7 @@
       stack_map.Dump(vios,
                      *this,
                      encoding,
+                     method_info,
                      code_offset,
                      number_of_dex_registers,
                      instruction_set,
@@ -189,6 +191,7 @@
 void StackMap::Dump(VariableIndentationOutputStream* vios,
                     const CodeInfo& code_info,
                     const CodeInfoEncoding& encoding,
+                    const MethodInfo& method_info,
                     uint32_t code_offset,
                     uint16_t number_of_dex_registers,
                     InstructionSet instruction_set,
@@ -222,12 +225,13 @@
     // We do not know the length of the dex register maps of inlined frames
     // at this level, so we just pass null to `InlineInfo::Dump` to tell
     // it not to look at these maps.
-    inline_info.Dump(vios, code_info, nullptr);
+    inline_info.Dump(vios, code_info, method_info, nullptr);
   }
 }
 
 void InlineInfo::Dump(VariableIndentationOutputStream* vios,
                       const CodeInfo& code_info,
+                      const MethodInfo& method_info,
                       uint16_t number_of_dex_registers[]) const {
   InlineInfoEncoding inline_info_encoding = code_info.ExtractEncoding().inline_info.encoding;
   vios->Stream() << "InlineInfo with depth "
@@ -245,7 +249,7 @@
     } else {
       vios->Stream()
           << std::dec
-          << ", method_index=" << GetMethodIndexAtDepth(inline_info_encoding, i);
+          << ", method_index=" << GetMethodIndexAtDepth(inline_info_encoding, method_info, i);
     }
     vios->Stream() << ")\n";
     if (HasDexRegisterMapAtDepth(inline_info_encoding, i) && (number_of_dex_registers != nullptr)) {
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index d936ce9..ffa17c9 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -23,6 +23,7 @@
 #include "bit_memory_region.h"
 #include "dex_file.h"
 #include "memory_region.h"
+#include "method_info.h"
 #include "leb128.h"
 
 namespace art {
@@ -367,7 +368,8 @@
     return region_.size();
   }
 
-  void Dump(VariableIndentationOutputStream* vios, const CodeInfo& code_info);
+  void Dump(VariableIndentationOutputStream* vios,
+            const CodeInfo& code_info);
 
   // Special (invalid) Dex register location catalog entry index meaning
   // that there is no location for a given Dex register (i.e., it is
@@ -862,6 +864,7 @@
   void Dump(VariableIndentationOutputStream* vios,
             const CodeInfo& code_info,
             const CodeInfoEncoding& encoding,
+            const MethodInfo& method_info,
             uint32_t code_offset,
             uint16_t number_of_dex_registers,
             InstructionSet instruction_set,
@@ -885,12 +888,12 @@
 
 class InlineInfoEncoding {
  public:
-  void SetFromSizes(size_t method_index_max,
+  void SetFromSizes(size_t method_index_idx_max,
                     size_t dex_pc_max,
                     size_t extra_data_max,
                     size_t dex_register_map_size) {
     total_bit_size_ = kMethodIndexBitOffset;
-    total_bit_size_ += MinimumBitsToStore(method_index_max);
+    total_bit_size_ += MinimumBitsToStore(method_index_idx_max);
 
     dex_pc_bit_offset_ = dchecked_integral_cast<uint8_t>(total_bit_size_);
     // Note: We're not encoding the dex pc if there is none. That's the case
@@ -908,7 +911,7 @@
     total_bit_size_ += MinimumBitsToStore(dex_register_map_size);
   }
 
-  ALWAYS_INLINE FieldEncoding GetMethodIndexEncoding() const {
+  ALWAYS_INLINE FieldEncoding GetMethodIndexIdxEncoding() const {
     return FieldEncoding(kMethodIndexBitOffset, dex_pc_bit_offset_);
   }
   ALWAYS_INLINE FieldEncoding GetDexPcEncoding() const {
@@ -975,16 +978,23 @@
     }
   }
 
-  ALWAYS_INLINE uint32_t GetMethodIndexAtDepth(const InlineInfoEncoding& encoding,
-                                               uint32_t depth) const {
+  ALWAYS_INLINE uint32_t GetMethodIndexIdxAtDepth(const InlineInfoEncoding& encoding,
+                                                  uint32_t depth) const {
     DCHECK(!EncodesArtMethodAtDepth(encoding, depth));
-    return encoding.GetMethodIndexEncoding().Load(GetRegionAtDepth(encoding, depth));
+    return encoding.GetMethodIndexIdxEncoding().Load(GetRegionAtDepth(encoding, depth));
   }
 
-  ALWAYS_INLINE void SetMethodIndexAtDepth(const InlineInfoEncoding& encoding,
-                                           uint32_t depth,
-                                           uint32_t index) {
-    encoding.GetMethodIndexEncoding().Store(GetRegionAtDepth(encoding, depth), index);
+  ALWAYS_INLINE void SetMethodIndexIdxAtDepth(const InlineInfoEncoding& encoding,
+                                              uint32_t depth,
+                                              uint32_t index) {
+    encoding.GetMethodIndexIdxEncoding().Store(GetRegionAtDepth(encoding, depth), index);
+  }
+
+
+  ALWAYS_INLINE uint32_t GetMethodIndexAtDepth(const InlineInfoEncoding& encoding,
+                                               const MethodInfo& method_info,
+                                               uint32_t depth) const {
+    return method_info.GetMethodIndex(GetMethodIndexIdxAtDepth(encoding, depth));
   }
 
   ALWAYS_INLINE uint32_t GetDexPcAtDepth(const InlineInfoEncoding& encoding,
@@ -1012,7 +1022,8 @@
   ALWAYS_INLINE ArtMethod* GetArtMethodAtDepth(const InlineInfoEncoding& encoding,
                                                uint32_t depth) const {
     uint32_t low_bits = encoding.GetExtraDataEncoding().Load(GetRegionAtDepth(encoding, depth));
-    uint32_t high_bits = encoding.GetMethodIndexEncoding().Load(GetRegionAtDepth(encoding, depth));
+    uint32_t high_bits = encoding.GetMethodIndexIdxEncoding().Load(
+        GetRegionAtDepth(encoding, depth));
     if (high_bits == 0) {
       return reinterpret_cast<ArtMethod*>(low_bits);
     } else {
@@ -1040,6 +1051,7 @@
 
   void Dump(VariableIndentationOutputStream* vios,
             const CodeInfo& info,
+            const MethodInfo& method_info,
             uint16_t* number_of_dex_registers) const;
 
  private:
@@ -1219,12 +1231,18 @@
     encoding.GetInvokeTypeEncoding().Store(region_, invoke_type);
   }
 
-  ALWAYS_INLINE uint32_t GetMethodIndex(const InvokeInfoEncoding& encoding) const {
+  ALWAYS_INLINE uint32_t GetMethodIndexIdx(const InvokeInfoEncoding& encoding) const {
     return encoding.GetMethodIndexEncoding().Load(region_);
   }
 
-  ALWAYS_INLINE void SetMethodIndex(const InvokeInfoEncoding& encoding, uint32_t method_index) {
-    encoding.GetMethodIndexEncoding().Store(region_, method_index);
+  ALWAYS_INLINE void SetMethodIndexIdx(const InvokeInfoEncoding& encoding,
+                                       uint32_t method_index_idx) {
+    encoding.GetMethodIndexEncoding().Store(region_, method_index_idx);
+  }
+
+  ALWAYS_INLINE uint32_t GetMethodIndex(const InvokeInfoEncoding& encoding,
+                                        MethodInfo method_info) const {
+    return method_info.GetMethodIndex(GetMethodIndexIdx(encoding));
   }
 
   bool IsValid() const { return region_.pointer() != nullptr; }
@@ -1542,7 +1560,8 @@
             uint32_t code_offset,
             uint16_t number_of_dex_registers,
             bool dump_stack_maps,
-            InstructionSet instruction_set) const;
+            InstructionSet instruction_set,
+            const MethodInfo& method_info) const;
 
   // Check that the code info has valid stack map and abort if it does not.
   void AssertValidStackMap(const CodeInfoEncoding& encoding) const {