xref: /aosp_15_r20/art/compiler/optimizing/stack_map_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "oat/stack_map.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include "art_method.h"
20*795d594fSAndroid Build Coastguard Worker #include "base/arena_bit_vector.h"
21*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
22*795d594fSAndroid Build Coastguard Worker #include "base/malloc_arena_pool.h"
23*795d594fSAndroid Build Coastguard Worker #include "stack_map_stream.h"
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
26*795d594fSAndroid Build Coastguard Worker 
27*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
28*795d594fSAndroid Build Coastguard Worker 
29*795d594fSAndroid Build Coastguard Worker // Check that the stack mask of given stack map is identical
30*795d594fSAndroid Build Coastguard Worker // to the given bit vector. Returns true if they are same.
CheckStackMask(const CodeInfo & code_info,const StackMap & stack_map,const BitVector & bit_vector)31*795d594fSAndroid Build Coastguard Worker static bool CheckStackMask(
32*795d594fSAndroid Build Coastguard Worker     const CodeInfo& code_info,
33*795d594fSAndroid Build Coastguard Worker     const StackMap& stack_map,
34*795d594fSAndroid Build Coastguard Worker     const BitVector& bit_vector) {
35*795d594fSAndroid Build Coastguard Worker   BitMemoryRegion stack_mask = code_info.GetStackMaskOf(stack_map);
36*795d594fSAndroid Build Coastguard Worker   if (bit_vector.GetNumberOfBits() > stack_mask.size_in_bits()) {
37*795d594fSAndroid Build Coastguard Worker     return false;
38*795d594fSAndroid Build Coastguard Worker   }
39*795d594fSAndroid Build Coastguard Worker   for (size_t i = 0; i < stack_mask.size_in_bits(); ++i) {
40*795d594fSAndroid Build Coastguard Worker     if (stack_mask.LoadBit(i) != bit_vector.IsBitSet(i)) {
41*795d594fSAndroid Build Coastguard Worker       return false;
42*795d594fSAndroid Build Coastguard Worker     }
43*795d594fSAndroid Build Coastguard Worker   }
44*795d594fSAndroid Build Coastguard Worker   return true;
45*795d594fSAndroid Build Coastguard Worker }
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker using Kind = DexRegisterLocation::Kind;
48*795d594fSAndroid Build Coastguard Worker 
49*795d594fSAndroid Build Coastguard Worker constexpr static uint32_t kPcAlign = GetInstructionSetInstructionAlignment(kRuntimeISA);
50*795d594fSAndroid Build Coastguard Worker 
TEST(StackMapTest,Test1)51*795d594fSAndroid Build Coastguard Worker TEST(StackMapTest, Test1) {
52*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
53*795d594fSAndroid Build Coastguard Worker   ArenaStack arena_stack(&pool);
54*795d594fSAndroid Build Coastguard Worker   ScopedArenaAllocator allocator(&arena_stack);
55*795d594fSAndroid Build Coastguard Worker   StackMapStream stream(&allocator, kRuntimeISA);
56*795d594fSAndroid Build Coastguard Worker   stream.BeginMethod(/* frame_size_in_bytes= */ 32,
57*795d594fSAndroid Build Coastguard Worker                      /* core_spill_mask= */ 0,
58*795d594fSAndroid Build Coastguard Worker                      /* fp_spill_mask= */ 0,
59*795d594fSAndroid Build Coastguard Worker                      /* num_dex_registers= */ 2,
60*795d594fSAndroid Build Coastguard Worker                      /* baseline= */ false,
61*795d594fSAndroid Build Coastguard Worker                      /* debuggable= */ false);
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask(&allocator, 0, false);
64*795d594fSAndroid Build Coastguard Worker   size_t number_of_dex_registers = 2;
65*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask);
66*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 0);         // Short location.
67*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, -2);       // Short location.
68*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
69*795d594fSAndroid Build Coastguard Worker 
70*795d594fSAndroid Build Coastguard Worker   stream.EndMethod(64 * kPcAlign);
71*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<uint8_t> memory = stream.Encode();
72*795d594fSAndroid Build Coastguard Worker 
73*795d594fSAndroid Build Coastguard Worker   CodeInfo code_info(memory.data());
74*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
75*795d594fSAndroid Build Coastguard Worker 
76*795d594fSAndroid Build Coastguard Worker   uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
77*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(2u, number_of_catalog_entries);
78*795d594fSAndroid Build Coastguard Worker 
79*795d594fSAndroid Build Coastguard Worker   StackMap stack_map = code_info.GetStackMapAt(0);
80*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
81*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
82*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0u, stack_map.GetDexPc());
83*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
84*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(stack_map));
85*795d594fSAndroid Build Coastguard Worker 
86*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask));
87*795d594fSAndroid Build Coastguard Worker 
88*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.HasDexRegisterMap());
89*795d594fSAndroid Build Coastguard Worker   DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
90*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
91*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_register_map[0].IsLive());
92*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_register_map[1].IsLive());
93*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters());
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(Kind::kInStack, dex_register_map[0].GetKind());
96*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind());
97*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0, dex_register_map[0].GetStackOffsetInBytes());
98*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(-2, dex_register_map[1].GetConstant());
99*795d594fSAndroid Build Coastguard Worker 
100*795d594fSAndroid Build Coastguard Worker   DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(0);
101*795d594fSAndroid Build Coastguard Worker   DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(1);
102*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(Kind::kInStack, location0.GetKind());
103*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(Kind::kConstant, location1.GetKind());
104*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0, location0.GetValue());
105*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(-2, location1.GetValue());
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(stack_map.HasInlineInfo());
108*795d594fSAndroid Build Coastguard Worker }
109*795d594fSAndroid Build Coastguard Worker 
TEST(StackMapTest,Test2)110*795d594fSAndroid Build Coastguard Worker TEST(StackMapTest, Test2) {
111*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
112*795d594fSAndroid Build Coastguard Worker   ArenaStack arena_stack(&pool);
113*795d594fSAndroid Build Coastguard Worker   ScopedArenaAllocator allocator(&arena_stack);
114*795d594fSAndroid Build Coastguard Worker   StackMapStream stream(&allocator, kRuntimeISA);
115*795d594fSAndroid Build Coastguard Worker   stream.BeginMethod(/* frame_size_in_bytes= */ 32,
116*795d594fSAndroid Build Coastguard Worker                      /* core_spill_mask= */ 0,
117*795d594fSAndroid Build Coastguard Worker                      /* fp_spill_mask= */ 0,
118*795d594fSAndroid Build Coastguard Worker                      /* num_dex_registers= */ 2,
119*795d594fSAndroid Build Coastguard Worker                      /* baseline= */ false,
120*795d594fSAndroid Build Coastguard Worker                      /* debuggable= */ false);
121*795d594fSAndroid Build Coastguard Worker   ArtMethod art_method;
122*795d594fSAndroid Build Coastguard Worker 
123*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask1(&allocator, 0, true);
124*795d594fSAndroid Build Coastguard Worker   sp_mask1.SetBit(2);
125*795d594fSAndroid Build Coastguard Worker   sp_mask1.SetBit(4);
126*795d594fSAndroid Build Coastguard Worker   size_t number_of_dex_registers = 2;
127*795d594fSAndroid Build Coastguard Worker   size_t number_of_dex_registers_in_inline_info = 0;
128*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask1);
129*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 0);         // Short location.
130*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, -2);       // Large location.
131*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 3, number_of_dex_registers_in_inline_info);
132*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
133*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 2, number_of_dex_registers_in_inline_info);
134*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
135*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
136*795d594fSAndroid Build Coastguard Worker 
137*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask2(&allocator, 0, true);
138*795d594fSAndroid Build Coastguard Worker   sp_mask2.SetBit(3);
139*795d594fSAndroid Build Coastguard Worker   sp_mask2.SetBit(8);
140*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(1, 128 * kPcAlign, 0xFF, &sp_mask2);
141*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInRegister, 18);     // Short location.
142*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3);   // Short location.
143*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
144*795d594fSAndroid Build Coastguard Worker 
145*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask3(&allocator, 0, true);
146*795d594fSAndroid Build Coastguard Worker   sp_mask3.SetBit(1);
147*795d594fSAndroid Build Coastguard Worker   sp_mask3.SetBit(5);
148*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(2, 192 * kPcAlign, 0xAB, &sp_mask3);
149*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInRegister, 6);       // Short location.
150*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInRegisterHigh, 8);   // Short location.
151*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
152*795d594fSAndroid Build Coastguard Worker 
153*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask4(&allocator, 0, true);
154*795d594fSAndroid Build Coastguard Worker   sp_mask4.SetBit(6);
155*795d594fSAndroid Build Coastguard Worker   sp_mask4.SetBit(7);
156*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(3, 256 * kPcAlign, 0xCD, &sp_mask4);
157*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3);      // Short location, same in stack map 2.
158*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInFpuRegisterHigh, 1);  // Short location.
159*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
160*795d594fSAndroid Build Coastguard Worker 
161*795d594fSAndroid Build Coastguard Worker   stream.EndMethod(256 * kPcAlign);
162*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<uint8_t> memory = stream.Encode();
163*795d594fSAndroid Build Coastguard Worker 
164*795d594fSAndroid Build Coastguard Worker   CodeInfo code_info(memory.data());
165*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(4u, code_info.GetNumberOfStackMaps());
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker   uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
168*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(7u, number_of_catalog_entries);
169*795d594fSAndroid Build Coastguard Worker 
170*795d594fSAndroid Build Coastguard Worker   // First stack map.
171*795d594fSAndroid Build Coastguard Worker   {
172*795d594fSAndroid Build Coastguard Worker     StackMap stack_map = code_info.GetStackMapAt(0);
173*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
174*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
175*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0u, stack_map.GetDexPc());
176*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
177*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(stack_map));
178*795d594fSAndroid Build Coastguard Worker 
179*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask1));
180*795d594fSAndroid Build Coastguard Worker 
181*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.HasDexRegisterMap());
182*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
183*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
184*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(dex_register_map[0].IsLive());
185*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(dex_register_map[1].IsLive());
186*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters());
187*795d594fSAndroid Build Coastguard Worker 
188*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInStack, dex_register_map[0].GetKind());
189*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind());
190*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0, dex_register_map[0].GetStackOffsetInBytes());
191*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(-2, dex_register_map[1].GetConstant());
192*795d594fSAndroid Build Coastguard Worker 
193*795d594fSAndroid Build Coastguard Worker     DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(0);
194*795d594fSAndroid Build Coastguard Worker     DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(1);
195*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInStack, location0.GetKind());
196*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kConstant, location1.GetKind());
197*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0, location0.GetValue());
198*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(-2, location1.GetValue());
199*795d594fSAndroid Build Coastguard Worker 
200*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.HasInlineInfo());
201*795d594fSAndroid Build Coastguard Worker     auto inline_infos = code_info.GetInlineInfosOf(stack_map);
202*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, inline_infos.size());
203*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3u, inline_infos[0].GetDexPc());
204*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, inline_infos[1].GetDexPc());
205*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
206*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
207*795d594fSAndroid Build Coastguard Worker   }
208*795d594fSAndroid Build Coastguard Worker 
209*795d594fSAndroid Build Coastguard Worker   // Second stack map.
210*795d594fSAndroid Build Coastguard Worker   {
211*795d594fSAndroid Build Coastguard Worker     StackMap stack_map = code_info.GetStackMapAt(1);
212*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u)));
213*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u * kPcAlign)));
214*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(1u, stack_map.GetDexPc());
215*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(128u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
216*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0xFFu, code_info.GetRegisterMaskOf(stack_map));
217*795d594fSAndroid Build Coastguard Worker 
218*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask2));
219*795d594fSAndroid Build Coastguard Worker 
220*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.HasDexRegisterMap());
221*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
222*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
223*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(dex_register_map[0].IsLive());
224*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(dex_register_map[1].IsLive());
225*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters());
226*795d594fSAndroid Build Coastguard Worker 
227*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInRegister, dex_register_map[0].GetKind());
228*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInFpuRegister, dex_register_map[1].GetKind());
229*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(18, dex_register_map[0].GetMachineRegister());
230*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3, dex_register_map[1].GetMachineRegister());
231*795d594fSAndroid Build Coastguard Worker 
232*795d594fSAndroid Build Coastguard Worker     DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(2);
233*795d594fSAndroid Build Coastguard Worker     DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(3);
234*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInRegister, location0.GetKind());
235*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInFpuRegister, location1.GetKind());
236*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(18, location0.GetValue());
237*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3, location1.GetValue());
238*795d594fSAndroid Build Coastguard Worker 
239*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(stack_map.HasInlineInfo());
240*795d594fSAndroid Build Coastguard Worker   }
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker   // Third stack map.
243*795d594fSAndroid Build Coastguard Worker   {
244*795d594fSAndroid Build Coastguard Worker     StackMap stack_map = code_info.GetStackMapAt(2);
245*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(2u)));
246*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(192u * kPcAlign)));
247*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, stack_map.GetDexPc());
248*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(192u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
249*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0xABu, code_info.GetRegisterMaskOf(stack_map));
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask3));
252*795d594fSAndroid Build Coastguard Worker 
253*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.HasDexRegisterMap());
254*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
255*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
256*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(dex_register_map[0].IsLive());
257*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(dex_register_map[1].IsLive());
258*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters());
259*795d594fSAndroid Build Coastguard Worker 
260*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInRegister, dex_register_map[0].GetKind());
261*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map[1].GetKind());
262*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(6, dex_register_map[0].GetMachineRegister());
263*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(8, dex_register_map[1].GetMachineRegister());
264*795d594fSAndroid Build Coastguard Worker 
265*795d594fSAndroid Build Coastguard Worker     DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(4);
266*795d594fSAndroid Build Coastguard Worker     DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(5);
267*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInRegister, location0.GetKind());
268*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInRegisterHigh, location1.GetKind());
269*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(6, location0.GetValue());
270*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(8, location1.GetValue());
271*795d594fSAndroid Build Coastguard Worker 
272*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(stack_map.HasInlineInfo());
273*795d594fSAndroid Build Coastguard Worker   }
274*795d594fSAndroid Build Coastguard Worker 
275*795d594fSAndroid Build Coastguard Worker   // Fourth stack map.
276*795d594fSAndroid Build Coastguard Worker   {
277*795d594fSAndroid Build Coastguard Worker     StackMap stack_map = code_info.GetStackMapAt(3);
278*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(3u)));
279*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(256u * kPcAlign)));
280*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3u, stack_map.GetDexPc());
281*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(256u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
282*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0xCDu, code_info.GetRegisterMaskOf(stack_map));
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask4));
285*795d594fSAndroid Build Coastguard Worker 
286*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.HasDexRegisterMap());
287*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
288*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
289*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(dex_register_map[0].IsLive());
290*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(dex_register_map[1].IsLive());
291*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters());
292*795d594fSAndroid Build Coastguard Worker 
293*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInFpuRegister, dex_register_map[0].GetKind());
294*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map[1].GetKind());
295*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3, dex_register_map[0].GetMachineRegister());
296*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(1, dex_register_map[1].GetMachineRegister());
297*795d594fSAndroid Build Coastguard Worker 
298*795d594fSAndroid Build Coastguard Worker     DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(3);
299*795d594fSAndroid Build Coastguard Worker     DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(6);
300*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInFpuRegister, location0.GetKind());
301*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInFpuRegisterHigh, location1.GetKind());
302*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3, location0.GetValue());
303*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(1, location1.GetValue());
304*795d594fSAndroid Build Coastguard Worker 
305*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(stack_map.HasInlineInfo());
306*795d594fSAndroid Build Coastguard Worker   }
307*795d594fSAndroid Build Coastguard Worker }
308*795d594fSAndroid Build Coastguard Worker 
TEST(StackMapTest,TestDeduplicateInlineInfoDexRegisterMap)309*795d594fSAndroid Build Coastguard Worker TEST(StackMapTest, TestDeduplicateInlineInfoDexRegisterMap) {
310*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
311*795d594fSAndroid Build Coastguard Worker   ArenaStack arena_stack(&pool);
312*795d594fSAndroid Build Coastguard Worker   ScopedArenaAllocator allocator(&arena_stack);
313*795d594fSAndroid Build Coastguard Worker   StackMapStream stream(&allocator, kRuntimeISA);
314*795d594fSAndroid Build Coastguard Worker   stream.BeginMethod(/* frame_size_in_bytes= */ 32,
315*795d594fSAndroid Build Coastguard Worker                      /* core_spill_mask= */ 0,
316*795d594fSAndroid Build Coastguard Worker                      /* fp_spill_mask= */ 0,
317*795d594fSAndroid Build Coastguard Worker                      /* num_dex_registers= */ 2,
318*795d594fSAndroid Build Coastguard Worker                      /* baseline= */ false,
319*795d594fSAndroid Build Coastguard Worker                      /* debuggable= */ false);
320*795d594fSAndroid Build Coastguard Worker   ArtMethod art_method;
321*795d594fSAndroid Build Coastguard Worker 
322*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask1(&allocator, 0, true);
323*795d594fSAndroid Build Coastguard Worker   sp_mask1.SetBit(2);
324*795d594fSAndroid Build Coastguard Worker   sp_mask1.SetBit(4);
325*795d594fSAndroid Build Coastguard Worker   const size_t number_of_dex_registers = 2;
326*795d594fSAndroid Build Coastguard Worker   const size_t number_of_dex_registers_in_inline_info = 2;
327*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask1);
328*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 0);         // Short location.
329*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, -2);       // Large location.
330*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 3, number_of_dex_registers_in_inline_info);
331*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 0);         // Short location.
332*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, -2);       // Large location.
333*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
334*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
335*795d594fSAndroid Build Coastguard Worker 
336*795d594fSAndroid Build Coastguard Worker   stream.EndMethod(64 * kPcAlign);
337*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<uint8_t> memory = stream.Encode();
338*795d594fSAndroid Build Coastguard Worker 
339*795d594fSAndroid Build Coastguard Worker   CodeInfo code_info(memory.data());
340*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
341*795d594fSAndroid Build Coastguard Worker 
342*795d594fSAndroid Build Coastguard Worker   uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
343*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(2u, number_of_catalog_entries);
344*795d594fSAndroid Build Coastguard Worker 
345*795d594fSAndroid Build Coastguard Worker   // First stack map.
346*795d594fSAndroid Build Coastguard Worker   {
347*795d594fSAndroid Build Coastguard Worker     StackMap stack_map = code_info.GetStackMapAt(0);
348*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
349*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
350*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0u, stack_map.GetDexPc());
351*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
352*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(stack_map));
353*795d594fSAndroid Build Coastguard Worker 
354*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(CheckStackMask(code_info, stack_map, sp_mask1));
355*795d594fSAndroid Build Coastguard Worker 
356*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(stack_map.HasDexRegisterMap());
357*795d594fSAndroid Build Coastguard Worker     DexRegisterMap map(code_info.GetDexRegisterMapOf(stack_map));
358*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(number_of_dex_registers, map.size());
359*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(map[0].IsLive());
360*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(map[1].IsLive());
361*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, map.GetNumberOfLiveDexRegisters());
362*795d594fSAndroid Build Coastguard Worker 
363*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInStack, map[0].GetKind());
364*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kConstant, map[1].GetKind());
365*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0, map[0].GetStackOffsetInBytes());
366*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(-2, map[1].GetConstant());
367*795d594fSAndroid Build Coastguard Worker 
368*795d594fSAndroid Build Coastguard Worker     DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(0);
369*795d594fSAndroid Build Coastguard Worker     DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(1);
370*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kInStack, location0.GetKind());
371*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(Kind::kConstant, location1.GetKind());
372*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0, location0.GetValue());
373*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(-2, location1.GetValue());
374*795d594fSAndroid Build Coastguard Worker   }
375*795d594fSAndroid Build Coastguard Worker }
376*795d594fSAndroid Build Coastguard Worker 
TEST(StackMapTest,TestNonLiveDexRegisters)377*795d594fSAndroid Build Coastguard Worker TEST(StackMapTest, TestNonLiveDexRegisters) {
378*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
379*795d594fSAndroid Build Coastguard Worker   ArenaStack arena_stack(&pool);
380*795d594fSAndroid Build Coastguard Worker   ScopedArenaAllocator allocator(&arena_stack);
381*795d594fSAndroid Build Coastguard Worker   StackMapStream stream(&allocator, kRuntimeISA);
382*795d594fSAndroid Build Coastguard Worker   stream.BeginMethod(/* frame_size_in_bytes= */ 32,
383*795d594fSAndroid Build Coastguard Worker                      /* core_spill_mask= */ 0,
384*795d594fSAndroid Build Coastguard Worker                      /* fp_spill_mask= */ 0,
385*795d594fSAndroid Build Coastguard Worker                      /* num_dex_registers= */ 2,
386*795d594fSAndroid Build Coastguard Worker                      /* baseline= */ false,
387*795d594fSAndroid Build Coastguard Worker                      /* debuggable= */ false);
388*795d594fSAndroid Build Coastguard Worker 
389*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask(&allocator, 0, false);
390*795d594fSAndroid Build Coastguard Worker   uint32_t number_of_dex_registers = 2;
391*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask);
392*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kNone, 0);            // No location.
393*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, -2);       // Large location.
394*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
395*795d594fSAndroid Build Coastguard Worker 
396*795d594fSAndroid Build Coastguard Worker   stream.EndMethod(64 * kPcAlign);
397*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<uint8_t> memory = stream.Encode();
398*795d594fSAndroid Build Coastguard Worker 
399*795d594fSAndroid Build Coastguard Worker   CodeInfo code_info(memory.data());
400*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
401*795d594fSAndroid Build Coastguard Worker 
402*795d594fSAndroid Build Coastguard Worker   uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
403*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(1u, number_of_catalog_entries);
404*795d594fSAndroid Build Coastguard Worker 
405*795d594fSAndroid Build Coastguard Worker   StackMap stack_map = code_info.GetStackMapAt(0);
406*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
407*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
408*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0u, stack_map.GetDexPc());
409*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
410*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(stack_map));
411*795d594fSAndroid Build Coastguard Worker 
412*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.HasDexRegisterMap());
413*795d594fSAndroid Build Coastguard Worker   DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
414*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(number_of_dex_registers, dex_register_map.size());
415*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(dex_register_map[0].IsLive());
416*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(dex_register_map[1].IsLive());
417*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters());
418*795d594fSAndroid Build Coastguard Worker 
419*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(Kind::kNone, dex_register_map[0].GetKind());
420*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind());
421*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(-2, dex_register_map[1].GetConstant());
422*795d594fSAndroid Build Coastguard Worker 
423*795d594fSAndroid Build Coastguard Worker   DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(0);
424*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(Kind::kConstant, location1.GetKind());
425*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(-2, location1.GetValue());
426*795d594fSAndroid Build Coastguard Worker 
427*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(stack_map.HasInlineInfo());
428*795d594fSAndroid Build Coastguard Worker }
429*795d594fSAndroid Build Coastguard Worker 
TEST(StackMapTest,TestShareDexRegisterMap)430*795d594fSAndroid Build Coastguard Worker TEST(StackMapTest, TestShareDexRegisterMap) {
431*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
432*795d594fSAndroid Build Coastguard Worker   ArenaStack arena_stack(&pool);
433*795d594fSAndroid Build Coastguard Worker   ScopedArenaAllocator allocator(&arena_stack);
434*795d594fSAndroid Build Coastguard Worker   StackMapStream stream(&allocator, kRuntimeISA);
435*795d594fSAndroid Build Coastguard Worker   stream.BeginMethod(/* frame_size_in_bytes= */ 32,
436*795d594fSAndroid Build Coastguard Worker                      /* core_spill_mask= */ 0,
437*795d594fSAndroid Build Coastguard Worker                      /* fp_spill_mask= */ 0,
438*795d594fSAndroid Build Coastguard Worker                      /* num_dex_registers= */ 2,
439*795d594fSAndroid Build Coastguard Worker                      /* baseline= */ false,
440*795d594fSAndroid Build Coastguard Worker                      /* debuggable= */ false);
441*795d594fSAndroid Build Coastguard Worker 
442*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask(&allocator, 0, false);
443*795d594fSAndroid Build Coastguard Worker   uint32_t number_of_dex_registers = 2;
444*795d594fSAndroid Build Coastguard Worker   // First stack map.
445*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask);
446*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInRegister, 0);  // Short location.
447*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, -2);   // Large location.
448*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
449*795d594fSAndroid Build Coastguard Worker   // Second stack map, which should share the same dex register map.
450*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 65 * kPcAlign, 0x3, &sp_mask);
451*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInRegister, 0);  // Short location.
452*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, -2);   // Large location.
453*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
454*795d594fSAndroid Build Coastguard Worker   // Third stack map (doesn't share the dex register map).
455*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 66 * kPcAlign, 0x3, &sp_mask);
456*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInRegister, 2);  // Short location.
457*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, -2);   // Large location.
458*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
459*795d594fSAndroid Build Coastguard Worker 
460*795d594fSAndroid Build Coastguard Worker   stream.EndMethod(66 * kPcAlign);
461*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<uint8_t> memory = stream.Encode();
462*795d594fSAndroid Build Coastguard Worker 
463*795d594fSAndroid Build Coastguard Worker   CodeInfo ci(memory.data());
464*795d594fSAndroid Build Coastguard Worker 
465*795d594fSAndroid Build Coastguard Worker   // Verify first stack map.
466*795d594fSAndroid Build Coastguard Worker   StackMap sm0 = ci.GetStackMapAt(0);
467*795d594fSAndroid Build Coastguard Worker   DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0);
468*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(number_of_dex_registers, dex_registers0.size());
469*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0, dex_registers0[0].GetMachineRegister());
470*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(-2, dex_registers0[1].GetConstant());
471*795d594fSAndroid Build Coastguard Worker 
472*795d594fSAndroid Build Coastguard Worker   // Verify second stack map.
473*795d594fSAndroid Build Coastguard Worker   StackMap sm1 = ci.GetStackMapAt(1);
474*795d594fSAndroid Build Coastguard Worker   DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1);
475*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(number_of_dex_registers, dex_registers1.size());
476*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0, dex_registers1[0].GetMachineRegister());
477*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(-2, dex_registers1[1].GetConstant());
478*795d594fSAndroid Build Coastguard Worker 
479*795d594fSAndroid Build Coastguard Worker   // Verify third stack map.
480*795d594fSAndroid Build Coastguard Worker   StackMap sm2 = ci.GetStackMapAt(2);
481*795d594fSAndroid Build Coastguard Worker   DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2);
482*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(number_of_dex_registers, dex_registers2.size());
483*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(2, dex_registers2[0].GetMachineRegister());
484*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(-2, dex_registers2[1].GetConstant());
485*795d594fSAndroid Build Coastguard Worker 
486*795d594fSAndroid Build Coastguard Worker   // Verify dex register mask offsets.
487*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(sm1.HasDexRegisterMaskIndex());  // No delta.
488*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(sm2.HasDexRegisterMaskIndex());  // Has delta.
489*795d594fSAndroid Build Coastguard Worker }
490*795d594fSAndroid Build Coastguard Worker 
TEST(StackMapTest,TestNoDexRegisterMap)491*795d594fSAndroid Build Coastguard Worker TEST(StackMapTest, TestNoDexRegisterMap) {
492*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
493*795d594fSAndroid Build Coastguard Worker   ArenaStack arena_stack(&pool);
494*795d594fSAndroid Build Coastguard Worker   ScopedArenaAllocator allocator(&arena_stack);
495*795d594fSAndroid Build Coastguard Worker   StackMapStream stream(&allocator, kRuntimeISA);
496*795d594fSAndroid Build Coastguard Worker   stream.BeginMethod(/* frame_size_in_bytes= */ 32,
497*795d594fSAndroid Build Coastguard Worker                      /* core_spill_mask= */ 0,
498*795d594fSAndroid Build Coastguard Worker                      /* fp_spill_mask= */ 0,
499*795d594fSAndroid Build Coastguard Worker                      /* num_dex_registers= */ 1,
500*795d594fSAndroid Build Coastguard Worker                      /* baseline= */ false,
501*795d594fSAndroid Build Coastguard Worker                      /* debuggable= */ false);
502*795d594fSAndroid Build Coastguard Worker 
503*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask(&allocator, 0, false);
504*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 64 * kPcAlign, 0x3, &sp_mask);
505*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
506*795d594fSAndroid Build Coastguard Worker 
507*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(1, 68 * kPcAlign, 0x4, &sp_mask);
508*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kNone, 0);
509*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
510*795d594fSAndroid Build Coastguard Worker 
511*795d594fSAndroid Build Coastguard Worker   stream.EndMethod(68 * kPcAlign);
512*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<uint8_t> memory = stream.Encode();
513*795d594fSAndroid Build Coastguard Worker 
514*795d594fSAndroid Build Coastguard Worker   CodeInfo code_info(memory.data());
515*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
516*795d594fSAndroid Build Coastguard Worker 
517*795d594fSAndroid Build Coastguard Worker   uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
518*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0u, number_of_catalog_entries);
519*795d594fSAndroid Build Coastguard Worker 
520*795d594fSAndroid Build Coastguard Worker   StackMap stack_map = code_info.GetStackMapAt(0);
521*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
522*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
523*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0u, stack_map.GetDexPc());
524*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
525*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(stack_map));
526*795d594fSAndroid Build Coastguard Worker 
527*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(stack_map.HasDexRegisterMap());
528*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(stack_map.HasInlineInfo());
529*795d594fSAndroid Build Coastguard Worker 
530*795d594fSAndroid Build Coastguard Worker   stack_map = code_info.GetStackMapAt(1);
531*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1)));
532*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(68 * kPcAlign)));
533*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(1u, stack_map.GetDexPc());
534*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(68u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
535*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(0x4u, code_info.GetRegisterMaskOf(stack_map));
536*795d594fSAndroid Build Coastguard Worker 
537*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(stack_map.HasDexRegisterMap());
538*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(stack_map.HasInlineInfo());
539*795d594fSAndroid Build Coastguard Worker }
540*795d594fSAndroid Build Coastguard Worker 
TEST(StackMapTest,InlineTest)541*795d594fSAndroid Build Coastguard Worker TEST(StackMapTest, InlineTest) {
542*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
543*795d594fSAndroid Build Coastguard Worker   ArenaStack arena_stack(&pool);
544*795d594fSAndroid Build Coastguard Worker   ScopedArenaAllocator allocator(&arena_stack);
545*795d594fSAndroid Build Coastguard Worker   StackMapStream stream(&allocator, kRuntimeISA);
546*795d594fSAndroid Build Coastguard Worker   stream.BeginMethod(/* frame_size_in_bytes= */ 32,
547*795d594fSAndroid Build Coastguard Worker                      /* core_spill_mask= */ 0,
548*795d594fSAndroid Build Coastguard Worker                      /* fp_spill_mask= */ 0,
549*795d594fSAndroid Build Coastguard Worker                      /* num_dex_registers= */ 2,
550*795d594fSAndroid Build Coastguard Worker                      /* baseline= */ false,
551*795d594fSAndroid Build Coastguard Worker                      /* debuggable= */ false);
552*795d594fSAndroid Build Coastguard Worker   ArtMethod art_method;
553*795d594fSAndroid Build Coastguard Worker 
554*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask1(&allocator, 0, true);
555*795d594fSAndroid Build Coastguard Worker   sp_mask1.SetBit(2);
556*795d594fSAndroid Build Coastguard Worker   sp_mask1.SetBit(4);
557*795d594fSAndroid Build Coastguard Worker 
558*795d594fSAndroid Build Coastguard Worker   // First stack map.
559*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 10 * kPcAlign, 0x3, &sp_mask1);
560*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 0);
561*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, 4);
562*795d594fSAndroid Build Coastguard Worker 
563*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 2, 1);
564*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 8);
565*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
566*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 3, 3);
567*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 16);
568*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, 20);
569*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInRegister, 15);
570*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
571*795d594fSAndroid Build Coastguard Worker 
572*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
573*795d594fSAndroid Build Coastguard Worker 
574*795d594fSAndroid Build Coastguard Worker   // Second stack map.
575*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(2, 22 * kPcAlign, 0x3, &sp_mask1);
576*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 56);
577*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, 0);
578*795d594fSAndroid Build Coastguard Worker 
579*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 2, 1);
580*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 12);
581*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
582*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 3, 3);
583*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 80);
584*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, 10);
585*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInRegister, 5);
586*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
587*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 5, 0);
588*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
589*795d594fSAndroid Build Coastguard Worker 
590*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
591*795d594fSAndroid Build Coastguard Worker 
592*795d594fSAndroid Build Coastguard Worker   // Third stack map.
593*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(4, 56 * kPcAlign, 0x3, &sp_mask1);
594*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kNone, 0);
595*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, 4);
596*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
597*795d594fSAndroid Build Coastguard Worker 
598*795d594fSAndroid Build Coastguard Worker   // Fourth stack map.
599*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(6, 78 * kPcAlign, 0x3, &sp_mask1);
600*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInStack, 56);
601*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kConstant, 0);
602*795d594fSAndroid Build Coastguard Worker 
603*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 2, 0);
604*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
605*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 5, 1);
606*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInRegister, 2);
607*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
608*795d594fSAndroid Build Coastguard Worker   stream.BeginInlineInfoEntry(&art_method, 10, 2);
609*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kNone, 0);
610*795d594fSAndroid Build Coastguard Worker   stream.AddDexRegisterEntry(Kind::kInRegister, 3);
611*795d594fSAndroid Build Coastguard Worker   stream.EndInlineInfoEntry();
612*795d594fSAndroid Build Coastguard Worker 
613*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
614*795d594fSAndroid Build Coastguard Worker 
615*795d594fSAndroid Build Coastguard Worker   stream.EndMethod(78 * kPcAlign);
616*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<uint8_t> memory = stream.Encode();
617*795d594fSAndroid Build Coastguard Worker 
618*795d594fSAndroid Build Coastguard Worker   CodeInfo ci(memory.data());
619*795d594fSAndroid Build Coastguard Worker 
620*795d594fSAndroid Build Coastguard Worker   {
621*795d594fSAndroid Build Coastguard Worker     // Verify first stack map.
622*795d594fSAndroid Build Coastguard Worker     StackMap sm0 = ci.GetStackMapAt(0);
623*795d594fSAndroid Build Coastguard Worker 
624*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0);
625*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, dex_registers0.size());
626*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0, dex_registers0[0].GetStackOffsetInBytes());
627*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(4, dex_registers0[1].GetConstant());
628*795d594fSAndroid Build Coastguard Worker 
629*795d594fSAndroid Build Coastguard Worker     auto inline_infos = ci.GetInlineInfosOf(sm0);
630*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, inline_infos.size());
631*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, inline_infos[0].GetDexPc());
632*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
633*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3u, inline_infos[1].GetDexPc());
634*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
635*795d594fSAndroid Build Coastguard Worker 
636*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_registers1 = ci.GetInlineDexRegisterMapOf(sm0, inline_infos[0]);
637*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(1u, dex_registers1.size());
638*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(8, dex_registers1[0].GetStackOffsetInBytes());
639*795d594fSAndroid Build Coastguard Worker 
640*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_registers2 = ci.GetInlineDexRegisterMapOf(sm0, inline_infos[1]);
641*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3u, dex_registers2.size());
642*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(16, dex_registers2[0].GetStackOffsetInBytes());
643*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(20, dex_registers2[1].GetConstant());
644*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(15, dex_registers2[2].GetMachineRegister());
645*795d594fSAndroid Build Coastguard Worker   }
646*795d594fSAndroid Build Coastguard Worker 
647*795d594fSAndroid Build Coastguard Worker   {
648*795d594fSAndroid Build Coastguard Worker     // Verify second stack map.
649*795d594fSAndroid Build Coastguard Worker     StackMap sm1 = ci.GetStackMapAt(1);
650*795d594fSAndroid Build Coastguard Worker 
651*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm1);
652*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, dex_registers0.size());
653*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(56, dex_registers0[0].GetStackOffsetInBytes());
654*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0, dex_registers0[1].GetConstant());
655*795d594fSAndroid Build Coastguard Worker 
656*795d594fSAndroid Build Coastguard Worker     auto inline_infos = ci.GetInlineInfosOf(sm1);
657*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3u, inline_infos.size());
658*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, inline_infos[0].GetDexPc());
659*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
660*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3u, inline_infos[1].GetDexPc());
661*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
662*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(5u, inline_infos[2].GetDexPc());
663*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(inline_infos[2].EncodesArtMethod());
664*795d594fSAndroid Build Coastguard Worker 
665*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_registers1 = ci.GetInlineDexRegisterMapOf(sm1, inline_infos[0]);
666*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(1u, dex_registers1.size());
667*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(12, dex_registers1[0].GetStackOffsetInBytes());
668*795d594fSAndroid Build Coastguard Worker 
669*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_registers2 = ci.GetInlineDexRegisterMapOf(sm1, inline_infos[1]);
670*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3u, dex_registers2.size());
671*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(80, dex_registers2[0].GetStackOffsetInBytes());
672*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(10, dex_registers2[1].GetConstant());
673*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(5, dex_registers2[2].GetMachineRegister());
674*795d594fSAndroid Build Coastguard Worker   }
675*795d594fSAndroid Build Coastguard Worker 
676*795d594fSAndroid Build Coastguard Worker   {
677*795d594fSAndroid Build Coastguard Worker     // Verify third stack map.
678*795d594fSAndroid Build Coastguard Worker     StackMap sm2 = ci.GetStackMapAt(2);
679*795d594fSAndroid Build Coastguard Worker 
680*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm2);
681*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, dex_registers0.size());
682*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(dex_registers0[0].IsLive());
683*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(4, dex_registers0[1].GetConstant());
684*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(sm2.HasInlineInfo());
685*795d594fSAndroid Build Coastguard Worker   }
686*795d594fSAndroid Build Coastguard Worker 
687*795d594fSAndroid Build Coastguard Worker   {
688*795d594fSAndroid Build Coastguard Worker     // Verify fourth stack map.
689*795d594fSAndroid Build Coastguard Worker     StackMap sm3 = ci.GetStackMapAt(3);
690*795d594fSAndroid Build Coastguard Worker 
691*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm3);
692*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, dex_registers0.size());
693*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(56, dex_registers0[0].GetStackOffsetInBytes());
694*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(0, dex_registers0[1].GetConstant());
695*795d594fSAndroid Build Coastguard Worker 
696*795d594fSAndroid Build Coastguard Worker     auto inline_infos = ci.GetInlineInfosOf(sm3);
697*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3u, inline_infos.size());
698*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, inline_infos[0].GetDexPc());
699*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
700*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(5u, inline_infos[1].GetDexPc());
701*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
702*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(10u, inline_infos[2].GetDexPc());
703*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(inline_infos[2].EncodesArtMethod());
704*795d594fSAndroid Build Coastguard Worker 
705*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_registers1 = ci.GetInlineDexRegisterMapOf(sm3, inline_infos[1]);
706*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(1u, dex_registers1.size());
707*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2, dex_registers1[0].GetMachineRegister());
708*795d594fSAndroid Build Coastguard Worker 
709*795d594fSAndroid Build Coastguard Worker     DexRegisterMap dex_registers2 = ci.GetInlineDexRegisterMapOf(sm3, inline_infos[2]);
710*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(2u, dex_registers2.size());
711*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(dex_registers2[0].IsLive());
712*795d594fSAndroid Build Coastguard Worker     ASSERT_EQ(3, dex_registers2[1].GetMachineRegister());
713*795d594fSAndroid Build Coastguard Worker   }
714*795d594fSAndroid Build Coastguard Worker }
715*795d594fSAndroid Build Coastguard Worker 
TEST(StackMapTest,PackedNativePcTest)716*795d594fSAndroid Build Coastguard Worker TEST(StackMapTest, PackedNativePcTest) {
717*795d594fSAndroid Build Coastguard Worker   // Test minimum alignments, and decoding.
718*795d594fSAndroid Build Coastguard Worker   uint32_t packed_thumb2 =
719*795d594fSAndroid Build Coastguard Worker       StackMap::PackNativePc(kThumb2InstructionAlignment, InstructionSet::kThumb2);
720*795d594fSAndroid Build Coastguard Worker   uint32_t packed_arm64 =
721*795d594fSAndroid Build Coastguard Worker       StackMap::PackNativePc(kArm64InstructionAlignment, InstructionSet::kArm64);
722*795d594fSAndroid Build Coastguard Worker   uint32_t packed_x86 =
723*795d594fSAndroid Build Coastguard Worker       StackMap::PackNativePc(kX86InstructionAlignment, InstructionSet::kX86);
724*795d594fSAndroid Build Coastguard Worker   uint32_t packed_x86_64 =
725*795d594fSAndroid Build Coastguard Worker       StackMap::PackNativePc(kX86_64InstructionAlignment, InstructionSet::kX86_64);
726*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(StackMap::UnpackNativePc(packed_thumb2, InstructionSet::kThumb2),
727*795d594fSAndroid Build Coastguard Worker             kThumb2InstructionAlignment);
728*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(StackMap::UnpackNativePc(packed_arm64, InstructionSet::kArm64),
729*795d594fSAndroid Build Coastguard Worker             kArm64InstructionAlignment);
730*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(StackMap::UnpackNativePc(packed_x86, InstructionSet::kX86),
731*795d594fSAndroid Build Coastguard Worker             kX86InstructionAlignment);
732*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(StackMap::UnpackNativePc(packed_x86_64, InstructionSet::kX86_64),
733*795d594fSAndroid Build Coastguard Worker             kX86_64InstructionAlignment);
734*795d594fSAndroid Build Coastguard Worker }
735*795d594fSAndroid Build Coastguard Worker 
TEST(StackMapTest,TestDeduplicateStackMask)736*795d594fSAndroid Build Coastguard Worker TEST(StackMapTest, TestDeduplicateStackMask) {
737*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
738*795d594fSAndroid Build Coastguard Worker   ArenaStack arena_stack(&pool);
739*795d594fSAndroid Build Coastguard Worker   ScopedArenaAllocator allocator(&arena_stack);
740*795d594fSAndroid Build Coastguard Worker   StackMapStream stream(&allocator, kRuntimeISA);
741*795d594fSAndroid Build Coastguard Worker   stream.BeginMethod(/* frame_size_in_bytes= */ 32,
742*795d594fSAndroid Build Coastguard Worker                      /* core_spill_mask= */ 0,
743*795d594fSAndroid Build Coastguard Worker                      /* fp_spill_mask= */ 0,
744*795d594fSAndroid Build Coastguard Worker                      /* num_dex_registers= */ 0,
745*795d594fSAndroid Build Coastguard Worker                      /* baseline= */ false,
746*795d594fSAndroid Build Coastguard Worker                      /* debuggable= */ false);
747*795d594fSAndroid Build Coastguard Worker 
748*795d594fSAndroid Build Coastguard Worker   ArenaBitVector sp_mask(&allocator, 0, true);
749*795d594fSAndroid Build Coastguard Worker   sp_mask.SetBit(1);
750*795d594fSAndroid Build Coastguard Worker   sp_mask.SetBit(4);
751*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 4 * kPcAlign, 0x3, &sp_mask);
752*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
753*795d594fSAndroid Build Coastguard Worker   stream.BeginStackMapEntry(0, 8 * kPcAlign, 0x3, &sp_mask);
754*795d594fSAndroid Build Coastguard Worker   stream.EndStackMapEntry();
755*795d594fSAndroid Build Coastguard Worker 
756*795d594fSAndroid Build Coastguard Worker   stream.EndMethod(8 * kPcAlign);
757*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<uint8_t> memory = stream.Encode();
758*795d594fSAndroid Build Coastguard Worker 
759*795d594fSAndroid Build Coastguard Worker   CodeInfo code_info(memory.data());
760*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
761*795d594fSAndroid Build Coastguard Worker 
762*795d594fSAndroid Build Coastguard Worker   StackMap stack_map1 = code_info.GetStackMapForNativePcOffset(4 * kPcAlign);
763*795d594fSAndroid Build Coastguard Worker   StackMap stack_map2 = code_info.GetStackMapForNativePcOffset(8 * kPcAlign);
764*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(stack_map1.GetStackMaskIndex(),
765*795d594fSAndroid Build Coastguard Worker             stack_map2.GetStackMaskIndex());
766*795d594fSAndroid Build Coastguard Worker }
767*795d594fSAndroid Build Coastguard Worker 
768*795d594fSAndroid Build Coastguard Worker }  // namespace art
769