blob: da68b60811e45583a3ea416098167d4d538a1512 [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"
Mathieu Chartiere5d80f82015-10-15 17:47:48 -070018
Nicolas Geoffray5d37c152017-01-12 13:25:19 +000019#include "art_method.h"
Mathieu Chartiere5d80f82015-10-15 17:47:48 -070020#include "base/arena_bit_vector.h"
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010021#include "stack_map_stream.h"
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010022
23#include "gtest/gtest.h"
24
25namespace art {
26
David Srbecky09ed0982016-02-12 21:58:43 +000027// Check that the stack mask of given stack map is identical
28// to the given bit vector. Returns true if they are same.
29static bool CheckStackMask(
David Srbecky45aa5982016-03-18 02:15:09 +000030 const CodeInfo& code_info,
31 const CodeInfoEncoding& encoding,
David Srbecky09ed0982016-02-12 21:58:43 +000032 const StackMap& stack_map,
David Srbecky09ed0982016-02-12 21:58:43 +000033 const BitVector& bit_vector) {
David Srbecky45aa5982016-03-18 02:15:09 +000034 BitMemoryRegion stack_mask = code_info.GetStackMaskOf(encoding, stack_map);
35 if (bit_vector.GetNumberOfBits() > encoding.stack_mask_size_in_bits) {
David Srbecky09ed0982016-02-12 21:58:43 +000036 return false;
37 }
David Srbecky45aa5982016-03-18 02:15:09 +000038 for (size_t i = 0; i < encoding.stack_mask_size_in_bits; ++i) {
39 if (stack_mask.LoadBit(i) != bit_vector.IsBitSet(i)) {
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010040 return false;
41 }
42 }
43 return true;
44}
45
Roland Levillaina552e1c2015-03-26 15:01:03 +000046using Kind = DexRegisterLocation::Kind;
47
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010048TEST(StackMapTest, Test1) {
49 ArenaPool pool;
50 ArenaAllocator arena(&pool);
Mathieu Chartiera2f526f2017-01-19 14:48:48 -080051 StackMapStream stream(&arena, kRuntimeISA);
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010052
53 ArenaBitVector sp_mask(&arena, 0, false);
Roland Levillain12baf472015-03-05 12:41:42 +000054 size_t number_of_dex_registers = 2;
Calin Juravle4f46ac52015-04-23 18:47:21 +010055 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +010056 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
57 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Short location.
Calin Juravle4f46ac52015-04-23 18:47:21 +010058 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010059
Calin Juravle4f46ac52015-04-23 18:47:21 +010060 size_t size = stream.PrepareForFillIn();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010061 void* memory = arena.Alloc(size, kArenaAllocMisc);
62 MemoryRegion region(memory, size);
63 stream.FillIn(region);
64
Nicolas Geoffray39468442014-09-02 15:17:15 +010065 CodeInfo code_info(region);
David Srbecky09ed0982016-02-12 21:58:43 +000066 CodeInfoEncoding encoding = code_info.ExtractEncoding();
67 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps(encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010068
David Srbecky09ed0982016-02-12 21:58:43 +000069 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
70 ASSERT_EQ(2u, number_of_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +010071 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +000072 // The Dex register location catalog contains:
73 // - one 1-byte short Dex register location, and
74 // - one 5-byte large Dex register location.
75 size_t expected_location_catalog_size = 1u + 5u;
76 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
77
David Brazdilf677ebf2015-05-29 16:29:43 +010078 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
79 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
80 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
David Srbecky09ed0982016-02-12 21:58:43 +000081 ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding));
Mathieu Chartiera2f526f2017-01-19 14:48:48 -080082 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
David Srbecky09ed0982016-02-12 21:58:43 +000083 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010084
David Srbecky45aa5982016-03-18 02:15:09 +000085 ASSERT_TRUE(CheckStackMask(code_info, encoding, stack_map, sp_mask));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +010086
David Srbecky09ed0982016-02-12 21:58:43 +000087 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +000088 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +010089 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +000090 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
91 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
92 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
93 // The Dex register map contains:
94 // - one 1-byte live bit mask, and
95 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
96 size_t expected_dex_register_map_size = 1u + 1u;
97 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
98
David Brazdilf677ebf2015-05-29 16:29:43 +010099 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(
100 0, number_of_dex_registers, code_info, encoding));
101 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
102 1, number_of_dex_registers, code_info, encoding));
103 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind(
104 0, number_of_dex_registers, code_info, encoding));
105 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
106 1, number_of_dex_registers, code_info, encoding));
107 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(
108 0, number_of_dex_registers, code_info, encoding));
109 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000110
111 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000112 0, number_of_dex_registers, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000113 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000114 1, number_of_dex_registers, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000115 ASSERT_EQ(0u, index0);
116 ASSERT_EQ(1u, index1);
117 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
118 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
119 ASSERT_EQ(Kind::kInStack, location0.GetKind());
120 ASSERT_EQ(Kind::kConstant, location1.GetKind());
121 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
122 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000123 ASSERT_EQ(0, location0.GetValue());
124 ASSERT_EQ(-2, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000125
David Srbecky09ed0982016-02-12 21:58:43 +0000126 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100127}
128
129TEST(StackMapTest, Test2) {
130 ArenaPool pool;
131 ArenaAllocator arena(&pool);
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800132 StackMapStream stream(&arena, kRuntimeISA);
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000133 ArtMethod art_method;
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100134
135 ArenaBitVector sp_mask1(&arena, 0, true);
136 sp_mask1.SetBit(2);
137 sp_mask1.SetBit(4);
Roland Levillain12baf472015-03-05 12:41:42 +0000138 size_t number_of_dex_registers = 2;
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100139 size_t number_of_dex_registers_in_inline_info = 0;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100140 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100141 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
142 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000143 stream.BeginInlineInfoEntry(&art_method, 3, number_of_dex_registers_in_inline_info);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100144 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000145 stream.BeginInlineInfoEntry(&art_method, 2, number_of_dex_registers_in_inline_info);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100146 stream.EndInlineInfoEntry();
Calin Juravle4f46ac52015-04-23 18:47:21 +0100147 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100148
149 ArenaBitVector sp_mask2(&arena, 0, true);
150 sp_mask2.SetBit(3);
David Brazdilf10a25f2015-06-02 14:29:52 +0100151 sp_mask2.SetBit(8);
Calin Juravle4f46ac52015-04-23 18:47:21 +0100152 stream.BeginStackMapEntry(1, 128, 0xFF, &sp_mask2, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100153 stream.AddDexRegisterEntry(Kind::kInRegister, 18); // Short location.
154 stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3); // Short location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100155 stream.EndStackMapEntry();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100156
David Brazdild9cb68e2015-08-25 13:52:43 +0100157 ArenaBitVector sp_mask3(&arena, 0, true);
158 sp_mask3.SetBit(1);
159 sp_mask3.SetBit(5);
160 stream.BeginStackMapEntry(2, 192, 0xAB, &sp_mask3, number_of_dex_registers, 0);
161 stream.AddDexRegisterEntry(Kind::kInRegister, 6); // Short location.
162 stream.AddDexRegisterEntry(Kind::kInRegisterHigh, 8); // Short location.
163 stream.EndStackMapEntry();
164
165 ArenaBitVector sp_mask4(&arena, 0, true);
166 sp_mask4.SetBit(6);
167 sp_mask4.SetBit(7);
168 stream.BeginStackMapEntry(3, 256, 0xCD, &sp_mask4, number_of_dex_registers, 0);
169 stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3); // Short location, same in stack map 2.
170 stream.AddDexRegisterEntry(Kind::kInFpuRegisterHigh, 1); // Short location.
171 stream.EndStackMapEntry();
172
Calin Juravle4f46ac52015-04-23 18:47:21 +0100173 size_t size = stream.PrepareForFillIn();
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100174 void* memory = arena.Alloc(size, kArenaAllocMisc);
175 MemoryRegion region(memory, size);
176 stream.FillIn(region);
177
Nicolas Geoffray39468442014-09-02 15:17:15 +0100178 CodeInfo code_info(region);
David Srbecky09ed0982016-02-12 21:58:43 +0000179 CodeInfoEncoding encoding = code_info.ExtractEncoding();
180 ASSERT_EQ(4u, code_info.GetNumberOfStackMaps(encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100181
David Srbecky09ed0982016-02-12 21:58:43 +0000182 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
183 ASSERT_EQ(7u, number_of_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +0100184 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000185 // The Dex register location catalog contains:
David Brazdild9cb68e2015-08-25 13:52:43 +0100186 // - six 1-byte short Dex register locations, and
Roland Levillaina552e1c2015-03-26 15:01:03 +0000187 // - one 5-byte large Dex register location.
David Brazdild9cb68e2015-08-25 13:52:43 +0100188 size_t expected_location_catalog_size = 6u * 1u + 5u;
Roland Levillaina552e1c2015-03-26 15:01:03 +0000189 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
190
Roland Levillain12baf472015-03-05 12:41:42 +0000191 // First stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000192 {
David Brazdilf677ebf2015-05-29 16:29:43 +0100193 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
194 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
195 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
David Srbecky09ed0982016-02-12 21:58:43 +0000196 ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding));
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800197 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
David Srbecky09ed0982016-02-12 21:58:43 +0000198 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100199
David Srbecky45aa5982016-03-18 02:15:09 +0000200 ASSERT_TRUE(CheckStackMask(code_info, encoding, stack_map, sp_mask1));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100201
David Srbecky09ed0982016-02-12 21:58:43 +0000202 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000203 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +0100204 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000205 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
206 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
207 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
208 // The Dex register map contains:
209 // - one 1-byte live bit mask, and
210 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
211 size_t expected_dex_register_map_size = 1u + 1u;
212 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
213
David Brazdilf677ebf2015-05-29 16:29:43 +0100214 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(
215 0, number_of_dex_registers, code_info, encoding));
216 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
217 1, number_of_dex_registers, code_info, encoding));
218 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind(
219 0, number_of_dex_registers, code_info, encoding));
220 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
221 1, number_of_dex_registers, code_info, encoding));
222 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(
223 0, number_of_dex_registers, code_info, encoding));
224 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000225
226 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000227 0, number_of_dex_registers, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000228 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000229 1, number_of_dex_registers, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000230 ASSERT_EQ(0u, index0);
231 ASSERT_EQ(1u, index1);
232 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
233 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
234 ASSERT_EQ(Kind::kInStack, location0.GetKind());
235 ASSERT_EQ(Kind::kConstant, location1.GetKind());
236 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
237 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000238 ASSERT_EQ(0, location0.GetValue());
239 ASSERT_EQ(-2, location1.GetValue());
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100240
David Srbecky09ed0982016-02-12 21:58:43 +0000241 ASSERT_TRUE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
David Brazdilf677ebf2015-05-29 16:29:43 +0100242 InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
David Srbecky61b28a12016-02-25 21:55:03 +0000243 ASSERT_EQ(2u, inline_info.GetDepth(encoding.inline_info_encoding));
David Srbecky61b28a12016-02-25 21:55:03 +0000244 ASSERT_EQ(3u, inline_info.GetDexPcAtDepth(encoding.inline_info_encoding, 0));
245 ASSERT_EQ(2u, inline_info.GetDexPcAtDepth(encoding.inline_info_encoding, 1));
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000246 ASSERT_TRUE(inline_info.EncodesArtMethodAtDepth(encoding.inline_info_encoding, 0));
247 ASSERT_TRUE(inline_info.EncodesArtMethodAtDepth(encoding.inline_info_encoding, 1));
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000248 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100249
Roland Levillain12baf472015-03-05 12:41:42 +0000250 // Second stack map.
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000251 {
David Brazdilf677ebf2015-05-29 16:29:43 +0100252 StackMap stack_map = code_info.GetStackMapAt(1, encoding);
253 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u, encoding)));
254 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u, encoding)));
David Srbecky09ed0982016-02-12 21:58:43 +0000255 ASSERT_EQ(1u, stack_map.GetDexPc(encoding.stack_map_encoding));
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800256 ASSERT_EQ(128u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
David Srbecky09ed0982016-02-12 21:58:43 +0000257 ASSERT_EQ(0xFFu, stack_map.GetRegisterMask(encoding.stack_map_encoding));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100258
David Srbecky45aa5982016-03-18 02:15:09 +0000259 ASSERT_TRUE(CheckStackMask(code_info, encoding, stack_map, sp_mask2));
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100260
David Srbecky09ed0982016-02-12 21:58:43 +0000261 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000262 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +0100263 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000264 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
265 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
266 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
267 // The Dex register map contains:
268 // - one 1-byte live bit mask, and
269 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
270 size_t expected_dex_register_map_size = 1u + 1u;
271 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
272
David Brazdilf677ebf2015-05-29 16:29:43 +0100273 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind(
274 0, number_of_dex_registers, code_info, encoding));
275 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind(
276 1, number_of_dex_registers, code_info, encoding));
277 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationInternalKind(
278 0, number_of_dex_registers, code_info, encoding));
279 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationInternalKind(
280 1, number_of_dex_registers, code_info, encoding));
281 ASSERT_EQ(18, dex_register_map.GetMachineRegister(
282 0, number_of_dex_registers, code_info, encoding));
283 ASSERT_EQ(3, dex_register_map.GetMachineRegister(
284 1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000285
286 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000287 0, number_of_dex_registers, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000288 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000289 1, number_of_dex_registers, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000290 ASSERT_EQ(2u, index0);
291 ASSERT_EQ(3u, index1);
292 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
293 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
294 ASSERT_EQ(Kind::kInRegister, location0.GetKind());
295 ASSERT_EQ(Kind::kInFpuRegister, location1.GetKind());
296 ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind());
297 ASSERT_EQ(Kind::kInFpuRegister, location1.GetInternalKind());
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000298 ASSERT_EQ(18, location0.GetValue());
299 ASSERT_EQ(3, location1.GetValue());
Roland Levillain12baf472015-03-05 12:41:42 +0000300
David Srbecky09ed0982016-02-12 21:58:43 +0000301 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
Roland Levillaina2d8ec62015-03-12 15:25:29 +0000302 }
David Brazdild9cb68e2015-08-25 13:52:43 +0100303
304 // Third stack map.
305 {
306 StackMap stack_map = code_info.GetStackMapAt(2, encoding);
307 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(2u, encoding)));
308 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(192u, encoding)));
David Srbecky09ed0982016-02-12 21:58:43 +0000309 ASSERT_EQ(2u, stack_map.GetDexPc(encoding.stack_map_encoding));
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800310 ASSERT_EQ(192u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
David Srbecky09ed0982016-02-12 21:58:43 +0000311 ASSERT_EQ(0xABu, stack_map.GetRegisterMask(encoding.stack_map_encoding));
David Brazdild9cb68e2015-08-25 13:52:43 +0100312
David Srbecky45aa5982016-03-18 02:15:09 +0000313 ASSERT_TRUE(CheckStackMask(code_info, encoding, stack_map, sp_mask3));
David Brazdild9cb68e2015-08-25 13:52:43 +0100314
David Srbecky09ed0982016-02-12 21:58:43 +0000315 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
David Brazdild9cb68e2015-08-25 13:52:43 +0100316 DexRegisterMap dex_register_map =
317 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
318 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
319 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
320 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
321 // The Dex register map contains:
322 // - one 1-byte live bit mask, and
323 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
324 size_t expected_dex_register_map_size = 1u + 1u;
325 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
326
327 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind(
328 0, number_of_dex_registers, code_info, encoding));
329 ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map.GetLocationKind(
330 1, number_of_dex_registers, code_info, encoding));
331 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationInternalKind(
332 0, number_of_dex_registers, code_info, encoding));
333 ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map.GetLocationInternalKind(
334 1, number_of_dex_registers, code_info, encoding));
335 ASSERT_EQ(6, dex_register_map.GetMachineRegister(
336 0, number_of_dex_registers, code_info, encoding));
337 ASSERT_EQ(8, dex_register_map.GetMachineRegister(
338 1, number_of_dex_registers, code_info, encoding));
339
340 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000341 0, number_of_dex_registers, number_of_catalog_entries);
David Brazdild9cb68e2015-08-25 13:52:43 +0100342 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000343 1, number_of_dex_registers, number_of_catalog_entries);
David Brazdild9cb68e2015-08-25 13:52:43 +0100344 ASSERT_EQ(4u, index0);
345 ASSERT_EQ(5u, index1);
346 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
347 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
348 ASSERT_EQ(Kind::kInRegister, location0.GetKind());
349 ASSERT_EQ(Kind::kInRegisterHigh, location1.GetKind());
350 ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind());
351 ASSERT_EQ(Kind::kInRegisterHigh, location1.GetInternalKind());
352 ASSERT_EQ(6, location0.GetValue());
353 ASSERT_EQ(8, location1.GetValue());
354
David Srbecky09ed0982016-02-12 21:58:43 +0000355 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
David Brazdild9cb68e2015-08-25 13:52:43 +0100356 }
357
358 // Fourth stack map.
359 {
360 StackMap stack_map = code_info.GetStackMapAt(3, encoding);
361 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(3u, encoding)));
362 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(256u, encoding)));
David Srbecky09ed0982016-02-12 21:58:43 +0000363 ASSERT_EQ(3u, stack_map.GetDexPc(encoding.stack_map_encoding));
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800364 ASSERT_EQ(256u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
David Srbecky09ed0982016-02-12 21:58:43 +0000365 ASSERT_EQ(0xCDu, stack_map.GetRegisterMask(encoding.stack_map_encoding));
David Brazdild9cb68e2015-08-25 13:52:43 +0100366
David Srbecky45aa5982016-03-18 02:15:09 +0000367 ASSERT_TRUE(CheckStackMask(code_info, encoding, stack_map, sp_mask4));
David Brazdild9cb68e2015-08-25 13:52:43 +0100368
David Srbecky09ed0982016-02-12 21:58:43 +0000369 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
David Brazdild9cb68e2015-08-25 13:52:43 +0100370 DexRegisterMap dex_register_map =
371 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
372 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
373 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
374 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
375 // The Dex register map contains:
376 // - one 1-byte live bit mask, and
377 // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
378 size_t expected_dex_register_map_size = 1u + 1u;
379 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
380
381 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind(
382 0, number_of_dex_registers, code_info, encoding));
383 ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map.GetLocationKind(
384 1, number_of_dex_registers, code_info, encoding));
385 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationInternalKind(
386 0, number_of_dex_registers, code_info, encoding));
387 ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map.GetLocationInternalKind(
388 1, number_of_dex_registers, code_info, encoding));
389 ASSERT_EQ(3, dex_register_map.GetMachineRegister(
390 0, number_of_dex_registers, code_info, encoding));
391 ASSERT_EQ(1, dex_register_map.GetMachineRegister(
392 1, number_of_dex_registers, code_info, encoding));
393
394 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000395 0, number_of_dex_registers, number_of_catalog_entries);
David Brazdild9cb68e2015-08-25 13:52:43 +0100396 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000397 1, number_of_dex_registers, number_of_catalog_entries);
David Brazdild9cb68e2015-08-25 13:52:43 +0100398 ASSERT_EQ(3u, index0); // Shared with second stack map.
399 ASSERT_EQ(6u, index1);
400 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
401 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
402 ASSERT_EQ(Kind::kInFpuRegister, location0.GetKind());
403 ASSERT_EQ(Kind::kInFpuRegisterHigh, location1.GetKind());
404 ASSERT_EQ(Kind::kInFpuRegister, location0.GetInternalKind());
405 ASSERT_EQ(Kind::kInFpuRegisterHigh, location1.GetInternalKind());
406 ASSERT_EQ(3, location0.GetValue());
407 ASSERT_EQ(1, location1.GetValue());
408
David Srbecky09ed0982016-02-12 21:58:43 +0000409 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
David Brazdild9cb68e2015-08-25 13:52:43 +0100410 }
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100411}
412
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000413TEST(StackMapTest, TestNonLiveDexRegisters) {
414 ArenaPool pool;
415 ArenaAllocator arena(&pool);
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800416 StackMapStream stream(&arena, kRuntimeISA);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000417
418 ArenaBitVector sp_mask(&arena, 0, false);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000419 uint32_t number_of_dex_registers = 2;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100420 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100421 stream.AddDexRegisterEntry(Kind::kNone, 0); // No location.
422 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100423 stream.EndStackMapEntry();
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000424
Calin Juravle4f46ac52015-04-23 18:47:21 +0100425 size_t size = stream.PrepareForFillIn();
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000426 void* memory = arena.Alloc(size, kArenaAllocMisc);
427 MemoryRegion region(memory, size);
428 stream.FillIn(region);
429
430 CodeInfo code_info(region);
David Srbecky09ed0982016-02-12 21:58:43 +0000431 CodeInfoEncoding encoding = code_info.ExtractEncoding();
432 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000433
David Srbecky09ed0982016-02-12 21:58:43 +0000434 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
435 ASSERT_EQ(1u, number_of_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +0100436 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000437 // The Dex register location catalog contains:
438 // - one 5-byte large Dex register location.
439 size_t expected_location_catalog_size = 5u;
440 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
441
David Brazdilf677ebf2015-05-29 16:29:43 +0100442 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
443 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
444 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
David Srbecky09ed0982016-02-12 21:58:43 +0000445 ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding));
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800446 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
David Srbecky09ed0982016-02-12 21:58:43 +0000447 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000448
David Srbecky09ed0982016-02-12 21:58:43 +0000449 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000450 DexRegisterMap dex_register_map =
David Brazdilf677ebf2015-05-29 16:29:43 +0100451 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000452 ASSERT_FALSE(dex_register_map.IsDexRegisterLive(0));
453 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
454 ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
455 // The Dex register map contains:
456 // - one 1-byte live bit mask.
457 // No space is allocated for the sole location catalog entry index, as it is useless.
458 size_t expected_dex_register_map_size = 1u + 0u;
459 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
460
David Brazdilf677ebf2015-05-29 16:29:43 +0100461 ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationKind(
462 0, number_of_dex_registers, code_info, encoding));
463 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
464 1, number_of_dex_registers, code_info, encoding));
465 ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationInternalKind(
466 0, number_of_dex_registers, code_info, encoding));
467 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
468 1, number_of_dex_registers, code_info, encoding));
469 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000470
471 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000472 0, number_of_dex_registers, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000473 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
David Srbecky09ed0982016-02-12 21:58:43 +0000474 1, number_of_dex_registers, number_of_catalog_entries);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000475 ASSERT_EQ(DexRegisterLocationCatalog::kNoLocationEntryIndex, index0);
476 ASSERT_EQ(0u, index1);
477 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
478 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
479 ASSERT_EQ(Kind::kNone, location0.GetKind());
480 ASSERT_EQ(Kind::kConstant, location1.GetKind());
481 ASSERT_EQ(Kind::kNone, location0.GetInternalKind());
482 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
483 ASSERT_EQ(0, location0.GetValue());
484 ASSERT_EQ(-2, location1.GetValue());
485
David Srbecky09ed0982016-02-12 21:58:43 +0000486 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000487}
488
489// Generate a stack map whose dex register offset is
490// StackMap::kNoDexRegisterMapSmallEncoding, and ensure we do
491// not treat it as kNoDexRegisterMap.
492TEST(StackMapTest, DexRegisterMapOffsetOverflow) {
493 ArenaPool pool;
494 ArenaAllocator arena(&pool);
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800495 StackMapStream stream(&arena, kRuntimeISA);
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000496
497 ArenaBitVector sp_mask(&arena, 0, false);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000498 uint32_t number_of_dex_registers = 1024;
499 // Create the first stack map (and its Dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100500 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000501 uint32_t number_of_dex_live_registers_in_dex_register_map_0 = number_of_dex_registers - 8;
502 for (uint32_t i = 0; i < number_of_dex_live_registers_in_dex_register_map_0; ++i) {
503 // Use two different Dex register locations to populate this map,
504 // as using a single value (in the whole CodeInfo object) would
505 // make this Dex register mapping data empty (see
506 // art::DexRegisterMap::SingleEntrySizeInBits).
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100507 stream.AddDexRegisterEntry(Kind::kConstant, i % 2); // Short location.
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000508 }
Calin Juravle4f46ac52015-04-23 18:47:21 +0100509 stream.EndStackMapEntry();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000510 // Create the second stack map (and its Dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100511 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000512 for (uint32_t i = 0; i < number_of_dex_registers; ++i) {
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100513 stream.AddDexRegisterEntry(Kind::kConstant, 0); // Short location.
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000514 }
Calin Juravle4f46ac52015-04-23 18:47:21 +0100515 stream.EndStackMapEntry();
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000516
Calin Juravle4f46ac52015-04-23 18:47:21 +0100517 size_t size = stream.PrepareForFillIn();
Nicolas Geoffray004c2302015-03-20 10:06:38 +0000518 void* memory = arena.Alloc(size, kArenaAllocMisc);
519 MemoryRegion region(memory, size);
520 stream.FillIn(region);
521
522 CodeInfo code_info(region);
David Srbecky09ed0982016-02-12 21:58:43 +0000523 CodeInfoEncoding encoding = code_info.ExtractEncoding();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000524 // The location catalog contains two entries (DexRegisterLocation(kConstant, 0)
525 // and DexRegisterLocation(kConstant, 1)), therefore the location catalog index
526 // has a size of 1 bit.
David Srbecky09ed0982016-02-12 21:58:43 +0000527 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
528 ASSERT_EQ(2u, number_of_catalog_entries);
529 ASSERT_EQ(1u, DexRegisterMap::SingleEntrySizeInBits(number_of_catalog_entries));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000530
531 // The first Dex register map contains:
532 // - a live register bit mask for 1024 registers (that is, 128 bytes of
533 // data); and
534 // - Dex register mapping information for 1016 1-bit Dex (live) register
535 // locations (that is, 127 bytes of data).
536 // Hence it has a size of 255 bytes, and therefore...
537 ASSERT_EQ(128u, DexRegisterMap::GetLiveBitMaskSize(number_of_dex_registers));
David Brazdilf677ebf2015-05-29 16:29:43 +0100538 StackMap stack_map0 = code_info.GetStackMapAt(0, encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000539 DexRegisterMap dex_register_map0 =
David Brazdilf677ebf2015-05-29 16:29:43 +0100540 code_info.GetDexRegisterMapOf(stack_map0, encoding, number_of_dex_registers);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000541 ASSERT_EQ(127u, dex_register_map0.GetLocationMappingDataSize(number_of_dex_registers,
David Srbecky09ed0982016-02-12 21:58:43 +0000542 number_of_catalog_entries));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000543 ASSERT_EQ(255u, dex_register_map0.Size());
544
David Brazdilf677ebf2015-05-29 16:29:43 +0100545 StackMap stack_map1 = code_info.GetStackMapAt(1, encoding);
David Srbecky09ed0982016-02-12 21:58:43 +0000546 ASSERT_TRUE(stack_map1.HasDexRegisterMap(encoding.stack_map_encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000547 // ...the offset of the second Dex register map (relative to the
548 // beginning of the Dex register maps region) is 255 (i.e.,
549 // kNoDexRegisterMapSmallEncoding).
David Srbecky09ed0982016-02-12 21:58:43 +0000550 ASSERT_NE(stack_map1.GetDexRegisterMapOffset(encoding.stack_map_encoding),
551 StackMap::kNoDexRegisterMap);
552 ASSERT_EQ(stack_map1.GetDexRegisterMapOffset(encoding.stack_map_encoding), 0xFFu);
Nicolas Geoffrayfead4e42015-03-13 14:39:40 +0000553}
554
Calin Juravle6ae70962015-03-18 16:31:28 +0000555TEST(StackMapTest, TestShareDexRegisterMap) {
556 ArenaPool pool;
557 ArenaAllocator arena(&pool);
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800558 StackMapStream stream(&arena, kRuntimeISA);
Calin Juravle6ae70962015-03-18 16:31:28 +0000559
560 ArenaBitVector sp_mask(&arena, 0, false);
561 uint32_t number_of_dex_registers = 2;
562 // First stack map.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100563 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100564 stream.AddDexRegisterEntry(Kind::kInRegister, 0); // Short location.
565 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100566 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000567 // Second stack map, which should share the same dex register map.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100568 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100569 stream.AddDexRegisterEntry(Kind::kInRegister, 0); // Short location.
570 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100571 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000572 // Third stack map (doesn't share the dex register map).
Calin Juravle4f46ac52015-04-23 18:47:21 +0100573 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100574 stream.AddDexRegisterEntry(Kind::kInRegister, 2); // Short location.
575 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
Calin Juravle4f46ac52015-04-23 18:47:21 +0100576 stream.EndStackMapEntry();
Calin Juravle6ae70962015-03-18 16:31:28 +0000577
Calin Juravle4f46ac52015-04-23 18:47:21 +0100578 size_t size = stream.PrepareForFillIn();
Calin Juravle6ae70962015-03-18 16:31:28 +0000579 void* memory = arena.Alloc(size, kArenaAllocMisc);
580 MemoryRegion region(memory, size);
581 stream.FillIn(region);
582
583 CodeInfo ci(region);
David Srbecky09ed0982016-02-12 21:58:43 +0000584 CodeInfoEncoding encoding = ci.ExtractEncoding();
David Brazdilf677ebf2015-05-29 16:29:43 +0100585
Calin Juravle6ae70962015-03-18 16:31:28 +0000586 // Verify first stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100587 StackMap sm0 = ci.GetStackMapAt(0, encoding);
588 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, number_of_dex_registers);
589 ASSERT_EQ(0, dex_registers0.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
590 ASSERT_EQ(-2, dex_registers0.GetConstant(1, number_of_dex_registers, ci, encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000591
592 // Verify second stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100593 StackMap sm1 = ci.GetStackMapAt(1, encoding);
594 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1, encoding, number_of_dex_registers);
595 ASSERT_EQ(0, dex_registers1.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
596 ASSERT_EQ(-2, dex_registers1.GetConstant(1, number_of_dex_registers, ci, encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000597
598 // Verify third stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100599 StackMap sm2 = ci.GetStackMapAt(2, encoding);
600 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2, encoding, number_of_dex_registers);
601 ASSERT_EQ(2, dex_registers2.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
602 ASSERT_EQ(-2, dex_registers2.GetConstant(1, number_of_dex_registers, ci, encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000603
604 // Verify dex register map offsets.
David Srbecky09ed0982016-02-12 21:58:43 +0000605 ASSERT_EQ(sm0.GetDexRegisterMapOffset(encoding.stack_map_encoding),
606 sm1.GetDexRegisterMapOffset(encoding.stack_map_encoding));
607 ASSERT_NE(sm0.GetDexRegisterMapOffset(encoding.stack_map_encoding),
608 sm2.GetDexRegisterMapOffset(encoding.stack_map_encoding));
609 ASSERT_NE(sm1.GetDexRegisterMapOffset(encoding.stack_map_encoding),
610 sm2.GetDexRegisterMapOffset(encoding.stack_map_encoding));
Calin Juravle6ae70962015-03-18 16:31:28 +0000611}
612
Roland Levillaina552e1c2015-03-26 15:01:03 +0000613TEST(StackMapTest, TestNoDexRegisterMap) {
614 ArenaPool pool;
615 ArenaAllocator arena(&pool);
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800616 StackMapStream stream(&arena, kRuntimeISA);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000617
618 ArenaBitVector sp_mask(&arena, 0, false);
619 uint32_t number_of_dex_registers = 0;
Calin Juravle4f46ac52015-04-23 18:47:21 +0100620 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
621 stream.EndStackMapEntry();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000622
Nicolas Geoffray012fc4e2016-01-08 15:58:19 +0000623 number_of_dex_registers = 1;
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800624 stream.BeginStackMapEntry(1, 68, 0x4, &sp_mask, number_of_dex_registers, 0);
Nicolas Geoffray012fc4e2016-01-08 15:58:19 +0000625 stream.EndStackMapEntry();
626
Calin Juravle4f46ac52015-04-23 18:47:21 +0100627 size_t size = stream.PrepareForFillIn();
Roland Levillaina552e1c2015-03-26 15:01:03 +0000628 void* memory = arena.Alloc(size, kArenaAllocMisc);
629 MemoryRegion region(memory, size);
630 stream.FillIn(region);
631
632 CodeInfo code_info(region);
David Srbecky09ed0982016-02-12 21:58:43 +0000633 CodeInfoEncoding encoding = code_info.ExtractEncoding();
634 ASSERT_EQ(2u, code_info.GetNumberOfStackMaps(encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000635
David Srbecky09ed0982016-02-12 21:58:43 +0000636 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
637 ASSERT_EQ(0u, number_of_catalog_entries);
David Brazdilf677ebf2015-05-29 16:29:43 +0100638 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
Roland Levillaina552e1c2015-03-26 15:01:03 +0000639 ASSERT_EQ(0u, location_catalog.Size());
640
David Brazdilf677ebf2015-05-29 16:29:43 +0100641 StackMap stack_map = code_info.GetStackMapAt(0, encoding);
642 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
643 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
David Srbecky09ed0982016-02-12 21:58:43 +0000644 ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding));
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800645 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
David Srbecky09ed0982016-02-12 21:58:43 +0000646 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000647
David Srbecky09ed0982016-02-12 21:58:43 +0000648 ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
649 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
Nicolas Geoffray012fc4e2016-01-08 15:58:19 +0000650
651 stack_map = code_info.GetStackMapAt(1, encoding);
652 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1, encoding)));
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800653 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(68, encoding)));
David Srbecky09ed0982016-02-12 21:58:43 +0000654 ASSERT_EQ(1u, stack_map.GetDexPc(encoding.stack_map_encoding));
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800655 ASSERT_EQ(68u, stack_map.GetNativePcOffset(encoding.stack_map_encoding, kRuntimeISA));
David Srbecky09ed0982016-02-12 21:58:43 +0000656 ASSERT_EQ(0x4u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
Nicolas Geoffray012fc4e2016-01-08 15:58:19 +0000657
David Srbecky09ed0982016-02-12 21:58:43 +0000658 ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
659 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
Roland Levillaina552e1c2015-03-26 15:01:03 +0000660}
661
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100662TEST(StackMapTest, InlineTest) {
663 ArenaPool pool;
664 ArenaAllocator arena(&pool);
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800665 StackMapStream stream(&arena, kRuntimeISA);
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000666 ArtMethod art_method;
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100667
668 ArenaBitVector sp_mask1(&arena, 0, true);
669 sp_mask1.SetBit(2);
670 sp_mask1.SetBit(4);
671
672 // First stack map.
673 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, 2, 2);
674 stream.AddDexRegisterEntry(Kind::kInStack, 0);
675 stream.AddDexRegisterEntry(Kind::kConstant, 4);
676
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000677 stream.BeginInlineInfoEntry(&art_method, 2, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100678 stream.AddDexRegisterEntry(Kind::kInStack, 8);
679 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000680 stream.BeginInlineInfoEntry(&art_method, 3, 3);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100681 stream.AddDexRegisterEntry(Kind::kInStack, 16);
682 stream.AddDexRegisterEntry(Kind::kConstant, 20);
683 stream.AddDexRegisterEntry(Kind::kInRegister, 15);
684 stream.EndInlineInfoEntry();
685
686 stream.EndStackMapEntry();
687
688 // Second stack map.
689 stream.BeginStackMapEntry(2, 22, 0x3, &sp_mask1, 2, 3);
690 stream.AddDexRegisterEntry(Kind::kInStack, 56);
691 stream.AddDexRegisterEntry(Kind::kConstant, 0);
692
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000693 stream.BeginInlineInfoEntry(&art_method, 2, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100694 stream.AddDexRegisterEntry(Kind::kInStack, 12);
695 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000696 stream.BeginInlineInfoEntry(&art_method, 3, 3);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100697 stream.AddDexRegisterEntry(Kind::kInStack, 80);
698 stream.AddDexRegisterEntry(Kind::kConstant, 10);
699 stream.AddDexRegisterEntry(Kind::kInRegister, 5);
700 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000701 stream.BeginInlineInfoEntry(&art_method, 5, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100702 stream.EndInlineInfoEntry();
703
704 stream.EndStackMapEntry();
705
706 // Third stack map.
707 stream.BeginStackMapEntry(4, 56, 0x3, &sp_mask1, 2, 0);
708 stream.AddDexRegisterEntry(Kind::kNone, 0);
709 stream.AddDexRegisterEntry(Kind::kConstant, 4);
710 stream.EndStackMapEntry();
711
712 // Fourth stack map.
713 stream.BeginStackMapEntry(6, 78, 0x3, &sp_mask1, 2, 3);
714 stream.AddDexRegisterEntry(Kind::kInStack, 56);
715 stream.AddDexRegisterEntry(Kind::kConstant, 0);
716
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000717 stream.BeginInlineInfoEntry(&art_method, 2, 0);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100718 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000719 stream.BeginInlineInfoEntry(&art_method, 5, 1);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100720 stream.AddDexRegisterEntry(Kind::kInRegister, 2);
721 stream.EndInlineInfoEntry();
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000722 stream.BeginInlineInfoEntry(&art_method, 10, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100723 stream.AddDexRegisterEntry(Kind::kNone, 0);
724 stream.AddDexRegisterEntry(Kind::kInRegister, 3);
725 stream.EndInlineInfoEntry();
726
727 stream.EndStackMapEntry();
728
729 size_t size = stream.PrepareForFillIn();
730 void* memory = arena.Alloc(size, kArenaAllocMisc);
731 MemoryRegion region(memory, size);
732 stream.FillIn(region);
733
734 CodeInfo ci(region);
David Srbecky09ed0982016-02-12 21:58:43 +0000735 CodeInfoEncoding encoding = ci.ExtractEncoding();
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100736
737 {
738 // Verify first stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100739 StackMap sm0 = ci.GetStackMapAt(0, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100740
David Brazdilf677ebf2015-05-29 16:29:43 +0100741 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, 2);
742 ASSERT_EQ(0, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
743 ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100744
David Brazdilf677ebf2015-05-29 16:29:43 +0100745 InlineInfo if0 = ci.GetInlineInfoOf(sm0, encoding);
David Srbecky61b28a12016-02-25 21:55:03 +0000746 ASSERT_EQ(2u, if0.GetDepth(encoding.inline_info_encoding));
747 ASSERT_EQ(2u, if0.GetDexPcAtDepth(encoding.inline_info_encoding, 0));
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000748 ASSERT_TRUE(if0.EncodesArtMethodAtDepth(encoding.inline_info_encoding, 0));
David Srbecky61b28a12016-02-25 21:55:03 +0000749 ASSERT_EQ(3u, if0.GetDexPcAtDepth(encoding.inline_info_encoding, 1));
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000750 ASSERT_TRUE(if0.EncodesArtMethodAtDepth(encoding.inline_info_encoding, 1));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100751
David Brazdilf677ebf2015-05-29 16:29:43 +0100752 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if0, encoding, 1);
753 ASSERT_EQ(8, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100754
David Brazdilf677ebf2015-05-29 16:29:43 +0100755 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if0, encoding, 3);
756 ASSERT_EQ(16, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding));
757 ASSERT_EQ(20, dex_registers2.GetConstant(1, 3, ci, encoding));
758 ASSERT_EQ(15, dex_registers2.GetMachineRegister(2, 3, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100759 }
760
761 {
762 // Verify second stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100763 StackMap sm1 = ci.GetStackMapAt(1, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100764
David Brazdilf677ebf2015-05-29 16:29:43 +0100765 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm1, encoding, 2);
766 ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
767 ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100768
David Brazdilf677ebf2015-05-29 16:29:43 +0100769 InlineInfo if1 = ci.GetInlineInfoOf(sm1, encoding);
David Srbecky61b28a12016-02-25 21:55:03 +0000770 ASSERT_EQ(3u, if1.GetDepth(encoding.inline_info_encoding));
771 ASSERT_EQ(2u, if1.GetDexPcAtDepth(encoding.inline_info_encoding, 0));
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000772 ASSERT_TRUE(if1.EncodesArtMethodAtDepth(encoding.inline_info_encoding, 0));
David Srbecky61b28a12016-02-25 21:55:03 +0000773 ASSERT_EQ(3u, if1.GetDexPcAtDepth(encoding.inline_info_encoding, 1));
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000774 ASSERT_TRUE(if1.EncodesArtMethodAtDepth(encoding.inline_info_encoding, 1));
David Srbecky61b28a12016-02-25 21:55:03 +0000775 ASSERT_EQ(5u, if1.GetDexPcAtDepth(encoding.inline_info_encoding, 2));
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000776 ASSERT_TRUE(if1.EncodesArtMethodAtDepth(encoding.inline_info_encoding, 2));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100777
David Brazdilf677ebf2015-05-29 16:29:43 +0100778 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if1, encoding, 1);
779 ASSERT_EQ(12, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100780
David Brazdilf677ebf2015-05-29 16:29:43 +0100781 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if1, encoding, 3);
782 ASSERT_EQ(80, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding));
783 ASSERT_EQ(10, dex_registers2.GetConstant(1, 3, ci, encoding));
784 ASSERT_EQ(5, dex_registers2.GetMachineRegister(2, 3, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100785
David Srbecky61b28a12016-02-25 21:55:03 +0000786 ASSERT_FALSE(if1.HasDexRegisterMapAtDepth(encoding.inline_info_encoding, 2));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100787 }
788
789 {
790 // Verify third stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100791 StackMap sm2 = ci.GetStackMapAt(2, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100792
David Brazdilf677ebf2015-05-29 16:29:43 +0100793 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm2, encoding, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100794 ASSERT_FALSE(dex_registers0.IsDexRegisterLive(0));
David Brazdilf677ebf2015-05-29 16:29:43 +0100795 ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding));
David Srbecky09ed0982016-02-12 21:58:43 +0000796 ASSERT_FALSE(sm2.HasInlineInfo(encoding.stack_map_encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100797 }
798
799 {
800 // Verify fourth stack map.
David Brazdilf677ebf2015-05-29 16:29:43 +0100801 StackMap sm3 = ci.GetStackMapAt(3, encoding);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100802
David Brazdilf677ebf2015-05-29 16:29:43 +0100803 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm3, encoding, 2);
804 ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
805 ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100806
David Brazdilf677ebf2015-05-29 16:29:43 +0100807 InlineInfo if2 = ci.GetInlineInfoOf(sm3, encoding);
David Srbecky61b28a12016-02-25 21:55:03 +0000808 ASSERT_EQ(3u, if2.GetDepth(encoding.inline_info_encoding));
809 ASSERT_EQ(2u, if2.GetDexPcAtDepth(encoding.inline_info_encoding, 0));
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000810 ASSERT_TRUE(if2.EncodesArtMethodAtDepth(encoding.inline_info_encoding, 0));
David Srbecky61b28a12016-02-25 21:55:03 +0000811 ASSERT_EQ(5u, if2.GetDexPcAtDepth(encoding.inline_info_encoding, 1));
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000812 ASSERT_TRUE(if2.EncodesArtMethodAtDepth(encoding.inline_info_encoding, 1));
David Srbecky61b28a12016-02-25 21:55:03 +0000813 ASSERT_EQ(10u, if2.GetDexPcAtDepth(encoding.inline_info_encoding, 2));
Nicolas Geoffray5d37c152017-01-12 13:25:19 +0000814 ASSERT_TRUE(if2.EncodesArtMethodAtDepth(encoding.inline_info_encoding, 2));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100815
David Srbecky61b28a12016-02-25 21:55:03 +0000816 ASSERT_FALSE(if2.HasDexRegisterMapAtDepth(encoding.inline_info_encoding, 0));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100817
David Brazdilf677ebf2015-05-29 16:29:43 +0100818 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(1, if2, encoding, 1);
819 ASSERT_EQ(2, dex_registers1.GetMachineRegister(0, 1, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100820
David Brazdilf677ebf2015-05-29 16:29:43 +0100821 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(2, if2, encoding, 2);
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100822 ASSERT_FALSE(dex_registers2.IsDexRegisterLive(0));
David Brazdilf677ebf2015-05-29 16:29:43 +0100823 ASSERT_EQ(3, dex_registers2.GetMachineRegister(1, 2, ci, encoding));
Nicolas Geoffrayb1d0f3f2015-05-14 12:41:51 +0100824 }
825}
826
Mathieu Chartiera2f526f2017-01-19 14:48:48 -0800827TEST(StackMapTest, CodeOffsetTest) {
828 // Test minimum alignments, encoding, and decoding.
829 CodeOffset offset_thumb2 = CodeOffset::FromOffset(kThumb2InstructionAlignment, kThumb2);
830 CodeOffset offset_arm64 = CodeOffset::FromOffset(kArm64InstructionAlignment, kArm64);
831 CodeOffset offset_x86 = CodeOffset::FromOffset(kX86InstructionAlignment, kX86);
832 CodeOffset offset_x86_64 = CodeOffset::FromOffset(kX86_64InstructionAlignment, kX86_64);
833 CodeOffset offset_mips = CodeOffset::FromOffset(kMipsInstructionAlignment, kMips);
834 CodeOffset offset_mips64 = CodeOffset::FromOffset(kMips64InstructionAlignment, kMips64);
835 EXPECT_EQ(offset_thumb2.Uint32Value(kThumb2), kThumb2InstructionAlignment);
836 EXPECT_EQ(offset_arm64.Uint32Value(kArm64), kArm64InstructionAlignment);
837 EXPECT_EQ(offset_x86.Uint32Value(kX86), kX86InstructionAlignment);
838 EXPECT_EQ(offset_x86_64.Uint32Value(kX86_64), kX86_64InstructionAlignment);
839 EXPECT_EQ(offset_mips.Uint32Value(kMips), kMipsInstructionAlignment);
840 EXPECT_EQ(offset_mips64.Uint32Value(kMips64), kMips64InstructionAlignment);
841}
842
David Srbecky45aa5982016-03-18 02:15:09 +0000843
844TEST(StackMapTest, TestDeduplicateStackMask) {
845 ArenaPool pool;
846 ArenaAllocator arena(&pool);
847 StackMapStream stream(&arena, kRuntimeISA);
848
849 ArenaBitVector sp_mask(&arena, 0, true);
850 sp_mask.SetBit(1);
851 sp_mask.SetBit(4);
852 stream.BeginStackMapEntry(0, 4, 0x3, &sp_mask, 0, 0);
853 stream.EndStackMapEntry();
854 stream.BeginStackMapEntry(0, 8, 0x3, &sp_mask, 0, 0);
855 stream.EndStackMapEntry();
856
857 size_t size = stream.PrepareForFillIn();
858 void* memory = arena.Alloc(size, kArenaAllocMisc);
859 MemoryRegion region(memory, size);
860 stream.FillIn(region);
861
862 CodeInfo code_info(region);
863 CodeInfoEncoding encoding = code_info.ExtractEncoding();
864 ASSERT_EQ(2u, code_info.GetNumberOfStackMaps(encoding));
865
866 StackMap stack_map1 = code_info.GetStackMapForNativePcOffset(4, encoding);
867 StackMap stack_map2 = code_info.GetStackMapForNativePcOffset(8, encoding);
868 EXPECT_EQ(stack_map1.GetStackMaskIndex(encoding.stack_map_encoding),
869 stack_map2.GetStackMaskIndex(encoding.stack_map_encoding));
870}
871
Nicolas Geoffray99ea58c2014-07-02 15:08:17 +0100872} // namespace art