blob: 8d160bc81e5aad386f16595890a348a5a6913e2a [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"
18#include "stack_map_stream.h"
19#include "utils/arena_bit_vector.h"
20
21#include "gtest/gtest.h"
22
23namespace art {
24
Roland Levillaina2d8ec62015-03-12 15:25:29 +000025static bool SameBits(MemoryRegion region, const BitVector& bit_vector) {
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010026 for (size_t i = 0; i < region.size_in_bits(); ++i) {
27 if (region.LoadBit(i) != bit_vector.IsBitSet(i)) {
28 return false;
29 }
30 }
31 return true;
32}
33
Roland Levillaina552e1c2015-03-26 15:01:03 +000034using Kind = DexRegisterLocation::Kind;
35
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010036TEST(StackMapTest, Test1) {
37 ArenaPool pool;
38 ArenaAllocator arena(&pool);
Nicolas Geoffray39468442014-09-02 15:17:15 +010039 StackMapStream stream(&arena);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010040
41 ArenaBitVector sp_mask(&arena, 0, false);
Roland Levillain12baf472015-03-05 12:41:42 +000042 size_t number_of_dex_registers = 2;
Nicolas Geoffrayeeefa122015-03-13 18:52:59 +000043 stream.AddStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +000044 stream.AddDexRegisterEntry(0, Kind::kInStack, 0); // Short location.
45 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Short location.
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010046
47 size_t size = stream.ComputeNeededSize();
48 void* memory = arena.Alloc(size, kArenaAllocMisc);
49 MemoryRegion region(memory, size);
50 stream.FillIn(region);
51
Nicolas Geoffray39468442014-09-02 15:17:15 +010052 CodeInfo code_info(region);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010053 ASSERT_EQ(0u, code_info.GetStackMaskSize());
54 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
55
Roland Levillaina552e1c2015-03-26 15:01:03 +000056 uint32_t number_of_location_catalog_entries =
57 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
58 ASSERT_EQ(2u, number_of_location_catalog_entries);
59 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
60 // The Dex register location catalog contains:
61 // - one 1-byte short Dex register location, and
62 // - one 5-byte large Dex register location.
63 size_t expected_location_catalog_size = 1u + 5u;
64 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
65
Nicolas Geoffray39468442014-09-02 15:17:15 +010066 StackMap stack_map = code_info.GetStackMapAt(0);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010067 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
Nicolas Geoffray39468442014-09-02 15:17:15 +010068 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
Nicolas Geoffray004c2302015-03-20 10:06:38 +000069 ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
70 ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
71 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010072
Nicolas Geoffray004c2302015-03-20 10:06:38 +000073 MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010074 ASSERT_TRUE(SameBits(stack_mask, sp_mask));
75
Nicolas Geoffray004c2302015-03-20 10:06:38 +000076 ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
Roland Levillaina552e1c2015-03-26 15:01:03 +000077 DexRegisterMap dex_register_map =
78 code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
79 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
80 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
81 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
82 // The Dex register map contains:
83 // - one 1-byte live bit mask, and
84 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
85 size_t expected_dex_register_map_size = 1u + 1u;
86 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
87
88 ASSERT_EQ(Kind::kInStack,
89 dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
90 ASSERT_EQ(Kind::kConstant,
91 dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
92 ASSERT_EQ(Kind::kInStack,
93 dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
94 ASSERT_EQ(Kind::kConstantLargeValue,
95 dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
96 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(0, number_of_dex_registers, code_info));
97 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info));
98
99 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
100 0, number_of_dex_registers, number_of_location_catalog_entries);
101 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
102 1, number_of_dex_registers, number_of_location_catalog_entries);
103 ASSERT_EQ(0u, index0);
104 ASSERT_EQ(1u, index1);
105 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
106 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
107 ASSERT_EQ(Kind::kInStack, location0.GetKind());
108 ASSERT_EQ(Kind::kConstant, location1.GetKind());
109 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
110 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000111 ASSERT_EQ(0, location0.GetValue());
112 ASSERT_EQ(-2, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000113
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000114 ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100115}
116
117TEST(StackMapTest, Test2) {
118 ArenaPool pool;
119 ArenaAllocator arena(&pool);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100120 StackMapStream stream(&arena);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100121
122 ArenaBitVector sp_mask1(&arena, 0, true);
123 sp_mask1.SetBit(2);
124 sp_mask1.SetBit(4);
Roland Levillain12baf472015-03-05 12:41:42 +0000125 size_t number_of_dex_registers = 2;
Nicolas Geoffrayeeefa122015-03-13 18:52:59 +0000126 stream.AddStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 2);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000127 stream.AddDexRegisterEntry(0, Kind::kInStack, 0); // Short location.
128 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Large location.
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100129 stream.AddInlineInfoEntry(42);
130 stream.AddInlineInfoEntry(82);
131
132 ArenaBitVector sp_mask2(&arena, 0, true);
133 sp_mask2.SetBit(3);
134 sp_mask1.SetBit(8);
Nicolas Geoffrayeeefa122015-03-13 18:52:59 +0000135 stream.AddStackMapEntry(1, 128, 0xFF, &sp_mask2, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000136 stream.AddDexRegisterEntry(0, Kind::kInRegister, 18); // Short location.
137 stream.AddDexRegisterEntry(1, Kind::kInFpuRegister, 3); // Short location.
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100138
139 size_t size = stream.ComputeNeededSize();
140 void* memory = arena.Alloc(size, kArenaAllocMisc);
141 MemoryRegion region(memory, size);
142 stream.FillIn(region);
143
Nicolas Geoffray39468442014-09-02 15:17:15 +0100144 CodeInfo code_info(region);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100145 ASSERT_EQ(1u, code_info.GetStackMaskSize());
146 ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
147
Roland Levillaina552e1c2015-03-26 15:01:03 +0000148 uint32_t number_of_location_catalog_entries =
149 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
150 ASSERT_EQ(4u, number_of_location_catalog_entries);
151 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
152 // The Dex register location catalog contains:
153 // - three 1-byte short Dex register locations, and
154 // - one 5-byte large Dex register location.
155 size_t expected_location_catalog_size = 3u * 1u + 5u;
156 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
157
Roland Levillain12baf472015-03-05 12:41:42 +0000158 // First stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000159 {
160 StackMap stack_map = code_info.GetStackMapAt(0);
161 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
162 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000163 ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
164 ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
165 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100166
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000167 MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000168 ASSERT_TRUE(SameBits(stack_mask, sp_mask1));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100169
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000170 ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000171 DexRegisterMap dex_register_map =
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000172 code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000173 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
174 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
175 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
176 // The Dex register map contains:
177 // - one 1-byte live bit mask, and
178 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
179 size_t expected_dex_register_map_size = 1u + 1u;
180 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
181
182 ASSERT_EQ(Kind::kInStack,
183 dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
184 ASSERT_EQ(Kind::kConstant,
185 dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
186 ASSERT_EQ(Kind::kInStack,
187 dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
188 ASSERT_EQ(Kind::kConstantLargeValue,
189 dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
190 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(0, number_of_dex_registers, code_info));
191 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info));
192
193 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
194 0, number_of_dex_registers, number_of_location_catalog_entries);
195 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
196 1, number_of_dex_registers, number_of_location_catalog_entries);
197 ASSERT_EQ(0u, index0);
198 ASSERT_EQ(1u, index1);
199 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
200 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
201 ASSERT_EQ(Kind::kInStack, location0.GetKind());
202 ASSERT_EQ(Kind::kConstant, location1.GetKind());
203 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
204 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000205 ASSERT_EQ(0, location0.GetValue());
206 ASSERT_EQ(-2, location1.GetValue());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100207
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000208 ASSERT_TRUE(stack_map.HasInlineInfo(code_info));
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000209 InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
210 ASSERT_EQ(2u, inline_info.GetDepth());
211 ASSERT_EQ(42u, inline_info.GetMethodReferenceIndexAtDepth(0));
212 ASSERT_EQ(82u, inline_info.GetMethodReferenceIndexAtDepth(1));
213 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100214
Roland Levillain12baf472015-03-05 12:41:42 +0000215 // Second stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000216 {
217 StackMap stack_map = code_info.GetStackMapAt(1);
218 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u)));
219 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u)));
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000220 ASSERT_EQ(1u, stack_map.GetDexPc(code_info));
221 ASSERT_EQ(128u, stack_map.GetNativePcOffset(code_info));
222 ASSERT_EQ(0xFFu, stack_map.GetRegisterMask(code_info));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100223
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000224 MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000225 ASSERT_TRUE(SameBits(stack_mask, sp_mask2));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100226
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000227 ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000228 DexRegisterMap dex_register_map =
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000229 code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000230 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
231 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
232 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
233 // The Dex register map contains:
234 // - one 1-byte live bit mask, and
235 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
236 size_t expected_dex_register_map_size = 1u + 1u;
237 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
238
239 ASSERT_EQ(Kind::kInRegister,
240 dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
241 ASSERT_EQ(Kind::kInFpuRegister,
242 dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
243 ASSERT_EQ(Kind::kInRegister,
244 dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
245 ASSERT_EQ(Kind::kInFpuRegister,
246 dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
247 ASSERT_EQ(18, dex_register_map.GetMachineRegister(0, number_of_dex_registers, code_info));
248 ASSERT_EQ(3, dex_register_map.GetMachineRegister(1, number_of_dex_registers, code_info));
249
250 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
251 0, number_of_dex_registers, number_of_location_catalog_entries);
252 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
253 1, number_of_dex_registers, number_of_location_catalog_entries);
254 ASSERT_EQ(2u, index0);
255 ASSERT_EQ(3u, index1);
256 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
257 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
258 ASSERT_EQ(Kind::kInRegister, location0.GetKind());
259 ASSERT_EQ(Kind::kInFpuRegister, location1.GetKind());
260 ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind());
261 ASSERT_EQ(Kind::kInFpuRegister, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000262 ASSERT_EQ(18, location0.GetValue());
263 ASSERT_EQ(3, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000264
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000265 ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000266 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100267}
268
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000269TEST(StackMapTest, TestNonLiveDexRegisters) {
270 ArenaPool pool;
271 ArenaAllocator arena(&pool);
272 StackMapStream stream(&arena);
273
274 ArenaBitVector sp_mask(&arena, 0, false);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000275 uint32_t number_of_dex_registers = 2;
Nicolas Geoffrayeeefa122015-03-13 18:52:59 +0000276 stream.AddStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000277 stream.AddDexRegisterEntry(0, Kind::kNone, 0); // No location.
278 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Large location.
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000279
280 size_t size = stream.ComputeNeededSize();
281 void* memory = arena.Alloc(size, kArenaAllocMisc);
282 MemoryRegion region(memory, size);
283 stream.FillIn(region);
284
285 CodeInfo code_info(region);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000286 ASSERT_EQ(0u, code_info.GetStackMaskSize());
287 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
288
289 uint32_t number_of_location_catalog_entries =
290 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
291 ASSERT_EQ(1u, number_of_location_catalog_entries);
292 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
293 // The Dex register location catalog contains:
294 // - one 5-byte large Dex register location.
295 size_t expected_location_catalog_size = 5u;
296 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
297
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000298 StackMap stack_map = code_info.GetStackMapAt(0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000299 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
300 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
301 ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
302 ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
303 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
304
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000305 ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000306 DexRegisterMap dex_register_map =
307 code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
308 ASSERT_FALSE(dex_register_map.IsDexRegisterLive(0));
309 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
310 ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
311 // The Dex register map contains:
312 // - one 1-byte live bit mask.
313 // No space is allocated for the sole location catalog entry index, as it is useless.
314 size_t expected_dex_register_map_size = 1u + 0u;
315 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
316
317 ASSERT_EQ(Kind::kNone,
318 dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
319 ASSERT_EQ(Kind::kConstant,
320 dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
321 ASSERT_EQ(Kind::kNone,
322 dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
323 ASSERT_EQ(Kind::kConstantLargeValue,
324 dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
325 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info));
326
327 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
328 0, number_of_dex_registers, number_of_location_catalog_entries);
329 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
330 1, number_of_dex_registers, number_of_location_catalog_entries);
331 ASSERT_EQ(DexRegisterLocationCatalog::kNoLocationEntryIndex, index0);
332 ASSERT_EQ(0u, index1);
333 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
334 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
335 ASSERT_EQ(Kind::kNone, location0.GetKind());
336 ASSERT_EQ(Kind::kConstant, location1.GetKind());
337 ASSERT_EQ(Kind::kNone, location0.GetInternalKind());
338 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
339 ASSERT_EQ(0, location0.GetValue());
340 ASSERT_EQ(-2, location1.GetValue());
341
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000342 ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
343}
344
345// Generate a stack map whose dex register offset is
346// StackMap::kNoDexRegisterMapSmallEncoding, and ensure we do
347// not treat it as kNoDexRegisterMap.
348TEST(StackMapTest, DexRegisterMapOffsetOverflow) {
349 ArenaPool pool;
350 ArenaAllocator arena(&pool);
351 StackMapStream stream(&arena);
352
353 ArenaBitVector sp_mask(&arena, 0, false);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000354 uint32_t number_of_dex_registers = 1024;
355 // Create the first stack map (and its Dex register map).
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000356 stream.AddStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000357 uint32_t number_of_dex_live_registers_in_dex_register_map_0 = number_of_dex_registers - 8;
358 for (uint32_t i = 0; i < number_of_dex_live_registers_in_dex_register_map_0; ++i) {
359 // Use two different Dex register locations to populate this map,
360 // as using a single value (in the whole CodeInfo object) would
361 // make this Dex register mapping data empty (see
362 // art::DexRegisterMap::SingleEntrySizeInBits).
363 stream.AddDexRegisterEntry(i, Kind::kConstant, i % 2); // Short location.
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000364 }
Roland Levillaina552e1c2015-03-26 15:01:03 +0000365 // Create the second stack map (and its Dex register map).
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000366 stream.AddStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
367 for (uint32_t i = 0; i < number_of_dex_registers; ++i) {
Roland Levillaina552e1c2015-03-26 15:01:03 +0000368 stream.AddDexRegisterEntry(i, Kind::kConstant, 0); // Short location.
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000369 }
370
371 size_t size = stream.ComputeNeededSize();
372 void* memory = arena.Alloc(size, kArenaAllocMisc);
373 MemoryRegion region(memory, size);
374 stream.FillIn(region);
375
376 CodeInfo code_info(region);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000377 // The location catalog contains two entries (DexRegisterLocation(kConstant, 0)
378 // and DexRegisterLocation(kConstant, 1)), therefore the location catalog index
379 // has a size of 1 bit.
380 uint32_t number_of_location_catalog_entries =
381 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
382 ASSERT_EQ(2u, number_of_location_catalog_entries);
383 ASSERT_EQ(1u, DexRegisterMap::SingleEntrySizeInBits(number_of_location_catalog_entries));
384
385 // The first Dex register map contains:
386 // - a live register bit mask for 1024 registers (that is, 128 bytes of
387 // data); and
388 // - Dex register mapping information for 1016 1-bit Dex (live) register
389 // locations (that is, 127 bytes of data).
390 // Hence it has a size of 255 bytes, and therefore...
391 ASSERT_EQ(128u, DexRegisterMap::GetLiveBitMaskSize(number_of_dex_registers));
392 StackMap stack_map0 = code_info.GetStackMapAt(0);
393 DexRegisterMap dex_register_map0 =
394 code_info.GetDexRegisterMapOf(stack_map0, number_of_dex_registers);
395 ASSERT_EQ(127u, dex_register_map0.GetLocationMappingDataSize(number_of_dex_registers,
396 number_of_location_catalog_entries));
397 ASSERT_EQ(255u, dex_register_map0.Size());
398
399 StackMap stack_map1 = code_info.GetStackMapAt(1);
400 ASSERT_TRUE(stack_map1.HasDexRegisterMap(code_info));
401 // ...the offset of the second Dex register map (relative to the
402 // beginning of the Dex register maps region) is 255 (i.e.,
403 // kNoDexRegisterMapSmallEncoding).
Nicolas Geoffray896f8f72015-03-30 15:44:25 +0100404 ASSERT_NE(stack_map1.GetDexRegisterMapOffset(code_info), StackMap::kNoDexRegisterMap);
405 ASSERT_EQ(stack_map1.GetDexRegisterMapOffset(code_info), 0xFFu);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000406}
407
Calin Juravle6ae70962015-03-18 16:31:28 +0000408TEST(StackMapTest, TestShareDexRegisterMap) {
409 ArenaPool pool;
410 ArenaAllocator arena(&pool);
411 StackMapStream stream(&arena);
412
413 ArenaBitVector sp_mask(&arena, 0, false);
414 uint32_t number_of_dex_registers = 2;
415 // First stack map.
416 stream.AddStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000417 stream.AddDexRegisterEntry(0, Kind::kInRegister, 0); // Short location.
418 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Large location.
Calin Juravle6ae70962015-03-18 16:31:28 +0000419 // Second stack map, which should share the same dex register map.
420 stream.AddStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000421 stream.AddDexRegisterEntry(0, Kind::kInRegister, 0); // Short location.
422 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Large location.
Calin Juravle6ae70962015-03-18 16:31:28 +0000423 // Third stack map (doesn't share the dex register map).
424 stream.AddStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000425 stream.AddDexRegisterEntry(0, Kind::kInRegister, 2); // Short location.
426 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Large location.
Calin Juravle6ae70962015-03-18 16:31:28 +0000427
428 size_t size = stream.ComputeNeededSize();
429 void* memory = arena.Alloc(size, kArenaAllocMisc);
430 MemoryRegion region(memory, size);
431 stream.FillIn(region);
432
433 CodeInfo ci(region);
434 // Verify first stack map.
435 StackMap sm0 = ci.GetStackMapAt(0);
436 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000437 ASSERT_EQ(0, dex_registers0.GetMachineRegister(0, number_of_dex_registers, ci));
438 ASSERT_EQ(-2, dex_registers0.GetConstant(1, number_of_dex_registers, ci));
Calin Juravle6ae70962015-03-18 16:31:28 +0000439
440 // Verify second stack map.
441 StackMap sm1 = ci.GetStackMapAt(1);
442 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000443 ASSERT_EQ(0, dex_registers1.GetMachineRegister(0, number_of_dex_registers, ci));
444 ASSERT_EQ(-2, dex_registers1.GetConstant(1, number_of_dex_registers, ci));
Calin Juravle6ae70962015-03-18 16:31:28 +0000445
446 // Verify third stack map.
447 StackMap sm2 = ci.GetStackMapAt(2);
448 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000449 ASSERT_EQ(2, dex_registers2.GetMachineRegister(0, number_of_dex_registers, ci));
450 ASSERT_EQ(-2, dex_registers2.GetConstant(1, number_of_dex_registers, ci));
Calin Juravle6ae70962015-03-18 16:31:28 +0000451
452 // Verify dex register map offsets.
453 ASSERT_EQ(sm0.GetDexRegisterMapOffset(ci), sm1.GetDexRegisterMapOffset(ci));
454 ASSERT_NE(sm0.GetDexRegisterMapOffset(ci), sm2.GetDexRegisterMapOffset(ci));
455 ASSERT_NE(sm1.GetDexRegisterMapOffset(ci), sm2.GetDexRegisterMapOffset(ci));
456}
457
Roland Levillaina552e1c2015-03-26 15:01:03 +0000458TEST(StackMapTest, TestNoDexRegisterMap) {
459 ArenaPool pool;
460 ArenaAllocator arena(&pool);
461 StackMapStream stream(&arena);
462
463 ArenaBitVector sp_mask(&arena, 0, false);
464 uint32_t number_of_dex_registers = 0;
465 stream.AddStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
466
467 size_t size = stream.ComputeNeededSize();
468 void* memory = arena.Alloc(size, kArenaAllocMisc);
469 MemoryRegion region(memory, size);
470 stream.FillIn(region);
471
472 CodeInfo code_info(region);
473 ASSERT_EQ(0u, code_info.GetStackMaskSize());
474 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
475
476 uint32_t number_of_location_catalog_entries =
477 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
478 ASSERT_EQ(0u, number_of_location_catalog_entries);
479 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
480 ASSERT_EQ(0u, location_catalog.Size());
481
482 StackMap stack_map = code_info.GetStackMapAt(0);
483 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
484 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
485 ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
486 ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
487 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
488
489 ASSERT_FALSE(stack_map.HasDexRegisterMap(code_info));
490 ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
491}
492
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100493} // namespace art