blob: 62c00b0a223abe9b2befe01f0572c640a1a5a72d [file] [log] [blame]
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "stack_map.h"
Mathieu Chartiere5d80f82015-10-15 17:47:48 -070018
Nicolas Geoffray5d37c152017-01-12 13:25:19 +000019#include "art_method.h"
Mathieu Chartiere5d80f82015-10-15 17:47:48 -070020#include "base/arena_bit_vector.h"
Vladimir Markoe2727152019-10-10 10:46:42 +010021#include "base/macros.h"
David Sehr3215fff2018-04-03 17:10:12 -070022#include "base/malloc_arena_pool.h"
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010023#include "stack_map_stream.h"
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010024
25#include "gtest/gtest.h"
26
Vladimir Markoe2727152019-10-10 10:46:42 +010027namespace art HIDDEN {
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010028
David Srbecky09ed0982016-02-12 21:58:43 +000029// Check that the stack mask of given stack map is identical
30// to the given bit vector. Returns true if they are same.
31static bool CheckStackMask(
David Srbecky45aa5982016-03-18 02:15:09 +000032 const CodeInfo& code_info,
David Srbecky09ed0982016-02-12 21:58:43 +000033 const StackMap& stack_map,
David Srbecky09ed0982016-02-12 21:58:43 +000034 const BitVector& bit_vector) {
David Srbecky052f8ca2018-04-26 15:42:54 +010035 BitMemoryRegion stack_mask = code_info.GetStackMaskOf(stack_map);
David Srbecky4b59d102018-05-29 21:46:10 +000036 if (bit_vector.GetNumberOfBits() > stack_mask.size_in_bits()) {
David Srbecky09ed0982016-02-12 21:58:43 +000037 return false;
38 }
David Srbecky4b59d102018-05-29 21:46:10 +000039 for (size_t i = 0; i < stack_mask.size_in_bits(); ++i) {
David Srbecky45aa5982016-03-18 02:15:09 +000040 if (stack_mask.LoadBit(i) != bit_vector.IsBitSet(i)) {
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010041 return false;
42 }
43 }
44 return true;
45}
46
Roland Levillaina552e1c2015-03-26 15:01:03 +000047using Kind = DexRegisterLocation::Kind;
48
David Srbeckyd775f962018-05-30 18:12:52 +010049constexpr static uint32_t kPcAlign = GetInstructionSetInstructionAlignment(kRuntimeISA);
50
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010051TEST(StackMapTest, Test1) {
David Sehr3215fff2018-04-03 17:10:12 -070052 MallocArenaPool pool;
Vladimir Marko174b2e22017-10-12 13:34:49 +010053 ArenaStack arena_stack(&pool);
54 ScopedArenaAllocator allocator(&arena_stack);
Vladimir Marko69d310e2017-10-09 14:12:23 +010055 StackMapStream stream(&allocator, kRuntimeISA);
David Srbeckyf6ba5b32018-06-23 22:05:49 +010056 stream.BeginMethod(32, 0, 0, 2);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010057
Vladimir Marko69d310e2017-10-09 14:12:23 +010058 ArenaBitVector sp_mask(&allocator, 0, false);
Roland Levillain12baf472015-03-05 12:41:42 +000059 size_t number_of_dex_registers = 2;
David Srbeckyf6ba5b32018-06-23 22:05:49 +010060 stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +010061 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
62 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Short location.
Calin Juravle4f46ac52015-04-23 18:47:21 +010063 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010064
Nicolas Geoffraybf5f0f32019-03-05 15:41:50 +000065 stream.EndMethod();
David Srbeckye7a91942018-08-01 17:23:53 +010066 ScopedArenaVector<uint8_t> memory = stream.Encode();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010067
David Srbeckye7a91942018-08-01 17:23:53 +010068 CodeInfo code_info(memory.data());
David Srbecky052f8ca2018-04-26 15:42:54 +010069 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010070
David Srbecky052f8ca2018-04-26 15:42:54 +010071 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
David Srbecky09ed0982016-02-12 21:58:43 +000072 ASSERT_EQ(2u, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +000073
David Srbecky052f8ca2018-04-26 15:42:54 +010074 StackMap stack_map = code_info.GetStackMapAt(0);
75 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
David Srbeckyd775f962018-05-30 18:12:52 +010076 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
David Srbecky052f8ca2018-04-26 15:42:54 +010077 ASSERT_EQ(0u, stack_map.GetDexPc());
David Srbeckyd775f962018-05-30 18:12:52 +010078 ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
David Srbecky052f8ca2018-04-26 15:42:54 +010079 ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(stack_map));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010080
David Srbecky052f8ca2018-04-26 15:42:54 +010081 ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010082
David Srbecky052f8ca2018-04-26 15:42:54 +010083 ASSERT_TRUE(stack_map.HasDexRegisterMap());
David Srbeckyfd89b072018-06-03 12:00:22 +010084 DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
85 ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
David Srbeckye1402122018-06-13 18:20:45 +010086 ASSERT_TRUE(dex_register_map[0].IsLive());
87 ASSERT_TRUE(dex_register_map[1].IsLive());
David Srbecky71ec1cc2018-05-18 15:57:25 +010088 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters());
Roland Levillaina552e1c2015-03-26 15:01:03 +000089
David Srbeckye1402122018-06-13 18:20:45 +010090 ASSERT_EQ(Kind::kInStack, dex_register_map[0].GetKind());
91 ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind());
92 ASSERT_EQ(0, dex_register_map[0].GetStackOffsetInBytes());
93 ASSERT_EQ(-2, dex_register_map[1].GetConstant());
Roland Levillaina552e1c2015-03-26 15:01:03 +000094
David Srbecky71ec1cc2018-05-18 15:57:25 +010095 DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(0);
96 DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(1);
Roland Levillaina552e1c2015-03-26 15:01:03 +000097 ASSERT_EQ(Kind::kInStack, location0.GetKind());
98 ASSERT_EQ(Kind::kConstant, location1.GetKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +000099 ASSERT_EQ(0, location0.GetValue());
100 ASSERT_EQ(-2, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000101
David Srbecky052f8ca2018-04-26 15:42:54 +0100102 ASSERT_FALSE(stack_map.HasInlineInfo());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100103}
104
105TEST(StackMapTest, Test2) {
David Sehr3215fff2018-04-03 17:10:12 -0700106 MallocArenaPool pool;
Vladimir Marko174b2e22017-10-12 13:34:49 +0100107 ArenaStack arena_stack(&pool);
108 ScopedArenaAllocator allocator(&arena_stack);
Vladimir Marko69d310e2017-10-09 14:12:23 +0100109 StackMapStream stream(&allocator, kRuntimeISA);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100110 stream.BeginMethod(32, 0, 0, 2);
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000111 ArtMethod art_method;
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100112
Vladimir Marko69d310e2017-10-09 14:12:23 +0100113 ArenaBitVector sp_mask1(&allocator, 0, true);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100114 sp_mask1.SetBit(2);
115 sp_mask1.SetBit(4);
Roland Levillain12baf472015-03-05 12:41:42 +0000116 size_t number_of_dex_registers = 2;
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100117 size_t number_of_dex_registers_in_inline_info = 0;
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100118 stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100119 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
120 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000121 stream.BeginInlineInfoEntry(&art_method, 3, number_of_dex_registers_in_inline_info);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100122 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000123 stream.BeginInlineInfoEntry(&art_method, 2, number_of_dex_registers_in_inline_info);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100124 stream.EndInlineInfoEntry();
Calin Juravle4f46ac52015-04-23 18:47:21 +0100125 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100126
Vladimir Marko69d310e2017-10-09 14:12:23 +0100127 ArenaBitVector sp_mask2(&allocator, 0, true);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100128 sp_mask2.SetBit(3);
David Brazdilf10a25f2015-06-02 14:29:52 +0100129 sp_mask2.SetBit(8);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100130 stream.BeginStackMapEntry(1, 128 * kPcAlign, 0xFF, &sp_mask2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100131 stream.AddDexRegisterEntry(Kind::kInRegister, 18); // Short location.
132 stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3); // Short location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100133 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100134
Vladimir Marko69d310e2017-10-09 14:12:23 +0100135 ArenaBitVector sp_mask3(&allocator, 0, true);
David Brazdild9cb68e2015-08-25 13:52:43 +0100136 sp_mask3.SetBit(1);
137 sp_mask3.SetBit(5);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100138 stream.BeginStackMapEntry(2, 192 * kPcAlign, 0xAB, &sp_mask3);
David Brazdild9cb68e2015-08-25 13:52:43 +0100139 stream.AddDexRegisterEntry(Kind::kInRegister, 6); // Short location.
140 stream.AddDexRegisterEntry(Kind::kInRegisterHigh, 8); // Short location.
141 stream.EndStackMapEntry();
142
Vladimir Marko69d310e2017-10-09 14:12:23 +0100143 ArenaBitVector sp_mask4(&allocator, 0, true);
David Brazdild9cb68e2015-08-25 13:52:43 +0100144 sp_mask4.SetBit(6);
145 sp_mask4.SetBit(7);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100146 stream.BeginStackMapEntry(3, 256 * kPcAlign, 0xCD, &sp_mask4);
David Brazdild9cb68e2015-08-25 13:52:43 +0100147 stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3); // Short location, same in stack map 2.
148 stream.AddDexRegisterEntry(Kind::kInFpuRegisterHigh, 1); // Short location.
149 stream.EndStackMapEntry();
150
Nicolas Geoffraybf5f0f32019-03-05 15:41:50 +0000151 stream.EndMethod();
David Srbeckye7a91942018-08-01 17:23:53 +0100152 ScopedArenaVector<uint8_t> memory = stream.Encode();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100153
David Srbeckye7a91942018-08-01 17:23:53 +0100154 CodeInfo code_info(memory.data());
David Srbecky052f8ca2018-04-26 15:42:54 +0100155 ASSERT_EQ(4u, code_info.GetNumberOfStackMaps());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100156
David Srbecky052f8ca2018-04-26 15:42:54 +0100157 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
David Srbecky09ed0982016-02-12 21:58:43 +0000158 ASSERT_EQ(7u, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000159
Roland Levillain12baf472015-03-05 12:41:42 +0000160 // First stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000161 {
David Srbecky052f8ca2018-04-26 15:42:54 +0100162 StackMap stack_map = code_info.GetStackMapAt(0);
163 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
David Srbeckyd775f962018-05-30 18:12:52 +0100164 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
David Srbecky052f8ca2018-04-26 15:42:54 +0100165 ASSERT_EQ(0u, stack_map.GetDexPc());
David Srbeckyd775f962018-05-30 18:12:52 +0100166 ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
David Srbecky052f8ca2018-04-26 15:42:54 +0100167 ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(stack_map));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100168
David Srbecky052f8ca2018-04-26 15:42:54 +0100169 ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask1));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100170
David Srbecky052f8ca2018-04-26 15:42:54 +0100171 ASSERT_TRUE(stack_map.HasDexRegisterMap());
David Srbeckyfd89b072018-06-03 12:00:22 +0100172 DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
173 ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
David Srbeckye1402122018-06-13 18:20:45 +0100174 ASSERT_TRUE(dex_register_map[0].IsLive());
175 ASSERT_TRUE(dex_register_map[1].IsLive());
David Srbecky71ec1cc2018-05-18 15:57:25 +0100176 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000177
David Srbeckye1402122018-06-13 18:20:45 +0100178 ASSERT_EQ(Kind::kInStack, dex_register_map[0].GetKind());
179 ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind());
180 ASSERT_EQ(0, dex_register_map[0].GetStackOffsetInBytes());
181 ASSERT_EQ(-2, dex_register_map[1].GetConstant());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000182
David Srbecky71ec1cc2018-05-18 15:57:25 +0100183 DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(0);
184 DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(1);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000185 ASSERT_EQ(Kind::kInStack, location0.GetKind());
186 ASSERT_EQ(Kind::kConstant, location1.GetKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000187 ASSERT_EQ(0, location0.GetValue());
188 ASSERT_EQ(-2, location1.GetValue());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100189
David Srbecky052f8ca2018-04-26 15:42:54 +0100190 ASSERT_TRUE(stack_map.HasInlineInfo());
David Srbecky93bd3612018-07-02 19:30:18 +0100191 auto inline_infos = code_info.GetInlineInfosOf(stack_map);
192 ASSERT_EQ(2u, inline_infos.size());
193 ASSERT_EQ(3u, inline_infos[0].GetDexPc());
194 ASSERT_EQ(2u, inline_infos[1].GetDexPc());
195 ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
196 ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000197 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100198
Roland Levillain12baf472015-03-05 12:41:42 +0000199 // Second stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000200 {
David Srbecky052f8ca2018-04-26 15:42:54 +0100201 StackMap stack_map = code_info.GetStackMapAt(1);
202 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u)));
David Srbeckyd775f962018-05-30 18:12:52 +0100203 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u * kPcAlign)));
David Srbecky052f8ca2018-04-26 15:42:54 +0100204 ASSERT_EQ(1u, stack_map.GetDexPc());
David Srbeckyd775f962018-05-30 18:12:52 +0100205 ASSERT_EQ(128u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
David Srbecky052f8ca2018-04-26 15:42:54 +0100206 ASSERT_EQ(0xFFu, code_info.GetRegisterMaskOf(stack_map));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100207
David Srbecky052f8ca2018-04-26 15:42:54 +0100208 ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask2));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100209
David Srbecky052f8ca2018-04-26 15:42:54 +0100210 ASSERT_TRUE(stack_map.HasDexRegisterMap());
David Srbeckyfd89b072018-06-03 12:00:22 +0100211 DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
212 ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
David Srbeckye1402122018-06-13 18:20:45 +0100213 ASSERT_TRUE(dex_register_map[0].IsLive());
214 ASSERT_TRUE(dex_register_map[1].IsLive());
David Srbecky71ec1cc2018-05-18 15:57:25 +0100215 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000216
David Srbeckye1402122018-06-13 18:20:45 +0100217 ASSERT_EQ(Kind::kInRegister, dex_register_map[0].GetKind());
218 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map[1].GetKind());
219 ASSERT_EQ(18, dex_register_map[0].GetMachineRegister());
220 ASSERT_EQ(3, dex_register_map[1].GetMachineRegister());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000221
David Srbecky71ec1cc2018-05-18 15:57:25 +0100222 DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(2);
223 DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(3);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000224 ASSERT_EQ(Kind::kInRegister, location0.GetKind());
225 ASSERT_EQ(Kind::kInFpuRegister, location1.GetKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000226 ASSERT_EQ(18, location0.GetValue());
227 ASSERT_EQ(3, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000228
David Srbecky052f8ca2018-04-26 15:42:54 +0100229 ASSERT_FALSE(stack_map.HasInlineInfo());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000230 }
David Brazdild9cb68e2015-08-25 13:52:43 +0100231
232 // Third stack map.
233 {
David Srbecky052f8ca2018-04-26 15:42:54 +0100234 StackMap stack_map = code_info.GetStackMapAt(2);
235 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(2u)));
David Srbeckyd775f962018-05-30 18:12:52 +0100236 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(192u * kPcAlign)));
David Srbecky052f8ca2018-04-26 15:42:54 +0100237 ASSERT_EQ(2u, stack_map.GetDexPc());
David Srbeckyd775f962018-05-30 18:12:52 +0100238 ASSERT_EQ(192u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
David Srbecky052f8ca2018-04-26 15:42:54 +0100239 ASSERT_EQ(0xABu, code_info.GetRegisterMaskOf(stack_map));
David Brazdild9cb68e2015-08-25 13:52:43 +0100240
David Srbecky052f8ca2018-04-26 15:42:54 +0100241 ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask3));
David Brazdild9cb68e2015-08-25 13:52:43 +0100242
David Srbecky052f8ca2018-04-26 15:42:54 +0100243 ASSERT_TRUE(stack_map.HasDexRegisterMap());
David Srbeckyfd89b072018-06-03 12:00:22 +0100244 DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
245 ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
David Srbeckye1402122018-06-13 18:20:45 +0100246 ASSERT_TRUE(dex_register_map[0].IsLive());
247 ASSERT_TRUE(dex_register_map[1].IsLive());
David Srbecky71ec1cc2018-05-18 15:57:25 +0100248 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters());
David Brazdild9cb68e2015-08-25 13:52:43 +0100249
David Srbeckye1402122018-06-13 18:20:45 +0100250 ASSERT_EQ(Kind::kInRegister, dex_register_map[0].GetKind());
251 ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map[1].GetKind());
252 ASSERT_EQ(6, dex_register_map[0].GetMachineRegister());
253 ASSERT_EQ(8, dex_register_map[1].GetMachineRegister());
David Brazdild9cb68e2015-08-25 13:52:43 +0100254
David Srbecky71ec1cc2018-05-18 15:57:25 +0100255 DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(4);
256 DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(5);
David Brazdild9cb68e2015-08-25 13:52:43 +0100257 ASSERT_EQ(Kind::kInRegister, location0.GetKind());
258 ASSERT_EQ(Kind::kInRegisterHigh, location1.GetKind());
David Brazdild9cb68e2015-08-25 13:52:43 +0100259 ASSERT_EQ(6, location0.GetValue());
260 ASSERT_EQ(8, location1.GetValue());
261
David Srbecky052f8ca2018-04-26 15:42:54 +0100262 ASSERT_FALSE(stack_map.HasInlineInfo());
David Brazdild9cb68e2015-08-25 13:52:43 +0100263 }
264
265 // Fourth stack map.
266 {
David Srbecky052f8ca2018-04-26 15:42:54 +0100267 StackMap stack_map = code_info.GetStackMapAt(3);
268 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(3u)));
David Srbeckyd775f962018-05-30 18:12:52 +0100269 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(256u * kPcAlign)));
David Srbecky052f8ca2018-04-26 15:42:54 +0100270 ASSERT_EQ(3u, stack_map.GetDexPc());
David Srbeckyd775f962018-05-30 18:12:52 +0100271 ASSERT_EQ(256u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
David Srbecky052f8ca2018-04-26 15:42:54 +0100272 ASSERT_EQ(0xCDu, code_info.GetRegisterMaskOf(stack_map));
David Brazdild9cb68e2015-08-25 13:52:43 +0100273
David Srbecky052f8ca2018-04-26 15:42:54 +0100274 ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask4));
David Brazdild9cb68e2015-08-25 13:52:43 +0100275
David Srbecky052f8ca2018-04-26 15:42:54 +0100276 ASSERT_TRUE(stack_map.HasDexRegisterMap());
David Srbeckyfd89b072018-06-03 12:00:22 +0100277 DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
278 ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
David Srbeckye1402122018-06-13 18:20:45 +0100279 ASSERT_TRUE(dex_register_map[0].IsLive());
280 ASSERT_TRUE(dex_register_map[1].IsLive());
David Srbecky71ec1cc2018-05-18 15:57:25 +0100281 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters());
David Brazdild9cb68e2015-08-25 13:52:43 +0100282
David Srbeckye1402122018-06-13 18:20:45 +0100283 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map[0].GetKind());
284 ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map[1].GetKind());
285 ASSERT_EQ(3, dex_register_map[0].GetMachineRegister());
286 ASSERT_EQ(1, dex_register_map[1].GetMachineRegister());
David Brazdild9cb68e2015-08-25 13:52:43 +0100287
David Srbecky71ec1cc2018-05-18 15:57:25 +0100288 DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(3);
289 DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(6);
David Brazdild9cb68e2015-08-25 13:52:43 +0100290 ASSERT_EQ(Kind::kInFpuRegister, location0.GetKind());
291 ASSERT_EQ(Kind::kInFpuRegisterHigh, location1.GetKind());
David Brazdild9cb68e2015-08-25 13:52:43 +0100292 ASSERT_EQ(3, location0.GetValue());
293 ASSERT_EQ(1, location1.GetValue());
294
David Srbecky052f8ca2018-04-26 15:42:54 +0100295 ASSERT_FALSE(stack_map.HasInlineInfo());
David Brazdild9cb68e2015-08-25 13:52:43 +0100296 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100297}
298
Mathieu Chartier32289082017-02-09 15:57:37 -0800299TEST(StackMapTest, TestDeduplicateInlineInfoDexRegisterMap) {
David Sehr3215fff2018-04-03 17:10:12 -0700300 MallocArenaPool pool;
Vladimir Marko174b2e22017-10-12 13:34:49 +0100301 ArenaStack arena_stack(&pool);
302 ScopedArenaAllocator allocator(&arena_stack);
Vladimir Marko69d310e2017-10-09 14:12:23 +0100303 StackMapStream stream(&allocator, kRuntimeISA);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100304 stream.BeginMethod(32, 0, 0, 2);
Mathieu Chartier32289082017-02-09 15:57:37 -0800305 ArtMethod art_method;
306
Vladimir Marko69d310e2017-10-09 14:12:23 +0100307 ArenaBitVector sp_mask1(&allocator, 0, true);
Mathieu Chartier32289082017-02-09 15:57:37 -0800308 sp_mask1.SetBit(2);
309 sp_mask1.SetBit(4);
310 const size_t number_of_dex_registers = 2;
311 const size_t number_of_dex_registers_in_inline_info = 2;
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100312 stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask1);
Mathieu Chartier32289082017-02-09 15:57:37 -0800313 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
314 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
315 stream.BeginInlineInfoEntry(&art_method, 3, number_of_dex_registers_in_inline_info);
316 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
317 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
318 stream.EndInlineInfoEntry();
319 stream.EndStackMapEntry();
320
Nicolas Geoffraybf5f0f32019-03-05 15:41:50 +0000321 stream.EndMethod();
David Srbeckye7a91942018-08-01 17:23:53 +0100322 ScopedArenaVector<uint8_t> memory = stream.Encode();
Mathieu Chartier32289082017-02-09 15:57:37 -0800323
David Srbeckye7a91942018-08-01 17:23:53 +0100324 CodeInfo code_info(memory.data());
David Srbecky052f8ca2018-04-26 15:42:54 +0100325 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
Mathieu Chartier32289082017-02-09 15:57:37 -0800326
David Srbecky052f8ca2018-04-26 15:42:54 +0100327 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
Mathieu Chartier32289082017-02-09 15:57:37 -0800328 ASSERT_EQ(2u, number_of_catalog_entries);
Mathieu Chartier32289082017-02-09 15:57:37 -0800329
330 // First stack map.
331 {
David Srbecky052f8ca2018-04-26 15:42:54 +0100332 StackMap stack_map = code_info.GetStackMapAt(0);
333 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
David Srbeckyd775f962018-05-30 18:12:52 +0100334 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
David Srbecky052f8ca2018-04-26 15:42:54 +0100335 ASSERT_EQ(0u, stack_map.GetDexPc());
David Srbeckyd775f962018-05-30 18:12:52 +0100336 ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
David Srbecky052f8ca2018-04-26 15:42:54 +0100337 ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(stack_map));
Mathieu Chartier32289082017-02-09 15:57:37 -0800338
David Srbecky052f8ca2018-04-26 15:42:54 +0100339 ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask1));
Mathieu Chartier32289082017-02-09 15:57:37 -0800340
David Srbecky052f8ca2018-04-26 15:42:54 +0100341 ASSERT_TRUE(stack_map.HasDexRegisterMap());
David Srbeckyfd89b072018-06-03 12:00:22 +0100342 DexRegisterMap map(code_info.GetDexRegisterMapOf(stack_map));
343 ASSERT_EQ(number_of_dex_registers, map.size());
David Srbeckye1402122018-06-13 18:20:45 +0100344 ASSERT_TRUE(map[0].IsLive());
345 ASSERT_TRUE(map[1].IsLive());
David Srbecky71ec1cc2018-05-18 15:57:25 +0100346 ASSERT_EQ(2u, map.GetNumberOfLiveDexRegisters());
Mathieu Chartier32289082017-02-09 15:57:37 -0800347
David Srbeckye1402122018-06-13 18:20:45 +0100348 ASSERT_EQ(Kind::kInStack, map[0].GetKind());
349 ASSERT_EQ(Kind::kConstant, map[1].GetKind());
350 ASSERT_EQ(0, map[0].GetStackOffsetInBytes());
351 ASSERT_EQ(-2, map[1].GetConstant());
Mathieu Chartier32289082017-02-09 15:57:37 -0800352
David Srbecky71ec1cc2018-05-18 15:57:25 +0100353 DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(0);
354 DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(1);
Mathieu Chartier32289082017-02-09 15:57:37 -0800355 ASSERT_EQ(Kind::kInStack, location0.GetKind());
356 ASSERT_EQ(Kind::kConstant, location1.GetKind());
Mathieu Chartier32289082017-02-09 15:57:37 -0800357 ASSERT_EQ(0, location0.GetValue());
358 ASSERT_EQ(-2, location1.GetValue());
Mathieu Chartier32289082017-02-09 15:57:37 -0800359 }
360}
361
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000362TEST(StackMapTest, TestNonLiveDexRegisters) {
David Sehr3215fff2018-04-03 17:10:12 -0700363 MallocArenaPool pool;
Vladimir Marko174b2e22017-10-12 13:34:49 +0100364 ArenaStack arena_stack(&pool);
365 ScopedArenaAllocator allocator(&arena_stack);
Vladimir Marko69d310e2017-10-09 14:12:23 +0100366 StackMapStream stream(&allocator, kRuntimeISA);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100367 stream.BeginMethod(32, 0, 0, 2);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000368
Vladimir Marko69d310e2017-10-09 14:12:23 +0100369 ArenaBitVector sp_mask(&allocator, 0, false);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000370 uint32_t number_of_dex_registers = 2;
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100371 stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100372 stream.AddDexRegisterEntry(Kind::kNone, 0); // No location.
373 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100374 stream.EndStackMapEntry();
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000375
Nicolas Geoffraybf5f0f32019-03-05 15:41:50 +0000376 stream.EndMethod();
David Srbeckye7a91942018-08-01 17:23:53 +0100377 ScopedArenaVector<uint8_t> memory = stream.Encode();
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000378
David Srbeckye7a91942018-08-01 17:23:53 +0100379 CodeInfo code_info(memory.data());
David Srbecky052f8ca2018-04-26 15:42:54 +0100380 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000381
David Srbecky052f8ca2018-04-26 15:42:54 +0100382 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
David Srbecky09ed0982016-02-12 21:58:43 +0000383 ASSERT_EQ(1u, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000384
David Srbecky052f8ca2018-04-26 15:42:54 +0100385 StackMap stack_map = code_info.GetStackMapAt(0);
386 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
David Srbeckyd775f962018-05-30 18:12:52 +0100387 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
David Srbecky052f8ca2018-04-26 15:42:54 +0100388 ASSERT_EQ(0u, stack_map.GetDexPc());
David Srbeckyd775f962018-05-30 18:12:52 +0100389 ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
David Srbecky052f8ca2018-04-26 15:42:54 +0100390 ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(stack_map));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000391
David Srbecky052f8ca2018-04-26 15:42:54 +0100392 ASSERT_TRUE(stack_map.HasDexRegisterMap());
David Srbeckyfd89b072018-06-03 12:00:22 +0100393 DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
394 ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
David Srbeckye1402122018-06-13 18:20:45 +0100395 ASSERT_FALSE(dex_register_map[0].IsLive());
396 ASSERT_TRUE(dex_register_map[1].IsLive());
David Srbecky71ec1cc2018-05-18 15:57:25 +0100397 ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000398
David Srbeckye1402122018-06-13 18:20:45 +0100399 ASSERT_EQ(Kind::kNone, dex_register_map[0].GetKind());
400 ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind());
401 ASSERT_EQ(-2, dex_register_map[1].GetConstant());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000402
David Srbecky71ec1cc2018-05-18 15:57:25 +0100403 DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000404 ASSERT_EQ(Kind::kConstant, location1.GetKind());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000405 ASSERT_EQ(-2, location1.GetValue());
406
David Srbecky052f8ca2018-04-26 15:42:54 +0100407 ASSERT_FALSE(stack_map.HasInlineInfo());
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000408}
409
Calin Juravle6ae70962015-03-18 16:31:28 +0000410TEST(StackMapTest, TestShareDexRegisterMap) {
David Sehr3215fff2018-04-03 17:10:12 -0700411 MallocArenaPool pool;
Vladimir Marko174b2e22017-10-12 13:34:49 +0100412 ArenaStack arena_stack(&pool);
413 ScopedArenaAllocator allocator(&arena_stack);
Vladimir Marko69d310e2017-10-09 14:12:23 +0100414 StackMapStream stream(&allocator, kRuntimeISA);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100415 stream.BeginMethod(32, 0, 0, 2);
Calin Juravle6ae70962015-03-18 16:31:28 +0000416
Vladimir Marko69d310e2017-10-09 14:12:23 +0100417 ArenaBitVector sp_mask(&allocator, 0, false);
Calin Juravle6ae70962015-03-18 16:31:28 +0000418 uint32_t number_of_dex_registers = 2;
419 // First stack map.
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100420 stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100421 stream.AddDexRegisterEntry(Kind::kInRegister, 0); // Short location.
422 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100423 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000424 // Second stack map, which should share the same dex register map.
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100425 stream.BeginStackMapEntry(0, 65 * kPcAlign, 0x3, &sp_mask);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100426 stream.AddDexRegisterEntry(Kind::kInRegister, 0); // Short location.
427 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100428 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000429 // Third stack map (doesn't share the dex register map).
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100430 stream.BeginStackMapEntry(0, 66 * kPcAlign, 0x3, &sp_mask);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100431 stream.AddDexRegisterEntry(Kind::kInRegister, 2); // Short location.
432 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100433 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000434
Nicolas Geoffraybf5f0f32019-03-05 15:41:50 +0000435 stream.EndMethod();
David Srbeckye7a91942018-08-01 17:23:53 +0100436 ScopedArenaVector<uint8_t> memory = stream.Encode();
Calin Juravle6ae70962015-03-18 16:31:28 +0000437
David Srbeckye7a91942018-08-01 17:23:53 +0100438 CodeInfo ci(memory.data());
David Brazdilf677ebf2015-05-29 16:29:43 +0100439
Calin Juravle6ae70962015-03-18 16:31:28 +0000440 // Verify first stack map.
David Srbecky052f8ca2018-04-26 15:42:54 +0100441 StackMap sm0 = ci.GetStackMapAt(0);
David Srbeckyfd89b072018-06-03 12:00:22 +0100442 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0);
443 ASSERT_EQ(number_of_dex_registers, dex_registers0.size());
David Srbeckye1402122018-06-13 18:20:45 +0100444 ASSERT_EQ(0, dex_registers0[0].GetMachineRegister());
445 ASSERT_EQ(-2, dex_registers0[1].GetConstant());
Calin Juravle6ae70962015-03-18 16:31:28 +0000446
447 // Verify second stack map.
David Srbecky052f8ca2018-04-26 15:42:54 +0100448 StackMap sm1 = ci.GetStackMapAt(1);
David Srbeckyfd89b072018-06-03 12:00:22 +0100449 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1);
450 ASSERT_EQ(number_of_dex_registers, dex_registers1.size());
David Srbeckye1402122018-06-13 18:20:45 +0100451 ASSERT_EQ(0, dex_registers1[0].GetMachineRegister());
452 ASSERT_EQ(-2, dex_registers1[1].GetConstant());
Calin Juravle6ae70962015-03-18 16:31:28 +0000453
454 // Verify third stack map.
David Srbecky052f8ca2018-04-26 15:42:54 +0100455 StackMap sm2 = ci.GetStackMapAt(2);
David Srbeckyfd89b072018-06-03 12:00:22 +0100456 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2);
457 ASSERT_EQ(number_of_dex_registers, dex_registers2.size());
David Srbeckye1402122018-06-13 18:20:45 +0100458 ASSERT_EQ(2, dex_registers2[0].GetMachineRegister());
459 ASSERT_EQ(-2, dex_registers2[1].GetConstant());
Calin Juravle6ae70962015-03-18 16:31:28 +0000460
David Srbecky6de88332018-06-03 12:00:11 +0100461 // Verify dex register mask offsets.
462 ASSERT_FALSE(sm1.HasDexRegisterMaskIndex()); // No delta.
463 ASSERT_TRUE(sm2.HasDexRegisterMaskIndex()); // Has delta.
Calin Juravle6ae70962015-03-18 16:31:28 +0000464}
465
Roland Levillaina552e1c2015-03-26 15:01:03 +0000466TEST(StackMapTest, TestNoDexRegisterMap) {
David Sehr3215fff2018-04-03 17:10:12 -0700467 MallocArenaPool pool;
Vladimir Marko174b2e22017-10-12 13:34:49 +0100468 ArenaStack arena_stack(&pool);
469 ScopedArenaAllocator allocator(&arena_stack);
Vladimir Marko69d310e2017-10-09 14:12:23 +0100470 StackMapStream stream(&allocator, kRuntimeISA);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100471 stream.BeginMethod(32, 0, 0, 1);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000472
Vladimir Marko69d310e2017-10-09 14:12:23 +0100473 ArenaBitVector sp_mask(&allocator, 0, false);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000474 uint32_t number_of_dex_registers = 0;
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100475 stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask);
Calin Juravle4f46ac52015-04-23 18:47:21 +0100476 stream.EndStackMapEntry();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000477
Nicolas Geoffray012fc4e2016-01-08 15:58:19 +0000478 number_of_dex_registers = 1;
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100479 stream.BeginStackMapEntry(1, 68 * kPcAlign, 0x4, &sp_mask);
David Srbecky71ec1cc2018-05-18 15:57:25 +0100480 stream.AddDexRegisterEntry(Kind::kNone, 0);
Nicolas Geoffray012fc4e2016-01-08 15:58:19 +0000481 stream.EndStackMapEntry();
482
Nicolas Geoffraybf5f0f32019-03-05 15:41:50 +0000483 stream.EndMethod();
David Srbeckye7a91942018-08-01 17:23:53 +0100484 ScopedArenaVector<uint8_t> memory = stream.Encode();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000485
David Srbeckye7a91942018-08-01 17:23:53 +0100486 CodeInfo code_info(memory.data());
David Srbecky052f8ca2018-04-26 15:42:54 +0100487 ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000488
David Srbecky052f8ca2018-04-26 15:42:54 +0100489 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
David Srbecky09ed0982016-02-12 21:58:43 +0000490 ASSERT_EQ(0u, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000491
David Srbecky052f8ca2018-04-26 15:42:54 +0100492 StackMap stack_map = code_info.GetStackMapAt(0);
493 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
David Srbeckyd775f962018-05-30 18:12:52 +0100494 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
David Srbecky052f8ca2018-04-26 15:42:54 +0100495 ASSERT_EQ(0u, stack_map.GetDexPc());
David Srbeckyd775f962018-05-30 18:12:52 +0100496 ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
David Srbecky052f8ca2018-04-26 15:42:54 +0100497 ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(stack_map));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000498
David Srbecky052f8ca2018-04-26 15:42:54 +0100499 ASSERT_FALSE(stack_map.HasDexRegisterMap());
500 ASSERT_FALSE(stack_map.HasInlineInfo());
Nicolas Geoffray012fc4e2016-01-08 15:58:19 +0000501
David Srbecky052f8ca2018-04-26 15:42:54 +0100502 stack_map = code_info.GetStackMapAt(1);
503 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1)));
David Srbeckyd775f962018-05-30 18:12:52 +0100504 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(68 * kPcAlign)));
David Srbecky052f8ca2018-04-26 15:42:54 +0100505 ASSERT_EQ(1u, stack_map.GetDexPc());
David Srbeckyd775f962018-05-30 18:12:52 +0100506 ASSERT_EQ(68u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
David Srbecky052f8ca2018-04-26 15:42:54 +0100507 ASSERT_EQ(0x4u, code_info.GetRegisterMaskOf(stack_map));
Nicolas Geoffray012fc4e2016-01-08 15:58:19 +0000508
David Srbecky71ec1cc2018-05-18 15:57:25 +0100509 ASSERT_TRUE(stack_map.HasDexRegisterMap());
David Srbecky052f8ca2018-04-26 15:42:54 +0100510 ASSERT_FALSE(stack_map.HasInlineInfo());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000511}
512
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100513TEST(StackMapTest, InlineTest) {
David Sehr3215fff2018-04-03 17:10:12 -0700514 MallocArenaPool pool;
Vladimir Marko174b2e22017-10-12 13:34:49 +0100515 ArenaStack arena_stack(&pool);
516 ScopedArenaAllocator allocator(&arena_stack);
Vladimir Marko69d310e2017-10-09 14:12:23 +0100517 StackMapStream stream(&allocator, kRuntimeISA);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100518 stream.BeginMethod(32, 0, 0, 2);
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000519 ArtMethod art_method;
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100520
Vladimir Marko69d310e2017-10-09 14:12:23 +0100521 ArenaBitVector sp_mask1(&allocator, 0, true);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100522 sp_mask1.SetBit(2);
523 sp_mask1.SetBit(4);
524
525 // First stack map.
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100526 stream.BeginStackMapEntry(0, 10 * kPcAlign, 0x3, &sp_mask1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100527 stream.AddDexRegisterEntry(Kind::kInStack, 0);
528 stream.AddDexRegisterEntry(Kind::kConstant, 4);
529
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000530 stream.BeginInlineInfoEntry(&art_method, 2, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100531 stream.AddDexRegisterEntry(Kind::kInStack, 8);
532 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000533 stream.BeginInlineInfoEntry(&art_method, 3, 3);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100534 stream.AddDexRegisterEntry(Kind::kInStack, 16);
535 stream.AddDexRegisterEntry(Kind::kConstant, 20);
536 stream.AddDexRegisterEntry(Kind::kInRegister, 15);
537 stream.EndInlineInfoEntry();
538
539 stream.EndStackMapEntry();
540
541 // Second stack map.
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100542 stream.BeginStackMapEntry(2, 22 * kPcAlign, 0x3, &sp_mask1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100543 stream.AddDexRegisterEntry(Kind::kInStack, 56);
544 stream.AddDexRegisterEntry(Kind::kConstant, 0);
545
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000546 stream.BeginInlineInfoEntry(&art_method, 2, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100547 stream.AddDexRegisterEntry(Kind::kInStack, 12);
548 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000549 stream.BeginInlineInfoEntry(&art_method, 3, 3);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100550 stream.AddDexRegisterEntry(Kind::kInStack, 80);
551 stream.AddDexRegisterEntry(Kind::kConstant, 10);
552 stream.AddDexRegisterEntry(Kind::kInRegister, 5);
553 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000554 stream.BeginInlineInfoEntry(&art_method, 5, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100555 stream.EndInlineInfoEntry();
556
557 stream.EndStackMapEntry();
558
559 // Third stack map.
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100560 stream.BeginStackMapEntry(4, 56 * kPcAlign, 0x3, &sp_mask1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100561 stream.AddDexRegisterEntry(Kind::kNone, 0);
562 stream.AddDexRegisterEntry(Kind::kConstant, 4);
563 stream.EndStackMapEntry();
564
565 // Fourth stack map.
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100566 stream.BeginStackMapEntry(6, 78 * kPcAlign, 0x3, &sp_mask1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100567 stream.AddDexRegisterEntry(Kind::kInStack, 56);
568 stream.AddDexRegisterEntry(Kind::kConstant, 0);
569
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000570 stream.BeginInlineInfoEntry(&art_method, 2, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100571 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000572 stream.BeginInlineInfoEntry(&art_method, 5, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100573 stream.AddDexRegisterEntry(Kind::kInRegister, 2);
574 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000575 stream.BeginInlineInfoEntry(&art_method, 10, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100576 stream.AddDexRegisterEntry(Kind::kNone, 0);
577 stream.AddDexRegisterEntry(Kind::kInRegister, 3);
578 stream.EndInlineInfoEntry();
579
580 stream.EndStackMapEntry();
581
Nicolas Geoffraybf5f0f32019-03-05 15:41:50 +0000582 stream.EndMethod();
David Srbeckye7a91942018-08-01 17:23:53 +0100583 ScopedArenaVector<uint8_t> memory = stream.Encode();
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100584
David Srbeckye7a91942018-08-01 17:23:53 +0100585 CodeInfo ci(memory.data());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100586
587 {
588 // Verify first stack map.
David Srbecky052f8ca2018-04-26 15:42:54 +0100589 StackMap sm0 = ci.GetStackMapAt(0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100590
David Srbeckyfd89b072018-06-03 12:00:22 +0100591 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0);
592 ASSERT_EQ(2u, dex_registers0.size());
David Srbeckye1402122018-06-13 18:20:45 +0100593 ASSERT_EQ(0, dex_registers0[0].GetStackOffsetInBytes());
594 ASSERT_EQ(4, dex_registers0[1].GetConstant());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100595
David Srbecky93bd3612018-07-02 19:30:18 +0100596 auto inline_infos = ci.GetInlineInfosOf(sm0);
597 ASSERT_EQ(2u, inline_infos.size());
598 ASSERT_EQ(2u, inline_infos[0].GetDexPc());
599 ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
600 ASSERT_EQ(3u, inline_infos[1].GetDexPc());
601 ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100602
David Srbecky93bd3612018-07-02 19:30:18 +0100603 DexRegisterMap dex_registers1 = ci.GetInlineDexRegisterMapOf(sm0, inline_infos[0]);
David Srbeckyfd89b072018-06-03 12:00:22 +0100604 ASSERT_EQ(1u, dex_registers1.size());
David Srbeckye1402122018-06-13 18:20:45 +0100605 ASSERT_EQ(8, dex_registers1[0].GetStackOffsetInBytes());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100606
David Srbecky93bd3612018-07-02 19:30:18 +0100607 DexRegisterMap dex_registers2 = ci.GetInlineDexRegisterMapOf(sm0, inline_infos[1]);
David Srbeckyfd89b072018-06-03 12:00:22 +0100608 ASSERT_EQ(3u, dex_registers2.size());
David Srbeckye1402122018-06-13 18:20:45 +0100609 ASSERT_EQ(16, dex_registers2[0].GetStackOffsetInBytes());
610 ASSERT_EQ(20, dex_registers2[1].GetConstant());
611 ASSERT_EQ(15, dex_registers2[2].GetMachineRegister());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100612 }
613
614 {
615 // Verify second stack map.
David Srbecky052f8ca2018-04-26 15:42:54 +0100616 StackMap sm1 = ci.GetStackMapAt(1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100617
David Srbeckyfd89b072018-06-03 12:00:22 +0100618 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm1);
619 ASSERT_EQ(2u, dex_registers0.size());
David Srbeckye1402122018-06-13 18:20:45 +0100620 ASSERT_EQ(56, dex_registers0[0].GetStackOffsetInBytes());
621 ASSERT_EQ(0, dex_registers0[1].GetConstant());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100622
David Srbecky93bd3612018-07-02 19:30:18 +0100623 auto inline_infos = ci.GetInlineInfosOf(sm1);
624 ASSERT_EQ(3u, inline_infos.size());
625 ASSERT_EQ(2u, inline_infos[0].GetDexPc());
626 ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
627 ASSERT_EQ(3u, inline_infos[1].GetDexPc());
628 ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
629 ASSERT_EQ(5u, inline_infos[2].GetDexPc());
630 ASSERT_TRUE(inline_infos[2].EncodesArtMethod());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100631
David Srbecky93bd3612018-07-02 19:30:18 +0100632 DexRegisterMap dex_registers1 = ci.GetInlineDexRegisterMapOf(sm1, inline_infos[0]);
David Srbeckyfd89b072018-06-03 12:00:22 +0100633 ASSERT_EQ(1u, dex_registers1.size());
David Srbeckye1402122018-06-13 18:20:45 +0100634 ASSERT_EQ(12, dex_registers1[0].GetStackOffsetInBytes());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100635
David Srbecky93bd3612018-07-02 19:30:18 +0100636 DexRegisterMap dex_registers2 = ci.GetInlineDexRegisterMapOf(sm1, inline_infos[1]);
David Srbeckyfd89b072018-06-03 12:00:22 +0100637 ASSERT_EQ(3u, dex_registers2.size());
David Srbeckye1402122018-06-13 18:20:45 +0100638 ASSERT_EQ(80, dex_registers2[0].GetStackOffsetInBytes());
639 ASSERT_EQ(10, dex_registers2[1].GetConstant());
640 ASSERT_EQ(5, dex_registers2[2].GetMachineRegister());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100641 }
642
643 {
644 // Verify third stack map.
David Srbecky052f8ca2018-04-26 15:42:54 +0100645 StackMap sm2 = ci.GetStackMapAt(2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100646
David Srbeckyfd89b072018-06-03 12:00:22 +0100647 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm2);
648 ASSERT_EQ(2u, dex_registers0.size());
David Srbeckye1402122018-06-13 18:20:45 +0100649 ASSERT_FALSE(dex_registers0[0].IsLive());
650 ASSERT_EQ(4, dex_registers0[1].GetConstant());
David Srbecky052f8ca2018-04-26 15:42:54 +0100651 ASSERT_FALSE(sm2.HasInlineInfo());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100652 }
653
654 {
655 // Verify fourth stack map.
David Srbecky052f8ca2018-04-26 15:42:54 +0100656 StackMap sm3 = ci.GetStackMapAt(3);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100657
David Srbeckyfd89b072018-06-03 12:00:22 +0100658 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm3);
659 ASSERT_EQ(2u, dex_registers0.size());
David Srbeckye1402122018-06-13 18:20:45 +0100660 ASSERT_EQ(56, dex_registers0[0].GetStackOffsetInBytes());
661 ASSERT_EQ(0, dex_registers0[1].GetConstant());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100662
David Srbecky93bd3612018-07-02 19:30:18 +0100663 auto inline_infos = ci.GetInlineInfosOf(sm3);
664 ASSERT_EQ(3u, inline_infos.size());
665 ASSERT_EQ(2u, inline_infos[0].GetDexPc());
666 ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
667 ASSERT_EQ(5u, inline_infos[1].GetDexPc());
668 ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
669 ASSERT_EQ(10u, inline_infos[2].GetDexPc());
670 ASSERT_TRUE(inline_infos[2].EncodesArtMethod());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100671
David Srbecky93bd3612018-07-02 19:30:18 +0100672 DexRegisterMap dex_registers1 = ci.GetInlineDexRegisterMapOf(sm3, inline_infos[1]);
David Srbeckyfd89b072018-06-03 12:00:22 +0100673 ASSERT_EQ(1u, dex_registers1.size());
David Srbeckye1402122018-06-13 18:20:45 +0100674 ASSERT_EQ(2, dex_registers1[0].GetMachineRegister());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100675
David Srbecky93bd3612018-07-02 19:30:18 +0100676 DexRegisterMap dex_registers2 = ci.GetInlineDexRegisterMapOf(sm3, inline_infos[2]);
David Srbeckyfd89b072018-06-03 12:00:22 +0100677 ASSERT_EQ(2u, dex_registers2.size());
David Srbeckye1402122018-06-13 18:20:45 +0100678 ASSERT_FALSE(dex_registers2[0].IsLive());
679 ASSERT_EQ(3, dex_registers2[1].GetMachineRegister());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100680 }
681}
682
David Srbeckyd02b23f2018-05-29 23:27:22 +0100683TEST(StackMapTest, PackedNativePcTest) {
David Srbecky71ec1cc2018-05-18 15:57:25 +0100684 // Test minimum alignments, and decoding.
David Srbeckyd02b23f2018-05-29 23:27:22 +0100685 uint32_t packed_thumb2 =
686 StackMap::PackNativePc(kThumb2InstructionAlignment, InstructionSet::kThumb2);
687 uint32_t packed_arm64 =
688 StackMap::PackNativePc(kArm64InstructionAlignment, InstructionSet::kArm64);
689 uint32_t packed_x86 =
690 StackMap::PackNativePc(kX86InstructionAlignment, InstructionSet::kX86);
691 uint32_t packed_x86_64 =
692 StackMap::PackNativePc(kX86_64InstructionAlignment, InstructionSet::kX86_64);
693 uint32_t packed_mips =
694 StackMap::PackNativePc(kMipsInstructionAlignment, InstructionSet::kMips);
695 uint32_t packed_mips64 =
696 StackMap::PackNativePc(kMips64InstructionAlignment, InstructionSet::kMips64);
697 EXPECT_EQ(StackMap::UnpackNativePc(packed_thumb2, InstructionSet::kThumb2),
698 kThumb2InstructionAlignment);
699 EXPECT_EQ(StackMap::UnpackNativePc(packed_arm64, InstructionSet::kArm64),
700 kArm64InstructionAlignment);
701 EXPECT_EQ(StackMap::UnpackNativePc(packed_x86, InstructionSet::kX86),
702 kX86InstructionAlignment);
703 EXPECT_EQ(StackMap::UnpackNativePc(packed_x86_64, InstructionSet::kX86_64),
704 kX86_64InstructionAlignment);
705 EXPECT_EQ(StackMap::UnpackNativePc(packed_mips, InstructionSet::kMips),
706 kMipsInstructionAlignment);
707 EXPECT_EQ(StackMap::UnpackNativePc(packed_mips64, InstructionSet::kMips64),
708 kMips64InstructionAlignment);
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800709}
710
David Srbecky45aa5982016-03-18 02:15:09 +0000711TEST(StackMapTest, TestDeduplicateStackMask) {
David Sehr3215fff2018-04-03 17:10:12 -0700712 MallocArenaPool pool;
Vladimir Marko174b2e22017-10-12 13:34:49 +0100713 ArenaStack arena_stack(&pool);
714 ScopedArenaAllocator allocator(&arena_stack);
Vladimir Marko69d310e2017-10-09 14:12:23 +0100715 StackMapStream stream(&allocator, kRuntimeISA);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100716 stream.BeginMethod(32, 0, 0, 0);
David Srbecky45aa5982016-03-18 02:15:09 +0000717
Vladimir Marko69d310e2017-10-09 14:12:23 +0100718 ArenaBitVector sp_mask(&allocator, 0, true);
David Srbecky45aa5982016-03-18 02:15:09 +0000719 sp_mask.SetBit(1);
720 sp_mask.SetBit(4);
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100721 stream.BeginStackMapEntry(0, 4 * kPcAlign, 0x3, &sp_mask);
David Srbecky45aa5982016-03-18 02:15:09 +0000722 stream.EndStackMapEntry();
David Srbeckyf6ba5b32018-06-23 22:05:49 +0100723 stream.BeginStackMapEntry(0, 8 * kPcAlign, 0x3, &sp_mask);
David Srbecky45aa5982016-03-18 02:15:09 +0000724 stream.EndStackMapEntry();
725
Nicolas Geoffraybf5f0f32019-03-05 15:41:50 +0000726 stream.EndMethod();
David Srbeckye7a91942018-08-01 17:23:53 +0100727 ScopedArenaVector<uint8_t> memory = stream.Encode();
David Srbecky45aa5982016-03-18 02:15:09 +0000728
David Srbeckye7a91942018-08-01 17:23:53 +0100729 CodeInfo code_info(memory.data());
David Srbecky052f8ca2018-04-26 15:42:54 +0100730 ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
David Srbecky45aa5982016-03-18 02:15:09 +0000731
David Srbeckyd775f962018-05-30 18:12:52 +0100732 StackMap stack_map1 = code_info.GetStackMapForNativePcOffset(4 * kPcAlign);
733 StackMap stack_map2 = code_info.GetStackMapForNativePcOffset(8 * kPcAlign);
David Srbecky052f8ca2018-04-26 15:42:54 +0100734 EXPECT_EQ(stack_map1.GetStackMaskIndex(),
735 stack_map2.GetStackMaskIndex());
David Srbecky45aa5982016-03-18 02:15:09 +0000736}
737
David Srbeckyb73323c2018-07-15 23:58:44 +0100738TEST(StackMapTest, TestDedupeBitTables) {
739 MallocArenaPool pool;
740 ArenaStack arena_stack(&pool);
741 ScopedArenaAllocator allocator(&arena_stack);
742 StackMapStream stream(&allocator, kRuntimeISA);
743 stream.BeginMethod(32, 0, 0, 2);
744
745 stream.BeginStackMapEntry(0, 64 * kPcAlign);
746 stream.AddDexRegisterEntry(Kind::kInStack, 0);
747 stream.AddDexRegisterEntry(Kind::kConstant, -2);
748 stream.EndStackMapEntry();
749
Nicolas Geoffraybf5f0f32019-03-05 15:41:50 +0000750 stream.EndMethod();
David Srbeckye7a91942018-08-01 17:23:53 +0100751 ScopedArenaVector<uint8_t> memory = stream.Encode();
David Srbeckyb73323c2018-07-15 23:58:44 +0100752
753 std::vector<uint8_t> out;
David Srbeckyd1606412018-07-31 15:05:14 +0100754 CodeInfo::Deduper deduper(&out);
755 size_t deduped1 = deduper.Dedupe(memory.data());
756 size_t deduped2 = deduper.Dedupe(memory.data());
David Srbeckyb73323c2018-07-15 23:58:44 +0100757
758 for (size_t deduped : { deduped1, deduped2 }) {
759 CodeInfo code_info(out.data() + deduped);
760 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
761
762 StackMap stack_map = code_info.GetStackMapAt(0);
763 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
764 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
765 ASSERT_EQ(0u, stack_map.GetDexPc());
766 ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
767
768 ASSERT_TRUE(stack_map.HasDexRegisterMap());
769 DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
770
771 ASSERT_EQ(Kind::kInStack, dex_register_map[0].GetKind());
772 ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind());
773 ASSERT_EQ(0, dex_register_map[0].GetStackOffsetInBytes());
774 ASSERT_EQ(-2, dex_register_map[1].GetConstant());
775 }
776
777 ASSERT_GT(memory.size() * 2, out.size());
778}
779
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100780} // namespace art