blob: c4a3b28aedbc51a020ff1fea9980f49bfae38b64 [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);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +010044 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
45 stream.AddDexRegisterEntry(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);
David Brazdilf677ebf2015-05-29 16:29:43 +010054 StackMapEncoding encoding = code_info.ExtractEncoding();
55 ASSERT_EQ(0u, encoding.NumberOfBytesForStackMask());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010056 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
57
Roland Levillain1c1da432015-07-16 11:54:44 +010058 uint32_t number_of_location_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
Roland Levillaina552e1c2015-03-26 15:01:03 +000059 ASSERT_EQ(2u, number_of_location_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +010060 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +000061 // 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
David Brazdilf677ebf2015-05-29 16:29:43 +010067 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
68 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
69 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
70 ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
71 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
72 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010073
David Brazdilf677ebf2015-05-29 16:29:43 +010074 MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010075 ASSERT_TRUE(SameBits(stack_mask, sp_mask));
76
David Brazdilf677ebf2015-05-29 16:29:43 +010077 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +000078 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +010079 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +000080 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
David Brazdilf677ebf2015-05-29 16:29:43 +010089 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(
90 0, number_of_dex_registers, code_info, encoding));
91 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
92 1, number_of_dex_registers, code_info, encoding));
93 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind(
94 0, number_of_dex_registers, code_info, encoding));
95 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
96 1, number_of_dex_registers, code_info, encoding));
97 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(
98 0, number_of_dex_registers, code_info, encoding));
99 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000100
101 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
102 0, number_of_dex_registers, number_of_location_catalog_entries);
103 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
104 1, number_of_dex_registers, number_of_location_catalog_entries);
105 ASSERT_EQ(0u, index0);
106 ASSERT_EQ(1u, index1);
107 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
108 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
109 ASSERT_EQ(Kind::kInStack, location0.GetKind());
110 ASSERT_EQ(Kind::kConstant, location1.GetKind());
111 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
112 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000113 ASSERT_EQ(0, location0.GetValue());
114 ASSERT_EQ(-2, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000115
David Brazdilf677ebf2015-05-29 16:29:43 +0100116 ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100117}
118
119TEST(StackMapTest, Test2) {
120 ArenaPool pool;
121 ArenaAllocator arena(&pool);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100122 StackMapStream stream(&arena);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100123
124 ArenaBitVector sp_mask1(&arena, 0, true);
125 sp_mask1.SetBit(2);
126 sp_mask1.SetBit(4);
Roland Levillain12baf472015-03-05 12:41:42 +0000127 size_t number_of_dex_registers = 2;
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100128 size_t number_of_dex_registers_in_inline_info = 0;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100129 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100130 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
131 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100132 stream.BeginInlineInfoEntry(82, 3, kDirect, number_of_dex_registers_in_inline_info);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100133 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100134 stream.BeginInlineInfoEntry(42, 2, kStatic, number_of_dex_registers_in_inline_info);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100135 stream.EndInlineInfoEntry();
Calin Juravle4f46ac52015-04-23 18:47:21 +0100136 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100137
138 ArenaBitVector sp_mask2(&arena, 0, true);
139 sp_mask2.SetBit(3);
David Brazdilf10a25f2015-06-02 14:29:52 +0100140 sp_mask2.SetBit(8);
Calin Juravle4f46ac52015-04-23 18:47:21 +0100141 stream.BeginStackMapEntry(1, 128, 0xFF, &sp_mask2, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100142 stream.AddDexRegisterEntry(Kind::kInRegister, 18); // Short location.
143 stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3); // Short location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100144 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100145
David Brazdild9cb68e2015-08-25 13:52:43 +0100146 ArenaBitVector sp_mask3(&arena, 0, true);
147 sp_mask3.SetBit(1);
148 sp_mask3.SetBit(5);
149 stream.BeginStackMapEntry(2, 192, 0xAB, &sp_mask3, number_of_dex_registers, 0);
150 stream.AddDexRegisterEntry(Kind::kInRegister, 6); // Short location.
151 stream.AddDexRegisterEntry(Kind::kInRegisterHigh, 8); // Short location.
152 stream.EndStackMapEntry();
153
154 ArenaBitVector sp_mask4(&arena, 0, true);
155 sp_mask4.SetBit(6);
156 sp_mask4.SetBit(7);
157 stream.BeginStackMapEntry(3, 256, 0xCD, &sp_mask4, number_of_dex_registers, 0);
158 stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3); // Short location, same in stack map 2.
159 stream.AddDexRegisterEntry(Kind::kInFpuRegisterHigh, 1); // Short location.
160 stream.EndStackMapEntry();
161
Calin Juravle4f46ac52015-04-23 18:47:21 +0100162 size_t size = stream.PrepareForFillIn();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100163 void* memory = arena.Alloc(size, kArenaAllocMisc);
164 MemoryRegion region(memory, size);
165 stream.FillIn(region);
166
Nicolas Geoffray39468442014-09-02 15:17:15 +0100167 CodeInfo code_info(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100168 StackMapEncoding encoding = code_info.ExtractEncoding();
169 ASSERT_EQ(2u, encoding.NumberOfBytesForStackMask());
David Brazdild9cb68e2015-08-25 13:52:43 +0100170 ASSERT_EQ(4u, code_info.GetNumberOfStackMaps());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100171
Roland Levillain1c1da432015-07-16 11:54:44 +0100172 uint32_t number_of_location_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
David Brazdild9cb68e2015-08-25 13:52:43 +0100173 ASSERT_EQ(7u, number_of_location_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +0100174 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000175 // The Dex register location catalog contains:
David Brazdild9cb68e2015-08-25 13:52:43 +0100176 // - six 1-byte short Dex register locations, and
Roland Levillaina552e1c2015-03-26 15:01:03 +0000177 // - one 5-byte large Dex register location.
David Brazdild9cb68e2015-08-25 13:52:43 +0100178 size_t expected_location_catalog_size = 6u * 1u + 5u;
Roland Levillaina552e1c2015-03-26 15:01:03 +0000179 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
180
Roland Levillain12baf472015-03-05 12:41:42 +0000181 // First stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000182 {
David Brazdilf677ebf2015-05-29 16:29:43 +0100183 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
184 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
185 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
186 ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
187 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
188 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100189
David Brazdilf677ebf2015-05-29 16:29:43 +0100190 MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000191 ASSERT_TRUE(SameBits(stack_mask, sp_mask1));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100192
David Brazdilf677ebf2015-05-29 16:29:43 +0100193 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000194 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +0100195 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000196 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
197 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
198 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
199 // The Dex register map contains:
200 // - one 1-byte live bit mask, and
201 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
202 size_t expected_dex_register_map_size = 1u + 1u;
203 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
204
David Brazdilf677ebf2015-05-29 16:29:43 +0100205 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(
206 0, number_of_dex_registers, code_info, encoding));
207 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
208 1, number_of_dex_registers, code_info, encoding));
209 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind(
210 0, number_of_dex_registers, code_info, encoding));
211 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
212 1, number_of_dex_registers, code_info, encoding));
213 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(
214 0, number_of_dex_registers, code_info, encoding));
215 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000216
217 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
218 0, number_of_dex_registers, number_of_location_catalog_entries);
219 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
220 1, number_of_dex_registers, number_of_location_catalog_entries);
221 ASSERT_EQ(0u, index0);
222 ASSERT_EQ(1u, index1);
223 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
224 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
225 ASSERT_EQ(Kind::kInStack, location0.GetKind());
226 ASSERT_EQ(Kind::kConstant, location1.GetKind());
227 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
228 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000229 ASSERT_EQ(0, location0.GetValue());
230 ASSERT_EQ(-2, location1.GetValue());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100231
David Brazdilf677ebf2015-05-29 16:29:43 +0100232 ASSERT_TRUE(stack_map.HasInlineInfo(encoding));
233 InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000234 ASSERT_EQ(2u, inline_info.GetDepth());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100235 ASSERT_EQ(82u, inline_info.GetMethodIndexAtDepth(0));
236 ASSERT_EQ(42u, inline_info.GetMethodIndexAtDepth(1));
237 ASSERT_EQ(3u, inline_info.GetDexPcAtDepth(0));
238 ASSERT_EQ(2u, inline_info.GetDexPcAtDepth(1));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100239 ASSERT_EQ(kDirect, inline_info.GetInvokeTypeAtDepth(0));
240 ASSERT_EQ(kStatic, inline_info.GetInvokeTypeAtDepth(1));
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000241 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100242
Roland Levillain12baf472015-03-05 12:41:42 +0000243 // Second stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000244 {
David Brazdilf677ebf2015-05-29 16:29:43 +0100245 StackMap stack_map = code_info.GetStackMapAt(1, encoding);
246 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u, encoding)));
247 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u, encoding)));
248 ASSERT_EQ(1u, stack_map.GetDexPc(encoding));
249 ASSERT_EQ(128u, stack_map.GetNativePcOffset(encoding));
250 ASSERT_EQ(0xFFu, stack_map.GetRegisterMask(encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100251
David Brazdilf677ebf2015-05-29 16:29:43 +0100252 MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000253 ASSERT_TRUE(SameBits(stack_mask, sp_mask2));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100254
David Brazdilf677ebf2015-05-29 16:29:43 +0100255 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000256 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +0100257 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000258 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
259 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
260 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
261 // The Dex register map contains:
262 // - one 1-byte live bit mask, and
263 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
264 size_t expected_dex_register_map_size = 1u + 1u;
265 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
266
David Brazdilf677ebf2015-05-29 16:29:43 +0100267 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind(
268 0, number_of_dex_registers, code_info, encoding));
269 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind(
270 1, number_of_dex_registers, code_info, encoding));
271 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationInternalKind(
272 0, number_of_dex_registers, code_info, encoding));
273 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationInternalKind(
274 1, number_of_dex_registers, code_info, encoding));
275 ASSERT_EQ(18, dex_register_map.GetMachineRegister(
276 0, number_of_dex_registers, code_info, encoding));
277 ASSERT_EQ(3, dex_register_map.GetMachineRegister(
278 1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000279
280 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
281 0, number_of_dex_registers, number_of_location_catalog_entries);
282 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
283 1, number_of_dex_registers, number_of_location_catalog_entries);
284 ASSERT_EQ(2u, index0);
285 ASSERT_EQ(3u, index1);
286 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
287 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
288 ASSERT_EQ(Kind::kInRegister, location0.GetKind());
289 ASSERT_EQ(Kind::kInFpuRegister, location1.GetKind());
290 ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind());
291 ASSERT_EQ(Kind::kInFpuRegister, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000292 ASSERT_EQ(18, location0.GetValue());
293 ASSERT_EQ(3, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000294
David Brazdilf677ebf2015-05-29 16:29:43 +0100295 ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000296 }
David Brazdild9cb68e2015-08-25 13:52:43 +0100297
298 // Third stack map.
299 {
300 StackMap stack_map = code_info.GetStackMapAt(2, encoding);
301 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(2u, encoding)));
302 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(192u, encoding)));
303 ASSERT_EQ(2u, stack_map.GetDexPc(encoding));
304 ASSERT_EQ(192u, stack_map.GetNativePcOffset(encoding));
305 ASSERT_EQ(0xABu, stack_map.GetRegisterMask(encoding));
306
307 MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
308 ASSERT_TRUE(SameBits(stack_mask, sp_mask3));
309
310 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
311 DexRegisterMap dex_register_map =
312 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
313 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
314 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
315 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
316 // The Dex register map contains:
317 // - one 1-byte live bit mask, and
318 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
319 size_t expected_dex_register_map_size = 1u + 1u;
320 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
321
322 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind(
323 0, number_of_dex_registers, code_info, encoding));
324 ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map.GetLocationKind(
325 1, number_of_dex_registers, code_info, encoding));
326 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationInternalKind(
327 0, number_of_dex_registers, code_info, encoding));
328 ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map.GetLocationInternalKind(
329 1, number_of_dex_registers, code_info, encoding));
330 ASSERT_EQ(6, dex_register_map.GetMachineRegister(
331 0, number_of_dex_registers, code_info, encoding));
332 ASSERT_EQ(8, dex_register_map.GetMachineRegister(
333 1, number_of_dex_registers, code_info, encoding));
334
335 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
336 0, number_of_dex_registers, number_of_location_catalog_entries);
337 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
338 1, number_of_dex_registers, number_of_location_catalog_entries);
339 ASSERT_EQ(4u, index0);
340 ASSERT_EQ(5u, index1);
341 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
342 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
343 ASSERT_EQ(Kind::kInRegister, location0.GetKind());
344 ASSERT_EQ(Kind::kInRegisterHigh, location1.GetKind());
345 ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind());
346 ASSERT_EQ(Kind::kInRegisterHigh, location1.GetInternalKind());
347 ASSERT_EQ(6, location0.GetValue());
348 ASSERT_EQ(8, location1.GetValue());
349
350 ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
351 }
352
353 // Fourth stack map.
354 {
355 StackMap stack_map = code_info.GetStackMapAt(3, encoding);
356 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(3u, encoding)));
357 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(256u, encoding)));
358 ASSERT_EQ(3u, stack_map.GetDexPc(encoding));
359 ASSERT_EQ(256u, stack_map.GetNativePcOffset(encoding));
360 ASSERT_EQ(0xCDu, stack_map.GetRegisterMask(encoding));
361
362 MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
363 ASSERT_TRUE(SameBits(stack_mask, sp_mask4));
364
365 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
366 DexRegisterMap dex_register_map =
367 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
368 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
369 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
370 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
371 // The Dex register map contains:
372 // - one 1-byte live bit mask, and
373 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
374 size_t expected_dex_register_map_size = 1u + 1u;
375 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
376
377 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind(
378 0, number_of_dex_registers, code_info, encoding));
379 ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map.GetLocationKind(
380 1, number_of_dex_registers, code_info, encoding));
381 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationInternalKind(
382 0, number_of_dex_registers, code_info, encoding));
383 ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map.GetLocationInternalKind(
384 1, number_of_dex_registers, code_info, encoding));
385 ASSERT_EQ(3, dex_register_map.GetMachineRegister(
386 0, number_of_dex_registers, code_info, encoding));
387 ASSERT_EQ(1, dex_register_map.GetMachineRegister(
388 1, number_of_dex_registers, code_info, encoding));
389
390 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
391 0, number_of_dex_registers, number_of_location_catalog_entries);
392 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
393 1, number_of_dex_registers, number_of_location_catalog_entries);
394 ASSERT_EQ(3u, index0); // Shared with second stack map.
395 ASSERT_EQ(6u, index1);
396 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
397 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
398 ASSERT_EQ(Kind::kInFpuRegister, location0.GetKind());
399 ASSERT_EQ(Kind::kInFpuRegisterHigh, location1.GetKind());
400 ASSERT_EQ(Kind::kInFpuRegister, location0.GetInternalKind());
401 ASSERT_EQ(Kind::kInFpuRegisterHigh, location1.GetInternalKind());
402 ASSERT_EQ(3, location0.GetValue());
403 ASSERT_EQ(1, location1.GetValue());
404
405 ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
406 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100407}
408
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000409TEST(StackMapTest, TestNonLiveDexRegisters) {
410 ArenaPool pool;
411 ArenaAllocator arena(&pool);
412 StackMapStream stream(&arena);
413
414 ArenaBitVector sp_mask(&arena, 0, false);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000415 uint32_t number_of_dex_registers = 2;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100416 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100417 stream.AddDexRegisterEntry(Kind::kNone, 0); // No location.
418 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100419 stream.EndStackMapEntry();
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000420
Calin Juravle4f46ac52015-04-23 18:47:21 +0100421 size_t size = stream.PrepareForFillIn();
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000422 void* memory = arena.Alloc(size, kArenaAllocMisc);
423 MemoryRegion region(memory, size);
424 stream.FillIn(region);
425
426 CodeInfo code_info(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100427 StackMapEncoding encoding = code_info.ExtractEncoding();
428 ASSERT_EQ(0u, encoding.NumberOfBytesForStackMask());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000429 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
430
Roland Levillain1c1da432015-07-16 11:54:44 +0100431 uint32_t number_of_location_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000432 ASSERT_EQ(1u, number_of_location_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +0100433 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000434 // The Dex register location catalog contains:
435 // - one 5-byte large Dex register location.
436 size_t expected_location_catalog_size = 5u;
437 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
438
David Brazdilf677ebf2015-05-29 16:29:43 +0100439 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
440 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
441 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
442 ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
443 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
444 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000445
David Brazdilf677ebf2015-05-29 16:29:43 +0100446 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000447 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +0100448 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000449 ASSERT_FALSE(dex_register_map.IsDexRegisterLive(0));
450 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
451 ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
452 // The Dex register map contains:
453 // - one 1-byte live bit mask.
454 // No space is allocated for the sole location catalog entry index, as it is useless.
455 size_t expected_dex_register_map_size = 1u + 0u;
456 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
457
David Brazdilf677ebf2015-05-29 16:29:43 +0100458 ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationKind(
459 0, number_of_dex_registers, code_info, encoding));
460 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
461 1, number_of_dex_registers, code_info, encoding));
462 ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationInternalKind(
463 0, number_of_dex_registers, code_info, encoding));
464 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
465 1, number_of_dex_registers, code_info, encoding));
466 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000467
468 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
469 0, number_of_dex_registers, number_of_location_catalog_entries);
470 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
471 1, number_of_dex_registers, number_of_location_catalog_entries);
472 ASSERT_EQ(DexRegisterLocationCatalog::kNoLocationEntryIndex, index0);
473 ASSERT_EQ(0u, index1);
474 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
475 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
476 ASSERT_EQ(Kind::kNone, location0.GetKind());
477 ASSERT_EQ(Kind::kConstant, location1.GetKind());
478 ASSERT_EQ(Kind::kNone, location0.GetInternalKind());
479 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
480 ASSERT_EQ(0, location0.GetValue());
481 ASSERT_EQ(-2, location1.GetValue());
482
David Brazdilf677ebf2015-05-29 16:29:43 +0100483 ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000484}
485
486// Generate a stack map whose dex register offset is
487// StackMap::kNoDexRegisterMapSmallEncoding, and ensure we do
488// not treat it as kNoDexRegisterMap.
489TEST(StackMapTest, DexRegisterMapOffsetOverflow) {
490 ArenaPool pool;
491 ArenaAllocator arena(&pool);
492 StackMapStream stream(&arena);
493
494 ArenaBitVector sp_mask(&arena, 0, false);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000495 uint32_t number_of_dex_registers = 1024;
496 // Create the first stack map (and its Dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100497 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000498 uint32_t number_of_dex_live_registers_in_dex_register_map_0 = number_of_dex_registers - 8;
499 for (uint32_t i = 0; i < number_of_dex_live_registers_in_dex_register_map_0; ++i) {
500 // Use two different Dex register locations to populate this map,
501 // as using a single value (in the whole CodeInfo object) would
502 // make this Dex register mapping data empty (see
503 // art::DexRegisterMap::SingleEntrySizeInBits).
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100504 stream.AddDexRegisterEntry(Kind::kConstant, i % 2); // Short location.
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000505 }
Calin Juravle4f46ac52015-04-23 18:47:21 +0100506 stream.EndStackMapEntry();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000507 // Create the second stack map (and its Dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100508 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000509 for (uint32_t i = 0; i < number_of_dex_registers; ++i) {
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100510 stream.AddDexRegisterEntry(Kind::kConstant, 0); // Short location.
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000511 }
Calin Juravle4f46ac52015-04-23 18:47:21 +0100512 stream.EndStackMapEntry();
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000513
Calin Juravle4f46ac52015-04-23 18:47:21 +0100514 size_t size = stream.PrepareForFillIn();
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000515 void* memory = arena.Alloc(size, kArenaAllocMisc);
516 MemoryRegion region(memory, size);
517 stream.FillIn(region);
518
519 CodeInfo code_info(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100520 StackMapEncoding encoding = code_info.ExtractEncoding();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000521 // The location catalog contains two entries (DexRegisterLocation(kConstant, 0)
522 // and DexRegisterLocation(kConstant, 1)), therefore the location catalog index
523 // has a size of 1 bit.
Roland Levillain1c1da432015-07-16 11:54:44 +0100524 uint32_t number_of_location_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000525 ASSERT_EQ(2u, number_of_location_catalog_entries);
526 ASSERT_EQ(1u, DexRegisterMap::SingleEntrySizeInBits(number_of_location_catalog_entries));
527
528 // The first Dex register map contains:
529 // - a live register bit mask for 1024 registers (that is, 128 bytes of
530 // data); and
531 // - Dex register mapping information for 1016 1-bit Dex (live) register
532 // locations (that is, 127 bytes of data).
533 // Hence it has a size of 255 bytes, and therefore...
534 ASSERT_EQ(128u, DexRegisterMap::GetLiveBitMaskSize(number_of_dex_registers));
David Brazdilf677ebf2015-05-29 16:29:43 +0100535 StackMap stack_map0 = code_info.GetStackMapAt(0, encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000536 DexRegisterMap dex_register_map0 =
David Brazdilf677ebf2015-05-29 16:29:43 +0100537 code_info.GetDexRegisterMapOf(stack_map0, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000538 ASSERT_EQ(127u, dex_register_map0.GetLocationMappingDataSize(number_of_dex_registers,
539 number_of_location_catalog_entries));
540 ASSERT_EQ(255u, dex_register_map0.Size());
541
David Brazdilf677ebf2015-05-29 16:29:43 +0100542 StackMap stack_map1 = code_info.GetStackMapAt(1, encoding);
543 ASSERT_TRUE(stack_map1.HasDexRegisterMap(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000544 // ...the offset of the second Dex register map (relative to the
545 // beginning of the Dex register maps region) is 255 (i.e.,
546 // kNoDexRegisterMapSmallEncoding).
David Brazdilf677ebf2015-05-29 16:29:43 +0100547 ASSERT_NE(stack_map1.GetDexRegisterMapOffset(encoding), StackMap::kNoDexRegisterMap);
548 ASSERT_EQ(stack_map1.GetDexRegisterMapOffset(encoding), 0xFFu);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000549}
550
Calin Juravle6ae70962015-03-18 16:31:28 +0000551TEST(StackMapTest, TestShareDexRegisterMap) {
552 ArenaPool pool;
553 ArenaAllocator arena(&pool);
554 StackMapStream stream(&arena);
555
556 ArenaBitVector sp_mask(&arena, 0, false);
557 uint32_t number_of_dex_registers = 2;
558 // First stack map.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100559 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100560 stream.AddDexRegisterEntry(Kind::kInRegister, 0); // Short location.
561 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100562 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000563 // Second stack map, which should share the same dex register map.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100564 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100565 stream.AddDexRegisterEntry(Kind::kInRegister, 0); // Short location.
566 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100567 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000568 // Third stack map (doesn't share the dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100569 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100570 stream.AddDexRegisterEntry(Kind::kInRegister, 2); // Short location.
571 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100572 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000573
Calin Juravle4f46ac52015-04-23 18:47:21 +0100574 size_t size = stream.PrepareForFillIn();
Calin Juravle6ae70962015-03-18 16:31:28 +0000575 void* memory = arena.Alloc(size, kArenaAllocMisc);
576 MemoryRegion region(memory, size);
577 stream.FillIn(region);
578
579 CodeInfo ci(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100580 StackMapEncoding encoding = ci.ExtractEncoding();
581
Calin Juravle6ae70962015-03-18 16:31:28 +0000582 // Verify first stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100583 StackMap sm0 = ci.GetStackMapAt(0, encoding);
584 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, number_of_dex_registers);
585 ASSERT_EQ(0, dex_registers0.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
586 ASSERT_EQ(-2, dex_registers0.GetConstant(1, number_of_dex_registers, ci, encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000587
588 // Verify second stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100589 StackMap sm1 = ci.GetStackMapAt(1, encoding);
590 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1, encoding, number_of_dex_registers);
591 ASSERT_EQ(0, dex_registers1.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
592 ASSERT_EQ(-2, dex_registers1.GetConstant(1, number_of_dex_registers, ci, encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000593
594 // Verify third stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100595 StackMap sm2 = ci.GetStackMapAt(2, encoding);
596 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2, encoding, number_of_dex_registers);
597 ASSERT_EQ(2, dex_registers2.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
598 ASSERT_EQ(-2, dex_registers2.GetConstant(1, number_of_dex_registers, ci, encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000599
600 // Verify dex register map offsets.
David Brazdilf677ebf2015-05-29 16:29:43 +0100601 ASSERT_EQ(sm0.GetDexRegisterMapOffset(encoding), sm1.GetDexRegisterMapOffset(encoding));
602 ASSERT_NE(sm0.GetDexRegisterMapOffset(encoding), sm2.GetDexRegisterMapOffset(encoding));
603 ASSERT_NE(sm1.GetDexRegisterMapOffset(encoding), sm2.GetDexRegisterMapOffset(encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000604}
605
Roland Levillaina552e1c2015-03-26 15:01:03 +0000606TEST(StackMapTest, TestNoDexRegisterMap) {
607 ArenaPool pool;
608 ArenaAllocator arena(&pool);
609 StackMapStream stream(&arena);
610
611 ArenaBitVector sp_mask(&arena, 0, false);
612 uint32_t number_of_dex_registers = 0;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100613 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
614 stream.EndStackMapEntry();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000615
Calin Juravle4f46ac52015-04-23 18:47:21 +0100616 size_t size = stream.PrepareForFillIn();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000617 void* memory = arena.Alloc(size, kArenaAllocMisc);
618 MemoryRegion region(memory, size);
619 stream.FillIn(region);
620
621 CodeInfo code_info(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100622 StackMapEncoding encoding = code_info.ExtractEncoding();
623 ASSERT_EQ(0u, encoding.NumberOfBytesForStackMask());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000624 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
625
Roland Levillain1c1da432015-07-16 11:54:44 +0100626 uint32_t number_of_location_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000627 ASSERT_EQ(0u, number_of_location_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +0100628 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000629 ASSERT_EQ(0u, location_catalog.Size());
630
David Brazdilf677ebf2015-05-29 16:29:43 +0100631 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
632 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
633 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
634 ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
635 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
636 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000637
David Brazdilf677ebf2015-05-29 16:29:43 +0100638 ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding));
639 ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000640}
641
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100642TEST(StackMapTest, InlineTest) {
643 ArenaPool pool;
644 ArenaAllocator arena(&pool);
645 StackMapStream stream(&arena);
646
647 ArenaBitVector sp_mask1(&arena, 0, true);
648 sp_mask1.SetBit(2);
649 sp_mask1.SetBit(4);
650
651 // First stack map.
652 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, 2, 2);
653 stream.AddDexRegisterEntry(Kind::kInStack, 0);
654 stream.AddDexRegisterEntry(Kind::kConstant, 4);
655
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100656 stream.BeginInlineInfoEntry(42, 2, kStatic, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100657 stream.AddDexRegisterEntry(Kind::kInStack, 8);
658 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100659 stream.BeginInlineInfoEntry(82, 3, kStatic, 3);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100660 stream.AddDexRegisterEntry(Kind::kInStack, 16);
661 stream.AddDexRegisterEntry(Kind::kConstant, 20);
662 stream.AddDexRegisterEntry(Kind::kInRegister, 15);
663 stream.EndInlineInfoEntry();
664
665 stream.EndStackMapEntry();
666
667 // Second stack map.
668 stream.BeginStackMapEntry(2, 22, 0x3, &sp_mask1, 2, 3);
669 stream.AddDexRegisterEntry(Kind::kInStack, 56);
670 stream.AddDexRegisterEntry(Kind::kConstant, 0);
671
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100672 stream.BeginInlineInfoEntry(42, 2, kDirect, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100673 stream.AddDexRegisterEntry(Kind::kInStack, 12);
674 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100675 stream.BeginInlineInfoEntry(82, 3, kStatic, 3);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100676 stream.AddDexRegisterEntry(Kind::kInStack, 80);
677 stream.AddDexRegisterEntry(Kind::kConstant, 10);
678 stream.AddDexRegisterEntry(Kind::kInRegister, 5);
679 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100680 stream.BeginInlineInfoEntry(52, 5, kVirtual, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100681 stream.EndInlineInfoEntry();
682
683 stream.EndStackMapEntry();
684
685 // Third stack map.
686 stream.BeginStackMapEntry(4, 56, 0x3, &sp_mask1, 2, 0);
687 stream.AddDexRegisterEntry(Kind::kNone, 0);
688 stream.AddDexRegisterEntry(Kind::kConstant, 4);
689 stream.EndStackMapEntry();
690
691 // Fourth stack map.
692 stream.BeginStackMapEntry(6, 78, 0x3, &sp_mask1, 2, 3);
693 stream.AddDexRegisterEntry(Kind::kInStack, 56);
694 stream.AddDexRegisterEntry(Kind::kConstant, 0);
695
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100696 stream.BeginInlineInfoEntry(42, 2, kVirtual, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100697 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100698 stream.BeginInlineInfoEntry(52, 5, kInterface, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100699 stream.AddDexRegisterEntry(Kind::kInRegister, 2);
700 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100701 stream.BeginInlineInfoEntry(52, 10, kStatic, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100702 stream.AddDexRegisterEntry(Kind::kNone, 0);
703 stream.AddDexRegisterEntry(Kind::kInRegister, 3);
704 stream.EndInlineInfoEntry();
705
706 stream.EndStackMapEntry();
707
708 size_t size = stream.PrepareForFillIn();
709 void* memory = arena.Alloc(size, kArenaAllocMisc);
710 MemoryRegion region(memory, size);
711 stream.FillIn(region);
712
713 CodeInfo ci(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100714 StackMapEncoding encoding = ci.ExtractEncoding();
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100715
716 {
717 // Verify first stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100718 StackMap sm0 = ci.GetStackMapAt(0, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100719
David Brazdilf677ebf2015-05-29 16:29:43 +0100720 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, 2);
721 ASSERT_EQ(0, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
722 ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100723
David Brazdilf677ebf2015-05-29 16:29:43 +0100724 InlineInfo if0 = ci.GetInlineInfoOf(sm0, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100725 ASSERT_EQ(2u, if0.GetDepth());
726 ASSERT_EQ(2u, if0.GetDexPcAtDepth(0));
727 ASSERT_EQ(42u, if0.GetMethodIndexAtDepth(0));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100728 ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(0));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100729 ASSERT_EQ(3u, if0.GetDexPcAtDepth(1));
730 ASSERT_EQ(82u, if0.GetMethodIndexAtDepth(1));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100731 ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(1));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100732
David Brazdilf677ebf2015-05-29 16:29:43 +0100733 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if0, encoding, 1);
734 ASSERT_EQ(8, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100735
David Brazdilf677ebf2015-05-29 16:29:43 +0100736 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if0, encoding, 3);
737 ASSERT_EQ(16, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding));
738 ASSERT_EQ(20, dex_registers2.GetConstant(1, 3, ci, encoding));
739 ASSERT_EQ(15, dex_registers2.GetMachineRegister(2, 3, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100740 }
741
742 {
743 // Verify second stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100744 StackMap sm1 = ci.GetStackMapAt(1, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100745
David Brazdilf677ebf2015-05-29 16:29:43 +0100746 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm1, encoding, 2);
747 ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
748 ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100749
David Brazdilf677ebf2015-05-29 16:29:43 +0100750 InlineInfo if1 = ci.GetInlineInfoOf(sm1, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100751 ASSERT_EQ(3u, if1.GetDepth());
752 ASSERT_EQ(2u, if1.GetDexPcAtDepth(0));
753 ASSERT_EQ(42u, if1.GetMethodIndexAtDepth(0));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100754 ASSERT_EQ(kDirect, if1.GetInvokeTypeAtDepth(0));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100755 ASSERT_EQ(3u, if1.GetDexPcAtDepth(1));
756 ASSERT_EQ(82u, if1.GetMethodIndexAtDepth(1));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100757 ASSERT_EQ(kStatic, if1.GetInvokeTypeAtDepth(1));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100758 ASSERT_EQ(5u, if1.GetDexPcAtDepth(2));
759 ASSERT_EQ(52u, if1.GetMethodIndexAtDepth(2));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100760 ASSERT_EQ(kVirtual, if1.GetInvokeTypeAtDepth(2));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100761
David Brazdilf677ebf2015-05-29 16:29:43 +0100762 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if1, encoding, 1);
763 ASSERT_EQ(12, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100764
David Brazdilf677ebf2015-05-29 16:29:43 +0100765 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if1, encoding, 3);
766 ASSERT_EQ(80, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding));
767 ASSERT_EQ(10, dex_registers2.GetConstant(1, 3, ci, encoding));
768 ASSERT_EQ(5, dex_registers2.GetMachineRegister(2, 3, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100769
770 ASSERT_FALSE(if1.HasDexRegisterMapAtDepth(2));
771 }
772
773 {
774 // Verify third stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100775 StackMap sm2 = ci.GetStackMapAt(2, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100776
David Brazdilf677ebf2015-05-29 16:29:43 +0100777 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm2, encoding, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100778 ASSERT_FALSE(dex_registers0.IsDexRegisterLive(0));
David Brazdilf677ebf2015-05-29 16:29:43 +0100779 ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding));
780 ASSERT_FALSE(sm2.HasInlineInfo(encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100781 }
782
783 {
784 // Verify fourth stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100785 StackMap sm3 = ci.GetStackMapAt(3, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100786
David Brazdilf677ebf2015-05-29 16:29:43 +0100787 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm3, encoding, 2);
788 ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
789 ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100790
David Brazdilf677ebf2015-05-29 16:29:43 +0100791 InlineInfo if2 = ci.GetInlineInfoOf(sm3, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100792 ASSERT_EQ(3u, if2.GetDepth());
793 ASSERT_EQ(2u, if2.GetDexPcAtDepth(0));
794 ASSERT_EQ(42u, if2.GetMethodIndexAtDepth(0));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100795 ASSERT_EQ(kVirtual, if2.GetInvokeTypeAtDepth(0));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100796 ASSERT_EQ(5u, if2.GetDexPcAtDepth(1));
797 ASSERT_EQ(52u, if2.GetMethodIndexAtDepth(1));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100798 ASSERT_EQ(kInterface, if2.GetInvokeTypeAtDepth(1));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100799 ASSERT_EQ(10u, if2.GetDexPcAtDepth(2));
800 ASSERT_EQ(52u, if2.GetMethodIndexAtDepth(2));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100801 ASSERT_EQ(kStatic, if2.GetInvokeTypeAtDepth(2));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100802
803 ASSERT_FALSE(if2.HasDexRegisterMapAtDepth(0));
804
David Brazdilf677ebf2015-05-29 16:29:43 +0100805 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(1, if2, encoding, 1);
806 ASSERT_EQ(2, dex_registers1.GetMachineRegister(0, 1, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100807
David Brazdilf677ebf2015-05-29 16:29:43 +0100808 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(2, if2, encoding, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100809 ASSERT_FALSE(dex_registers2.IsDexRegisterLive(0));
David Brazdilf677ebf2015-05-29 16:29:43 +0100810 ASSERT_EQ(3, dex_registers2.GetMachineRegister(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100811 }
812}
813
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100814} // namespace art