blob: b4ac1b4d1a4440c99eca5f62d8896839299f9996 [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 Levillaina552e1c2015-03-26 15:01:03 +000058 uint32_t number_of_location_catalog_entries =
59 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
60 ASSERT_EQ(2u, number_of_location_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +010061 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +000062 // The Dex register location catalog contains:
63 // - one 1-byte short Dex register location, and
64 // - one 5-byte large Dex register location.
65 size_t expected_location_catalog_size = 1u + 5u;
66 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
67
David Brazdilf677ebf2015-05-29 16:29:43 +010068 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
69 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
70 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
71 ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
72 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
73 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010074
David Brazdilf677ebf2015-05-29 16:29:43 +010075 MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010076 ASSERT_TRUE(SameBits(stack_mask, sp_mask));
77
David Brazdilf677ebf2015-05-29 16:29:43 +010078 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +000079 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +010080 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +000081 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
82 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
83 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
84 // The Dex register map contains:
85 // - one 1-byte live bit mask, and
86 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
87 size_t expected_dex_register_map_size = 1u + 1u;
88 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
89
David Brazdilf677ebf2015-05-29 16:29:43 +010090 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(
91 0, number_of_dex_registers, code_info, encoding));
92 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
93 1, number_of_dex_registers, code_info, encoding));
94 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind(
95 0, number_of_dex_registers, code_info, encoding));
96 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
97 1, number_of_dex_registers, code_info, encoding));
98 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(
99 0, number_of_dex_registers, code_info, encoding));
100 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000101
102 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
103 0, number_of_dex_registers, number_of_location_catalog_entries);
104 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
105 1, number_of_dex_registers, number_of_location_catalog_entries);
106 ASSERT_EQ(0u, index0);
107 ASSERT_EQ(1u, index1);
108 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
109 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
110 ASSERT_EQ(Kind::kInStack, location0.GetKind());
111 ASSERT_EQ(Kind::kConstant, location1.GetKind());
112 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
113 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000114 ASSERT_EQ(0, location0.GetValue());
115 ASSERT_EQ(-2, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000116
David Brazdilf677ebf2015-05-29 16:29:43 +0100117 ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100118}
119
120TEST(StackMapTest, Test2) {
121 ArenaPool pool;
122 ArenaAllocator arena(&pool);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100123 StackMapStream stream(&arena);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100124
125 ArenaBitVector sp_mask1(&arena, 0, true);
126 sp_mask1.SetBit(2);
127 sp_mask1.SetBit(4);
Roland Levillain12baf472015-03-05 12:41:42 +0000128 size_t number_of_dex_registers = 2;
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100129 size_t number_of_dex_registers_in_inline_info = 0;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100130 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100131 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
132 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100133 stream.BeginInlineInfoEntry(82, 3, kDirect, number_of_dex_registers_in_inline_info);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100134 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100135 stream.BeginInlineInfoEntry(42, 2, kStatic, number_of_dex_registers_in_inline_info);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100136 stream.EndInlineInfoEntry();
Calin Juravle4f46ac52015-04-23 18:47:21 +0100137 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100138
139 ArenaBitVector sp_mask2(&arena, 0, true);
140 sp_mask2.SetBit(3);
David Brazdilf10a25f2015-06-02 14:29:52 +0100141 sp_mask2.SetBit(8);
Calin Juravle4f46ac52015-04-23 18:47:21 +0100142 stream.BeginStackMapEntry(1, 128, 0xFF, &sp_mask2, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100143 stream.AddDexRegisterEntry(Kind::kInRegister, 18); // Short location.
144 stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3); // Short location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100145 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100146
Calin Juravle4f46ac52015-04-23 18:47:21 +0100147 size_t size = stream.PrepareForFillIn();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100148 void* memory = arena.Alloc(size, kArenaAllocMisc);
149 MemoryRegion region(memory, size);
150 stream.FillIn(region);
151
Nicolas Geoffray39468442014-09-02 15:17:15 +0100152 CodeInfo code_info(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100153 StackMapEncoding encoding = code_info.ExtractEncoding();
154 ASSERT_EQ(2u, encoding.NumberOfBytesForStackMask());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100155 ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
156
Roland Levillaina552e1c2015-03-26 15:01:03 +0000157 uint32_t number_of_location_catalog_entries =
158 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
159 ASSERT_EQ(4u, number_of_location_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +0100160 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000161 // The Dex register location catalog contains:
162 // - three 1-byte short Dex register locations, and
163 // - one 5-byte large Dex register location.
164 size_t expected_location_catalog_size = 3u * 1u + 5u;
165 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
166
Roland Levillain12baf472015-03-05 12:41:42 +0000167 // First stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000168 {
David Brazdilf677ebf2015-05-29 16:29:43 +0100169 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
170 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
171 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
172 ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
173 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
174 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100175
David Brazdilf677ebf2015-05-29 16:29:43 +0100176 MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000177 ASSERT_TRUE(SameBits(stack_mask, sp_mask1));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100178
David Brazdilf677ebf2015-05-29 16:29:43 +0100179 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000180 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +0100181 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000182 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
183 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
184 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
185 // The Dex register map contains:
186 // - one 1-byte live bit mask, and
187 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
188 size_t expected_dex_register_map_size = 1u + 1u;
189 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
190
David Brazdilf677ebf2015-05-29 16:29:43 +0100191 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(
192 0, number_of_dex_registers, code_info, encoding));
193 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
194 1, number_of_dex_registers, code_info, encoding));
195 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind(
196 0, number_of_dex_registers, code_info, encoding));
197 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
198 1, number_of_dex_registers, code_info, encoding));
199 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(
200 0, number_of_dex_registers, code_info, encoding));
201 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000202
203 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
204 0, number_of_dex_registers, number_of_location_catalog_entries);
205 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
206 1, number_of_dex_registers, number_of_location_catalog_entries);
207 ASSERT_EQ(0u, index0);
208 ASSERT_EQ(1u, index1);
209 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
210 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
211 ASSERT_EQ(Kind::kInStack, location0.GetKind());
212 ASSERT_EQ(Kind::kConstant, location1.GetKind());
213 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
214 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000215 ASSERT_EQ(0, location0.GetValue());
216 ASSERT_EQ(-2, location1.GetValue());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100217
David Brazdilf677ebf2015-05-29 16:29:43 +0100218 ASSERT_TRUE(stack_map.HasInlineInfo(encoding));
219 InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000220 ASSERT_EQ(2u, inline_info.GetDepth());
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100221 ASSERT_EQ(82u, inline_info.GetMethodIndexAtDepth(0));
222 ASSERT_EQ(42u, inline_info.GetMethodIndexAtDepth(1));
223 ASSERT_EQ(3u, inline_info.GetDexPcAtDepth(0));
224 ASSERT_EQ(2u, inline_info.GetDexPcAtDepth(1));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100225 ASSERT_EQ(kDirect, inline_info.GetInvokeTypeAtDepth(0));
226 ASSERT_EQ(kStatic, inline_info.GetInvokeTypeAtDepth(1));
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000227 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100228
Roland Levillain12baf472015-03-05 12:41:42 +0000229 // Second stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000230 {
David Brazdilf677ebf2015-05-29 16:29:43 +0100231 StackMap stack_map = code_info.GetStackMapAt(1, encoding);
232 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u, encoding)));
233 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u, encoding)));
234 ASSERT_EQ(1u, stack_map.GetDexPc(encoding));
235 ASSERT_EQ(128u, stack_map.GetNativePcOffset(encoding));
236 ASSERT_EQ(0xFFu, stack_map.GetRegisterMask(encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100237
David Brazdilf677ebf2015-05-29 16:29:43 +0100238 MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000239 ASSERT_TRUE(SameBits(stack_mask, sp_mask2));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100240
David Brazdilf677ebf2015-05-29 16:29:43 +0100241 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000242 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +0100243 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000244 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
245 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
246 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
247 // The Dex register map contains:
248 // - one 1-byte live bit mask, and
249 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
250 size_t expected_dex_register_map_size = 1u + 1u;
251 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
252
David Brazdilf677ebf2015-05-29 16:29:43 +0100253 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind(
254 0, number_of_dex_registers, code_info, encoding));
255 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind(
256 1, number_of_dex_registers, code_info, encoding));
257 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationInternalKind(
258 0, number_of_dex_registers, code_info, encoding));
259 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationInternalKind(
260 1, number_of_dex_registers, code_info, encoding));
261 ASSERT_EQ(18, dex_register_map.GetMachineRegister(
262 0, number_of_dex_registers, code_info, encoding));
263 ASSERT_EQ(3, dex_register_map.GetMachineRegister(
264 1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000265
266 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
267 0, number_of_dex_registers, number_of_location_catalog_entries);
268 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
269 1, number_of_dex_registers, number_of_location_catalog_entries);
270 ASSERT_EQ(2u, index0);
271 ASSERT_EQ(3u, index1);
272 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
273 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
274 ASSERT_EQ(Kind::kInRegister, location0.GetKind());
275 ASSERT_EQ(Kind::kInFpuRegister, location1.GetKind());
276 ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind());
277 ASSERT_EQ(Kind::kInFpuRegister, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000278 ASSERT_EQ(18, location0.GetValue());
279 ASSERT_EQ(3, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000280
David Brazdilf677ebf2015-05-29 16:29:43 +0100281 ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000282 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100283}
284
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000285TEST(StackMapTest, TestNonLiveDexRegisters) {
286 ArenaPool pool;
287 ArenaAllocator arena(&pool);
288 StackMapStream stream(&arena);
289
290 ArenaBitVector sp_mask(&arena, 0, false);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000291 uint32_t number_of_dex_registers = 2;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100292 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100293 stream.AddDexRegisterEntry(Kind::kNone, 0); // No location.
294 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100295 stream.EndStackMapEntry();
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000296
Calin Juravle4f46ac52015-04-23 18:47:21 +0100297 size_t size = stream.PrepareForFillIn();
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000298 void* memory = arena.Alloc(size, kArenaAllocMisc);
299 MemoryRegion region(memory, size);
300 stream.FillIn(region);
301
302 CodeInfo code_info(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100303 StackMapEncoding encoding = code_info.ExtractEncoding();
304 ASSERT_EQ(0u, encoding.NumberOfBytesForStackMask());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000305 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
306
307 uint32_t number_of_location_catalog_entries =
308 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
309 ASSERT_EQ(1u, number_of_location_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +0100310 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000311 // The Dex register location catalog contains:
312 // - one 5-byte large Dex register location.
313 size_t expected_location_catalog_size = 5u;
314 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
315
David Brazdilf677ebf2015-05-29 16:29:43 +0100316 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
317 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
318 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
319 ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
320 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
321 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000322
David Brazdilf677ebf2015-05-29 16:29:43 +0100323 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000324 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +0100325 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000326 ASSERT_FALSE(dex_register_map.IsDexRegisterLive(0));
327 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
328 ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
329 // The Dex register map contains:
330 // - one 1-byte live bit mask.
331 // No space is allocated for the sole location catalog entry index, as it is useless.
332 size_t expected_dex_register_map_size = 1u + 0u;
333 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
334
David Brazdilf677ebf2015-05-29 16:29:43 +0100335 ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationKind(
336 0, number_of_dex_registers, code_info, encoding));
337 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
338 1, number_of_dex_registers, code_info, encoding));
339 ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationInternalKind(
340 0, number_of_dex_registers, code_info, encoding));
341 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
342 1, number_of_dex_registers, code_info, encoding));
343 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000344
345 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
346 0, number_of_dex_registers, number_of_location_catalog_entries);
347 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
348 1, number_of_dex_registers, number_of_location_catalog_entries);
349 ASSERT_EQ(DexRegisterLocationCatalog::kNoLocationEntryIndex, index0);
350 ASSERT_EQ(0u, index1);
351 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
352 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
353 ASSERT_EQ(Kind::kNone, location0.GetKind());
354 ASSERT_EQ(Kind::kConstant, location1.GetKind());
355 ASSERT_EQ(Kind::kNone, location0.GetInternalKind());
356 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
357 ASSERT_EQ(0, location0.GetValue());
358 ASSERT_EQ(-2, location1.GetValue());
359
David Brazdilf677ebf2015-05-29 16:29:43 +0100360 ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000361}
362
363// Generate a stack map whose dex register offset is
364// StackMap::kNoDexRegisterMapSmallEncoding, and ensure we do
365// not treat it as kNoDexRegisterMap.
366TEST(StackMapTest, DexRegisterMapOffsetOverflow) {
367 ArenaPool pool;
368 ArenaAllocator arena(&pool);
369 StackMapStream stream(&arena);
370
371 ArenaBitVector sp_mask(&arena, 0, false);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000372 uint32_t number_of_dex_registers = 1024;
373 // Create the first stack map (and its Dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100374 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000375 uint32_t number_of_dex_live_registers_in_dex_register_map_0 = number_of_dex_registers - 8;
376 for (uint32_t i = 0; i < number_of_dex_live_registers_in_dex_register_map_0; ++i) {
377 // Use two different Dex register locations to populate this map,
378 // as using a single value (in the whole CodeInfo object) would
379 // make this Dex register mapping data empty (see
380 // art::DexRegisterMap::SingleEntrySizeInBits).
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100381 stream.AddDexRegisterEntry(Kind::kConstant, i % 2); // Short location.
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000382 }
Calin Juravle4f46ac52015-04-23 18:47:21 +0100383 stream.EndStackMapEntry();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000384 // Create the second stack map (and its Dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100385 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000386 for (uint32_t i = 0; i < number_of_dex_registers; ++i) {
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100387 stream.AddDexRegisterEntry(Kind::kConstant, 0); // Short location.
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000388 }
Calin Juravle4f46ac52015-04-23 18:47:21 +0100389 stream.EndStackMapEntry();
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000390
Calin Juravle4f46ac52015-04-23 18:47:21 +0100391 size_t size = stream.PrepareForFillIn();
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000392 void* memory = arena.Alloc(size, kArenaAllocMisc);
393 MemoryRegion region(memory, size);
394 stream.FillIn(region);
395
396 CodeInfo code_info(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100397 StackMapEncoding encoding = code_info.ExtractEncoding();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000398 // The location catalog contains two entries (DexRegisterLocation(kConstant, 0)
399 // and DexRegisterLocation(kConstant, 1)), therefore the location catalog index
400 // has a size of 1 bit.
401 uint32_t number_of_location_catalog_entries =
402 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
403 ASSERT_EQ(2u, number_of_location_catalog_entries);
404 ASSERT_EQ(1u, DexRegisterMap::SingleEntrySizeInBits(number_of_location_catalog_entries));
405
406 // The first Dex register map contains:
407 // - a live register bit mask for 1024 registers (that is, 128 bytes of
408 // data); and
409 // - Dex register mapping information for 1016 1-bit Dex (live) register
410 // locations (that is, 127 bytes of data).
411 // Hence it has a size of 255 bytes, and therefore...
412 ASSERT_EQ(128u, DexRegisterMap::GetLiveBitMaskSize(number_of_dex_registers));
David Brazdilf677ebf2015-05-29 16:29:43 +0100413 StackMap stack_map0 = code_info.GetStackMapAt(0, encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000414 DexRegisterMap dex_register_map0 =
David Brazdilf677ebf2015-05-29 16:29:43 +0100415 code_info.GetDexRegisterMapOf(stack_map0, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000416 ASSERT_EQ(127u, dex_register_map0.GetLocationMappingDataSize(number_of_dex_registers,
417 number_of_location_catalog_entries));
418 ASSERT_EQ(255u, dex_register_map0.Size());
419
David Brazdilf677ebf2015-05-29 16:29:43 +0100420 StackMap stack_map1 = code_info.GetStackMapAt(1, encoding);
421 ASSERT_TRUE(stack_map1.HasDexRegisterMap(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000422 // ...the offset of the second Dex register map (relative to the
423 // beginning of the Dex register maps region) is 255 (i.e.,
424 // kNoDexRegisterMapSmallEncoding).
David Brazdilf677ebf2015-05-29 16:29:43 +0100425 ASSERT_NE(stack_map1.GetDexRegisterMapOffset(encoding), StackMap::kNoDexRegisterMap);
426 ASSERT_EQ(stack_map1.GetDexRegisterMapOffset(encoding), 0xFFu);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000427}
428
Calin Juravle6ae70962015-03-18 16:31:28 +0000429TEST(StackMapTest, TestShareDexRegisterMap) {
430 ArenaPool pool;
431 ArenaAllocator arena(&pool);
432 StackMapStream stream(&arena);
433
434 ArenaBitVector sp_mask(&arena, 0, false);
435 uint32_t number_of_dex_registers = 2;
436 // First stack map.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100437 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100438 stream.AddDexRegisterEntry(Kind::kInRegister, 0); // Short location.
439 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100440 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000441 // Second stack map, which should share the same dex register map.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100442 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100443 stream.AddDexRegisterEntry(Kind::kInRegister, 0); // Short location.
444 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100445 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000446 // Third stack map (doesn't share the dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100447 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100448 stream.AddDexRegisterEntry(Kind::kInRegister, 2); // Short location.
449 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100450 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000451
Calin Juravle4f46ac52015-04-23 18:47:21 +0100452 size_t size = stream.PrepareForFillIn();
Calin Juravle6ae70962015-03-18 16:31:28 +0000453 void* memory = arena.Alloc(size, kArenaAllocMisc);
454 MemoryRegion region(memory, size);
455 stream.FillIn(region);
456
457 CodeInfo ci(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100458 StackMapEncoding encoding = ci.ExtractEncoding();
459
Calin Juravle6ae70962015-03-18 16:31:28 +0000460 // Verify first stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100461 StackMap sm0 = ci.GetStackMapAt(0, encoding);
462 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, number_of_dex_registers);
463 ASSERT_EQ(0, dex_registers0.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
464 ASSERT_EQ(-2, dex_registers0.GetConstant(1, number_of_dex_registers, ci, encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000465
466 // Verify second stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100467 StackMap sm1 = ci.GetStackMapAt(1, encoding);
468 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1, encoding, number_of_dex_registers);
469 ASSERT_EQ(0, dex_registers1.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
470 ASSERT_EQ(-2, dex_registers1.GetConstant(1, number_of_dex_registers, ci, encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000471
472 // Verify third stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100473 StackMap sm2 = ci.GetStackMapAt(2, encoding);
474 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2, encoding, number_of_dex_registers);
475 ASSERT_EQ(2, dex_registers2.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
476 ASSERT_EQ(-2, dex_registers2.GetConstant(1, number_of_dex_registers, ci, encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000477
478 // Verify dex register map offsets.
David Brazdilf677ebf2015-05-29 16:29:43 +0100479 ASSERT_EQ(sm0.GetDexRegisterMapOffset(encoding), sm1.GetDexRegisterMapOffset(encoding));
480 ASSERT_NE(sm0.GetDexRegisterMapOffset(encoding), sm2.GetDexRegisterMapOffset(encoding));
481 ASSERT_NE(sm1.GetDexRegisterMapOffset(encoding), sm2.GetDexRegisterMapOffset(encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000482}
483
Roland Levillaina552e1c2015-03-26 15:01:03 +0000484TEST(StackMapTest, TestNoDexRegisterMap) {
485 ArenaPool pool;
486 ArenaAllocator arena(&pool);
487 StackMapStream stream(&arena);
488
489 ArenaBitVector sp_mask(&arena, 0, false);
490 uint32_t number_of_dex_registers = 0;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100491 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
492 stream.EndStackMapEntry();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000493
Calin Juravle4f46ac52015-04-23 18:47:21 +0100494 size_t size = stream.PrepareForFillIn();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000495 void* memory = arena.Alloc(size, kArenaAllocMisc);
496 MemoryRegion region(memory, size);
497 stream.FillIn(region);
498
499 CodeInfo code_info(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100500 StackMapEncoding encoding = code_info.ExtractEncoding();
501 ASSERT_EQ(0u, encoding.NumberOfBytesForStackMask());
Roland Levillaina552e1c2015-03-26 15:01:03 +0000502 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
503
504 uint32_t number_of_location_catalog_entries =
505 code_info.GetNumberOfDexRegisterLocationCatalogEntries();
506 ASSERT_EQ(0u, number_of_location_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +0100507 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000508 ASSERT_EQ(0u, location_catalog.Size());
509
David Brazdilf677ebf2015-05-29 16:29:43 +0100510 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
511 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
512 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
513 ASSERT_EQ(0u, stack_map.GetDexPc(encoding));
514 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding));
515 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000516
David Brazdilf677ebf2015-05-29 16:29:43 +0100517 ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding));
518 ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000519}
520
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100521TEST(StackMapTest, InlineTest) {
522 ArenaPool pool;
523 ArenaAllocator arena(&pool);
524 StackMapStream stream(&arena);
525
526 ArenaBitVector sp_mask1(&arena, 0, true);
527 sp_mask1.SetBit(2);
528 sp_mask1.SetBit(4);
529
530 // First stack map.
531 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, 2, 2);
532 stream.AddDexRegisterEntry(Kind::kInStack, 0);
533 stream.AddDexRegisterEntry(Kind::kConstant, 4);
534
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100535 stream.BeginInlineInfoEntry(42, 2, kStatic, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100536 stream.AddDexRegisterEntry(Kind::kInStack, 8);
537 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100538 stream.BeginInlineInfoEntry(82, 3, kStatic, 3);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100539 stream.AddDexRegisterEntry(Kind::kInStack, 16);
540 stream.AddDexRegisterEntry(Kind::kConstant, 20);
541 stream.AddDexRegisterEntry(Kind::kInRegister, 15);
542 stream.EndInlineInfoEntry();
543
544 stream.EndStackMapEntry();
545
546 // Second stack map.
547 stream.BeginStackMapEntry(2, 22, 0x3, &sp_mask1, 2, 3);
548 stream.AddDexRegisterEntry(Kind::kInStack, 56);
549 stream.AddDexRegisterEntry(Kind::kConstant, 0);
550
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100551 stream.BeginInlineInfoEntry(42, 2, kDirect, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100552 stream.AddDexRegisterEntry(Kind::kInStack, 12);
553 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100554 stream.BeginInlineInfoEntry(82, 3, kStatic, 3);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100555 stream.AddDexRegisterEntry(Kind::kInStack, 80);
556 stream.AddDexRegisterEntry(Kind::kConstant, 10);
557 stream.AddDexRegisterEntry(Kind::kInRegister, 5);
558 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100559 stream.BeginInlineInfoEntry(52, 5, kVirtual, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100560 stream.EndInlineInfoEntry();
561
562 stream.EndStackMapEntry();
563
564 // Third stack map.
565 stream.BeginStackMapEntry(4, 56, 0x3, &sp_mask1, 2, 0);
566 stream.AddDexRegisterEntry(Kind::kNone, 0);
567 stream.AddDexRegisterEntry(Kind::kConstant, 4);
568 stream.EndStackMapEntry();
569
570 // Fourth stack map.
571 stream.BeginStackMapEntry(6, 78, 0x3, &sp_mask1, 2, 3);
572 stream.AddDexRegisterEntry(Kind::kInStack, 56);
573 stream.AddDexRegisterEntry(Kind::kConstant, 0);
574
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100575 stream.BeginInlineInfoEntry(42, 2, kVirtual, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100576 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100577 stream.BeginInlineInfoEntry(52, 5, kInterface, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100578 stream.AddDexRegisterEntry(Kind::kInRegister, 2);
579 stream.EndInlineInfoEntry();
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100580 stream.BeginInlineInfoEntry(52, 10, kStatic, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100581 stream.AddDexRegisterEntry(Kind::kNone, 0);
582 stream.AddDexRegisterEntry(Kind::kInRegister, 3);
583 stream.EndInlineInfoEntry();
584
585 stream.EndStackMapEntry();
586
587 size_t size = stream.PrepareForFillIn();
588 void* memory = arena.Alloc(size, kArenaAllocMisc);
589 MemoryRegion region(memory, size);
590 stream.FillIn(region);
591
592 CodeInfo ci(region);
David Brazdilf677ebf2015-05-29 16:29:43 +0100593 StackMapEncoding encoding = ci.ExtractEncoding();
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100594
595 {
596 // Verify first stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100597 StackMap sm0 = ci.GetStackMapAt(0, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100598
David Brazdilf677ebf2015-05-29 16:29:43 +0100599 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, 2);
600 ASSERT_EQ(0, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
601 ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100602
David Brazdilf677ebf2015-05-29 16:29:43 +0100603 InlineInfo if0 = ci.GetInlineInfoOf(sm0, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100604 ASSERT_EQ(2u, if0.GetDepth());
605 ASSERT_EQ(2u, if0.GetDexPcAtDepth(0));
606 ASSERT_EQ(42u, if0.GetMethodIndexAtDepth(0));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100607 ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(0));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100608 ASSERT_EQ(3u, if0.GetDexPcAtDepth(1));
609 ASSERT_EQ(82u, if0.GetMethodIndexAtDepth(1));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100610 ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(1));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100611
David Brazdilf677ebf2015-05-29 16:29:43 +0100612 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if0, encoding, 1);
613 ASSERT_EQ(8, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100614
David Brazdilf677ebf2015-05-29 16:29:43 +0100615 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if0, encoding, 3);
616 ASSERT_EQ(16, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding));
617 ASSERT_EQ(20, dex_registers2.GetConstant(1, 3, ci, encoding));
618 ASSERT_EQ(15, dex_registers2.GetMachineRegister(2, 3, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100619 }
620
621 {
622 // Verify second stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100623 StackMap sm1 = ci.GetStackMapAt(1, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100624
David Brazdilf677ebf2015-05-29 16:29:43 +0100625 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm1, encoding, 2);
626 ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
627 ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100628
David Brazdilf677ebf2015-05-29 16:29:43 +0100629 InlineInfo if1 = ci.GetInlineInfoOf(sm1, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100630 ASSERT_EQ(3u, if1.GetDepth());
631 ASSERT_EQ(2u, if1.GetDexPcAtDepth(0));
632 ASSERT_EQ(42u, if1.GetMethodIndexAtDepth(0));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100633 ASSERT_EQ(kDirect, if1.GetInvokeTypeAtDepth(0));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100634 ASSERT_EQ(3u, if1.GetDexPcAtDepth(1));
635 ASSERT_EQ(82u, if1.GetMethodIndexAtDepth(1));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100636 ASSERT_EQ(kStatic, if1.GetInvokeTypeAtDepth(1));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100637 ASSERT_EQ(5u, if1.GetDexPcAtDepth(2));
638 ASSERT_EQ(52u, if1.GetMethodIndexAtDepth(2));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100639 ASSERT_EQ(kVirtual, if1.GetInvokeTypeAtDepth(2));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100640
David Brazdilf677ebf2015-05-29 16:29:43 +0100641 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if1, encoding, 1);
642 ASSERT_EQ(12, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100643
David Brazdilf677ebf2015-05-29 16:29:43 +0100644 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if1, encoding, 3);
645 ASSERT_EQ(80, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding));
646 ASSERT_EQ(10, dex_registers2.GetConstant(1, 3, ci, encoding));
647 ASSERT_EQ(5, dex_registers2.GetMachineRegister(2, 3, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100648
649 ASSERT_FALSE(if1.HasDexRegisterMapAtDepth(2));
650 }
651
652 {
653 // Verify third stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100654 StackMap sm2 = ci.GetStackMapAt(2, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100655
David Brazdilf677ebf2015-05-29 16:29:43 +0100656 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm2, encoding, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100657 ASSERT_FALSE(dex_registers0.IsDexRegisterLive(0));
David Brazdilf677ebf2015-05-29 16:29:43 +0100658 ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding));
659 ASSERT_FALSE(sm2.HasInlineInfo(encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100660 }
661
662 {
663 // Verify fourth stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100664 StackMap sm3 = ci.GetStackMapAt(3, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100665
David Brazdilf677ebf2015-05-29 16:29:43 +0100666 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm3, encoding, 2);
667 ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
668 ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100669
David Brazdilf677ebf2015-05-29 16:29:43 +0100670 InlineInfo if2 = ci.GetInlineInfoOf(sm3, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100671 ASSERT_EQ(3u, if2.GetDepth());
672 ASSERT_EQ(2u, if2.GetDexPcAtDepth(0));
673 ASSERT_EQ(42u, if2.GetMethodIndexAtDepth(0));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100674 ASSERT_EQ(kVirtual, if2.GetInvokeTypeAtDepth(0));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100675 ASSERT_EQ(5u, if2.GetDexPcAtDepth(1));
676 ASSERT_EQ(52u, if2.GetMethodIndexAtDepth(1));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100677 ASSERT_EQ(kInterface, if2.GetInvokeTypeAtDepth(1));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100678 ASSERT_EQ(10u, if2.GetDexPcAtDepth(2));
679 ASSERT_EQ(52u, if2.GetMethodIndexAtDepth(2));
Nicolas Geoffrayb176d7c2015-05-20 18:48:31 +0100680 ASSERT_EQ(kStatic, if2.GetInvokeTypeAtDepth(2));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100681
682 ASSERT_FALSE(if2.HasDexRegisterMapAtDepth(0));
683
David Brazdilf677ebf2015-05-29 16:29:43 +0100684 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(1, if2, encoding, 1);
685 ASSERT_EQ(2, dex_registers1.GetMachineRegister(0, 1, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100686
David Brazdilf677ebf2015-05-29 16:29:43 +0100687 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(2, if2, encoding, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100688 ASSERT_FALSE(dex_registers2.IsDexRegisterLive(0));
David Brazdilf677ebf2015-05-29 16:29:43 +0100689 ASSERT_EQ(3, dex_registers2.GetMachineRegister(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100690 }
691}
692
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100693} // namespace art