Compress the Dex register maps built by the optimizing compiler.
- Replace the current list-based (fixed-size) Dex register
encoding in stack maps emitted by the optimizing compiler
with another list-based variable-size Dex register
encoding compressing short locations on 1 byte (3 bits for
the location kind, 5 bits for the value); other (large)
values remain encoded on 5 bytes.
- In addition, use slot offsets instead of byte offsets to
encode the location of Dex registers placed in stack
slots at small offsets, as it enables more values to use
the short (1-byte wide) encoding instead of the large
(5-byte wide) one.
- Rename art::DexRegisterMap::LocationKind as
art::DexRegisterLocation::Kind, turn it into a
strongly-typed enum based on a uint8_t, and extend it to
support new kinds (kInStackLargeOffset and
kConstantLargeValue).
- Move art::DexRegisterEntry from
compiler/optimizing/stack_map_stream.h to
runtime/stack_map.h and rename it as
art::DexRegisterLocation.
- Adjust art::StackMapStream,
art::CodeGenerator::RecordPcInfo,
art::CheckReferenceMapVisitor::CheckOptimizedMethod,
art::StackVisitor::GetVRegFromOptimizedCode, and
art::StackVisitor::SetVRegFromOptimizedCode.
- Implement unaligned memory accesses in art::MemoryRegion.
- Use them to manipulate data in Dex register maps.
- Adjust oatdump to support the new Dex register encoding.
- Update compiler/optimizing/stack_map_test.cc.
Change-Id: Icefaa2e2b36b3c80bb1b882fe7ea2f77ba85c505
diff --git a/compiler/optimizing/stack_map_test.cc b/compiler/optimizing/stack_map_test.cc
index 5b02510..3a5f806 100644
--- a/compiler/optimizing/stack_map_test.cc
+++ b/compiler/optimizing/stack_map_test.cc
@@ -22,7 +22,7 @@
namespace art {
-bool SameBits(MemoryRegion region, const BitVector& bit_vector) {
+static bool SameBits(MemoryRegion region, const BitVector& bit_vector) {
for (size_t i = 0; i < region.size_in_bits(); ++i) {
if (region.LoadBit(i) != bit_vector.IsBitSet(i)) {
return false;
@@ -31,9 +31,9 @@
return true;
}
-size_t ComputeDexRegisterMapSize(size_t number_of_dex_registers) {
- return DexRegisterMap::kFixedSize
- + number_of_dex_registers * DexRegisterMap::SingleEntrySize();
+static size_t ComputeDexRegisterMapSize(const DexRegisterMap& dex_registers,
+ size_t number_of_dex_registers) {
+ return dex_registers.FindLocationOffset(number_of_dex_registers);
}
TEST(StackMapTest, Test1) {
@@ -44,8 +44,8 @@
ArenaBitVector sp_mask(&arena, 0, false);
size_t number_of_dex_registers = 2;
stream.AddStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
- stream.AddDexRegisterEntry(DexRegisterMap::kInStack, 0);
- stream.AddDexRegisterEntry(DexRegisterMap::kConstant, -2);
+ stream.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, 0);
+ stream.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, -2);
size_t size = stream.ComputeNeededSize();
void* memory = arena.Alloc(size, kArenaAllocMisc);
@@ -67,14 +67,17 @@
ASSERT_TRUE(SameBits(stack_mask, sp_mask));
ASSERT_TRUE(stack_map.HasDexRegisterMap());
- DexRegisterMap dex_registers =
- code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
- ASSERT_EQ(16u, dex_registers.Size());
- ASSERT_EQ(16u, ComputeDexRegisterMapSize(number_of_dex_registers));
- ASSERT_EQ(DexRegisterMap::kInStack, dex_registers.GetLocationKind(0));
- ASSERT_EQ(DexRegisterMap::kConstant, dex_registers.GetLocationKind(1));
- ASSERT_EQ(0, dex_registers.GetValue(0));
- ASSERT_EQ(-2, dex_registers.GetValue(1));
+ DexRegisterMap dex_registers = code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+ ASSERT_EQ(6u, dex_registers.Size());
+ ASSERT_EQ(6u, ComputeDexRegisterMapSize(dex_registers, number_of_dex_registers));
+ DexRegisterLocation location0 = dex_registers.GetLocationKindAndValue(0);
+ DexRegisterLocation location1 = dex_registers.GetLocationKindAndValue(1);
+ ASSERT_EQ(DexRegisterLocation::Kind::kInStack, location0.GetKind());
+ ASSERT_EQ(DexRegisterLocation::Kind::kConstant, location1.GetKind());
+ ASSERT_EQ(DexRegisterLocation::Kind::kInStack, location0.GetInternalKind());
+ ASSERT_EQ(DexRegisterLocation::Kind::kConstantLargeValue, location1.GetInternalKind());
+ ASSERT_EQ(0, location0.GetValue());
+ ASSERT_EQ(-2, location1.GetValue());
ASSERT_FALSE(stack_map.HasInlineInfo());
}
@@ -89,8 +92,8 @@
sp_mask1.SetBit(4);
size_t number_of_dex_registers = 2;
stream.AddStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 2);
- stream.AddDexRegisterEntry(DexRegisterMap::kInStack, 0);
- stream.AddDexRegisterEntry(DexRegisterMap::kConstant, -2);
+ stream.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, 0);
+ stream.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, -2);
stream.AddInlineInfoEntry(42);
stream.AddInlineInfoEntry(82);
@@ -98,8 +101,8 @@
sp_mask2.SetBit(3);
sp_mask1.SetBit(8);
stream.AddStackMapEntry(1, 128, 0xFF, &sp_mask2, number_of_dex_registers, 0);
- stream.AddDexRegisterEntry(DexRegisterMap::kInRegister, 18);
- stream.AddDexRegisterEntry(DexRegisterMap::kInFpuRegister, 3);
+ stream.AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister, 18);
+ stream.AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister, 3);
size_t size = stream.ComputeNeededSize();
void* memory = arena.Alloc(size, kArenaAllocMisc);
@@ -111,54 +114,66 @@
ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
// 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());
- ASSERT_EQ(64u, stack_map.GetNativePcOffset());
- ASSERT_EQ(0x3u, stack_map.GetRegisterMask());
+ {
+ 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());
+ ASSERT_EQ(64u, stack_map.GetNativePcOffset());
+ ASSERT_EQ(0x3u, stack_map.GetRegisterMask());
- MemoryRegion stack_mask = stack_map.GetStackMask();
- ASSERT_TRUE(SameBits(stack_mask, sp_mask1));
+ MemoryRegion stack_mask = stack_map.GetStackMask();
+ ASSERT_TRUE(SameBits(stack_mask, sp_mask1));
- ASSERT_TRUE(stack_map.HasDexRegisterMap());
- DexRegisterMap dex_registers =
- code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
- ASSERT_EQ(16u, dex_registers.Size());
- ASSERT_EQ(16u, ComputeDexRegisterMapSize(number_of_dex_registers));
- ASSERT_EQ(DexRegisterMap::kInStack, dex_registers.GetLocationKind(0));
- ASSERT_EQ(DexRegisterMap::kConstant, dex_registers.GetLocationKind(1));
- ASSERT_EQ(0, dex_registers.GetValue(0));
- ASSERT_EQ(-2, dex_registers.GetValue(1));
+ ASSERT_TRUE(stack_map.HasDexRegisterMap());
+ DexRegisterMap dex_registers =
+ code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+ ASSERT_EQ(6u, dex_registers.Size());
+ ASSERT_EQ(6u, ComputeDexRegisterMapSize(dex_registers, number_of_dex_registers));
+ DexRegisterLocation location0 = dex_registers.GetLocationKindAndValue(0);
+ DexRegisterLocation location1 = dex_registers.GetLocationKindAndValue(1);
+ ASSERT_EQ(DexRegisterLocation::Kind::kInStack, location0.GetKind());
+ ASSERT_EQ(DexRegisterLocation::Kind::kConstant, location1.GetKind());
+ ASSERT_EQ(DexRegisterLocation::Kind::kInStack, location0.GetInternalKind());
+ ASSERT_EQ(DexRegisterLocation::Kind::kConstantLargeValue, location1.GetInternalKind());
+ ASSERT_EQ(0, location0.GetValue());
+ ASSERT_EQ(-2, location1.GetValue());
- ASSERT_TRUE(stack_map.HasInlineInfo());
- InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
- ASSERT_EQ(2u, inline_info.GetDepth());
- ASSERT_EQ(42u, inline_info.GetMethodReferenceIndexAtDepth(0));
- ASSERT_EQ(82u, inline_info.GetMethodReferenceIndexAtDepth(1));
+ ASSERT_TRUE(stack_map.HasInlineInfo());
+ InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
+ ASSERT_EQ(2u, inline_info.GetDepth());
+ ASSERT_EQ(42u, inline_info.GetMethodReferenceIndexAtDepth(0));
+ ASSERT_EQ(82u, inline_info.GetMethodReferenceIndexAtDepth(1));
+ }
// Second stack map.
- 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());
- ASSERT_EQ(128u, stack_map.GetNativePcOffset());
- ASSERT_EQ(0xFFu, stack_map.GetRegisterMask());
+ {
+ 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());
+ ASSERT_EQ(128u, stack_map.GetNativePcOffset());
+ ASSERT_EQ(0xFFu, stack_map.GetRegisterMask());
- stack_mask = stack_map.GetStackMask();
- ASSERT_TRUE(SameBits(stack_mask, sp_mask2));
+ MemoryRegion stack_mask = stack_map.GetStackMask();
+ ASSERT_TRUE(SameBits(stack_mask, sp_mask2));
- ASSERT_TRUE(stack_map.HasDexRegisterMap());
- dex_registers =
- code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
- ASSERT_EQ(16u, dex_registers.Size());
- ASSERT_EQ(16u, ComputeDexRegisterMapSize(number_of_dex_registers));
- ASSERT_EQ(DexRegisterMap::kInRegister, dex_registers.GetLocationKind(0));
- ASSERT_EQ(DexRegisterMap::kInFpuRegister, dex_registers.GetLocationKind(1));
- ASSERT_EQ(18, dex_registers.GetValue(0));
- ASSERT_EQ(3, dex_registers.GetValue(1));
+ ASSERT_TRUE(stack_map.HasDexRegisterMap());
+ DexRegisterMap dex_registers =
+ code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+ ASSERT_EQ(2u, dex_registers.Size());
+ ASSERT_EQ(2u, ComputeDexRegisterMapSize(dex_registers, number_of_dex_registers));
+ DexRegisterLocation location0 = dex_registers.GetLocationKindAndValue(0);
+ DexRegisterLocation location1 = dex_registers.GetLocationKindAndValue(1);
+ ASSERT_EQ(DexRegisterLocation::Kind::kInRegister, location0.GetKind());
+ ASSERT_EQ(DexRegisterLocation::Kind::kInFpuRegister, location1.GetKind());
+ ASSERT_EQ(DexRegisterLocation::Kind::kInRegister, location0.GetInternalKind());
+ ASSERT_EQ(DexRegisterLocation::Kind::kInFpuRegister, location1.GetInternalKind());
+ ASSERT_EQ(18, location0.GetValue());
+ ASSERT_EQ(3, location1.GetValue());
- ASSERT_FALSE(stack_map.HasInlineInfo());
+ ASSERT_FALSE(stack_map.HasInlineInfo());
+ }
}
} // namespace art