OSDN Git Service

Cache stack map encoding
authorDavid Brazdil <dbrazdil@google.com>
Fri, 29 May 2015 15:29:43 +0000 (16:29 +0100)
committerDavid Brazdil <dbrazdil@google.com>
Thu, 4 Jun 2015 16:25:02 +0000 (17:25 +0100)
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

12 files changed:
compiler/optimizing/stack_map_stream.cc
compiler/optimizing/stack_map_stream.h
compiler/optimizing/stack_map_test.cc
oatdump/oatdump.cc
runtime/art_method.cc
runtime/check_reference_map_visitor.h
runtime/entrypoints/entrypoint_utils-inl.h
runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
runtime/stack.cc
runtime/stack_map.cc
runtime/stack_map.h
runtime/thread.cc

index 5663e39..42b9182 100644 (file)
@@ -133,13 +133,13 @@ size_t StackMapStream::PrepareForFillIn() {
   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 @@ void StackMapStream::FillIn(MemoryRegion region) {
   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 @@ void StackMapStream::FillIn(MemoryRegion region) {
   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 @@ void StackMapStream::FillIn(MemoryRegion region) {
         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 @@ void StackMapStream::FillIn(MemoryRegion region) {
 
       // 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 @@ void StackMapStream::FillIn(MemoryRegion region) {
       }
     } else {
       if (inline_info_size_ != 0) {
-        stack_map.SetInlineDescriptorOffset(code_info, StackMap::kNoInlineInfo);
+        stack_map.SetInlineDescriptorOffset(stack_map_encoding_, StackMap::kNoInlineInfo);
       }
     }
   }
index 0af983b..274d573 100644 (file)
@@ -171,6 +171,7 @@ class StackMapStream : public ValueObject {
 
   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_;
index 666fb60..b4ac1b4 100644 (file)
@@ -51,32 +51,33 @@ TEST(StackMapTest, Test1) {
   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 @@ TEST(StackMapTest, Test1) {
   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 @@ TEST(StackMapTest, Test1) {
   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 @@ TEST(StackMapTest, Test2) {
   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 @@ TEST(StackMapTest, Test2) {
 
   // 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));
-
-    MemoryRegion stack_mask = stack_map.GetStackMask(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(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 @@ TEST(StackMapTest, Test2) {
     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 @@ TEST(StackMapTest, Test2) {
     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 @@ TEST(StackMapTest, Test2) {
 
   // 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));
-
-    MemoryRegion stack_mask = stack_map.GetStackMask(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(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 @@ TEST(StackMapTest, Test2) {
     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 @@ TEST(StackMapTest, Test2) {
     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 @@ TEST(StackMapTest, TestNonLiveDexRegisters) {
   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 @@ TEST(StackMapTest, TestNonLiveDexRegisters) {
   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 @@ TEST(StackMapTest, TestNonLiveDexRegisters) {
   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 @@ TEST(StackMapTest, DexRegisterMapOffsetOverflow) {
   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 @@ TEST(StackMapTest, DexRegisterMapOffsetOverflow) {
   //   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 @@ TEST(StackMapTest, TestShareDexRegisterMap) {
   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 @@ TEST(StackMapTest, TestNoDexRegisterMap) {
   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 @@ TEST(StackMapTest, InlineTest) {
   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 @@ TEST(StackMapTest, InlineTest) {
     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 @@ TEST(StackMapTest, InlineTest) {
     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 @@ TEST(StackMapTest, InlineTest) {
 
     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));
   }
 }
 
index e039d10..96d5654 100644 (file)
@@ -1346,9 +1346,11 @@ class OatDumper {
     const void* raw_code_info = oat_method.GetVmapTable();
     if (raw_code_info != nullptr) {
       CodeInfo code_info(raw_code_info);
-      StackMap stack_map = code_info.GetStackMapForNativePcOffset(offset);
+      StackMapEncoding encoding = code_info.ExtractEncoding();
+      StackMap stack_map = code_info.GetStackMapForNativePcOffset(offset, encoding);
       if (stack_map.IsValid()) {
-        stack_map.Dump(os, code_info, oat_method.GetCodeOffset(), code_item->registers_size_);
+        stack_map.Dump(
+            os, code_info, encoding, oat_method.GetCodeOffset(), code_item->registers_size_);
       }
     }
   }
index 349013c..fe26438 100644 (file)
@@ -182,9 +182,10 @@ uint32_t ArtMethod::ToDexPc(const uintptr_t pc, bool abort_on_failure) {
   uint32_t sought_offset = pc - reinterpret_cast<uintptr_t>(entry_point);
   if (IsOptimized(sizeof(void*))) {
     CodeInfo code_info = GetOptimizedCodeInfo();
-    StackMap stack_map = code_info.GetStackMapForNativePcOffset(sought_offset);
+    StackMapEncoding encoding = code_info.ExtractEncoding();
+    StackMap stack_map = code_info.GetStackMapForNativePcOffset(sought_offset, encoding);
     if (stack_map.IsValid()) {
-      return stack_map.GetDexPc(code_info);
+      return stack_map.GetDexPc(encoding);
     }
   } else {
     MappingTable table(entry_point != nullptr ?
index d323379..504b753 100644 (file)
@@ -65,17 +65,18 @@ class CheckReferenceMapVisitor : public StackVisitor {
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     ArtMethod* m = GetMethod();
     CodeInfo code_info = m->GetOptimizedCodeInfo();
-    StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+    StackMapEncoding encoding = code_info.ExtractEncoding();
+    StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
     uint16_t number_of_dex_registers = m->GetCodeItem()->registers_size_;
     DexRegisterMap dex_register_map =
-        code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
-    MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
-    uint32_t register_mask = stack_map.GetRegisterMask(code_info);
+        code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
+    MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
+    uint32_t register_mask = stack_map.GetRegisterMask(encoding);
     for (int i = 0; i < number_of_references; ++i) {
       int reg = registers[i];
       CHECK(reg < m->GetCodeItem()->registers_size_);
-      DexRegisterLocation location =
-          dex_register_map.GetDexRegisterLocation(reg, number_of_dex_registers, code_info);
+      DexRegisterLocation location = dex_register_map.GetDexRegisterLocation(
+          reg, number_of_dex_registers, code_info, encoding);
       switch (location.GetKind()) {
         case DexRegisterLocation::Kind::kNone:
           // Not set, should not be a reference.
index dbd24a2..b0cbd02 100644 (file)
@@ -77,10 +77,11 @@ inline ArtMethod* GetCalleeSaveMethodCaller(ArtMethod** sp,
         (reinterpret_cast<uint8_t*>(sp) + callee_return_pc_offset));
     uintptr_t native_pc_offset = outer_method->NativeQuickPcOffset(caller_pc);
     CodeInfo code_info = outer_method->GetOptimizedCodeInfo();
-    StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+    StackMapEncoding encoding = code_info.ExtractEncoding();
+    StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
     DCHECK(stack_map.IsValid());
-    if (stack_map.HasInlineInfo(code_info)) {
-      InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
+    if (stack_map.HasInlineInfo(encoding)) {
+      InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
       uint32_t method_index = inline_info.GetMethodIndexAtDepth(inline_info.GetDepth() - 1);
       InvokeType invoke_type = static_cast<InvokeType>(
           inline_info.GetInvokeTypeAtDepth(inline_info.GetDepth() - 1));
index 042c33f..cc83db1 100644 (file)
@@ -314,13 +314,14 @@ class QuickArgumentVisitor {
 
     if (outer_method->IsOptimized(sizeof(void*))) {
       CodeInfo code_info = outer_method->GetOptimizedCodeInfo();
-      StackMap stack_map = code_info.GetStackMapForNativePcOffset(outer_pc_offset);
+      StackMapEncoding encoding = code_info.ExtractEncoding();
+      StackMap stack_map = code_info.GetStackMapForNativePcOffset(outer_pc_offset, encoding);
       DCHECK(stack_map.IsValid());
-      if (stack_map.HasInlineInfo(code_info)) {
-        InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
+      if (stack_map.HasInlineInfo(encoding)) {
+        InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
         return inline_info.GetDexPcAtDepth(inline_info.GetDepth() - 1);
       } else {
-        return stack_map.GetDexPc(code_info);
+        return stack_map.GetDexPc(encoding);
       }
     } else {
       return outer_method->ToDexPc(outer_pc);
index 4110887..5aeca98 100644 (file)
@@ -113,9 +113,10 @@ InlineInfo StackVisitor::GetCurrentInlineInfo() const {
   ArtMethod* outer_method = *GetCurrentQuickFrame();
   uint32_t native_pc_offset = outer_method->NativeQuickPcOffset(cur_quick_frame_pc_);
   CodeInfo code_info = outer_method->GetOptimizedCodeInfo();
-  StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+  StackMapEncoding encoding = code_info.ExtractEncoding();
+  StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
   DCHECK(stack_map.IsValid());
-  return code_info.GetInlineInfoOf(stack_map);
+  return code_info.GetInlineInfoOf(stack_map, encoding);
 }
 
 ArtMethod* StackVisitor::GetMethod() const {
@@ -274,34 +275,40 @@ bool StackVisitor::GetVRegFromOptimizedCode(ArtMethod* m, uint16_t vreg, VRegKin
   const void* code_pointer = outer_method->GetQuickOatCodePointer(sizeof(void*));
   DCHECK(code_pointer != nullptr);
   CodeInfo code_info = outer_method->GetOptimizedCodeInfo();
+  StackMapEncoding encoding = code_info.ExtractEncoding();
 
   uint32_t native_pc_offset = outer_method->NativeQuickPcOffset(cur_quick_frame_pc_);
-  StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+  StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
   DCHECK(stack_map.IsValid());
   size_t depth_in_stack_map = current_inlining_depth_ - 1;
 
   DexRegisterMap dex_register_map = IsInInlinedFrame()
-      ? code_info.GetDexRegisterMapAtDepth(
-            depth_in_stack_map, code_info.GetInlineInfoOf(stack_map), number_of_dex_registers)
-      : code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+      ? code_info.GetDexRegisterMapAtDepth(depth_in_stack_map,
+                                           code_info.GetInlineInfoOf(stack_map, encoding),
+                                           encoding,
+                                           number_of_dex_registers)
+      : code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
 
   DexRegisterLocation::Kind location_kind =
-      dex_register_map.GetLocationKind(vreg, number_of_dex_registers, code_info);
+      dex_register_map.GetLocationKind(vreg, number_of_dex_registers, code_info, encoding);
   switch (location_kind) {
     case DexRegisterLocation::Kind::kInStack: {
-      const int32_t offset =
-          dex_register_map.GetStackOffsetInBytes(vreg, number_of_dex_registers, code_info);
+      const int32_t offset = dex_register_map.GetStackOffsetInBytes(vreg,
+                                                                    number_of_dex_registers,
+                                                                    code_info,
+                                                                    encoding);
       const uint8_t* addr = reinterpret_cast<const uint8_t*>(cur_quick_frame_) + offset;
       *val = *reinterpret_cast<const uint32_t*>(addr);
       return true;
     }
     case DexRegisterLocation::Kind::kInRegister:
     case DexRegisterLocation::Kind::kInFpuRegister: {
-      uint32_t reg = dex_register_map.GetMachineRegister(vreg, number_of_dex_registers, code_info);
+      uint32_t reg =
+          dex_register_map.GetMachineRegister(vreg, number_of_dex_registers, code_info, encoding);
       return GetRegisterIfAccessible(reg, kind, val);
     }
     case DexRegisterLocation::Kind::kConstant:
-      *val = dex_register_map.GetConstant(vreg, number_of_dex_registers, code_info);
+      *val = dex_register_map.GetConstant(vreg, number_of_dex_registers, code_info, encoding);
       return true;
     case DexRegisterLocation::Kind::kNone:
       return false;
@@ -309,7 +316,10 @@ bool StackVisitor::GetVRegFromOptimizedCode(ArtMethod* m, uint16_t vreg, VRegKin
       LOG(FATAL)
           << "Unexpected location kind"
           << DexRegisterLocation::PrettyDescriptor(
-                dex_register_map.GetLocationInternalKind(vreg, number_of_dex_registers, code_info));
+                dex_register_map.GetLocationInternalKind(vreg,
+                                                         number_of_dex_registers,
+                                                         code_info,
+                                                         encoding));
       UNREACHABLE();
   }
 }
@@ -782,10 +792,11 @@ void StackVisitor::WalkStack(bool include_transitions) {
         if ((walk_kind_ == StackWalkKind::kIncludeInlinedFrames)
             && method->IsOptimized(sizeof(void*))) {
           CodeInfo code_info = method->GetOptimizedCodeInfo();
+          StackMapEncoding encoding = code_info.ExtractEncoding();
           uint32_t native_pc_offset = method->NativeQuickPcOffset(cur_quick_frame_pc_);
-          StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
-          if (stack_map.IsValid() && stack_map.HasInlineInfo(code_info)) {
-            InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
+          StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
+          if (stack_map.IsValid() && stack_map.HasInlineInfo(encoding)) {
+            InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
             DCHECK_EQ(current_inlining_depth_, 0u);
             for (current_inlining_depth_ = inline_info.GetDepth();
                  current_inlining_depth_ != 0;
index a64071f..f8fc2a9 100644 (file)
@@ -28,9 +28,10 @@ constexpr uint32_t StackMap::kNoInlineInfo;
 
 DexRegisterLocation::Kind DexRegisterMap::GetLocationInternalKind(uint16_t dex_register_number,
                                                                   uint16_t number_of_dex_registers,
-                                                                  const CodeInfo& code_info) const {
+                                                                  const CodeInfo& code_info,
+                                                                  const StackMapEncoding& enc) const {
   DexRegisterLocationCatalog dex_register_location_catalog =
-      code_info.GetDexRegisterLocationCatalog();
+      code_info.GetDexRegisterLocationCatalog(enc);
   size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
       dex_register_number,
       number_of_dex_registers,
@@ -40,9 +41,10 @@ DexRegisterLocation::Kind DexRegisterMap::GetLocationInternalKind(uint16_t dex_r
 
 DexRegisterLocation DexRegisterMap::GetDexRegisterLocation(uint16_t dex_register_number,
                                                            uint16_t number_of_dex_registers,
-                                                           const CodeInfo& code_info) const {
+                                                           const CodeInfo& code_info,
+                                                           const StackMapEncoding& enc) const {
   DexRegisterLocationCatalog dex_register_location_catalog =
-      code_info.GetDexRegisterLocationCatalog();
+      code_info.GetDexRegisterLocationCatalog(enc);
   size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
       dex_register_number,
       number_of_dex_registers,
@@ -50,156 +52,43 @@ DexRegisterLocation DexRegisterMap::GetDexRegisterLocation(uint16_t dex_register
   return dex_register_location_catalog.GetDexRegisterLocation(location_catalog_entry_index);
 }
 
-// Loads `number_of_bytes` at the given `offset` and assemble a uint32_t. If `check_max` is true,
-// this method converts a maximum value of size `number_of_bytes` into a uint32_t 0xFFFFFFFF.
-static uint32_t LoadAt(MemoryRegion region,
-                       size_t number_of_bytes,
-                       size_t offset,
-                       bool check_max = false) {
+uint32_t StackMap::LoadAt(size_t number_of_bytes, size_t offset, bool check_max) const {
   if (number_of_bytes == 0u) {
     DCHECK(!check_max);
     return 0;
   } else if (number_of_bytes == 1u) {
-    uint8_t value = region.LoadUnaligned<uint8_t>(offset);
-    if (check_max && value == 0xFF) {
-      return -1;
-    } else {
-      return value;
-    }
+    uint8_t value = region_.LoadUnaligned<uint8_t>(offset);
+    return (check_max && value == 0xFF) ? -1 : value;
   } else if (number_of_bytes == 2u) {
-    uint16_t value = region.LoadUnaligned<uint16_t>(offset);
-    if (check_max && value == 0xFFFF) {
-      return -1;
-    } else {
-      return value;
-    }
+    uint16_t value = region_.LoadUnaligned<uint16_t>(offset);
+    return (check_max && value == 0xFFFF) ? -1 : value;
   } else if (number_of_bytes == 3u) {
-    uint16_t low = region.LoadUnaligned<uint16_t>(offset);
-    uint16_t high = region.LoadUnaligned<uint8_t>(offset + sizeof(uint16_t));
+    uint16_t low = region_.LoadUnaligned<uint16_t>(offset);
+    uint16_t high = region_.LoadUnaligned<uint8_t>(offset + sizeof(uint16_t));
     uint32_t value = (high << 16) + low;
-    if (check_max && value == 0xFFFFFF) {
-      return -1;
-    } else {
-      return value;
-    }
+    return (check_max && value == 0xFFFFFF) ? -1 : value;
   } else {
     DCHECK_EQ(number_of_bytes, 4u);
-    return region.LoadUnaligned<uint32_t>(offset);
+    return region_.LoadUnaligned<uint32_t>(offset);
   }
 }
 
-static void StoreAt(MemoryRegion region, size_t number_of_bytes, size_t offset, uint32_t value) {
+void StackMap::StoreAt(size_t number_of_bytes, size_t offset, uint32_t value) const {
   if (number_of_bytes == 0u) {
     DCHECK_EQ(value, 0u);
   } else if (number_of_bytes == 1u) {
-    region.StoreUnaligned<uint8_t>(offset, value);
+    region_.StoreUnaligned<uint8_t>(offset, value);
   } else if (number_of_bytes == 2u) {
-    region.StoreUnaligned<uint16_t>(offset, value);
+    region_.StoreUnaligned<uint16_t>(offset, value);
   } else if (number_of_bytes == 3u) {
-    region.StoreUnaligned<uint16_t>(offset, Low16Bits(value));
-    region.StoreUnaligned<uint8_t>(offset + sizeof(uint16_t), High16Bits(value));
+    region_.StoreUnaligned<uint16_t>(offset, Low16Bits(value));
+    region_.StoreUnaligned<uint8_t>(offset + sizeof(uint16_t), High16Bits(value));
   } else {
-    region.StoreUnaligned<uint32_t>(offset, value);
+    region_.StoreUnaligned<uint32_t>(offset, value);
     DCHECK_EQ(number_of_bytes, 4u);
   }
 }
 
-uint32_t StackMap::GetDexPc(const CodeInfo& info) const {
-  return LoadAt(region_, info.NumberOfBytesForDexPc(), info.ComputeStackMapDexPcOffset());
-}
-
-void StackMap::SetDexPc(const CodeInfo& info, uint32_t dex_pc) {
-  StoreAt(region_, info.NumberOfBytesForDexPc(), info.ComputeStackMapDexPcOffset(), dex_pc);
-}
-
-uint32_t StackMap::GetNativePcOffset(const CodeInfo& info) const {
-  return LoadAt(region_, info.NumberOfBytesForNativePc(), info.ComputeStackMapNativePcOffset());
-}
-
-void StackMap::SetNativePcOffset(const CodeInfo& info, uint32_t native_pc_offset) {
-  StoreAt(region_, info.NumberOfBytesForNativePc(), info.ComputeStackMapNativePcOffset(), native_pc_offset);
-}
-
-uint32_t StackMap::GetDexRegisterMapOffset(const CodeInfo& info) const {
-  return LoadAt(region_,
-                info.NumberOfBytesForDexRegisterMap(),
-                info.ComputeStackMapDexRegisterMapOffset(),
-                /* check_max */ true);
-}
-
-void StackMap::SetDexRegisterMapOffset(const CodeInfo& info, uint32_t offset) {
-  StoreAt(region_,
-          info.NumberOfBytesForDexRegisterMap(),
-          info.ComputeStackMapDexRegisterMapOffset(),
-          offset);
-}
-
-uint32_t StackMap::GetInlineDescriptorOffset(const CodeInfo& info) const {
-  if (!info.HasInlineInfo()) return kNoInlineInfo;
-  return LoadAt(region_,
-                info.NumberOfBytesForInlineInfo(),
-                info.ComputeStackMapInlineInfoOffset(),
-                /* check_max */ true);
-}
-
-void StackMap::SetInlineDescriptorOffset(const CodeInfo& info, uint32_t offset) {
-  DCHECK(info.HasInlineInfo());
-  StoreAt(region_,
-          info.NumberOfBytesForInlineInfo(),
-          info.ComputeStackMapInlineInfoOffset(),
-          offset);
-}
-
-uint32_t StackMap::GetRegisterMask(const CodeInfo& info) const {
-  return LoadAt(region_,
-                info.NumberOfBytesForRegisterMask(),
-                info.ComputeStackMapRegisterMaskOffset());
-}
-
-void StackMap::SetRegisterMask(const CodeInfo& info, uint32_t mask) {
-  StoreAt(region_,
-          info.NumberOfBytesForRegisterMask(),
-          info.ComputeStackMapRegisterMaskOffset(),
-          mask);
-}
-
-size_t StackMap::ComputeStackMapSizeInternal(size_t stack_mask_size,
-                                             size_t number_of_bytes_for_inline_info,
-                                             size_t number_of_bytes_for_dex_map,
-                                             size_t number_of_bytes_for_dex_pc,
-                                             size_t number_of_bytes_for_native_pc,
-                                             size_t number_of_bytes_for_register_mask) {
-  return stack_mask_size
-      + number_of_bytes_for_inline_info
-      + number_of_bytes_for_dex_map
-      + number_of_bytes_for_dex_pc
-      + number_of_bytes_for_native_pc
-      + number_of_bytes_for_register_mask;
-}
-
-size_t StackMap::ComputeStackMapSize(size_t stack_mask_size,
-                                     size_t inline_info_size,
-                                     size_t dex_register_map_size,
-                                     size_t dex_pc_max,
-                                     size_t native_pc_max,
-                                     size_t register_mask_max) {
-  return ComputeStackMapSizeInternal(
-      stack_mask_size,
-      inline_info_size == 0
-          ? 0
-            // + 1 to also encode kNoInlineInfo.
-          :  CodeInfo::EncodingSizeInBytes(inline_info_size + dex_register_map_size + 1),
-      // + 1 to also encode kNoDexRegisterMap.
-      CodeInfo::EncodingSizeInBytes(dex_register_map_size + 1),
-      CodeInfo::EncodingSizeInBytes(dex_pc_max),
-      CodeInfo::EncodingSizeInBytes(native_pc_max),
-      CodeInfo::EncodingSizeInBytes(register_mask_max));
-}
-
-MemoryRegion StackMap::GetStackMask(const CodeInfo& info) const {
-  return region_.Subregion(info.ComputeStackMapStackMaskOffset(), info.GetStackMaskSize());
-}
-
 static void DumpRegisterMapping(std::ostream& os,
                                 size_t dex_register_num,
                                 DexRegisterLocation location,
@@ -216,6 +105,7 @@ void CodeInfo::Dump(std::ostream& os,
                     uint32_t code_offset,
                     uint16_t number_of_dex_registers,
                     bool dump_stack_maps) const {
+  StackMapEncoding encoding = ExtractEncoding();
   uint32_t code_info_size = GetOverallSize();
   size_t number_of_stack_maps = GetNumberOfStackMaps();
   Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
@@ -223,21 +113,26 @@ void CodeInfo::Dump(std::ostream& os,
   indented_os << "Optimized CodeInfo (size=" << code_info_size
               << ", number_of_dex_registers=" << number_of_dex_registers
               << ", number_of_stack_maps=" << number_of_stack_maps
-              << ", has_inline_info=" << HasInlineInfo()
-              << ", number_of_bytes_for_inline_info=" << NumberOfBytesForInlineInfo()
-              << ", number_of_bytes_for_dex_register_map=" << NumberOfBytesForDexRegisterMap()
-              << ", number_of_bytes_for_dex_pc=" << NumberOfBytesForDexPc()
-              << ", number_of_bytes_for_native_pc=" << NumberOfBytesForNativePc()
-              << ", number_of_bytes_for_register_mask=" << NumberOfBytesForRegisterMask()
+              << ", has_inline_info=" << encoding.HasInlineInfo()
+              << ", number_of_bytes_for_inline_info=" << encoding.NumberOfBytesForInlineInfo()
+              << ", number_of_bytes_for_dex_register_map="
+                  << encoding.NumberOfBytesForDexRegisterMap()
+              << ", number_of_bytes_for_dex_pc=" << encoding.NumberOfBytesForDexPc()
+              << ", number_of_bytes_for_native_pc=" << encoding.NumberOfBytesForNativePc()
+              << ", number_of_bytes_for_register_mask=" << encoding.NumberOfBytesForRegisterMask()
               << ")\n";
   // Display the Dex register location catalog.
-  GetDexRegisterLocationCatalog().Dump(indented_os, *this);
+  GetDexRegisterLocationCatalog(encoding).Dump(indented_os, *this);
   // Display stack maps along with (live) Dex register maps.
   if (dump_stack_maps) {
     for (size_t i = 0; i < number_of_stack_maps; ++i) {
-      StackMap stack_map = GetStackMapAt(i);
-      stack_map.Dump(
-          indented_os, *this, code_offset, number_of_dex_registers, " " + std::to_string(i));
+      StackMap stack_map = GetStackMapAt(i, encoding);
+      stack_map.Dump(indented_os,
+                     *this,
+                     encoding,
+                     code_offset,
+                     number_of_dex_registers,
+                     " " + std::to_string(i));
     }
   }
   // TODO: Dump the stack map's inline information? We need to know more from the caller:
@@ -245,9 +140,10 @@ void CodeInfo::Dump(std::ostream& os,
 }
 
 void DexRegisterLocationCatalog::Dump(std::ostream& os, const CodeInfo& code_info) {
+  StackMapEncoding encoding = code_info.ExtractEncoding();
   size_t number_of_location_catalog_entries =
       code_info.GetNumberOfDexRegisterLocationCatalogEntries();
-  size_t location_catalog_size_in_bytes = code_info.GetDexRegisterLocationCatalogSize();
+  size_t location_catalog_size_in_bytes = code_info.GetDexRegisterLocationCatalogSize(encoding);
   Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
   std::ostream indented_os(&indent_filter);
   indented_os
@@ -262,6 +158,7 @@ void DexRegisterLocationCatalog::Dump(std::ostream& os, const CodeInfo& code_inf
 void DexRegisterMap::Dump(std::ostream& os,
                           const CodeInfo& code_info,
                           uint16_t number_of_dex_registers) const {
+  StackMapEncoding encoding = code_info.ExtractEncoding();
   size_t number_of_location_catalog_entries =
       code_info.GetNumberOfDexRegisterLocationCatalogEntries();
   Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
@@ -271,7 +168,10 @@ void DexRegisterMap::Dump(std::ostream& os,
     if (IsDexRegisterLive(j)) {
       size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
           j, number_of_dex_registers, number_of_location_catalog_entries);
-      DexRegisterLocation location = GetDexRegisterLocation(j, number_of_dex_registers, code_info);
+      DexRegisterLocation location = GetDexRegisterLocation(j,
+                                                            number_of_dex_registers,
+                                                            code_info,
+                                                            encoding);
       DumpRegisterMapping(
           indented_os, j, location, "v",
           "\t[entry " + std::to_string(static_cast<int>(location_catalog_entry_index)) + "]");
@@ -281,6 +181,7 @@ void DexRegisterMap::Dump(std::ostream& os,
 
 void StackMap::Dump(std::ostream& os,
                     const CodeInfo& code_info,
+                    const StackMapEncoding& encoding,
                     uint32_t code_offset,
                     uint16_t number_of_dex_registers,
                     const std::string& header_suffix) const {
@@ -288,21 +189,22 @@ void StackMap::Dump(std::ostream& os,
   std::ostream indented_os(&indent_filter);
   indented_os << "StackMap" << header_suffix
               << std::hex
-              << " [native_pc=0x" << code_offset + GetNativePcOffset(code_info) << "]"
-              << " (dex_pc=0x" << GetDexPc(code_info)
-              << ", native_pc_offset=0x" << GetNativePcOffset(code_info)
-              << ", dex_register_map_offset=0x" << GetDexRegisterMapOffset(code_info)
-              << ", inline_info_offset=0x" << GetInlineDescriptorOffset(code_info)
-              << ", register_mask=0x" << GetRegisterMask(code_info)
+              << " [native_pc=0x" << code_offset + GetNativePcOffset(encoding) << "]"
+              << " (dex_pc=0x" << GetDexPc(encoding)
+              << ", native_pc_offset=0x" << GetNativePcOffset(encoding)
+              << ", dex_register_map_offset=0x" << GetDexRegisterMapOffset(encoding)
+              << ", inline_info_offset=0x" << GetInlineDescriptorOffset(encoding)
+              << ", register_mask=0x" << GetRegisterMask(encoding)
               << std::dec
               << ", stack_mask=0b";
-  MemoryRegion stack_mask = GetStackMask(code_info);
+  MemoryRegion stack_mask = GetStackMask(encoding);
   for (size_t i = 0, e = stack_mask.size_in_bits(); i < e; ++i) {
     indented_os << stack_mask.LoadBit(e - i - 1);
   }
   indented_os << ")\n";
-  if (HasDexRegisterMap(code_info)) {
-    DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(*this, number_of_dex_registers);
+  if (HasDexRegisterMap(encoding)) {
+    DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(
+        *this, encoding, number_of_dex_registers);
     dex_register_map.Dump(os, code_info, number_of_dex_registers);
   }
 }
@@ -321,8 +223,9 @@ void InlineInfo::Dump(std::ostream& os,
                 << ", method_index=0x" << GetMethodIndexAtDepth(i)
                 << ")\n";
     if (HasDexRegisterMapAtDepth(i)) {
+      StackMapEncoding encoding = code_info.ExtractEncoding();
       DexRegisterMap dex_register_map =
-          code_info.GetDexRegisterMapAtDepth(i, *this, number_of_dex_registers[i]);
+          code_info.GetDexRegisterMapAtDepth(i, *this, encoding, number_of_dex_registers[i]);
       dex_register_map.Dump(indented_os, code_info, number_of_dex_registers[i]);
     }
   }
index 7f33e6d..4e42008 100644 (file)
@@ -32,6 +32,7 @@ static constexpr ssize_t kFrameSlotSize = 4;
 static constexpr size_t kVRegSize = 4;
 
 class CodeInfo;
+class StackMapEncoding;
 
 /**
  * Classes in the following file are wrapper on stack map information backed
@@ -437,26 +438,30 @@ class DexRegisterMap {
   // Get the surface kind of Dex register `dex_register_number`.
   DexRegisterLocation::Kind GetLocationKind(uint16_t dex_register_number,
                                             uint16_t number_of_dex_registers,
-                                            const CodeInfo& code_info) const {
+                                            const CodeInfo& code_info,
+                                            const StackMapEncoding& enc) const {
     return DexRegisterLocation::ConvertToSurfaceKind(
-        GetLocationInternalKind(dex_register_number, number_of_dex_registers, code_info));
+        GetLocationInternalKind(dex_register_number, number_of_dex_registers, code_info, enc));
   }
 
   // Get the internal kind of Dex register `dex_register_number`.
   DexRegisterLocation::Kind GetLocationInternalKind(uint16_t dex_register_number,
                                                     uint16_t number_of_dex_registers,
-                                                    const CodeInfo& code_info) const;
+                                                    const CodeInfo& code_info,
+                                                    const StackMapEncoding& enc) const;
 
   // Get the Dex register location `dex_register_number`.
   DexRegisterLocation GetDexRegisterLocation(uint16_t dex_register_number,
                                              uint16_t number_of_dex_registers,
-                                             const CodeInfo& code_info) const;
+                                             const CodeInfo& code_info,
+                                             const StackMapEncoding& enc) const;
 
   int32_t GetStackOffsetInBytes(uint16_t dex_register_number,
                                 uint16_t number_of_dex_registers,
-                                const CodeInfo& code_info) const {
+                                const CodeInfo& code_info,
+                                const StackMapEncoding& enc) const {
     DexRegisterLocation location =
-        GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info);
+        GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info, enc);
     DCHECK(location.GetKind() == DexRegisterLocation::Kind::kInStack);
     // GetDexRegisterLocation returns the offset in bytes.
     return location.GetValue();
@@ -464,9 +469,10 @@ class DexRegisterMap {
 
   int32_t GetConstant(uint16_t dex_register_number,
                       uint16_t number_of_dex_registers,
-                      const CodeInfo& code_info) const {
+                      const CodeInfo& code_info,
+                      const StackMapEncoding& enc) const {
     DexRegisterLocation location =
-        GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info);
+        GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info, enc);
     DCHECK(location.GetKind() == DexRegisterLocation::Kind::kConstant)
         << DexRegisterLocation::PrettyDescriptor(location.GetKind());
     return location.GetValue();
@@ -474,9 +480,10 @@ class DexRegisterMap {
 
   int32_t GetMachineRegister(uint16_t dex_register_number,
                              uint16_t number_of_dex_registers,
-                             const CodeInfo& code_info) const {
+                             const CodeInfo& code_info,
+                             const StackMapEncoding& enc) const {
     DexRegisterLocation location =
-        GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info);
+        GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info, enc);
     DCHECK(location.GetInternalKind() == DexRegisterLocation::Kind::kInRegister
            || location.GetInternalKind() == DexRegisterLocation::Kind::kInFpuRegister)
         << DexRegisterLocation::PrettyDescriptor(location.GetInternalKind());
@@ -628,6 +635,111 @@ class DexRegisterMap {
   friend class StackMapStream;
 };
 
+class StackMapEncoding {
+ public:
+  StackMapEncoding() {}
+
+  StackMapEncoding(size_t stack_mask_size,
+                   size_t bytes_for_inline_info,
+                   size_t bytes_for_dex_register_map,
+                   size_t bytes_for_dex_pc,
+                   size_t bytes_for_native_pc,
+                   size_t bytes_for_register_mask)
+      : bytes_for_stack_mask_(stack_mask_size),
+        bytes_for_inline_info_(bytes_for_inline_info),
+        bytes_for_dex_register_map_(bytes_for_dex_register_map),
+        bytes_for_dex_pc_(bytes_for_dex_pc),
+        bytes_for_native_pc_(bytes_for_native_pc),
+        bytes_for_register_mask_(bytes_for_register_mask) {}
+
+  static StackMapEncoding CreateFromSizes(size_t stack_mask_size,
+                                          size_t inline_info_size,
+                                          size_t dex_register_map_size,
+                                          size_t dex_pc_max,
+                                          size_t native_pc_max,
+                                          size_t register_mask_max) {
+    return StackMapEncoding(
+        stack_mask_size,
+        // + 1 to also encode kNoInlineInfo: if an inline info offset
+        // is at 0xFF, we want to overflow to a larger encoding, because it will
+        // conflict with kNoInlineInfo.
+        // The offset is relative to the dex register map. TODO: Change this.
+        inline_info_size == 0
+          ? 0
+          : EncodingSizeInBytes(dex_register_map_size + inline_info_size + 1),
+        // + 1 to also encode kNoDexRegisterMap: if a dex register map offset
+        // is at 0xFF, we want to overflow to a larger encoding, because it will
+        // conflict with kNoDexRegisterMap.
+        EncodingSizeInBytes(dex_register_map_size + 1),
+        EncodingSizeInBytes(dex_pc_max),
+        EncodingSizeInBytes(native_pc_max),
+        EncodingSizeInBytes(register_mask_max));
+  }
+
+  // Get the size of one stack map of this CodeInfo object, in bytes.
+  // All stack maps of a CodeInfo have the same size.
+  size_t ComputeStackMapSize() const {
+    return bytes_for_register_mask_
+         + bytes_for_stack_mask_
+         + bytes_for_inline_info_
+         + bytes_for_dex_register_map_
+         + bytes_for_dex_pc_
+         + bytes_for_native_pc_;
+  }
+
+  bool HasInlineInfo() const { return bytes_for_inline_info_ > 0; }
+
+  size_t NumberOfBytesForStackMask() const { return bytes_for_stack_mask_; }
+  size_t NumberOfBytesForInlineInfo() const { return bytes_for_inline_info_; }
+  size_t NumberOfBytesForDexRegisterMap() const { return bytes_for_dex_register_map_; }
+  size_t NumberOfBytesForDexPc() const { return bytes_for_dex_pc_; }
+  size_t NumberOfBytesForNativePc() const { return bytes_for_native_pc_; }
+  size_t NumberOfBytesForRegisterMask() const { return bytes_for_register_mask_; }
+
+  size_t ComputeStackMapRegisterMaskOffset() const {
+    return kRegisterMaskOffset;
+  }
+
+  size_t ComputeStackMapStackMaskOffset() const {
+    return ComputeStackMapRegisterMaskOffset() + bytes_for_register_mask_;
+  }
+
+  size_t ComputeStackMapDexPcOffset() const {
+    return ComputeStackMapStackMaskOffset() + bytes_for_stack_mask_;
+  }
+
+  size_t ComputeStackMapNativePcOffset() const {
+    return ComputeStackMapDexPcOffset() + bytes_for_dex_pc_;
+  }
+
+  size_t ComputeStackMapDexRegisterMapOffset() const {
+    return ComputeStackMapNativePcOffset() + bytes_for_native_pc_;
+  }
+
+  size_t ComputeStackMapInlineInfoOffset() const {
+    return ComputeStackMapDexRegisterMapOffset() + bytes_for_dex_register_map_;
+  }
+
+ private:
+  static size_t EncodingSizeInBytes(size_t max_element) {
+    DCHECK(IsUint<32>(max_element));
+    return (max_element == 0) ? 0
+         : IsUint<8>(max_element) ? 1
+         : IsUint<16>(max_element) ? 2
+         : IsUint<24>(max_element) ? 3
+         : 4;
+  }
+
+  static constexpr int kRegisterMaskOffset = 0;
+
+  size_t bytes_for_stack_mask_;
+  size_t bytes_for_inline_info_;
+  size_t bytes_for_dex_register_map_;
+  size_t bytes_for_dex_pc_;
+  size_t bytes_for_native_pc_;
+  size_t bytes_for_register_mask_;
+};
+
 /**
  * A Stack Map holds compilation information for a specific PC necessary for:
  * - Mapping it to a dex PC,
@@ -642,44 +754,82 @@ class DexRegisterMap {
  */
 class StackMap {
  public:
-  explicit StackMap(MemoryRegion region) : region_(region) {}
   StackMap() {}
+  explicit StackMap(MemoryRegion region) : region_(region) {}
 
   bool IsValid() const { return region_.pointer() != nullptr; }
 
-  uint32_t GetDexPc(const CodeInfo& info) const;
+  uint32_t GetDexPc(const StackMapEncoding& encoding) const {
+    return LoadAt(encoding.NumberOfBytesForDexPc(), encoding.ComputeStackMapDexPcOffset());
+  }
 
-  void SetDexPc(const CodeInfo& info, uint32_t dex_pc);
+  void SetDexPc(const StackMapEncoding& encoding, uint32_t dex_pc) {
+    StoreAt(encoding.NumberOfBytesForDexPc(), encoding.ComputeStackMapDexPcOffset(), dex_pc);
+  }
 
-  uint32_t GetNativePcOffset(const CodeInfo& info) const;
+  uint32_t GetNativePcOffset(const StackMapEncoding& encoding) const {
+    return LoadAt(encoding.NumberOfBytesForNativePc(), encoding.ComputeStackMapNativePcOffset());
+  }
 
-  void SetNativePcOffset(const CodeInfo& info, uint32_t native_pc_offset);
+  void SetNativePcOffset(const StackMapEncoding& encoding, uint32_t native_pc_offset) {
+    StoreAt(encoding.NumberOfBytesForNativePc(),
+            encoding.ComputeStackMapNativePcOffset(),
+            native_pc_offset);
+  }
 
-  uint32_t GetDexRegisterMapOffset(const CodeInfo& info) const;
+  uint32_t GetDexRegisterMapOffset(const StackMapEncoding& encoding) const {
+    return LoadAt(encoding.NumberOfBytesForDexRegisterMap(),
+                  encoding.ComputeStackMapDexRegisterMapOffset(),
+                  /* check_max */ true);
+  }
 
-  void SetDexRegisterMapOffset(const CodeInfo& info, uint32_t offset);
+  void SetDexRegisterMapOffset(const StackMapEncoding& encoding, uint32_t offset) {
+    StoreAt(encoding.NumberOfBytesForDexRegisterMap(),
+            encoding.ComputeStackMapDexRegisterMapOffset(),
+            offset);
+  }
 
-  uint32_t GetInlineDescriptorOffset(const CodeInfo& info) const;
+  uint32_t GetInlineDescriptorOffset(const StackMapEncoding& encoding) const {
+    if (!encoding.HasInlineInfo()) return kNoInlineInfo;
+    return LoadAt(encoding.NumberOfBytesForInlineInfo(),
+                  encoding.ComputeStackMapInlineInfoOffset(),
+                  /* check_max */ true);
+  }
 
-  void SetInlineDescriptorOffset(const CodeInfo& info, uint32_t offset);
+  void SetInlineDescriptorOffset(const StackMapEncoding& encoding, uint32_t offset) {
+    DCHECK(encoding.HasInlineInfo());
+    StoreAt(encoding.NumberOfBytesForInlineInfo(),
+            encoding.ComputeStackMapInlineInfoOffset(),
+            offset);
+  }
 
-  uint32_t GetRegisterMask(const CodeInfo& info) const;
+  uint32_t GetRegisterMask(const StackMapEncoding& encoding) const {
+    return LoadAt(encoding.NumberOfBytesForRegisterMask(),
+                  encoding.ComputeStackMapRegisterMaskOffset());
+  }
 
-  void SetRegisterMask(const CodeInfo& info, uint32_t mask);
+  void SetRegisterMask(const StackMapEncoding& encoding, uint32_t mask) {
+    StoreAt(encoding.NumberOfBytesForRegisterMask(),
+            encoding.ComputeStackMapRegisterMaskOffset(),
+            mask);
+  }
 
-  MemoryRegion GetStackMask(const CodeInfo& info) const;
+  MemoryRegion GetStackMask(const StackMapEncoding& encoding) const {
+    return region_.Subregion(encoding.ComputeStackMapStackMaskOffset(),
+                             encoding.NumberOfBytesForStackMask());
+  }
 
-  void SetStackMask(const CodeInfo& info, const BitVector& sp_map) {
-    MemoryRegion region = GetStackMask(info);
+  void SetStackMask(const StackMapEncoding& encoding, const BitVector& sp_map) {
+    MemoryRegion region = GetStackMask(encoding);
     sp_map.CopyTo(region.start(), region.size());
   }
 
-  bool HasDexRegisterMap(const CodeInfo& info) const {
-    return GetDexRegisterMapOffset(info) != kNoDexRegisterMap;
+  bool HasDexRegisterMap(const StackMapEncoding& encoding) const {
+    return GetDexRegisterMapOffset(encoding) != kNoDexRegisterMap;
   }
 
-  bool HasInlineInfo(const CodeInfo& info) const {
-    return GetInlineDescriptorOffset(info) != kNoInlineInfo;
+  bool HasInlineInfo(const StackMapEncoding& encoding) const {
+    return GetInlineDescriptorOffset(encoding) != kNoInlineInfo;
   }
 
   bool Equals(const StackMap& other) const {
@@ -687,15 +837,9 @@ class StackMap {
        && region_.size() == other.region_.size();
   }
 
-  static size_t ComputeStackMapSize(size_t stack_mask_size,
-                                    size_t inline_info_size,
-                                    size_t dex_register_map_size,
-                                    size_t dex_pc_max,
-                                    size_t native_pc_max,
-                                    size_t register_mask_max);
-
   void Dump(std::ostream& os,
             const CodeInfo& code_info,
+            const StackMapEncoding& encoding,
             uint32_t code_offset,
             uint16_t number_of_dex_registers,
             const std::string& header_suffix = "") const;
@@ -709,21 +853,17 @@ class StackMap {
   static constexpr uint32_t kNoInlineInfo = -1;
 
  private:
-  static size_t ComputeStackMapSizeInternal(size_t stack_mask_size,
-                                            size_t number_of_bytes_for_inline_info,
-                                            size_t number_of_bytes_for_dex_map,
-                                            size_t number_of_bytes_for_dex_pc,
-                                            size_t number_of_bytes_for_native_pc,
-                                            size_t number_of_bytes_for_register_mask);
-
   // TODO: Instead of plain types such as "uint32_t", introduce
   // typedefs (and document the memory layout of StackMap).
-  static constexpr int kRegisterMaskOffset = 0;
   static constexpr int kFixedSize = 0;
 
+  // Loads `number_of_bytes` at the given `offset` and assemble a uint32_t. If `check_max` is true,
+  // this method converts a maximum value of size `number_of_bytes` into a uint32_t 0xFFFFFFFF.
+  uint32_t LoadAt(size_t number_of_bytes, size_t offset, bool check_max = false) const;
+  void StoreAt(size_t number_of_bytes, size_t offset, uint32_t value) const;
+
   MemoryRegion region_;
 
-  friend class CodeInfo;
   friend class StackMapStream;
 };
 
@@ -827,39 +967,23 @@ class CodeInfo {
     region_ = MemoryRegion(const_cast<void*>(data), size);
   }
 
-  static size_t EncodingSizeInBytes(size_t max_element) {
-    DCHECK(IsUint<32>(max_element));
-    return (max_element == 0) ? 0
-         : IsUint<8>(max_element) ? 1
-         : IsUint<16>(max_element) ? 2
-         : IsUint<24>(max_element) ? 3
-         : 4;
+  StackMapEncoding ExtractEncoding() const {
+    return StackMapEncoding(region_.LoadUnaligned<uint32_t>(kStackMaskSizeOffset),
+                            GetNumberOfBytesForEncoding(kInlineInfoBitOffset),
+                            GetNumberOfBytesForEncoding(kDexRegisterMapBitOffset),
+                            GetNumberOfBytesForEncoding(kDexPcBitOffset),
+                            GetNumberOfBytesForEncoding(kNativePcBitOffset),
+                            GetNumberOfBytesForEncoding(kRegisterMaskBitOffset));
   }
 
-  void SetEncoding(size_t inline_info_size,
-                   size_t dex_register_map_size,
-                   size_t dex_pc_max,
-                   size_t native_pc_max,
-                   size_t register_mask_max) {
-    if (inline_info_size != 0) {
-      region_.StoreBit(kHasInlineInfoBitOffset, 1);
-      // + 1 to also encode kNoInlineInfo: if an inline info offset
-      // is at 0xFF, we want to overflow to a larger encoding, because it will
-      // conflict with kNoInlineInfo.
-      // The offset is relative to the dex register map. TODO: Change this.
-      SetEncodingAt(kInlineInfoBitOffset,
-                    EncodingSizeInBytes(dex_register_map_size + inline_info_size + 1));
-    } else {
-      region_.StoreBit(kHasInlineInfoBitOffset, 0);
-      SetEncodingAt(kInlineInfoBitOffset, 0);
-    }
-    // + 1 to also encode kNoDexRegisterMap: if a dex register map offset
-    // is at 0xFF, we want to overflow to a larger encoding, because it will
-    // conflict with kNoDexRegisterMap.
-    SetEncodingAt(kDexRegisterMapBitOffset, EncodingSizeInBytes(dex_register_map_size + 1));
-    SetEncodingAt(kDexPcBitOffset, EncodingSizeInBytes(dex_pc_max));
-    SetEncodingAt(kNativePcBitOffset, EncodingSizeInBytes(native_pc_max));
-    SetEncodingAt(kRegisterMaskBitOffset, EncodingSizeInBytes(register_mask_max));
+  void SetEncoding(const StackMapEncoding& encoding) {
+    region_.StoreUnaligned<uint32_t>(kStackMaskSizeOffset, encoding.NumberOfBytesForStackMask());
+    region_.StoreBit(kHasInlineInfoBitOffset, encoding.NumberOfBytesForInlineInfo() != 0);
+    SetEncodingAt(kInlineInfoBitOffset, encoding.NumberOfBytesForInlineInfo());
+    SetEncodingAt(kDexRegisterMapBitOffset, encoding.NumberOfBytesForDexRegisterMap());
+    SetEncodingAt(kDexPcBitOffset, encoding.NumberOfBytesForDexPc());
+    SetEncodingAt(kNativePcBitOffset, encoding.NumberOfBytesForNativePc());
+    SetEncodingAt(kRegisterMaskBitOffset, encoding.NumberOfBytesForRegisterMask());
   }
 
   void SetEncodingAt(size_t bit_offset, size_t number_of_bytes) {
@@ -880,64 +1004,15 @@ class CodeInfo {
     return region_.LoadBit(kHasInlineInfoBitOffset);
   }
 
-  size_t NumberOfBytesForInlineInfo() const {
-    return GetNumberOfBytesForEncoding(kInlineInfoBitOffset);
-  }
-
-  size_t NumberOfBytesForDexRegisterMap() const {
-    return GetNumberOfBytesForEncoding(kDexRegisterMapBitOffset);
-  }
-
-  size_t NumberOfBytesForRegisterMask() const {
-    return GetNumberOfBytesForEncoding(kRegisterMaskBitOffset);
-  }
-
-  size_t NumberOfBytesForNativePc() const {
-    return GetNumberOfBytesForEncoding(kNativePcBitOffset);
-  }
-
-  size_t NumberOfBytesForDexPc() const {
-    return GetNumberOfBytesForEncoding(kDexPcBitOffset);
-  }
-
-  size_t ComputeStackMapRegisterMaskOffset() const {
-    return StackMap::kRegisterMaskOffset;
-  }
-
-  size_t ComputeStackMapStackMaskOffset() const {
-    return ComputeStackMapRegisterMaskOffset()
-        + (NumberOfBytesForRegisterMask() * sizeof(uint8_t));
-  }
-
-  size_t ComputeStackMapDexPcOffset() const {
-    return ComputeStackMapStackMaskOffset() + GetStackMaskSize();
-  }
-
-  size_t ComputeStackMapNativePcOffset() const {
-    return ComputeStackMapDexPcOffset()
-        + (NumberOfBytesForDexPc() * sizeof(uint8_t));
-  }
-
-  size_t ComputeStackMapDexRegisterMapOffset() const {
-    return ComputeStackMapNativePcOffset()
-        + (NumberOfBytesForNativePc() * sizeof(uint8_t));
-  }
-
-  size_t ComputeStackMapInlineInfoOffset() const {
-    CHECK(HasInlineInfo());
-    return ComputeStackMapDexRegisterMapOffset()
-        + (NumberOfBytesForDexRegisterMap() * sizeof(uint8_t));
-  }
-
-  DexRegisterLocationCatalog GetDexRegisterLocationCatalog() const {
+  DexRegisterLocationCatalog GetDexRegisterLocationCatalog(const StackMapEncoding& encoding) const {
     return DexRegisterLocationCatalog(region_.Subregion(
-        GetDexRegisterLocationCatalogOffset(),
-        GetDexRegisterLocationCatalogSize()));
+        GetDexRegisterLocationCatalogOffset(encoding),
+        GetDexRegisterLocationCatalogSize(encoding)));
   }
 
-  StackMap GetStackMapAt(size_t i) const {
-    size_t size = StackMapSize();
-    return StackMap(GetStackMaps().Subregion(i * size, size));
+  StackMap GetStackMapAt(size_t i, const StackMapEncoding& encoding) const {
+    size_t stack_map_size = encoding.ComputeStackMapSize();
+    return StackMap(GetStackMaps(encoding).Subregion(i * stack_map_size, stack_map_size));
   }
 
   uint32_t GetOverallSize() const {
@@ -956,19 +1031,11 @@ class CodeInfo {
     region_.StoreUnaligned<uint32_t>(kNumberOfDexRegisterLocationCatalogEntriesOffset, num_entries);
   }
 
-  uint32_t GetDexRegisterLocationCatalogSize() const {
-    return ComputeDexRegisterLocationCatalogSize(GetDexRegisterLocationCatalogOffset(),
+  uint32_t GetDexRegisterLocationCatalogSize(const StackMapEncoding& encoding) const {
+    return ComputeDexRegisterLocationCatalogSize(GetDexRegisterLocationCatalogOffset(encoding),
                                                  GetNumberOfDexRegisterLocationCatalogEntries());
   }
 
-  uint32_t GetStackMaskSize() const {
-    return region_.LoadUnaligned<uint32_t>(kStackMaskSizeOffset);
-  }
-
-  void SetStackMaskSize(uint32_t size) {
-    region_.StoreUnaligned<uint32_t>(kStackMaskSizeOffset, size);
-  }
-
   size_t GetNumberOfStackMaps() const {
     return region_.LoadUnaligned<uint32_t>(kNumberOfStackMapsOffset);
   }
@@ -977,37 +1044,30 @@ class CodeInfo {
     region_.StoreUnaligned<uint32_t>(kNumberOfStackMapsOffset, number_of_stack_maps);
   }
 
-  // Get the size of one stack map of this CodeInfo object, in bytes.
-  // All stack maps of a CodeInfo have the same size.
-  size_t StackMapSize() const {
-    return StackMap::ComputeStackMapSizeInternal(GetStackMaskSize(),
-                                                 NumberOfBytesForInlineInfo(),
-                                                 NumberOfBytesForDexRegisterMap(),
-                                                 NumberOfBytesForDexPc(),
-                                                 NumberOfBytesForNativePc(),
-                                                 NumberOfBytesForRegisterMask());
-  }
-
   // Get the size all the stack maps of this CodeInfo object, in bytes.
-  size_t GetStackMapsSize() const {
-    return StackMapSize() * GetNumberOfStackMaps();
+  size_t GetStackMapsSize(const StackMapEncoding& encoding) const {
+    return encoding.ComputeStackMapSize() * GetNumberOfStackMaps();
   }
 
-  uint32_t GetDexRegisterLocationCatalogOffset() const {
-    return GetStackMapsOffset() + GetStackMapsSize();
+  uint32_t GetDexRegisterLocationCatalogOffset(const StackMapEncoding& encoding) const {
+    return GetStackMapsOffset() + GetStackMapsSize(encoding);
   }
 
-  size_t GetDexRegisterMapsOffset() const {
-    return GetDexRegisterLocationCatalogOffset() + GetDexRegisterLocationCatalogSize();
+  size_t GetDexRegisterMapsOffset(const StackMapEncoding& encoding) const {
+    return GetDexRegisterLocationCatalogOffset(encoding)
+         + GetDexRegisterLocationCatalogSize(encoding);
   }
 
   uint32_t GetStackMapsOffset() const {
     return kFixedSize;
   }
 
-  DexRegisterMap GetDexRegisterMapOf(StackMap stack_map, uint32_t number_of_dex_registers) const {
-    DCHECK(stack_map.HasDexRegisterMap(*this));
-    uint32_t offset = GetDexRegisterMapsOffset() + stack_map.GetDexRegisterMapOffset(*this);
+  DexRegisterMap GetDexRegisterMapOf(StackMap stack_map,
+                                     const StackMapEncoding& encoding,
+                                     uint32_t number_of_dex_registers) const {
+    DCHECK(stack_map.HasDexRegisterMap(encoding));
+    uint32_t offset = GetDexRegisterMapsOffset(encoding)
+                      + stack_map.GetDexRegisterMapOffset(encoding);
     size_t size = ComputeDexRegisterMapSizeOf(offset, number_of_dex_registers);
     return DexRegisterMap(region_.Subregion(offset, size));
   }
@@ -1015,37 +1075,40 @@ class CodeInfo {
   // Return the `DexRegisterMap` pointed by `inline_info` at depth `depth`.
   DexRegisterMap GetDexRegisterMapAtDepth(uint8_t depth,
                                           InlineInfo inline_info,
+                                          const StackMapEncoding& encoding,
                                           uint32_t number_of_dex_registers) const {
     DCHECK(inline_info.HasDexRegisterMapAtDepth(depth));
-    uint32_t offset =
-        GetDexRegisterMapsOffset() + inline_info.GetDexRegisterMapOffsetAtDepth(depth);
+    uint32_t offset = GetDexRegisterMapsOffset(encoding)
+                      + inline_info.GetDexRegisterMapOffsetAtDepth(depth);
     size_t size = ComputeDexRegisterMapSizeOf(offset, number_of_dex_registers);
     return DexRegisterMap(region_.Subregion(offset, size));
   }
 
-  InlineInfo GetInlineInfoOf(StackMap stack_map) const {
-    DCHECK(stack_map.HasInlineInfo(*this));
-    uint32_t offset = stack_map.GetInlineDescriptorOffset(*this) + GetDexRegisterMapsOffset();
+  InlineInfo GetInlineInfoOf(StackMap stack_map, const StackMapEncoding& encoding) const {
+    DCHECK(stack_map.HasInlineInfo(encoding));
+    uint32_t offset = stack_map.GetInlineDescriptorOffset(encoding)
+                      + GetDexRegisterMapsOffset(encoding);
     uint8_t depth = region_.LoadUnaligned<uint8_t>(offset);
     return InlineInfo(region_.Subregion(offset,
         InlineInfo::kFixedSize + depth * InlineInfo::SingleEntrySize()));
   }
 
-  StackMap GetStackMapForDexPc(uint32_t dex_pc) const {
+  StackMap GetStackMapForDexPc(uint32_t dex_pc, const StackMapEncoding& encoding) const {
     for (size_t i = 0, e = GetNumberOfStackMaps(); i < e; ++i) {
-      StackMap stack_map = GetStackMapAt(i);
-      if (stack_map.GetDexPc(*this) == dex_pc) {
+      StackMap stack_map = GetStackMapAt(i, encoding);
+      if (stack_map.GetDexPc(encoding) == dex_pc) {
         return stack_map;
       }
     }
     return StackMap();
   }
 
-  StackMap GetStackMapForNativePcOffset(uint32_t native_pc_offset) const {
+  StackMap GetStackMapForNativePcOffset(uint32_t native_pc_offset,
+                                        const StackMapEncoding& encoding) const {
     // TODO: stack maps are sorted by native pc, we can do a binary search.
     for (size_t i = 0, e = GetNumberOfStackMaps(); i < e; ++i) {
-      StackMap stack_map = GetStackMapAt(i);
-      if (stack_map.GetNativePcOffset(*this) == native_pc_offset) {
+      StackMap stack_map = GetStackMapAt(i, encoding);
+      if (stack_map.GetNativePcOffset(encoding) == native_pc_offset) {
         return stack_map;
       }
     }
@@ -1081,10 +1144,10 @@ class CodeInfo {
   static constexpr int kNativePcBitOffset = kDexPcBitOffset + 3;
   static constexpr int kRegisterMaskBitOffset = kNativePcBitOffset + 3;
 
-  MemoryRegion GetStackMaps() const {
+  MemoryRegion GetStackMaps(const StackMapEncoding& encoding) const {
     return region_.size() == 0
         ? MemoryRegion()
-        : region_.Subregion(GetStackMapsOffset(), GetStackMapsSize());
+        : region_.Subregion(GetStackMapsOffset(), GetStackMapsSize(encoding));
   }
 
   // Compute the size of the Dex register map associated to the stack map at
index 67f611e..4203b96 100644 (file)
@@ -2273,9 +2273,10 @@ class ReferenceMapVisitor : public StackVisitor {
         const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(m, sizeof(void*));
         uintptr_t native_pc_offset = m->NativeQuickPcOffset(GetCurrentQuickFramePc(), entry_point);
         CodeInfo code_info = m->GetOptimizedCodeInfo();
-        StackMap map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+        StackMapEncoding encoding = code_info.ExtractEncoding();
+        StackMap map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
         DCHECK(map.IsValid());
-        MemoryRegion mask = map.GetStackMask(code_info);
+        MemoryRegion mask = map.GetStackMask(encoding);
         // Visit stack entries that hold pointers.
         for (size_t i = 0; i < mask.size_in_bits(); ++i) {
           if (mask.LoadBit(i)) {
@@ -2291,7 +2292,7 @@ class ReferenceMapVisitor : public StackVisitor {
           }
         }
         // Visit callee-save registers that hold pointers.
-        uint32_t register_mask = map.GetRegisterMask(code_info);
+        uint32_t register_mask = map.GetRegisterMask(encoding);
         for (size_t i = 0; i < BitSizeOf<uint32_t>(); ++i) {
           if (register_mask & (1 << i)) {
             mirror::Object** ref_addr = reinterpret_cast<mirror::Object**>(GetGPRAddress(i));