Cache stack map encoding

Operations on CodeInfo and StackMap objects repeatedly read encoding
information from the MemoryRegion. Since these are 3-bit-loads of
values that never change, caching them can measurably reduce compile
times.

According to benchmarks, this patch saves 1-3% on armv7, 2-4% on x86,
and 0-1% on x64.

Change-Id: I46b197513601325d8bab562cc80100c00ec28a3b
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc
index 5663e39..42b9182 100644
--- a/compiler/optimizing/stack_map_stream.cc
+++ b/compiler/optimizing/stack_map_stream.cc
@@ -133,13 +133,13 @@
   stack_mask_size_ = RoundUp(stack_mask_number_of_bits, kBitsPerByte) / kBitsPerByte;
   inline_info_size_ = ComputeInlineInfoSize();
   dex_register_maps_size_ = ComputeDexRegisterMapsSize();
-  stack_maps_size_ = stack_maps_.Size()
-      * StackMap::ComputeStackMapSize(stack_mask_size_,
-                                      inline_info_size_,
-                                      dex_register_maps_size_,
-                                      dex_pc_max_,
-                                      native_pc_offset_max_,
-                                      register_mask_max_);
+  stack_map_encoding_ = StackMapEncoding::CreateFromSizes(stack_mask_size_,
+                                                          inline_info_size_,
+                                                          dex_register_maps_size_,
+                                                          dex_pc_max_,
+                                                          native_pc_offset_max_,
+                                                          register_mask_max_);
+  stack_maps_size_ = stack_maps_.Size() * stack_map_encoding_.ComputeStackMapSize();
   dex_register_location_catalog_size_ = ComputeDexRegisterLocationCatalogSize();
 
   // Note: use RoundUp to word-size here if you want CodeInfo objects to be word aligned.
@@ -235,14 +235,9 @@
   MemoryRegion inline_infos_region = region.Subregion(
       inline_infos_start_, inline_info_size_);
 
-  code_info.SetEncoding(inline_info_size_,
-                        dex_register_maps_size_,
-                        dex_pc_max_,
-                        native_pc_offset_max_,
-                        register_mask_max_);
+  code_info.SetEncoding(stack_map_encoding_);
   code_info.SetNumberOfStackMaps(stack_maps_.Size());
-  code_info.SetStackMaskSize(stack_mask_size_);
-  DCHECK_EQ(code_info.GetStackMapsSize(), stack_maps_size_);
+  DCHECK_EQ(code_info.GetStackMapsSize(code_info.ExtractEncoding()), stack_maps_size_);
 
   // Set the Dex register location catalog.
   code_info.SetNumberOfDexRegisterLocationCatalogEntries(location_catalog_entries_.Size());
@@ -263,26 +258,27 @@
   uintptr_t next_dex_register_map_offset = 0;
   uintptr_t next_inline_info_offset = 0;
   for (size_t i = 0, e = stack_maps_.Size(); i < e; ++i) {
-    StackMap stack_map = code_info.GetStackMapAt(i);
+    StackMap stack_map = code_info.GetStackMapAt(i, stack_map_encoding_);
     StackMapEntry entry = stack_maps_.Get(i);
 
-    stack_map.SetDexPc(code_info, entry.dex_pc);
-    stack_map.SetNativePcOffset(code_info, entry.native_pc_offset);
-    stack_map.SetRegisterMask(code_info, entry.register_mask);
+    stack_map.SetDexPc(stack_map_encoding_, entry.dex_pc);
+    stack_map.SetNativePcOffset(stack_map_encoding_, entry.native_pc_offset);
+    stack_map.SetRegisterMask(stack_map_encoding_, entry.register_mask);
     if (entry.sp_mask != nullptr) {
-      stack_map.SetStackMask(code_info, *entry.sp_mask);
+      stack_map.SetStackMask(stack_map_encoding_, *entry.sp_mask);
     }
 
     if (entry.num_dex_registers == 0) {
       // No dex map available.
-      stack_map.SetDexRegisterMapOffset(code_info, StackMap::kNoDexRegisterMap);
+      stack_map.SetDexRegisterMapOffset(stack_map_encoding_, StackMap::kNoDexRegisterMap);
     } else {
       // Search for an entry with the same dex map.
       if (entry.same_dex_register_map_as_ != kNoSameDexMapFound) {
         // If we have a hit reuse the offset.
-        stack_map.SetDexRegisterMapOffset(code_info,
-            code_info.GetStackMapAt(entry.same_dex_register_map_as_)
-                     .GetDexRegisterMapOffset(code_info));
+        stack_map.SetDexRegisterMapOffset(
+            stack_map_encoding_,
+            code_info.GetStackMapAt(entry.same_dex_register_map_as_, stack_map_encoding_)
+                     .GetDexRegisterMapOffset(stack_map_encoding_));
       } else {
         // New dex registers maps should be added to the stack map.
         MemoryRegion register_region = dex_register_locations_region.Subregion(
@@ -291,7 +287,7 @@
         next_dex_register_map_offset += register_region.size();
         DexRegisterMap dex_register_map(register_region);
         stack_map.SetDexRegisterMapOffset(
-          code_info, register_region.start() - dex_register_locations_region.start());
+            stack_map_encoding_, register_region.start() - dex_register_locations_region.start());
 
         // Set the dex register location.
         FillInDexRegisterMap(dex_register_map,
@@ -311,7 +307,7 @@
 
       // Currently relative to the dex register map.
       stack_map.SetInlineDescriptorOffset(
-          code_info, inline_region.start() - dex_register_locations_region.start());
+          stack_map_encoding_, inline_region.start() - dex_register_locations_region.start());
 
       inline_info.SetDepth(entry.inlining_depth);
       for (size_t depth = 0; depth < entry.inlining_depth; ++depth) {
@@ -341,7 +337,7 @@
       }
     } else {
       if (inline_info_size_ != 0) {
-        stack_map.SetInlineDescriptorOffset(code_info, StackMap::kNoInlineInfo);
+        stack_map.SetInlineDescriptorOffset(stack_map_encoding_, StackMap::kNoInlineInfo);
       }
     }
   }
diff --git a/compiler/optimizing/stack_map_stream.h b/compiler/optimizing/stack_map_stream.h
index 0af983b..274d573 100644
--- a/compiler/optimizing/stack_map_stream.h
+++ b/compiler/optimizing/stack_map_stream.h
@@ -171,6 +171,7 @@
 
   StackMapEntry current_entry_;
   InlineInfoEntry current_inline_info_;
+  StackMapEncoding stack_map_encoding_;
   size_t stack_mask_size_;
   size_t inline_info_size_;
   size_t dex_register_maps_size_;
diff --git a/compiler/optimizing/stack_map_test.cc b/compiler/optimizing/stack_map_test.cc
index 666fb60..b4ac1b4 100644
--- a/compiler/optimizing/stack_map_test.cc
+++ b/compiler/optimizing/stack_map_test.cc
@@ -51,32 +51,33 @@
   stream.FillIn(region);
 
   CodeInfo code_info(region);
-  ASSERT_EQ(0u, code_info.GetStackMaskSize());
+  StackMapEncoding encoding = code_info.ExtractEncoding();
+  ASSERT_EQ(0u, encoding.NumberOfBytesForStackMask());
   ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
 
   uint32_t number_of_location_catalog_entries =
       code_info.GetNumberOfDexRegisterLocationCatalogEntries();
   ASSERT_EQ(2u, number_of_location_catalog_entries);
-  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
+  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
   // The Dex register location catalog contains:
   // - one 1-byte short Dex register location, and
   // - one 5-byte large Dex register location.
   size_t expected_location_catalog_size = 1u + 5u;
   ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
 
-  StackMap stack_map = code_info.GetStackMapAt(0);
-  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
-  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
-  ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
-  ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
-  ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
+  StackMap stack_map = code_info.GetStackMapAt(0, encoding);
+  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
+  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
+  ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
+  ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
+  ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
 
-  MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
+  MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
   ASSERT_TRUE(SameBits(stack_mask, sp_mask));
 
-  ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
+  ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
   DexRegisterMap dex_register_map =
-      code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+      code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
   ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
   ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
   ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
@@ -86,16 +87,17 @@
   size_t expected_dex_register_map_size = 1u + 1u;
   ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
 
-  ASSERT_EQ(Kind::kInStack,
-            dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
-  ASSERT_EQ(Kind::kConstant,
-            dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
-  ASSERT_EQ(Kind::kInStack,
-            dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
-  ASSERT_EQ(Kind::kConstantLargeValue,
-            dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
-  ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(0, number_of_dex_registers, code_info));
-  ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info));
+  ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(
+                0, number_of_dex_registers, code_info, encoding));
+  ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
+                1, number_of_dex_registers, code_info, encoding));
+  ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind(
+                0, number_of_dex_registers, code_info, encoding));
+  ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
+                1, number_of_dex_registers, code_info, encoding));
+  ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(
+                0, number_of_dex_registers, code_info, encoding));
+  ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
 
   size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
       0, number_of_dex_registers, number_of_location_catalog_entries);
@@ -112,7 +114,7 @@
   ASSERT_EQ(0, location0.GetValue());
   ASSERT_EQ(-2, location1.GetValue());
 
-  ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
+  ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
 }
 
 TEST(StackMapTest, Test2) {
@@ -148,13 +150,14 @@
   stream.FillIn(region);
 
   CodeInfo code_info(region);
-  ASSERT_EQ(2u, code_info.GetStackMaskSize());
+  StackMapEncoding encoding = code_info.ExtractEncoding();
+  ASSERT_EQ(2u, encoding.NumberOfBytesForStackMask());
   ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
 
   uint32_t number_of_location_catalog_entries =
       code_info.GetNumberOfDexRegisterLocationCatalogEntries();
   ASSERT_EQ(4u, number_of_location_catalog_entries);
-  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
+  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
   // The Dex register location catalog contains:
   // - three 1-byte short Dex register locations, and
   // - one 5-byte large Dex register location.
@@ -163,19 +166,19 @@
 
   // First stack map.
   {
-    StackMap stack_map = code_info.GetStackMapAt(0);
-    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
-    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
-    ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
-    ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
-    ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
+    StackMap stack_map = code_info.GetStackMapAt(0, encoding);
+    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
+    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
+    ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
+    ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
+    ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
 
-    MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
+    MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
     ASSERT_TRUE(SameBits(stack_mask, sp_mask1));
 
-    ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
+    ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
     DexRegisterMap dex_register_map =
-        code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+        code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
     ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
     ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
     ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
@@ -185,16 +188,17 @@
     size_t expected_dex_register_map_size = 1u + 1u;
     ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
 
-    ASSERT_EQ(Kind::kInStack,
-              dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
-    ASSERT_EQ(Kind::kConstant,
-              dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
-    ASSERT_EQ(Kind::kInStack,
-              dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
-    ASSERT_EQ(Kind::kConstantLargeValue,
-              dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
-    ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(0, number_of_dex_registers, code_info));
-    ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info));
+    ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(
+                  0, number_of_dex_registers, code_info, encoding));
+    ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
+                  1, number_of_dex_registers, code_info, encoding));
+    ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind(
+                  0, number_of_dex_registers, code_info, encoding));
+    ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
+                  1, number_of_dex_registers, code_info, encoding));
+    ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(
+                  0, number_of_dex_registers, code_info, encoding));
+    ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
 
     size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
         0, number_of_dex_registers, number_of_location_catalog_entries);
@@ -211,8 +215,8 @@
     ASSERT_EQ(0, location0.GetValue());
     ASSERT_EQ(-2, location1.GetValue());
 
-    ASSERT_TRUE(stack_map.HasInlineInfo(code_info));
-    InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
+    ASSERT_TRUE(stack_map.HasInlineInfo(encoding));
+    InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
     ASSERT_EQ(2u, inline_info.GetDepth());
     ASSERT_EQ(82u, inline_info.GetMethodIndexAtDepth(0));
     ASSERT_EQ(42u, inline_info.GetMethodIndexAtDepth(1));
@@ -224,19 +228,19 @@
 
   // Second stack map.
   {
-    StackMap stack_map = code_info.GetStackMapAt(1);
-    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u)));
-    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u)));
-    ASSERT_EQ(1u, stack_map.GetDexPc(code_info));
-    ASSERT_EQ(128u, stack_map.GetNativePcOffset(code_info));
-    ASSERT_EQ(0xFFu, stack_map.GetRegisterMask(code_info));
+    StackMap stack_map = code_info.GetStackMapAt(1, encoding);
+    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u, encoding)));
+    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u, encoding)));
+    ASSERT_EQ(1u, stack_map.GetDexPc(encoding));
+    ASSERT_EQ(128u, stack_map.GetNativePcOffset(encoding));
+    ASSERT_EQ(0xFFu, stack_map.GetRegisterMask(encoding));
 
-    MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
+    MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
     ASSERT_TRUE(SameBits(stack_mask, sp_mask2));
 
-    ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
+    ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
     DexRegisterMap dex_register_map =
-        code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+        code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
     ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
     ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
     ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
@@ -246,16 +250,18 @@
     size_t expected_dex_register_map_size = 1u + 1u;
     ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
 
-    ASSERT_EQ(Kind::kInRegister,
-              dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
-    ASSERT_EQ(Kind::kInFpuRegister,
-              dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
-    ASSERT_EQ(Kind::kInRegister,
-              dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
-    ASSERT_EQ(Kind::kInFpuRegister,
-              dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
-    ASSERT_EQ(18, dex_register_map.GetMachineRegister(0, number_of_dex_registers, code_info));
-    ASSERT_EQ(3, dex_register_map.GetMachineRegister(1, number_of_dex_registers, code_info));
+    ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind(
+                  0, number_of_dex_registers, code_info, encoding));
+    ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind(
+                  1, number_of_dex_registers, code_info, encoding));
+    ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationInternalKind(
+                  0, number_of_dex_registers, code_info, encoding));
+    ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationInternalKind(
+                  1, number_of_dex_registers, code_info, encoding));
+    ASSERT_EQ(18, dex_register_map.GetMachineRegister(
+                  0, number_of_dex_registers, code_info, encoding));
+    ASSERT_EQ(3, dex_register_map.GetMachineRegister(
+                  1, number_of_dex_registers, code_info, encoding));
 
     size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
         0, number_of_dex_registers, number_of_location_catalog_entries);
@@ -272,7 +278,7 @@
     ASSERT_EQ(18, location0.GetValue());
     ASSERT_EQ(3, location1.GetValue());
 
-    ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
+    ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
   }
 }
 
@@ -294,28 +300,29 @@
   stream.FillIn(region);
 
   CodeInfo code_info(region);
-  ASSERT_EQ(0u, code_info.GetStackMaskSize());
+  StackMapEncoding encoding = code_info.ExtractEncoding();
+  ASSERT_EQ(0u, encoding.NumberOfBytesForStackMask());
   ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
 
   uint32_t number_of_location_catalog_entries =
       code_info.GetNumberOfDexRegisterLocationCatalogEntries();
   ASSERT_EQ(1u, number_of_location_catalog_entries);
-  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
+  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
   // The Dex register location catalog contains:
   // - one 5-byte large Dex register location.
   size_t expected_location_catalog_size = 5u;
   ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
 
-  StackMap stack_map = code_info.GetStackMapAt(0);
-  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
-  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
-  ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
-  ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
-  ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
+  StackMap stack_map = code_info.GetStackMapAt(0, encoding);
+  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
+  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
+  ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
+  ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
+  ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
 
-  ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
+  ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
   DexRegisterMap dex_register_map =
-      code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+      code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
   ASSERT_FALSE(dex_register_map.IsDexRegisterLive(0));
   ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
   ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
@@ -325,15 +332,15 @@
   size_t expected_dex_register_map_size = 1u + 0u;
   ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
 
-  ASSERT_EQ(Kind::kNone,
-            dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
-  ASSERT_EQ(Kind::kConstant,
-            dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
-  ASSERT_EQ(Kind::kNone,
-            dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
-  ASSERT_EQ(Kind::kConstantLargeValue,
-            dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
-  ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info));
+  ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationKind(
+                0, number_of_dex_registers, code_info, encoding));
+  ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
+                1, number_of_dex_registers, code_info, encoding));
+  ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationInternalKind(
+                0, number_of_dex_registers, code_info, encoding));
+  ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
+                1, number_of_dex_registers, code_info, encoding));
+  ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
 
   size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
       0, number_of_dex_registers, number_of_location_catalog_entries);
@@ -350,7 +357,7 @@
   ASSERT_EQ(0, location0.GetValue());
   ASSERT_EQ(-2, location1.GetValue());
 
-  ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
+  ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
 }
 
 // Generate a stack map whose dex register offset is
@@ -387,6 +394,7 @@
   stream.FillIn(region);
 
   CodeInfo code_info(region);
+  StackMapEncoding encoding = code_info.ExtractEncoding();
   // The location catalog contains two entries (DexRegisterLocation(kConstant, 0)
   // and DexRegisterLocation(kConstant, 1)), therefore the location catalog index
   // has a size of 1 bit.
@@ -402,20 +410,20 @@
   //   locations (that is, 127 bytes of data).
   // Hence it has a size of 255 bytes, and therefore...
   ASSERT_EQ(128u, DexRegisterMap::GetLiveBitMaskSize(number_of_dex_registers));
-  StackMap stack_map0 = code_info.GetStackMapAt(0);
+  StackMap stack_map0 = code_info.GetStackMapAt(0, encoding);
   DexRegisterMap dex_register_map0 =
-      code_info.GetDexRegisterMapOf(stack_map0, number_of_dex_registers);
+      code_info.GetDexRegisterMapOf(stack_map0, encoding, number_of_dex_registers);
   ASSERT_EQ(127u, dex_register_map0.GetLocationMappingDataSize(number_of_dex_registers,
                                                                number_of_location_catalog_entries));
   ASSERT_EQ(255u, dex_register_map0.Size());
 
-  StackMap stack_map1 = code_info.GetStackMapAt(1);
-  ASSERT_TRUE(stack_map1.HasDexRegisterMap(code_info));
+  StackMap stack_map1 = code_info.GetStackMapAt(1, encoding);
+  ASSERT_TRUE(stack_map1.HasDexRegisterMap(encoding));
   // ...the offset of the second Dex register map (relative to the
   // beginning of the Dex register maps region) is 255 (i.e.,
   // kNoDexRegisterMapSmallEncoding).
-  ASSERT_NE(stack_map1.GetDexRegisterMapOffset(code_info), StackMap::kNoDexRegisterMap);
-  ASSERT_EQ(stack_map1.GetDexRegisterMapOffset(code_info), 0xFFu);
+  ASSERT_NE(stack_map1.GetDexRegisterMapOffset(encoding), StackMap::kNoDexRegisterMap);
+  ASSERT_EQ(stack_map1.GetDexRegisterMapOffset(encoding), 0xFFu);
 }
 
 TEST(StackMapTest, TestShareDexRegisterMap) {
@@ -447,28 +455,30 @@
   stream.FillIn(region);
 
   CodeInfo ci(region);
+  StackMapEncoding encoding = ci.ExtractEncoding();
+
   // Verify first stack map.
-  StackMap sm0 = ci.GetStackMapAt(0);
-  DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, number_of_dex_registers);
-  ASSERT_EQ(0, dex_registers0.GetMachineRegister(0, number_of_dex_registers, ci));
-  ASSERT_EQ(-2, dex_registers0.GetConstant(1, number_of_dex_registers, ci));
+  StackMap sm0 = ci.GetStackMapAt(0, encoding);
+  DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, number_of_dex_registers);
+  ASSERT_EQ(0, dex_registers0.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
+  ASSERT_EQ(-2, dex_registers0.GetConstant(1, number_of_dex_registers, ci, encoding));
 
   // Verify second stack map.
-  StackMap sm1 = ci.GetStackMapAt(1);
-  DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1, number_of_dex_registers);
-  ASSERT_EQ(0, dex_registers1.GetMachineRegister(0, number_of_dex_registers, ci));
-  ASSERT_EQ(-2, dex_registers1.GetConstant(1, number_of_dex_registers, ci));
+  StackMap sm1 = ci.GetStackMapAt(1, encoding);
+  DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1, encoding, number_of_dex_registers);
+  ASSERT_EQ(0, dex_registers1.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
+  ASSERT_EQ(-2, dex_registers1.GetConstant(1, number_of_dex_registers, ci, encoding));
 
   // Verify third stack map.
-  StackMap sm2 = ci.GetStackMapAt(2);
-  DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2, number_of_dex_registers);
-  ASSERT_EQ(2, dex_registers2.GetMachineRegister(0, number_of_dex_registers, ci));
-  ASSERT_EQ(-2, dex_registers2.GetConstant(1, number_of_dex_registers, ci));
+  StackMap sm2 = ci.GetStackMapAt(2, encoding);
+  DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2, encoding, number_of_dex_registers);
+  ASSERT_EQ(2, dex_registers2.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
+  ASSERT_EQ(-2, dex_registers2.GetConstant(1, number_of_dex_registers, ci, encoding));
 
   // Verify dex register map offsets.
-  ASSERT_EQ(sm0.GetDexRegisterMapOffset(ci), sm1.GetDexRegisterMapOffset(ci));
-  ASSERT_NE(sm0.GetDexRegisterMapOffset(ci), sm2.GetDexRegisterMapOffset(ci));
-  ASSERT_NE(sm1.GetDexRegisterMapOffset(ci), sm2.GetDexRegisterMapOffset(ci));
+  ASSERT_EQ(sm0.GetDexRegisterMapOffset(encoding), sm1.GetDexRegisterMapOffset(encoding));
+  ASSERT_NE(sm0.GetDexRegisterMapOffset(encoding), sm2.GetDexRegisterMapOffset(encoding));
+  ASSERT_NE(sm1.GetDexRegisterMapOffset(encoding), sm2.GetDexRegisterMapOffset(encoding));
 }
 
 TEST(StackMapTest, TestNoDexRegisterMap) {
@@ -487,24 +497,25 @@
   stream.FillIn(region);
 
   CodeInfo code_info(region);
-  ASSERT_EQ(0u, code_info.GetStackMaskSize());
+  StackMapEncoding encoding = code_info.ExtractEncoding();
+  ASSERT_EQ(0u, encoding.NumberOfBytesForStackMask());
   ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
 
   uint32_t number_of_location_catalog_entries =
       code_info.GetNumberOfDexRegisterLocationCatalogEntries();
   ASSERT_EQ(0u, number_of_location_catalog_entries);
-  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
+  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
   ASSERT_EQ(0u, location_catalog.Size());
 
-  StackMap stack_map = code_info.GetStackMapAt(0);
-  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
-  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
-  ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
-  ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
-  ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
+  StackMap stack_map = code_info.GetStackMapAt(0, encoding);
+  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
+  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
+  ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
+  ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
+  ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
 
-  ASSERT_FALSE(stack_map.HasDexRegisterMap(code_info));
-  ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
+  ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding));
+  ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
 }
 
 TEST(StackMapTest, InlineTest) {
@@ -579,16 +590,17 @@
   stream.FillIn(region);
 
   CodeInfo ci(region);
+  StackMapEncoding encoding = ci.ExtractEncoding();
 
   {
     // Verify first stack map.
-    StackMap sm0 = ci.GetStackMapAt(0);
+    StackMap sm0 = ci.GetStackMapAt(0, encoding);
 
-    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, 2);
-    ASSERT_EQ(0, dex_registers0.GetStackOffsetInBytes(0, 2, ci));
-    ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci));
+    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, 2);
+    ASSERT_EQ(0, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
+    ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding));
 
-    InlineInfo if0 = ci.GetInlineInfoOf(sm0);
+    InlineInfo if0 = ci.GetInlineInfoOf(sm0, encoding);
     ASSERT_EQ(2u, if0.GetDepth());
     ASSERT_EQ(2u, if0.GetDexPcAtDepth(0));
     ASSERT_EQ(42u, if0.GetMethodIndexAtDepth(0));
@@ -597,24 +609,24 @@
     ASSERT_EQ(82u, if0.GetMethodIndexAtDepth(1));
     ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(1));
 
-    DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if0, 1);
-    ASSERT_EQ(8, dex_registers1.GetStackOffsetInBytes(0, 1, ci));
+    DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if0, encoding, 1);
+    ASSERT_EQ(8, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding));
 
-    DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if0, 3);
-    ASSERT_EQ(16, dex_registers2.GetStackOffsetInBytes(0, 3, ci));
-    ASSERT_EQ(20, dex_registers2.GetConstant(1, 3, ci));
-    ASSERT_EQ(15, dex_registers2.GetMachineRegister(2, 3, ci));
+    DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if0, encoding, 3);
+    ASSERT_EQ(16, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding));
+    ASSERT_EQ(20, dex_registers2.GetConstant(1, 3, ci, encoding));
+    ASSERT_EQ(15, dex_registers2.GetMachineRegister(2, 3, ci, encoding));
   }
 
   {
     // Verify second stack map.
-    StackMap sm1 = ci.GetStackMapAt(1);
+    StackMap sm1 = ci.GetStackMapAt(1, encoding);
 
-    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm1, 2);
-    ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci));
-    ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci));
+    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm1, encoding, 2);
+    ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
+    ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding));
 
-    InlineInfo if1 = ci.GetInlineInfoOf(sm1);
+    InlineInfo if1 = ci.GetInlineInfoOf(sm1, encoding);
     ASSERT_EQ(3u, if1.GetDepth());
     ASSERT_EQ(2u, if1.GetDexPcAtDepth(0));
     ASSERT_EQ(42u, if1.GetMethodIndexAtDepth(0));
@@ -626,36 +638,36 @@
     ASSERT_EQ(52u, if1.GetMethodIndexAtDepth(2));
     ASSERT_EQ(kVirtual, if1.GetInvokeTypeAtDepth(2));
 
-    DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if1, 1);
-    ASSERT_EQ(12, dex_registers1.GetStackOffsetInBytes(0, 1, ci));
+    DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if1, encoding, 1);
+    ASSERT_EQ(12, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding));
 
-    DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if1, 3);
-    ASSERT_EQ(80, dex_registers2.GetStackOffsetInBytes(0, 3, ci));
-    ASSERT_EQ(10, dex_registers2.GetConstant(1, 3, ci));
-    ASSERT_EQ(5, dex_registers2.GetMachineRegister(2, 3, ci));
+    DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if1, encoding, 3);
+    ASSERT_EQ(80, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding));
+    ASSERT_EQ(10, dex_registers2.GetConstant(1, 3, ci, encoding));
+    ASSERT_EQ(5, dex_registers2.GetMachineRegister(2, 3, ci, encoding));
 
     ASSERT_FALSE(if1.HasDexRegisterMapAtDepth(2));
   }
 
   {
     // Verify third stack map.
-    StackMap sm2 = ci.GetStackMapAt(2);
+    StackMap sm2 = ci.GetStackMapAt(2, encoding);
 
-    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm2, 2);
+    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm2, encoding, 2);
     ASSERT_FALSE(dex_registers0.IsDexRegisterLive(0));
-    ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci));
-    ASSERT_FALSE(sm2.HasInlineInfo(ci));
+    ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding));
+    ASSERT_FALSE(sm2.HasInlineInfo(encoding));
   }
 
   {
     // Verify fourth stack map.
-    StackMap sm3 = ci.GetStackMapAt(3);
+    StackMap sm3 = ci.GetStackMapAt(3, encoding);
 
-    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm3, 2);
-    ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci));
-    ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci));
+    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm3, encoding, 2);
+    ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
+    ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding));
 
-    InlineInfo if2 = ci.GetInlineInfoOf(sm3);
+    InlineInfo if2 = ci.GetInlineInfoOf(sm3, encoding);
     ASSERT_EQ(3u, if2.GetDepth());
     ASSERT_EQ(2u, if2.GetDexPcAtDepth(0));
     ASSERT_EQ(42u, if2.GetMethodIndexAtDepth(0));
@@ -669,12 +681,12 @@
 
     ASSERT_FALSE(if2.HasDexRegisterMapAtDepth(0));
 
-    DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(1, if2, 1);
-    ASSERT_EQ(2, dex_registers1.GetMachineRegister(0, 1, ci));
+    DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(1, if2, encoding, 1);
+    ASSERT_EQ(2, dex_registers1.GetMachineRegister(0, 1, ci, encoding));
 
-    DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(2, if2, 2);
+    DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(2, if2, encoding, 2);
     ASSERT_FALSE(dex_registers2.IsDexRegisterLive(0));
-    ASSERT_EQ(3, dex_registers2.GetMachineRegister(1, 2, ci));
+    ASSERT_EQ(3, dex_registers2.GetMachineRegister(1, 2, ci, encoding));
   }
 }