blob: 3291a770213f16f64a710bb5de5d78238702bf8a [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;
Calin Juravle4f46ac52015-04-23 18:47:21 +010043 stream.BeginStackMapEntry(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.
Calin Juravle4f46ac52015-04-23 18:47:21 +010046 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010047
Calin Juravle4f46ac52015-04-23 18:47:21 +010048 size_t size = stream.PrepareForFillIn();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010049 void* memory = arena.Alloc(size, kArenaAllocMisc);
50 MemoryRegion region(memory, size);
51 stream.FillIn(region);
52
Nicolas Geoffray39468442014-09-02 15:17:15 +010053 CodeInfo code_info(region);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010054 ASSERT_EQ(0u, code_info.GetStackMaskSize());
55 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
56
Roland Levillaina552e1c2015-03-26 15:01:03 +000057 uint32_t number_of_location_catalog_entries =
58 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
59 ASSERT_EQ(2u, number_of_location_catalog_entries);
60 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
61 // The Dex register location catalog contains:
62 // - one 1-byte short Dex register location, and
63 // - one 5-byte large Dex register location.
64 size_t expected_location_catalog_size = 1u + 5u;
65 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
66
Nicolas Geoffray39468442014-09-02 15:17:15 +010067 StackMap stack_map = code_info.GetStackMapAt(0);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010068 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
Nicolas Geoffray39468442014-09-02 15:17:15 +010069 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
Nicolas Geoffray004c2302015-03-20 10:06:38 +000070 ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
71 ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
72 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010073
Nicolas Geoffray004c2302015-03-20 10:06:38 +000074 MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010075 ASSERT_TRUE(SameBits(stack_mask, sp_mask));
76
Nicolas Geoffray004c2302015-03-20 10:06:38 +000077 ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
Roland Levillaina552e1c2015-03-26 15:01:03 +000078 DexRegisterMap dex_register_map =
79 code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
80 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
81 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
82 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
83 // The Dex register map contains:
84 // - one 1-byte live bit mask, and
85 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
86 size_t expected_dex_register_map_size = 1u + 1u;
87 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
88
89 ASSERT_EQ(Kind::kInStack,
90 dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
91 ASSERT_EQ(Kind::kConstant,
92 dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
93 ASSERT_EQ(Kind::kInStack,
94 dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
95 ASSERT_EQ(Kind::kConstantLargeValue,
96 dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
97 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(0, number_of_dex_registers, code_info));
98 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info));
99
100 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
101 0, number_of_dex_registers, number_of_location_catalog_entries);
102 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
103 1, number_of_dex_registers, number_of_location_catalog_entries);
104 ASSERT_EQ(0u, index0);
105 ASSERT_EQ(1u, index1);
106 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
107 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
108 ASSERT_EQ(Kind::kInStack, location0.GetKind());
109 ASSERT_EQ(Kind::kConstant, location1.GetKind());
110 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
111 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000112 ASSERT_EQ(0, location0.GetValue());
113 ASSERT_EQ(-2, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000114
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000115 ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100116}
117
118TEST(StackMapTest, Test2) {
119 ArenaPool pool;
120 ArenaAllocator arena(&pool);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100121 StackMapStream stream(&arena);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100122
123 ArenaBitVector sp_mask1(&arena, 0, true);
124 sp_mask1.SetBit(2);
125 sp_mask1.SetBit(4);
Roland Levillain12baf472015-03-05 12:41:42 +0000126 size_t number_of_dex_registers = 2;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100127 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 2);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000128 stream.AddDexRegisterEntry(0, Kind::kInStack, 0); // Short location.
129 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Large location.
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100130 stream.AddInlineInfoEntry(42);
131 stream.AddInlineInfoEntry(82);
Calin Juravle4f46ac52015-04-23 18:47:21 +0100132 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100133
134 ArenaBitVector sp_mask2(&arena, 0, true);
135 sp_mask2.SetBit(3);
136 sp_mask1.SetBit(8);
Calin Juravle4f46ac52015-04-23 18:47:21 +0100137 stream.BeginStackMapEntry(1, 128, 0xFF, &sp_mask2, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000138 stream.AddDexRegisterEntry(0, Kind::kInRegister, 18); // Short location.
139 stream.AddDexRegisterEntry(1, Kind::kInFpuRegister, 3); // Short location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100140 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100141
Calin Juravle4f46ac52015-04-23 18:47:21 +0100142 size_t size = stream.PrepareForFillIn();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100143 void* memory = arena.Alloc(size, kArenaAllocMisc);
144 MemoryRegion region(memory, size);
145 stream.FillIn(region);
146
Nicolas Geoffray39468442014-09-02 15:17:15 +0100147 CodeInfo code_info(region);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100148 ASSERT_EQ(1u, code_info.GetStackMaskSize());
149 ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
150
Roland Levillaina552e1c2015-03-26 15:01:03 +0000151 uint32_t number_of_location_catalog_entries =
152 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
153 ASSERT_EQ(4u, number_of_location_catalog_entries);
154 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
155 // The Dex register location catalog contains:
156 // - three 1-byte short Dex register locations, and
157 // - one 5-byte large Dex register location.
158 size_t expected_location_catalog_size = 3u * 1u + 5u;
159 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
160
Roland Levillain12baf472015-03-05 12:41:42 +0000161 // First stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000162 {
163 StackMap stack_map = code_info.GetStackMapAt(0);
164 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
165 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000166 ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
167 ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
168 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100169
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000170 MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000171 ASSERT_TRUE(SameBits(stack_mask, sp_mask1));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100172
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000173 ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000174 DexRegisterMap dex_register_map =
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000175 code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000176 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
177 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
178 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
179 // The Dex register map contains:
180 // - one 1-byte live bit mask, and
181 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
182 size_t expected_dex_register_map_size = 1u + 1u;
183 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
184
185 ASSERT_EQ(Kind::kInStack,
186 dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
187 ASSERT_EQ(Kind::kConstant,
188 dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
189 ASSERT_EQ(Kind::kInStack,
190 dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
191 ASSERT_EQ(Kind::kConstantLargeValue,
192 dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
193 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(0, number_of_dex_registers, code_info));
194 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info));
195
196 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
197 0, number_of_dex_registers, number_of_location_catalog_entries);
198 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
199 1, number_of_dex_registers, number_of_location_catalog_entries);
200 ASSERT_EQ(0u, index0);
201 ASSERT_EQ(1u, index1);
202 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
203 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
204 ASSERT_EQ(Kind::kInStack, location0.GetKind());
205 ASSERT_EQ(Kind::kConstant, location1.GetKind());
206 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
207 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000208 ASSERT_EQ(0, location0.GetValue());
209 ASSERT_EQ(-2, location1.GetValue());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100210
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000211 ASSERT_TRUE(stack_map.HasInlineInfo(code_info));
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000212 InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
213 ASSERT_EQ(2u, inline_info.GetDepth());
214 ASSERT_EQ(42u, inline_info.GetMethodReferenceIndexAtDepth(0));
215 ASSERT_EQ(82u, inline_info.GetMethodReferenceIndexAtDepth(1));
216 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100217
Roland Levillain12baf472015-03-05 12:41:42 +0000218 // Second stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000219 {
220 StackMap stack_map = code_info.GetStackMapAt(1);
221 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u)));
222 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u)));
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000223 ASSERT_EQ(1u, stack_map.GetDexPc(code_info));
224 ASSERT_EQ(128u, stack_map.GetNativePcOffset(code_info));
225 ASSERT_EQ(0xFFu, stack_map.GetRegisterMask(code_info));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100226
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000227 MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000228 ASSERT_TRUE(SameBits(stack_mask, sp_mask2));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100229
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000230 ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000231 DexRegisterMap dex_register_map =
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000232 code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000233 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
234 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
235 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
236 // The Dex register map contains:
237 // - one 1-byte live bit mask, and
238 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
239 size_t expected_dex_register_map_size = 1u + 1u;
240 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
241
242 ASSERT_EQ(Kind::kInRegister,
243 dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
244 ASSERT_EQ(Kind::kInFpuRegister,
245 dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
246 ASSERT_EQ(Kind::kInRegister,
247 dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
248 ASSERT_EQ(Kind::kInFpuRegister,
249 dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
250 ASSERT_EQ(18, dex_register_map.GetMachineRegister(0, number_of_dex_registers, code_info));
251 ASSERT_EQ(3, dex_register_map.GetMachineRegister(1, number_of_dex_registers, code_info));
252
253 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
254 0, number_of_dex_registers, number_of_location_catalog_entries);
255 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
256 1, number_of_dex_registers, number_of_location_catalog_entries);
257 ASSERT_EQ(2u, index0);
258 ASSERT_EQ(3u, index1);
259 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
260 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
261 ASSERT_EQ(Kind::kInRegister, location0.GetKind());
262 ASSERT_EQ(Kind::kInFpuRegister, location1.GetKind());
263 ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind());
264 ASSERT_EQ(Kind::kInFpuRegister, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000265 ASSERT_EQ(18, location0.GetValue());
266 ASSERT_EQ(3, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000267
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000268 ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000269 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100270}
271
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000272TEST(StackMapTest, TestNonLiveDexRegisters) {
273 ArenaPool pool;
274 ArenaAllocator arena(&pool);
275 StackMapStream stream(&arena);
276
277 ArenaBitVector sp_mask(&arena, 0, false);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000278 uint32_t number_of_dex_registers = 2;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100279 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000280 stream.AddDexRegisterEntry(0, Kind::kNone, 0); // No location.
281 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100282 stream.EndStackMapEntry();
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000283
Calin Juravle4f46ac52015-04-23 18:47:21 +0100284 size_t size = stream.PrepareForFillIn();
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000285 void* memory = arena.Alloc(size, kArenaAllocMisc);
286 MemoryRegion region(memory, size);
287 stream.FillIn(region);
288
289 CodeInfo code_info(region);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000290 ASSERT_EQ(0u, code_info.GetStackMaskSize());
291 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
292
293 uint32_t number_of_location_catalog_entries =
294 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
295 ASSERT_EQ(1u, number_of_location_catalog_entries);
296 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
297 // The Dex register location catalog contains:
298 // - one 5-byte large Dex register location.
299 size_t expected_location_catalog_size = 5u;
300 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
301
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000302 StackMap stack_map = code_info.GetStackMapAt(0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000303 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
304 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
305 ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
306 ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
307 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
308
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000309 ASSERT_TRUE(stack_map.HasDexRegisterMap(code_info));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000310 DexRegisterMap dex_register_map =
311 code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
312 ASSERT_FALSE(dex_register_map.IsDexRegisterLive(0));
313 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
314 ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
315 // The Dex register map contains:
316 // - one 1-byte live bit mask.
317 // No space is allocated for the sole location catalog entry index, as it is useless.
318 size_t expected_dex_register_map_size = 1u + 0u;
319 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
320
321 ASSERT_EQ(Kind::kNone,
322 dex_register_map.GetLocationKind(0, number_of_dex_registers, code_info));
323 ASSERT_EQ(Kind::kConstant,
324 dex_register_map.GetLocationKind(1, number_of_dex_registers, code_info));
325 ASSERT_EQ(Kind::kNone,
326 dex_register_map.GetLocationInternalKind(0, number_of_dex_registers, code_info));
327 ASSERT_EQ(Kind::kConstantLargeValue,
328 dex_register_map.GetLocationInternalKind(1, number_of_dex_registers, code_info));
329 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info));
330
331 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
332 0, number_of_dex_registers, number_of_location_catalog_entries);
333 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
334 1, number_of_dex_registers, number_of_location_catalog_entries);
335 ASSERT_EQ(DexRegisterLocationCatalog::kNoLocationEntryIndex, index0);
336 ASSERT_EQ(0u, index1);
337 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
338 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
339 ASSERT_EQ(Kind::kNone, location0.GetKind());
340 ASSERT_EQ(Kind::kConstant, location1.GetKind());
341 ASSERT_EQ(Kind::kNone, location0.GetInternalKind());
342 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
343 ASSERT_EQ(0, location0.GetValue());
344 ASSERT_EQ(-2, location1.GetValue());
345
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000346 ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
347}
348
349// Generate a stack map whose dex register offset is
350// StackMap::kNoDexRegisterMapSmallEncoding, and ensure we do
351// not treat it as kNoDexRegisterMap.
352TEST(StackMapTest, DexRegisterMapOffsetOverflow) {
353 ArenaPool pool;
354 ArenaAllocator arena(&pool);
355 StackMapStream stream(&arena);
356
357 ArenaBitVector sp_mask(&arena, 0, false);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000358 uint32_t number_of_dex_registers = 1024;
359 // Create the first stack map (and its Dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100360 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000361 uint32_t number_of_dex_live_registers_in_dex_register_map_0 = number_of_dex_registers - 8;
362 for (uint32_t i = 0; i < number_of_dex_live_registers_in_dex_register_map_0; ++i) {
363 // Use two different Dex register locations to populate this map,
364 // as using a single value (in the whole CodeInfo object) would
365 // make this Dex register mapping data empty (see
366 // art::DexRegisterMap::SingleEntrySizeInBits).
367 stream.AddDexRegisterEntry(i, Kind::kConstant, i % 2); // Short location.
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000368 }
Calin Juravle4f46ac52015-04-23 18:47:21 +0100369 stream.EndStackMapEntry();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000370 // Create the second stack map (and its Dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100371 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000372 for (uint32_t i = 0; i < number_of_dex_registers; ++i) {
Roland Levillaina552e1c2015-03-26 15:01:03 +0000373 stream.AddDexRegisterEntry(i, Kind::kConstant, 0); // Short location.
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000374 }
Calin Juravle4f46ac52015-04-23 18:47:21 +0100375 stream.EndStackMapEntry();
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000376
Calin Juravle4f46ac52015-04-23 18:47:21 +0100377 size_t size = stream.PrepareForFillIn();
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000378 void* memory = arena.Alloc(size, kArenaAllocMisc);
379 MemoryRegion region(memory, size);
380 stream.FillIn(region);
381
382 CodeInfo code_info(region);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000383 // The location catalog contains two entries (DexRegisterLocation(kConstant, 0)
384 // and DexRegisterLocation(kConstant, 1)), therefore the location catalog index
385 // has a size of 1 bit.
386 uint32_t number_of_location_catalog_entries =
387 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
388 ASSERT_EQ(2u, number_of_location_catalog_entries);
389 ASSERT_EQ(1u, DexRegisterMap::SingleEntrySizeInBits(number_of_location_catalog_entries));
390
391 // The first Dex register map contains:
392 // - a live register bit mask for 1024 registers (that is, 128 bytes of
393 // data); and
394 // - Dex register mapping information for 1016 1-bit Dex (live) register
395 // locations (that is, 127 bytes of data).
396 // Hence it has a size of 255 bytes, and therefore...
397 ASSERT_EQ(128u, DexRegisterMap::GetLiveBitMaskSize(number_of_dex_registers));
398 StackMap stack_map0 = code_info.GetStackMapAt(0);
399 DexRegisterMap dex_register_map0 =
400 code_info.GetDexRegisterMapOf(stack_map0, number_of_dex_registers);
401 ASSERT_EQ(127u, dex_register_map0.GetLocationMappingDataSize(number_of_dex_registers,
402 number_of_location_catalog_entries));
403 ASSERT_EQ(255u, dex_register_map0.Size());
404
405 StackMap stack_map1 = code_info.GetStackMapAt(1);
406 ASSERT_TRUE(stack_map1.HasDexRegisterMap(code_info));
407 // ...the offset of the second Dex register map (relative to the
408 // beginning of the Dex register maps region) is 255 (i.e.,
409 // kNoDexRegisterMapSmallEncoding).
Nicolas Geoffray896f8f72015-03-30 15:44:25 +0100410 ASSERT_NE(stack_map1.GetDexRegisterMapOffset(code_info), StackMap::kNoDexRegisterMap);
411 ASSERT_EQ(stack_map1.GetDexRegisterMapOffset(code_info), 0xFFu);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000412}
413
Calin Juravle6ae70962015-03-18 16:31:28 +0000414TEST(StackMapTest, TestShareDexRegisterMap) {
415 ArenaPool pool;
416 ArenaAllocator arena(&pool);
417 StackMapStream stream(&arena);
418
419 ArenaBitVector sp_mask(&arena, 0, false);
420 uint32_t number_of_dex_registers = 2;
421 // First stack map.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100422 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000423 stream.AddDexRegisterEntry(0, Kind::kInRegister, 0); // Short location.
424 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100425 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000426 // Second stack map, which should share the same dex register map.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100427 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000428 stream.AddDexRegisterEntry(0, Kind::kInRegister, 0); // Short location.
429 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100430 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000431 // Third stack map (doesn't share the dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100432 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000433 stream.AddDexRegisterEntry(0, Kind::kInRegister, 2); // Short location.
434 stream.AddDexRegisterEntry(1, Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100435 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000436
Calin Juravle4f46ac52015-04-23 18:47:21 +0100437 size_t size = stream.PrepareForFillIn();
Calin Juravle6ae70962015-03-18 16:31:28 +0000438 void* memory = arena.Alloc(size, kArenaAllocMisc);
439 MemoryRegion region(memory, size);
440 stream.FillIn(region);
441
442 CodeInfo ci(region);
443 // Verify first stack map.
444 StackMap sm0 = ci.GetStackMapAt(0);
445 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000446 ASSERT_EQ(0, dex_registers0.GetMachineRegister(0, number_of_dex_registers, ci));
447 ASSERT_EQ(-2, dex_registers0.GetConstant(1, number_of_dex_registers, ci));
Calin Juravle6ae70962015-03-18 16:31:28 +0000448
449 // Verify second stack map.
450 StackMap sm1 = ci.GetStackMapAt(1);
451 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000452 ASSERT_EQ(0, dex_registers1.GetMachineRegister(0, number_of_dex_registers, ci));
453 ASSERT_EQ(-2, dex_registers1.GetConstant(1, number_of_dex_registers, ci));
Calin Juravle6ae70962015-03-18 16:31:28 +0000454
455 // Verify third stack map.
456 StackMap sm2 = ci.GetStackMapAt(2);
457 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000458 ASSERT_EQ(2, dex_registers2.GetMachineRegister(0, number_of_dex_registers, ci));
459 ASSERT_EQ(-2, dex_registers2.GetConstant(1, number_of_dex_registers, ci));
Calin Juravle6ae70962015-03-18 16:31:28 +0000460
461 // Verify dex register map offsets.
462 ASSERT_EQ(sm0.GetDexRegisterMapOffset(ci), sm1.GetDexRegisterMapOffset(ci));
463 ASSERT_NE(sm0.GetDexRegisterMapOffset(ci), sm2.GetDexRegisterMapOffset(ci));
464 ASSERT_NE(sm1.GetDexRegisterMapOffset(ci), sm2.GetDexRegisterMapOffset(ci));
465}
466
Roland Levillaina552e1c2015-03-26 15:01:03 +0000467TEST(StackMapTest, TestNoDexRegisterMap) {
468 ArenaPool pool;
469 ArenaAllocator arena(&pool);
470 StackMapStream stream(&arena);
471
472 ArenaBitVector sp_mask(&arena, 0, false);
473 uint32_t number_of_dex_registers = 0;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100474 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
475 stream.EndStackMapEntry();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000476
Calin Juravle4f46ac52015-04-23 18:47:21 +0100477 size_t size = stream.PrepareForFillIn();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000478 void* memory = arena.Alloc(size, kArenaAllocMisc);
479 MemoryRegion region(memory, size);
480 stream.FillIn(region);
481
482 CodeInfo code_info(region);
483 ASSERT_EQ(0u, code_info.GetStackMaskSize());
484 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
485
486 uint32_t number_of_location_catalog_entries =
487 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
488 ASSERT_EQ(0u, number_of_location_catalog_entries);
489 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog();
490 ASSERT_EQ(0u, location_catalog.Size());
491
492 StackMap stack_map = code_info.GetStackMapAt(0);
493 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
494 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64)));
495 ASSERT_EQ(0u, stack_map.GetDexPc(code_info));
496 ASSERT_EQ(64u, stack_map.GetNativePcOffset(code_info));
497 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(code_info));
498
499 ASSERT_FALSE(stack_map.HasDexRegisterMap(code_info));
500 ASSERT_FALSE(stack_map.HasInlineInfo(code_info));
501}
502
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100503} // namespace art