1/* 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 19#include "base/arena_bit_vector.h" 20#include "stack_map_stream.h" 21 22#include "gtest/gtest.h" 23 24namespace art { 25 26// Check that the stack mask of given stack map is identical 27// to the given bit vector. Returns true if they are same. 28static bool CheckStackMask( 29 const StackMap& stack_map, 30 StackMapEncoding& encoding, 31 const BitVector& bit_vector) { 32 int number_of_bits = stack_map.GetNumberOfStackMaskBits(encoding); 33 if (bit_vector.GetHighestBitSet() >= number_of_bits) { 34 return false; 35 } 36 for (int i = 0; i < number_of_bits; ++i) { 37 if (stack_map.GetStackMaskBit(encoding, i) != bit_vector.IsBitSet(i)) { 38 return false; 39 } 40 } 41 return true; 42} 43 44using Kind = DexRegisterLocation::Kind; 45 46TEST(StackMapTest, Test1) { 47 ArenaPool pool; 48 ArenaAllocator arena(&pool); 49 StackMapStream stream(&arena); 50 51 ArenaBitVector sp_mask(&arena, 0, false); 52 size_t number_of_dex_registers = 2; 53 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0); 54 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location. 55 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Short location. 56 stream.EndStackMapEntry(); 57 58 size_t size = stream.PrepareForFillIn(); 59 void* memory = arena.Alloc(size, kArenaAllocMisc); 60 MemoryRegion region(memory, size); 61 stream.FillIn(region); 62 63 CodeInfo code_info(region); 64 CodeInfoEncoding encoding = code_info.ExtractEncoding(); 65 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps(encoding)); 66 67 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding); 68 ASSERT_EQ(2u, number_of_catalog_entries); 69 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding); 70 // The Dex register location catalog contains: 71 // - one 1-byte short Dex register location, and 72 // - one 5-byte large Dex register location. 73 size_t expected_location_catalog_size = 1u + 5u; 74 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size()); 75 76 StackMap stack_map = code_info.GetStackMapAt(0, encoding); 77 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding))); 78 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding))); 79 ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding)); 80 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding)); 81 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding)); 82 83 ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask)); 84 85 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding)); 86 DexRegisterMap dex_register_map = 87 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers); 88 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0)); 89 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); 90 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers)); 91 // The Dex register map contains: 92 // - one 1-byte live bit mask, and 93 // - one 1-byte set of location catalog entry indices composed of two 2-bit values. 94 size_t expected_dex_register_map_size = 1u + 1u; 95 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size()); 96 97 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind( 98 0, number_of_dex_registers, code_info, encoding)); 99 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind( 100 1, number_of_dex_registers, code_info, encoding)); 101 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind( 102 0, number_of_dex_registers, code_info, encoding)); 103 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind( 104 1, number_of_dex_registers, code_info, encoding)); 105 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes( 106 0, number_of_dex_registers, code_info, encoding)); 107 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding)); 108 109 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex( 110 0, number_of_dex_registers, number_of_catalog_entries); 111 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex( 112 1, number_of_dex_registers, number_of_catalog_entries); 113 ASSERT_EQ(0u, index0); 114 ASSERT_EQ(1u, index1); 115 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0); 116 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1); 117 ASSERT_EQ(Kind::kInStack, location0.GetKind()); 118 ASSERT_EQ(Kind::kConstant, location1.GetKind()); 119 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind()); 120 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind()); 121 ASSERT_EQ(0, location0.GetValue()); 122 ASSERT_EQ(-2, location1.GetValue()); 123 124 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding)); 125} 126 127TEST(StackMapTest, Test2) { 128 ArenaPool pool; 129 ArenaAllocator arena(&pool); 130 StackMapStream stream(&arena); 131 132 ArenaBitVector sp_mask1(&arena, 0, true); 133 sp_mask1.SetBit(2); 134 sp_mask1.SetBit(4); 135 size_t number_of_dex_registers = 2; 136 size_t number_of_dex_registers_in_inline_info = 0; 137 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 2); 138 stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location. 139 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location. 140 stream.BeginInlineInfoEntry(82, 3, kDirect, number_of_dex_registers_in_inline_info); 141 stream.EndInlineInfoEntry(); 142 stream.BeginInlineInfoEntry(42, 2, kStatic, number_of_dex_registers_in_inline_info); 143 stream.EndInlineInfoEntry(); 144 stream.EndStackMapEntry(); 145 146 ArenaBitVector sp_mask2(&arena, 0, true); 147 sp_mask2.SetBit(3); 148 sp_mask2.SetBit(8); 149 stream.BeginStackMapEntry(1, 128, 0xFF, &sp_mask2, number_of_dex_registers, 0); 150 stream.AddDexRegisterEntry(Kind::kInRegister, 18); // Short location. 151 stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3); // Short location. 152 stream.EndStackMapEntry(); 153 154 ArenaBitVector sp_mask3(&arena, 0, true); 155 sp_mask3.SetBit(1); 156 sp_mask3.SetBit(5); 157 stream.BeginStackMapEntry(2, 192, 0xAB, &sp_mask3, number_of_dex_registers, 0); 158 stream.AddDexRegisterEntry(Kind::kInRegister, 6); // Short location. 159 stream.AddDexRegisterEntry(Kind::kInRegisterHigh, 8); // Short location. 160 stream.EndStackMapEntry(); 161 162 ArenaBitVector sp_mask4(&arena, 0, true); 163 sp_mask4.SetBit(6); 164 sp_mask4.SetBit(7); 165 stream.BeginStackMapEntry(3, 256, 0xCD, &sp_mask4, number_of_dex_registers, 0); 166 stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3); // Short location, same in stack map 2. 167 stream.AddDexRegisterEntry(Kind::kInFpuRegisterHigh, 1); // Short location. 168 stream.EndStackMapEntry(); 169 170 size_t size = stream.PrepareForFillIn(); 171 void* memory = arena.Alloc(size, kArenaAllocMisc); 172 MemoryRegion region(memory, size); 173 stream.FillIn(region); 174 175 CodeInfo code_info(region); 176 CodeInfoEncoding encoding = code_info.ExtractEncoding(); 177 ASSERT_EQ(4u, code_info.GetNumberOfStackMaps(encoding)); 178 179 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding); 180 ASSERT_EQ(7u, number_of_catalog_entries); 181 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding); 182 // The Dex register location catalog contains: 183 // - six 1-byte short Dex register locations, and 184 // - one 5-byte large Dex register location. 185 size_t expected_location_catalog_size = 6u * 1u + 5u; 186 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size()); 187 188 // First stack map. 189 { 190 StackMap stack_map = code_info.GetStackMapAt(0, encoding); 191 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding))); 192 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding))); 193 ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding)); 194 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding)); 195 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding)); 196 197 ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask1)); 198 199 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding)); 200 DexRegisterMap dex_register_map = 201 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers); 202 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0)); 203 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); 204 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers)); 205 // The Dex register map contains: 206 // - one 1-byte live bit mask, and 207 // - one 1-byte set of location catalog entry indices composed of two 2-bit values. 208 size_t expected_dex_register_map_size = 1u + 1u; 209 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size()); 210 211 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind( 212 0, number_of_dex_registers, code_info, encoding)); 213 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind( 214 1, number_of_dex_registers, code_info, encoding)); 215 ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind( 216 0, number_of_dex_registers, code_info, encoding)); 217 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind( 218 1, number_of_dex_registers, code_info, encoding)); 219 ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes( 220 0, number_of_dex_registers, code_info, encoding)); 221 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding)); 222 223 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex( 224 0, number_of_dex_registers, number_of_catalog_entries); 225 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex( 226 1, number_of_dex_registers, number_of_catalog_entries); 227 ASSERT_EQ(0u, index0); 228 ASSERT_EQ(1u, index1); 229 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0); 230 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1); 231 ASSERT_EQ(Kind::kInStack, location0.GetKind()); 232 ASSERT_EQ(Kind::kConstant, location1.GetKind()); 233 ASSERT_EQ(Kind::kInStack, location0.GetInternalKind()); 234 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind()); 235 ASSERT_EQ(0, location0.GetValue()); 236 ASSERT_EQ(-2, location1.GetValue()); 237 238 ASSERT_TRUE(stack_map.HasInlineInfo(encoding.stack_map_encoding)); 239 InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding); 240 ASSERT_EQ(2u, inline_info.GetDepth(encoding.inline_info_encoding)); 241 ASSERT_EQ(82u, inline_info.GetMethodIndexAtDepth(encoding.inline_info_encoding, 0)); 242 ASSERT_EQ(42u, inline_info.GetMethodIndexAtDepth(encoding.inline_info_encoding, 1)); 243 ASSERT_EQ(3u, inline_info.GetDexPcAtDepth(encoding.inline_info_encoding, 0)); 244 ASSERT_EQ(2u, inline_info.GetDexPcAtDepth(encoding.inline_info_encoding, 1)); 245 ASSERT_EQ(kDirect, inline_info.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 0)); 246 ASSERT_EQ(kStatic, inline_info.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 1)); 247 } 248 249 // Second stack map. 250 { 251 StackMap stack_map = code_info.GetStackMapAt(1, encoding); 252 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u, encoding))); 253 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u, encoding))); 254 ASSERT_EQ(1u, stack_map.GetDexPc(encoding.stack_map_encoding)); 255 ASSERT_EQ(128u, stack_map.GetNativePcOffset(encoding.stack_map_encoding)); 256 ASSERT_EQ(0xFFu, stack_map.GetRegisterMask(encoding.stack_map_encoding)); 257 258 ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask2)); 259 260 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding)); 261 DexRegisterMap dex_register_map = 262 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers); 263 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0)); 264 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); 265 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers)); 266 // The Dex register map contains: 267 // - one 1-byte live bit mask, and 268 // - one 1-byte set of location catalog entry indices composed of two 2-bit values. 269 size_t expected_dex_register_map_size = 1u + 1u; 270 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size()); 271 272 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind( 273 0, number_of_dex_registers, code_info, encoding)); 274 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind( 275 1, number_of_dex_registers, code_info, encoding)); 276 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationInternalKind( 277 0, number_of_dex_registers, code_info, encoding)); 278 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationInternalKind( 279 1, number_of_dex_registers, code_info, encoding)); 280 ASSERT_EQ(18, dex_register_map.GetMachineRegister( 281 0, number_of_dex_registers, code_info, encoding)); 282 ASSERT_EQ(3, dex_register_map.GetMachineRegister( 283 1, number_of_dex_registers, code_info, encoding)); 284 285 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex( 286 0, number_of_dex_registers, number_of_catalog_entries); 287 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex( 288 1, number_of_dex_registers, number_of_catalog_entries); 289 ASSERT_EQ(2u, index0); 290 ASSERT_EQ(3u, index1); 291 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0); 292 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1); 293 ASSERT_EQ(Kind::kInRegister, location0.GetKind()); 294 ASSERT_EQ(Kind::kInFpuRegister, location1.GetKind()); 295 ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind()); 296 ASSERT_EQ(Kind::kInFpuRegister, location1.GetInternalKind()); 297 ASSERT_EQ(18, location0.GetValue()); 298 ASSERT_EQ(3, location1.GetValue()); 299 300 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding)); 301 } 302 303 // Third stack map. 304 { 305 StackMap stack_map = code_info.GetStackMapAt(2, encoding); 306 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(2u, encoding))); 307 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(192u, encoding))); 308 ASSERT_EQ(2u, stack_map.GetDexPc(encoding.stack_map_encoding)); 309 ASSERT_EQ(192u, stack_map.GetNativePcOffset(encoding.stack_map_encoding)); 310 ASSERT_EQ(0xABu, stack_map.GetRegisterMask(encoding.stack_map_encoding)); 311 312 ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask3)); 313 314 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding)); 315 DexRegisterMap dex_register_map = 316 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers); 317 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0)); 318 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); 319 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers)); 320 // The Dex register map contains: 321 // - one 1-byte live bit mask, and 322 // - one 1-byte set of location catalog entry indices composed of two 2-bit values. 323 size_t expected_dex_register_map_size = 1u + 1u; 324 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size()); 325 326 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind( 327 0, number_of_dex_registers, code_info, encoding)); 328 ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map.GetLocationKind( 329 1, number_of_dex_registers, code_info, encoding)); 330 ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationInternalKind( 331 0, number_of_dex_registers, code_info, encoding)); 332 ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map.GetLocationInternalKind( 333 1, number_of_dex_registers, code_info, encoding)); 334 ASSERT_EQ(6, dex_register_map.GetMachineRegister( 335 0, number_of_dex_registers, code_info, encoding)); 336 ASSERT_EQ(8, dex_register_map.GetMachineRegister( 337 1, number_of_dex_registers, code_info, encoding)); 338 339 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex( 340 0, number_of_dex_registers, number_of_catalog_entries); 341 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex( 342 1, number_of_dex_registers, number_of_catalog_entries); 343 ASSERT_EQ(4u, index0); 344 ASSERT_EQ(5u, index1); 345 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0); 346 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1); 347 ASSERT_EQ(Kind::kInRegister, location0.GetKind()); 348 ASSERT_EQ(Kind::kInRegisterHigh, location1.GetKind()); 349 ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind()); 350 ASSERT_EQ(Kind::kInRegisterHigh, location1.GetInternalKind()); 351 ASSERT_EQ(6, location0.GetValue()); 352 ASSERT_EQ(8, location1.GetValue()); 353 354 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding)); 355 } 356 357 // Fourth stack map. 358 { 359 StackMap stack_map = code_info.GetStackMapAt(3, encoding); 360 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(3u, encoding))); 361 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(256u, encoding))); 362 ASSERT_EQ(3u, stack_map.GetDexPc(encoding.stack_map_encoding)); 363 ASSERT_EQ(256u, stack_map.GetNativePcOffset(encoding.stack_map_encoding)); 364 ASSERT_EQ(0xCDu, stack_map.GetRegisterMask(encoding.stack_map_encoding)); 365 366 ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask4)); 367 368 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding)); 369 DexRegisterMap dex_register_map = 370 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers); 371 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0)); 372 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); 373 ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers)); 374 // The Dex register map contains: 375 // - one 1-byte live bit mask, and 376 // - one 1-byte set of location catalog entry indices composed of two 2-bit values. 377 size_t expected_dex_register_map_size = 1u + 1u; 378 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size()); 379 380 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind( 381 0, number_of_dex_registers, code_info, encoding)); 382 ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map.GetLocationKind( 383 1, number_of_dex_registers, code_info, encoding)); 384 ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationInternalKind( 385 0, number_of_dex_registers, code_info, encoding)); 386 ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map.GetLocationInternalKind( 387 1, number_of_dex_registers, code_info, encoding)); 388 ASSERT_EQ(3, dex_register_map.GetMachineRegister( 389 0, number_of_dex_registers, code_info, encoding)); 390 ASSERT_EQ(1, dex_register_map.GetMachineRegister( 391 1, number_of_dex_registers, code_info, encoding)); 392 393 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex( 394 0, number_of_dex_registers, number_of_catalog_entries); 395 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex( 396 1, number_of_dex_registers, number_of_catalog_entries); 397 ASSERT_EQ(3u, index0); // Shared with second stack map. 398 ASSERT_EQ(6u, index1); 399 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0); 400 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1); 401 ASSERT_EQ(Kind::kInFpuRegister, location0.GetKind()); 402 ASSERT_EQ(Kind::kInFpuRegisterHigh, location1.GetKind()); 403 ASSERT_EQ(Kind::kInFpuRegister, location0.GetInternalKind()); 404 ASSERT_EQ(Kind::kInFpuRegisterHigh, location1.GetInternalKind()); 405 ASSERT_EQ(3, location0.GetValue()); 406 ASSERT_EQ(1, location1.GetValue()); 407 408 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding)); 409 } 410} 411 412TEST(StackMapTest, TestNonLiveDexRegisters) { 413 ArenaPool pool; 414 ArenaAllocator arena(&pool); 415 StackMapStream stream(&arena); 416 417 ArenaBitVector sp_mask(&arena, 0, false); 418 uint32_t number_of_dex_registers = 2; 419 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0); 420 stream.AddDexRegisterEntry(Kind::kNone, 0); // No location. 421 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location. 422 stream.EndStackMapEntry(); 423 424 size_t size = stream.PrepareForFillIn(); 425 void* memory = arena.Alloc(size, kArenaAllocMisc); 426 MemoryRegion region(memory, size); 427 stream.FillIn(region); 428 429 CodeInfo code_info(region); 430 CodeInfoEncoding encoding = code_info.ExtractEncoding(); 431 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps(encoding)); 432 433 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding); 434 ASSERT_EQ(1u, number_of_catalog_entries); 435 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding); 436 // The Dex register location catalog contains: 437 // - one 5-byte large Dex register location. 438 size_t expected_location_catalog_size = 5u; 439 ASSERT_EQ(expected_location_catalog_size, location_catalog.Size()); 440 441 StackMap stack_map = code_info.GetStackMapAt(0, encoding); 442 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding))); 443 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding))); 444 ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding)); 445 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding)); 446 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding)); 447 448 ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding)); 449 DexRegisterMap dex_register_map = 450 code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers); 451 ASSERT_FALSE(dex_register_map.IsDexRegisterLive(0)); 452 ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); 453 ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers)); 454 // The Dex register map contains: 455 // - one 1-byte live bit mask. 456 // No space is allocated for the sole location catalog entry index, as it is useless. 457 size_t expected_dex_register_map_size = 1u + 0u; 458 ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size()); 459 460 ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationKind( 461 0, number_of_dex_registers, code_info, encoding)); 462 ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind( 463 1, number_of_dex_registers, code_info, encoding)); 464 ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationInternalKind( 465 0, number_of_dex_registers, code_info, encoding)); 466 ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind( 467 1, number_of_dex_registers, code_info, encoding)); 468 ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding)); 469 470 size_t index0 = dex_register_map.GetLocationCatalogEntryIndex( 471 0, number_of_dex_registers, number_of_catalog_entries); 472 size_t index1 = dex_register_map.GetLocationCatalogEntryIndex( 473 1, number_of_dex_registers, number_of_catalog_entries); 474 ASSERT_EQ(DexRegisterLocationCatalog::kNoLocationEntryIndex, index0); 475 ASSERT_EQ(0u, index1); 476 DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0); 477 DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1); 478 ASSERT_EQ(Kind::kNone, location0.GetKind()); 479 ASSERT_EQ(Kind::kConstant, location1.GetKind()); 480 ASSERT_EQ(Kind::kNone, location0.GetInternalKind()); 481 ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind()); 482 ASSERT_EQ(0, location0.GetValue()); 483 ASSERT_EQ(-2, location1.GetValue()); 484 485 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding)); 486} 487 488// Generate a stack map whose dex register offset is 489// StackMap::kNoDexRegisterMapSmallEncoding, and ensure we do 490// not treat it as kNoDexRegisterMap. 491TEST(StackMapTest, DexRegisterMapOffsetOverflow) { 492 ArenaPool pool; 493 ArenaAllocator arena(&pool); 494 StackMapStream stream(&arena); 495 496 ArenaBitVector sp_mask(&arena, 0, false); 497 uint32_t number_of_dex_registers = 1024; 498 // Create the first stack map (and its Dex register map). 499 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0); 500 uint32_t number_of_dex_live_registers_in_dex_register_map_0 = number_of_dex_registers - 8; 501 for (uint32_t i = 0; i < number_of_dex_live_registers_in_dex_register_map_0; ++i) { 502 // Use two different Dex register locations to populate this map, 503 // as using a single value (in the whole CodeInfo object) would 504 // make this Dex register mapping data empty (see 505 // art::DexRegisterMap::SingleEntrySizeInBits). 506 stream.AddDexRegisterEntry(Kind::kConstant, i % 2); // Short location. 507 } 508 stream.EndStackMapEntry(); 509 // Create the second stack map (and its Dex register map). 510 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0); 511 for (uint32_t i = 0; i < number_of_dex_registers; ++i) { 512 stream.AddDexRegisterEntry(Kind::kConstant, 0); // Short location. 513 } 514 stream.EndStackMapEntry(); 515 516 size_t size = stream.PrepareForFillIn(); 517 void* memory = arena.Alloc(size, kArenaAllocMisc); 518 MemoryRegion region(memory, size); 519 stream.FillIn(region); 520 521 CodeInfo code_info(region); 522 CodeInfoEncoding encoding = code_info.ExtractEncoding(); 523 // The location catalog contains two entries (DexRegisterLocation(kConstant, 0) 524 // and DexRegisterLocation(kConstant, 1)), therefore the location catalog index 525 // has a size of 1 bit. 526 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding); 527 ASSERT_EQ(2u, number_of_catalog_entries); 528 ASSERT_EQ(1u, DexRegisterMap::SingleEntrySizeInBits(number_of_catalog_entries)); 529 530 // The first Dex register map contains: 531 // - a live register bit mask for 1024 registers (that is, 128 bytes of 532 // data); and 533 // - Dex register mapping information for 1016 1-bit Dex (live) register 534 // locations (that is, 127 bytes of data). 535 // Hence it has a size of 255 bytes, and therefore... 536 ASSERT_EQ(128u, DexRegisterMap::GetLiveBitMaskSize(number_of_dex_registers)); 537 StackMap stack_map0 = code_info.GetStackMapAt(0, encoding); 538 DexRegisterMap dex_register_map0 = 539 code_info.GetDexRegisterMapOf(stack_map0, encoding, number_of_dex_registers); 540 ASSERT_EQ(127u, dex_register_map0.GetLocationMappingDataSize(number_of_dex_registers, 541 number_of_catalog_entries)); 542 ASSERT_EQ(255u, dex_register_map0.Size()); 543 544 StackMap stack_map1 = code_info.GetStackMapAt(1, encoding); 545 ASSERT_TRUE(stack_map1.HasDexRegisterMap(encoding.stack_map_encoding)); 546 // ...the offset of the second Dex register map (relative to the 547 // beginning of the Dex register maps region) is 255 (i.e., 548 // kNoDexRegisterMapSmallEncoding). 549 ASSERT_NE(stack_map1.GetDexRegisterMapOffset(encoding.stack_map_encoding), 550 StackMap::kNoDexRegisterMap); 551 ASSERT_EQ(stack_map1.GetDexRegisterMapOffset(encoding.stack_map_encoding), 0xFFu); 552} 553 554TEST(StackMapTest, TestShareDexRegisterMap) { 555 ArenaPool pool; 556 ArenaAllocator arena(&pool); 557 StackMapStream stream(&arena); 558 559 ArenaBitVector sp_mask(&arena, 0, false); 560 uint32_t number_of_dex_registers = 2; 561 // First stack map. 562 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0); 563 stream.AddDexRegisterEntry(Kind::kInRegister, 0); // Short location. 564 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location. 565 stream.EndStackMapEntry(); 566 // Second stack map, which should share the same dex register map. 567 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0); 568 stream.AddDexRegisterEntry(Kind::kInRegister, 0); // Short location. 569 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location. 570 stream.EndStackMapEntry(); 571 // Third stack map (doesn't share the dex register map). 572 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0); 573 stream.AddDexRegisterEntry(Kind::kInRegister, 2); // Short location. 574 stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location. 575 stream.EndStackMapEntry(); 576 577 size_t size = stream.PrepareForFillIn(); 578 void* memory = arena.Alloc(size, kArenaAllocMisc); 579 MemoryRegion region(memory, size); 580 stream.FillIn(region); 581 582 CodeInfo ci(region); 583 CodeInfoEncoding encoding = ci.ExtractEncoding(); 584 585 // Verify first stack map. 586 StackMap sm0 = ci.GetStackMapAt(0, encoding); 587 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, number_of_dex_registers); 588 ASSERT_EQ(0, dex_registers0.GetMachineRegister(0, number_of_dex_registers, ci, encoding)); 589 ASSERT_EQ(-2, dex_registers0.GetConstant(1, number_of_dex_registers, ci, encoding)); 590 591 // Verify second stack map. 592 StackMap sm1 = ci.GetStackMapAt(1, encoding); 593 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1, encoding, number_of_dex_registers); 594 ASSERT_EQ(0, dex_registers1.GetMachineRegister(0, number_of_dex_registers, ci, encoding)); 595 ASSERT_EQ(-2, dex_registers1.GetConstant(1, number_of_dex_registers, ci, encoding)); 596 597 // Verify third stack map. 598 StackMap sm2 = ci.GetStackMapAt(2, encoding); 599 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2, encoding, number_of_dex_registers); 600 ASSERT_EQ(2, dex_registers2.GetMachineRegister(0, number_of_dex_registers, ci, encoding)); 601 ASSERT_EQ(-2, dex_registers2.GetConstant(1, number_of_dex_registers, ci, encoding)); 602 603 // Verify dex register map offsets. 604 ASSERT_EQ(sm0.GetDexRegisterMapOffset(encoding.stack_map_encoding), 605 sm1.GetDexRegisterMapOffset(encoding.stack_map_encoding)); 606 ASSERT_NE(sm0.GetDexRegisterMapOffset(encoding.stack_map_encoding), 607 sm2.GetDexRegisterMapOffset(encoding.stack_map_encoding)); 608 ASSERT_NE(sm1.GetDexRegisterMapOffset(encoding.stack_map_encoding), 609 sm2.GetDexRegisterMapOffset(encoding.stack_map_encoding)); 610} 611 612TEST(StackMapTest, TestNoDexRegisterMap) { 613 ArenaPool pool; 614 ArenaAllocator arena(&pool); 615 StackMapStream stream(&arena); 616 617 ArenaBitVector sp_mask(&arena, 0, false); 618 uint32_t number_of_dex_registers = 0; 619 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0); 620 stream.EndStackMapEntry(); 621 622 number_of_dex_registers = 1; 623 stream.BeginStackMapEntry(1, 67, 0x4, &sp_mask, number_of_dex_registers, 0); 624 stream.EndStackMapEntry(); 625 626 size_t size = stream.PrepareForFillIn(); 627 void* memory = arena.Alloc(size, kArenaAllocMisc); 628 MemoryRegion region(memory, size); 629 stream.FillIn(region); 630 631 CodeInfo code_info(region); 632 CodeInfoEncoding encoding = code_info.ExtractEncoding(); 633 ASSERT_EQ(2u, code_info.GetNumberOfStackMaps(encoding)); 634 635 uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding); 636 ASSERT_EQ(0u, number_of_catalog_entries); 637 DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding); 638 ASSERT_EQ(0u, location_catalog.Size()); 639 640 StackMap stack_map = code_info.GetStackMapAt(0, encoding); 641 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding))); 642 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding))); 643 ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding)); 644 ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding)); 645 ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding)); 646 647 ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding)); 648 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding)); 649 650 stack_map = code_info.GetStackMapAt(1, encoding); 651 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1, encoding))); 652 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(67, encoding))); 653 ASSERT_EQ(1u, stack_map.GetDexPc(encoding.stack_map_encoding)); 654 ASSERT_EQ(67u, stack_map.GetNativePcOffset(encoding.stack_map_encoding)); 655 ASSERT_EQ(0x4u, stack_map.GetRegisterMask(encoding.stack_map_encoding)); 656 657 ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding)); 658 ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding)); 659} 660 661TEST(StackMapTest, InlineTest) { 662 ArenaPool pool; 663 ArenaAllocator arena(&pool); 664 StackMapStream stream(&arena); 665 666 ArenaBitVector sp_mask1(&arena, 0, true); 667 sp_mask1.SetBit(2); 668 sp_mask1.SetBit(4); 669 670 // First stack map. 671 stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, 2, 2); 672 stream.AddDexRegisterEntry(Kind::kInStack, 0); 673 stream.AddDexRegisterEntry(Kind::kConstant, 4); 674 675 stream.BeginInlineInfoEntry(42, 2, kStatic, 1); 676 stream.AddDexRegisterEntry(Kind::kInStack, 8); 677 stream.EndInlineInfoEntry(); 678 stream.BeginInlineInfoEntry(82, 3, kStatic, 3); 679 stream.AddDexRegisterEntry(Kind::kInStack, 16); 680 stream.AddDexRegisterEntry(Kind::kConstant, 20); 681 stream.AddDexRegisterEntry(Kind::kInRegister, 15); 682 stream.EndInlineInfoEntry(); 683 684 stream.EndStackMapEntry(); 685 686 // Second stack map. 687 stream.BeginStackMapEntry(2, 22, 0x3, &sp_mask1, 2, 3); 688 stream.AddDexRegisterEntry(Kind::kInStack, 56); 689 stream.AddDexRegisterEntry(Kind::kConstant, 0); 690 691 stream.BeginInlineInfoEntry(42, 2, kDirect, 1); 692 stream.AddDexRegisterEntry(Kind::kInStack, 12); 693 stream.EndInlineInfoEntry(); 694 stream.BeginInlineInfoEntry(82, 3, kStatic, 3); 695 stream.AddDexRegisterEntry(Kind::kInStack, 80); 696 stream.AddDexRegisterEntry(Kind::kConstant, 10); 697 stream.AddDexRegisterEntry(Kind::kInRegister, 5); 698 stream.EndInlineInfoEntry(); 699 stream.BeginInlineInfoEntry(52, 5, kVirtual, 0); 700 stream.EndInlineInfoEntry(); 701 702 stream.EndStackMapEntry(); 703 704 // Third stack map. 705 stream.BeginStackMapEntry(4, 56, 0x3, &sp_mask1, 2, 0); 706 stream.AddDexRegisterEntry(Kind::kNone, 0); 707 stream.AddDexRegisterEntry(Kind::kConstant, 4); 708 stream.EndStackMapEntry(); 709 710 // Fourth stack map. 711 stream.BeginStackMapEntry(6, 78, 0x3, &sp_mask1, 2, 3); 712 stream.AddDexRegisterEntry(Kind::kInStack, 56); 713 stream.AddDexRegisterEntry(Kind::kConstant, 0); 714 715 stream.BeginInlineInfoEntry(42, 2, kVirtual, 0); 716 stream.EndInlineInfoEntry(); 717 stream.BeginInlineInfoEntry(52, 5, kInterface, 1); 718 stream.AddDexRegisterEntry(Kind::kInRegister, 2); 719 stream.EndInlineInfoEntry(); 720 stream.BeginInlineInfoEntry(52, 10, kStatic, 2); 721 stream.AddDexRegisterEntry(Kind::kNone, 0); 722 stream.AddDexRegisterEntry(Kind::kInRegister, 3); 723 stream.EndInlineInfoEntry(); 724 725 stream.EndStackMapEntry(); 726 727 size_t size = stream.PrepareForFillIn(); 728 void* memory = arena.Alloc(size, kArenaAllocMisc); 729 MemoryRegion region(memory, size); 730 stream.FillIn(region); 731 732 CodeInfo ci(region); 733 CodeInfoEncoding encoding = ci.ExtractEncoding(); 734 735 { 736 // Verify first stack map. 737 StackMap sm0 = ci.GetStackMapAt(0, encoding); 738 739 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, 2); 740 ASSERT_EQ(0, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding)); 741 ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding)); 742 743 InlineInfo if0 = ci.GetInlineInfoOf(sm0, encoding); 744 ASSERT_EQ(2u, if0.GetDepth(encoding.inline_info_encoding)); 745 ASSERT_EQ(2u, if0.GetDexPcAtDepth(encoding.inline_info_encoding, 0)); 746 ASSERT_EQ(42u, if0.GetMethodIndexAtDepth(encoding.inline_info_encoding, 0)); 747 ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 0)); 748 ASSERT_EQ(3u, if0.GetDexPcAtDepth(encoding.inline_info_encoding, 1)); 749 ASSERT_EQ(82u, if0.GetMethodIndexAtDepth(encoding.inline_info_encoding, 1)); 750 ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 1)); 751 752 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if0, encoding, 1); 753 ASSERT_EQ(8, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding)); 754 755 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)); 759 } 760 761 { 762 // Verify second stack map. 763 StackMap sm1 = ci.GetStackMapAt(1, encoding); 764 765 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)); 768 769 InlineInfo if1 = ci.GetInlineInfoOf(sm1, encoding); 770 ASSERT_EQ(3u, if1.GetDepth(encoding.inline_info_encoding)); 771 ASSERT_EQ(2u, if1.GetDexPcAtDepth(encoding.inline_info_encoding, 0)); 772 ASSERT_EQ(42u, if1.GetMethodIndexAtDepth(encoding.inline_info_encoding, 0)); 773 ASSERT_EQ(kDirect, if1.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 0)); 774 ASSERT_EQ(3u, if1.GetDexPcAtDepth(encoding.inline_info_encoding, 1)); 775 ASSERT_EQ(82u, if1.GetMethodIndexAtDepth(encoding.inline_info_encoding, 1)); 776 ASSERT_EQ(kStatic, if1.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 1)); 777 ASSERT_EQ(5u, if1.GetDexPcAtDepth(encoding.inline_info_encoding, 2)); 778 ASSERT_EQ(52u, if1.GetMethodIndexAtDepth(encoding.inline_info_encoding, 2)); 779 ASSERT_EQ(kVirtual, if1.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 2)); 780 781 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if1, encoding, 1); 782 ASSERT_EQ(12, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding)); 783 784 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if1, encoding, 3); 785 ASSERT_EQ(80, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding)); 786 ASSERT_EQ(10, dex_registers2.GetConstant(1, 3, ci, encoding)); 787 ASSERT_EQ(5, dex_registers2.GetMachineRegister(2, 3, ci, encoding)); 788 789 ASSERT_FALSE(if1.HasDexRegisterMapAtDepth(encoding.inline_info_encoding, 2)); 790 } 791 792 { 793 // Verify third stack map. 794 StackMap sm2 = ci.GetStackMapAt(2, encoding); 795 796 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm2, encoding, 2); 797 ASSERT_FALSE(dex_registers0.IsDexRegisterLive(0)); 798 ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding)); 799 ASSERT_FALSE(sm2.HasInlineInfo(encoding.stack_map_encoding)); 800 } 801 802 { 803 // Verify fourth stack map. 804 StackMap sm3 = ci.GetStackMapAt(3, encoding); 805 806 DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm3, encoding, 2); 807 ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding)); 808 ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding)); 809 810 InlineInfo if2 = ci.GetInlineInfoOf(sm3, encoding); 811 ASSERT_EQ(3u, if2.GetDepth(encoding.inline_info_encoding)); 812 ASSERT_EQ(2u, if2.GetDexPcAtDepth(encoding.inline_info_encoding, 0)); 813 ASSERT_EQ(42u, if2.GetMethodIndexAtDepth(encoding.inline_info_encoding, 0)); 814 ASSERT_EQ(kVirtual, if2.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 0)); 815 ASSERT_EQ(5u, if2.GetDexPcAtDepth(encoding.inline_info_encoding, 1)); 816 ASSERT_EQ(52u, if2.GetMethodIndexAtDepth(encoding.inline_info_encoding, 1)); 817 ASSERT_EQ(kInterface, if2.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 1)); 818 ASSERT_EQ(10u, if2.GetDexPcAtDepth(encoding.inline_info_encoding, 2)); 819 ASSERT_EQ(52u, if2.GetMethodIndexAtDepth(encoding.inline_info_encoding, 2)); 820 ASSERT_EQ(kStatic, if2.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 2)); 821 822 ASSERT_FALSE(if2.HasDexRegisterMapAtDepth(encoding.inline_info_encoding, 0)); 823 824 DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(1, if2, encoding, 1); 825 ASSERT_EQ(2, dex_registers1.GetMachineRegister(0, 1, ci, encoding)); 826 827 DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(2, if2, encoding, 2); 828 ASSERT_FALSE(dex_registers2.IsDexRegisterLive(0)); 829 ASSERT_EQ(3, dex_registers2.GetMachineRegister(1, 2, ci, encoding)); 830 } 831} 832 833} // namespace art 834