diff options
Diffstat (limited to 'compiler/optimizing/stack_map_test.cc')
-rw-r--r-- | compiler/optimizing/stack_map_test.cc | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/compiler/optimizing/stack_map_test.cc b/compiler/optimizing/stack_map_test.cc index bd0aa6dea7..041695187b 100644 --- a/compiler/optimizing/stack_map_test.cc +++ b/compiler/optimizing/stack_map_test.cc @@ -410,6 +410,100 @@ TEST(StackMapTest, Test2) { } } +TEST(StackMapTest, TestDeduplicateInlineInfoDexRegisterMap) { + ArenaPool pool; + ArenaAllocator arena(&pool); + StackMapStream stream(&arena, kRuntimeISA); + ArtMethod art_method; + + ArenaBitVector sp_mask1(&arena, 0, true); + sp_mask1.SetBit(2); + sp_mask1.SetBit(4); + const size_t number_of_dex_registers = 2; + const size_t number_of_dex_registers_in_inline_info = 2; + stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 1); + stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location. + stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location. + stream.BeginInlineInfoEntry(&art_method, 3, number_of_dex_registers_in_inline_info); + stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location. + stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location. + stream.EndInlineInfoEntry(); + stream.EndStackMapEntry(); + + size_t size = stream.PrepareForFillIn(); + void* memory = arena.Alloc(size, kArenaAllocMisc); + MemoryRegion region(memory, size); + stream.FillIn(region); + + CodeInfo code_info(region); + CodeInfoEncoding encoding = code_info.ExtractEncoding(); + ASSERT_EQ(1u, code_info.GetNumberOfStackMaps(encoding)); + + uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding); + ASSERT_EQ(2u, number_of_catalog_entries); + DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding); + // The Dex register location catalog contains: + // - one 1-byte short Dex register locations, and + // - one 5-byte large Dex register location. + const size_t expected_location_catalog_size = 1u + 5u; + ASSERT_EQ(expected_location_catalog_size, location_catalog.Size()); + + // First stack map. + { + 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.stack_map.encoding)); + ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map.encoding, kRuntimeISA)); + ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(encoding, stack_map)); + + ASSERT_TRUE(CheckStackMask(code_info, encoding, stack_map, sp_mask1)); + + ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map.encoding)); + DexRegisterMap map(code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers)); + ASSERT_TRUE(map.IsDexRegisterLive(0)); + ASSERT_TRUE(map.IsDexRegisterLive(1)); + ASSERT_EQ(2u, map.GetNumberOfLiveDexRegisters(number_of_dex_registers)); + // The Dex register map contains: + // - one 1-byte live bit mask, and + // - one 1-byte set of location catalog entry indices composed of two 2-bit values. + size_t expected_map_size = 1u + 1u; + ASSERT_EQ(expected_map_size, map.Size()); + + ASSERT_EQ(Kind::kInStack, map.GetLocationKind(0, number_of_dex_registers, code_info, encoding)); + ASSERT_EQ(Kind::kConstant, + map.GetLocationKind(1, number_of_dex_registers, code_info, encoding)); + ASSERT_EQ(Kind::kInStack, + map.GetLocationInternalKind(0, number_of_dex_registers, code_info, encoding)); + ASSERT_EQ(Kind::kConstantLargeValue, + map.GetLocationInternalKind(1, number_of_dex_registers, code_info, encoding)); + ASSERT_EQ(0, map.GetStackOffsetInBytes(0, number_of_dex_registers, code_info, encoding)); + ASSERT_EQ(-2, map.GetConstant(1, number_of_dex_registers, code_info, encoding)); + + const size_t index0 = + map.GetLocationCatalogEntryIndex(0, number_of_dex_registers, number_of_catalog_entries); + const size_t index1 = + map.GetLocationCatalogEntryIndex(1, number_of_dex_registers, number_of_catalog_entries); + ASSERT_EQ(0u, index0); + ASSERT_EQ(1u, index1); + DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0); + DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1); + ASSERT_EQ(Kind::kInStack, location0.GetKind()); + ASSERT_EQ(Kind::kConstant, location1.GetKind()); + ASSERT_EQ(Kind::kInStack, location0.GetInternalKind()); + ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind()); + ASSERT_EQ(0, location0.GetValue()); + ASSERT_EQ(-2, location1.GetValue()); + + // Test that the inline info dex register map deduplicated to the same offset as the stack map + // one. + ASSERT_TRUE(stack_map.HasInlineInfo(encoding.stack_map.encoding)); + InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding); + EXPECT_EQ(inline_info.GetDexRegisterMapOffsetAtDepth(encoding.inline_info.encoding, 0), + stack_map.GetDexRegisterMapOffset(encoding.stack_map.encoding)); + } +} + TEST(StackMapTest, TestNonLiveDexRegisters) { ArenaPool pool; ArenaAllocator arena(&pool); |