199ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray/*
299ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray * Copyright (C) 2014 The Android Open Source Project
399ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray *
499ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
599ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray * you may not use this file except in compliance with the License.
699ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray * You may obtain a copy of the License at
799ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray *
899ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
999ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray *
1099ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray * Unless required by applicable law or agreed to in writing, software
1199ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
1299ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1399ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray * See the License for the specific language governing permissions and
1499ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray * limitations under the License.
1599ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray */
1699ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
1799ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray#include "stack_map.h"
18e5d80f83ae53792bc1eebd4e33e4e99f7c031b0cMathieu Chartier
19e5d80f83ae53792bc1eebd4e33e4e99f7c031b0cMathieu Chartier#include "base/arena_bit_vector.h"
2099ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray#include "stack_map_stream.h"
2199ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
2299ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray#include "gtest/gtest.h"
2399ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
2499ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffraynamespace art {
2599ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
2609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky// Check that the stack mask of given stack map is identical
2709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky// to the given bit vector. Returns true if they are same.
2809ed09866da6d8c7448ef297c148bfa577a247c2David Srbeckystatic bool CheckStackMask(
2909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    const StackMap& stack_map,
3009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    StackMapEncoding& encoding,
3109ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    const BitVector& bit_vector) {
3209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  int number_of_bits = stack_map.GetNumberOfStackMaskBits(encoding);
3309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  if (bit_vector.GetHighestBitSet() >= number_of_bits) {
3409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    return false;
3509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  }
3609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  for (int i = 0; i < number_of_bits; ++i) {
3709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    if (stack_map.GetStackMaskBit(encoding, i) != bit_vector.IsBitSet(i)) {
3899ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray      return false;
3999ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray    }
4099ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  }
4199ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  return true;
4299ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray}
4399ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
44a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillainusing Kind = DexRegisterLocation::Kind;
45a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
4699ea58cc68b51837c065f4a2a54efbf208dd76faNicolas GeoffrayTEST(StackMapTest, Test1) {
4799ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  ArenaPool pool;
4899ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  ArenaAllocator arena(&pool);
493946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray  StackMapStream stream(&arena);
5099ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
5199ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  ArenaBitVector sp_mask(&arena, 0, false);
5212baf476389359d54ae04d7898190ef6f81ab0b2Roland Levillain  size_t number_of_dex_registers = 2;
534f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
54b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInStack, 0);         // Short location.
55b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, -2);       // Short location.
564f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.EndStackMapEntry();
5799ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
584f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  size_t size = stream.PrepareForFillIn();
5999ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  void* memory = arena.Alloc(size, kArenaAllocMisc);
6099ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  MemoryRegion region(memory, size);
6199ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  stream.FillIn(region);
6299ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
633946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray  CodeInfo code_info(region);
6409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  CodeInfoEncoding encoding = code_info.ExtractEncoding();
6509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(1u, code_info.GetNumberOfStackMaps(encoding));
6699ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
6709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
6809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(2u, number_of_catalog_entries);
69f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
70a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // The Dex register location catalog contains:
71a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // - one 1-byte short Dex register location, and
72a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // - one 5-byte large Dex register location.
73a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t expected_location_catalog_size = 1u + 5u;
74a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
75a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
76f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMap stack_map = code_info.GetStackMapAt(0, encoding);
77f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
78f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
7909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding));
8009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding));
8109ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
8299ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
8309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask));
8499ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
8509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
86a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterMap dex_register_map =
87f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
88a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
89a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
90a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
91a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // The Dex register map contains:
92a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // - one 1-byte live bit mask, and
93a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
94a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t expected_dex_register_map_size = 1u + 1u;
95a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
96a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
97f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(
98f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                0, number_of_dex_registers, code_info, encoding));
99f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
100f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                1, number_of_dex_registers, code_info, encoding));
101f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind(
102f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                0, number_of_dex_registers, code_info, encoding));
103f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
104f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                1, number_of_dex_registers, code_info, encoding));
105f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(
106f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                0, number_of_dex_registers, code_info, encoding));
107f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
108a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
109a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
11009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      0, number_of_dex_registers, number_of_catalog_entries);
111a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
11209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      1, number_of_dex_registers, number_of_catalog_entries);
113a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(0u, index0);
114a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(1u, index1);
115a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
116a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
117a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(Kind::kInStack, location0.GetKind());
118a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(Kind::kConstant, location1.GetKind());
119a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
120a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
121a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain  ASSERT_EQ(0, location0.GetValue());
122a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain  ASSERT_EQ(-2, location1.GetValue());
12312baf476389359d54ae04d7898190ef6f81ab0b2Roland Levillain
12409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
12599ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray}
12699ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
12799ea58cc68b51837c065f4a2a54efbf208dd76faNicolas GeoffrayTEST(StackMapTest, Test2) {
12899ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  ArenaPool pool;
12999ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  ArenaAllocator arena(&pool);
1303946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray  StackMapStream stream(&arena);
13199ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
13299ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  ArenaBitVector sp_mask1(&arena, 0, true);
13399ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  sp_mask1.SetBit(2);
13499ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  sp_mask1.SetBit(4);
13512baf476389359d54ae04d7898190ef6f81ab0b2Roland Levillain  size_t number_of_dex_registers = 2;
136b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  size_t number_of_dex_registers_in_inline_info = 0;
1374f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 2);
138b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInStack, 0);         // Short location.
139b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, -2);       // Large location.
140b176d7c6c8c01a50317f837a78de5da57ee84fb2Nicolas Geoffray  stream.BeginInlineInfoEntry(82, 3, kDirect, number_of_dex_registers_in_inline_info);
141b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndInlineInfoEntry();
142b176d7c6c8c01a50317f837a78de5da57ee84fb2Nicolas Geoffray  stream.BeginInlineInfoEntry(42, 2, kStatic, number_of_dex_registers_in_inline_info);
143b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndInlineInfoEntry();
1444f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.EndStackMapEntry();
14599ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
14699ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  ArenaBitVector sp_mask2(&arena, 0, true);
14799ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  sp_mask2.SetBit(3);
148f10a25f961eb8029c01c84fe8eabd405055cca37David Brazdil  sp_mask2.SetBit(8);
1494f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.BeginStackMapEntry(1, 128, 0xFF, &sp_mask2, number_of_dex_registers, 0);
150b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInRegister, 18);     // Short location.
151b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3);   // Short location.
1524f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.EndStackMapEntry();
15399ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
154d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  ArenaBitVector sp_mask3(&arena, 0, true);
155d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  sp_mask3.SetBit(1);
156d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  sp_mask3.SetBit(5);
157d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  stream.BeginStackMapEntry(2, 192, 0xAB, &sp_mask3, number_of_dex_registers, 0);
158d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  stream.AddDexRegisterEntry(Kind::kInRegister, 6);       // Short location.
159d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  stream.AddDexRegisterEntry(Kind::kInRegisterHigh, 8);   // Short location.
160d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  stream.EndStackMapEntry();
161d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
162d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  ArenaBitVector sp_mask4(&arena, 0, true);
163d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  sp_mask4.SetBit(6);
164d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  sp_mask4.SetBit(7);
165d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  stream.BeginStackMapEntry(3, 256, 0xCD, &sp_mask4, number_of_dex_registers, 0);
166d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3);      // Short location, same in stack map 2.
167d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  stream.AddDexRegisterEntry(Kind::kInFpuRegisterHigh, 1);  // Short location.
168d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  stream.EndStackMapEntry();
169d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
1704f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  size_t size = stream.PrepareForFillIn();
17199ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  void* memory = arena.Alloc(size, kArenaAllocMisc);
17299ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  MemoryRegion region(memory, size);
17399ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray  stream.FillIn(region);
17499ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
1753946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray  CodeInfo code_info(region);
17609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  CodeInfoEncoding encoding = code_info.ExtractEncoding();
17709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(4u, code_info.GetNumberOfStackMaps(encoding));
17899ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
17909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
18009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(7u, number_of_catalog_entries);
181f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
182a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // The Dex register location catalog contains:
183d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  // - six 1-byte short Dex register locations, and
184a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // - one 5-byte large Dex register location.
185d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  size_t expected_location_catalog_size = 6u * 1u + 5u;
186a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
187a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
18812baf476389359d54ae04d7898190ef6f81ab0b2Roland Levillain  // First stack map.
189a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain  {
190f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    StackMap stack_map = code_info.GetStackMapAt(0, encoding);
191f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
192f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
19309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding));
19409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding));
19509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
196f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil
19709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask1));
198a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain
19909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
200a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    DexRegisterMap dex_register_map =
201f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil        code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
202a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
203a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
204a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
205a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    // The Dex register map contains:
206a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    // - one 1-byte live bit mask, and
207a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
208a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    size_t expected_dex_register_map_size = 1u + 1u;
209a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
210a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
211f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(
212f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  0, number_of_dex_registers, code_info, encoding));
213f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
214f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  1, number_of_dex_registers, code_info, encoding));
215f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationInternalKind(
216f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  0, number_of_dex_registers, code_info, encoding));
217f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
218f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  1, number_of_dex_registers, code_info, encoding));
219f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(
220f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  0, number_of_dex_registers, code_info, encoding));
221f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
222a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
223a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
22409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky        0, number_of_dex_registers, number_of_catalog_entries);
225a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
22609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky        1, number_of_dex_registers, number_of_catalog_entries);
227a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(0u, index0);
228a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(1u, index1);
229a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
230a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
231a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(Kind::kInStack, location0.GetKind());
232a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(Kind::kConstant, location1.GetKind());
233a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
234a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
235a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain    ASSERT_EQ(0, location0.GetValue());
236a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain    ASSERT_EQ(-2, location1.GetValue());
237a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain
23809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_TRUE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
239f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
24061b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(2u, inline_info.GetDepth(encoding.inline_info_encoding));
24161b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(82u, inline_info.GetMethodIndexAtDepth(encoding.inline_info_encoding, 0));
24261b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(42u, inline_info.GetMethodIndexAtDepth(encoding.inline_info_encoding, 1));
24361b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(3u, inline_info.GetDexPcAtDepth(encoding.inline_info_encoding, 0));
24461b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(2u, inline_info.GetDexPcAtDepth(encoding.inline_info_encoding, 1));
24561b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(kDirect, inline_info.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 0));
24661b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(kStatic, inline_info.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 1));
247a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain  }
24899ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
24912baf476389359d54ae04d7898190ef6f81ab0b2Roland Levillain  // Second stack map.
250a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain  {
251f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    StackMap stack_map = code_info.GetStackMapAt(1, encoding);
252f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u, encoding)));
253f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(128u, encoding)));
25409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(1u, stack_map.GetDexPc(encoding.stack_map_encoding));
25509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(128u, stack_map.GetNativePcOffset(encoding.stack_map_encoding));
25609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(0xFFu, stack_map.GetRegisterMask(encoding.stack_map_encoding));
257f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil
25809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask2));
259a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain
26009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
261a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    DexRegisterMap dex_register_map =
262f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil        code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
263a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
264a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
265a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
266a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    // The Dex register map contains:
267a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    // - one 1-byte live bit mask, and
268a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
269a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    size_t expected_dex_register_map_size = 1u + 1u;
270a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
271a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
272f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind(
273f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  0, number_of_dex_registers, code_info, encoding));
274f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind(
275f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  1, number_of_dex_registers, code_info, encoding));
276f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationInternalKind(
277f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  0, number_of_dex_registers, code_info, encoding));
278f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationInternalKind(
279f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  1, number_of_dex_registers, code_info, encoding));
280f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(18, dex_register_map.GetMachineRegister(
281f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  0, number_of_dex_registers, code_info, encoding));
282f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(3, dex_register_map.GetMachineRegister(
283f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  1, number_of_dex_registers, code_info, encoding));
284a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
285a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
28609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky        0, number_of_dex_registers, number_of_catalog_entries);
287a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
28809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky        1, number_of_dex_registers, number_of_catalog_entries);
289a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(2u, index0);
290a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(3u, index1);
291a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
292a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
293a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(Kind::kInRegister, location0.GetKind());
294a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(Kind::kInFpuRegister, location1.GetKind());
295a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind());
296a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    ASSERT_EQ(Kind::kInFpuRegister, location1.GetInternalKind());
297a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain    ASSERT_EQ(18, location0.GetValue());
298a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain    ASSERT_EQ(3, location1.GetValue());
299a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain
30009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
301a2d8ec6876325e89e5d82f5dbeca59f96ced3ec1Roland Levillain  }
302d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
303d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  // Third stack map.
304d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  {
305d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    StackMap stack_map = code_info.GetStackMapAt(2, encoding);
306d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(2u, encoding)));
307d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(192u, encoding)));
30809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(2u, stack_map.GetDexPc(encoding.stack_map_encoding));
30909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(192u, stack_map.GetNativePcOffset(encoding.stack_map_encoding));
31009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(0xABu, stack_map.GetRegisterMask(encoding.stack_map_encoding));
311d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
31209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask3));
313d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
31409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
315d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    DexRegisterMap dex_register_map =
316d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil        code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
317d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
318d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
319d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
320d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    // The Dex register map contains:
321d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    // - one 1-byte live bit mask, and
322d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
323d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    size_t expected_dex_register_map_size = 1u + 1u;
324d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
325d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
326d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind(
327d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  0, number_of_dex_registers, code_info, encoding));
328d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map.GetLocationKind(
329d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  1, number_of_dex_registers, code_info, encoding));
330d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationInternalKind(
331d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  0, number_of_dex_registers, code_info, encoding));
332d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map.GetLocationInternalKind(
333d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  1, number_of_dex_registers, code_info, encoding));
334d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(6, dex_register_map.GetMachineRegister(
335d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  0, number_of_dex_registers, code_info, encoding));
336d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(8, dex_register_map.GetMachineRegister(
337d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  1, number_of_dex_registers, code_info, encoding));
338d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
339d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
34009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky        0, number_of_dex_registers, number_of_catalog_entries);
341d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
34209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky        1, number_of_dex_registers, number_of_catalog_entries);
343d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(4u, index0);
344d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(5u, index1);
345d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
346d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
347d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInRegister, location0.GetKind());
348d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInRegisterHigh, location1.GetKind());
349d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInRegister, location0.GetInternalKind());
350d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInRegisterHigh, location1.GetInternalKind());
351d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(6, location0.GetValue());
352d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(8, location1.GetValue());
353d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
35409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
355d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  }
356d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
357d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  // Fourth stack map.
358d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  {
359d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    StackMap stack_map = code_info.GetStackMapAt(3, encoding);
360d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(3u, encoding)));
361d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(256u, encoding)));
36209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(3u, stack_map.GetDexPc(encoding.stack_map_encoding));
36309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(256u, stack_map.GetNativePcOffset(encoding.stack_map_encoding));
36409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_EQ(0xCDu, stack_map.GetRegisterMask(encoding.stack_map_encoding));
365d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
36609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_TRUE(CheckStackMask(stack_map, encoding.stack_map_encoding, sp_mask4));
367d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
36809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
369d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    DexRegisterMap dex_register_map =
370d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil        code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
371d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0));
372d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
373d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
374d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    // The Dex register map contains:
375d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    // - one 1-byte live bit mask, and
376d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
377d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    size_t expected_dex_register_map_size = 1u + 1u;
378d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
379d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
380d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind(
381d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  0, number_of_dex_registers, code_info, encoding));
382d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map.GetLocationKind(
383d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  1, number_of_dex_registers, code_info, encoding));
384d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationInternalKind(
385d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  0, number_of_dex_registers, code_info, encoding));
386d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map.GetLocationInternalKind(
387d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  1, number_of_dex_registers, code_info, encoding));
388d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(3, dex_register_map.GetMachineRegister(
389d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  0, number_of_dex_registers, code_info, encoding));
390d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(1, dex_register_map.GetMachineRegister(
391d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil                  1, number_of_dex_registers, code_info, encoding));
392d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
393d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
39409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky        0, number_of_dex_registers, number_of_catalog_entries);
395d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    size_t index1 = dex_register_map.GetLocationCatalogEntryIndex(
39609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky        1, number_of_dex_registers, number_of_catalog_entries);
397d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(3u, index0);  // Shared with second stack map.
398d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(6u, index1);
399d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
400d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
401d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInFpuRegister, location0.GetKind());
402d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInFpuRegisterHigh, location1.GetKind());
403d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInFpuRegister, location0.GetInternalKind());
404d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(Kind::kInFpuRegisterHigh, location1.GetInternalKind());
405d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(3, location0.GetValue());
406d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil    ASSERT_EQ(1, location1.GetValue());
407d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil
40809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
409d9cb68e3212d31d61445fb7e8446f68991720009David Brazdil  }
41099ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray}
41199ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray
412fead4e4f397455aa31905b2982d4d861126ab89dNicolas GeoffrayTEST(StackMapTest, TestNonLiveDexRegisters) {
413fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray  ArenaPool pool;
414fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray  ArenaAllocator arena(&pool);
415fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray  StackMapStream stream(&arena);
416fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray
417fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray  ArenaBitVector sp_mask(&arena, 0, false);
418fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray  uint32_t number_of_dex_registers = 2;
4194f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
420b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kNone, 0);            // No location.
421b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, -2);       // Large location.
4224f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.EndStackMapEntry();
423fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray
4244f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  size_t size = stream.PrepareForFillIn();
425fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray  void* memory = arena.Alloc(size, kArenaAllocMisc);
426fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray  MemoryRegion region(memory, size);
427fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray  stream.FillIn(region);
428fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray
429fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray  CodeInfo code_info(region);
43009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  CodeInfoEncoding encoding = code_info.ExtractEncoding();
43109ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(1u, code_info.GetNumberOfStackMaps(encoding));
432a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
43309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
43409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(1u, number_of_catalog_entries);
435f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
436a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // The Dex register location catalog contains:
437a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // - one 5-byte large Dex register location.
438a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t expected_location_catalog_size = 5u;
439a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
440a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
441f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMap stack_map = code_info.GetStackMapAt(0, encoding);
442f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
443f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
44409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding));
44509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding));
44609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
447a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
44809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
449a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterMap dex_register_map =
450f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
451a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_FALSE(dex_register_map.IsDexRegisterLive(0));
452a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1));
453a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
454a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // The Dex register map contains:
455a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // - one 1-byte live bit mask.
456a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // No space is allocated for the sole location catalog entry index, as it is useless.
457a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t expected_dex_register_map_size = 1u + 0u;
458a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(expected_dex_register_map_size, dex_register_map.Size());
459a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
460f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationKind(
461f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                0, number_of_dex_registers, code_info, encoding));
462f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(
463f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                1, number_of_dex_registers, code_info, encoding));
464f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationInternalKind(
465f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                0, number_of_dex_registers, code_info, encoding));
466f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(Kind::kConstantLargeValue, dex_register_map.GetLocationInternalKind(
467f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                1, number_of_dex_registers, code_info, encoding));
468f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(-2, dex_register_map.GetConstant(1, number_of_dex_registers, code_info, encoding));
469a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
470a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t index0 = dex_register_map.GetLocationCatalogEntryIndex(
47109ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      0, number_of_dex_registers, number_of_catalog_entries);
472a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t index1 =  dex_register_map.GetLocationCatalogEntryIndex(
47309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      1, number_of_dex_registers, number_of_catalog_entries);
474a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(DexRegisterLocationCatalog::kNoLocationEntryIndex, index0);
475a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(0u, index1);
476a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
477a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
478a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(Kind::kNone, location0.GetKind());
479a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(Kind::kConstant, location1.GetKind());
480a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(Kind::kNone, location0.GetInternalKind());
481a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
482a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(0, location0.GetValue());
483a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(-2, location1.GetValue());
484a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
48509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
486004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray}
487004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
488004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray// Generate a stack map whose dex register offset is
489004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray// StackMap::kNoDexRegisterMapSmallEncoding, and ensure we do
490004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray// not treat it as kNoDexRegisterMap.
491004c230b4cfc856690c61faabc41864061813c88Nicolas GeoffrayTEST(StackMapTest, DexRegisterMapOffsetOverflow) {
492004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  ArenaPool pool;
493004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  ArenaAllocator arena(&pool);
494004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  StackMapStream stream(&arena);
495004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
496004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  ArenaBitVector sp_mask(&arena, 0, false);
497a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  uint32_t number_of_dex_registers = 1024;
498a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // Create the first stack map (and its Dex register map).
4994f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
500a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  uint32_t number_of_dex_live_registers_in_dex_register_map_0 = number_of_dex_registers - 8;
501a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  for (uint32_t i = 0; i < number_of_dex_live_registers_in_dex_register_map_0; ++i) {
502a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    // Use two different Dex register locations to populate this map,
503a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    // as using a single value (in the whole CodeInfo object) would
504a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    // make this Dex register mapping data empty (see
505a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain    // art::DexRegisterMap::SingleEntrySizeInBits).
506b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    stream.AddDexRegisterEntry(Kind::kConstant, i % 2);  // Short location.
507004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  }
5084f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.EndStackMapEntry();
509a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // Create the second stack map (and its Dex register map).
5104f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
511004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  for (uint32_t i = 0; i < number_of_dex_registers; ++i) {
512b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    stream.AddDexRegisterEntry(Kind::kConstant, 0);  // Short location.
513004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  }
5144f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.EndStackMapEntry();
515004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
5164f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  size_t size = stream.PrepareForFillIn();
517004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  void* memory = arena.Alloc(size, kArenaAllocMisc);
518004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  MemoryRegion region(memory, size);
519004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  stream.FillIn(region);
520004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
521004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  CodeInfo code_info(region);
52209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  CodeInfoEncoding encoding = code_info.ExtractEncoding();
523a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // The location catalog contains two entries (DexRegisterLocation(kConstant, 0)
524a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // and DexRegisterLocation(kConstant, 1)), therefore the location catalog index
525a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // has a size of 1 bit.
52609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
52709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(2u, number_of_catalog_entries);
52809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(1u, DexRegisterMap::SingleEntrySizeInBits(number_of_catalog_entries));
529a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
530a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // The first Dex register map contains:
531a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // - a live register bit mask for 1024 registers (that is, 128 bytes of
532a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  //   data); and
533a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // - Dex register mapping information for 1016 1-bit Dex (live) register
534a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  //   locations (that is, 127 bytes of data).
535a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // Hence it has a size of 255 bytes, and therefore...
536a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(128u, DexRegisterMap::GetLiveBitMaskSize(number_of_dex_registers));
537f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMap stack_map0 = code_info.GetStackMapAt(0, encoding);
538a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterMap dex_register_map0 =
539f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      code_info.GetDexRegisterMapOf(stack_map0, encoding, number_of_dex_registers);
540a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(127u, dex_register_map0.GetLocationMappingDataSize(number_of_dex_registers,
54109ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky                                                               number_of_catalog_entries));
542a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(255u, dex_register_map0.Size());
543a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
544f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMap stack_map1 = code_info.GetStackMapAt(1, encoding);
54509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_TRUE(stack_map1.HasDexRegisterMap(encoding.stack_map_encoding));
546a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // ...the offset of the second Dex register map (relative to the
547a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // beginning of the Dex register maps region) is 255 (i.e.,
548a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // kNoDexRegisterMapSmallEncoding).
54909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_NE(stack_map1.GetDexRegisterMapOffset(encoding.stack_map_encoding),
55009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky            StackMap::kNoDexRegisterMap);
55109ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(stack_map1.GetDexRegisterMapOffset(encoding.stack_map_encoding), 0xFFu);
552fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray}
553fead4e4f397455aa31905b2982d4d861126ab89dNicolas Geoffray
5546ae70962089e4af9718cc9b7c2b79a0c501c1844Calin JuravleTEST(StackMapTest, TestShareDexRegisterMap) {
5556ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  ArenaPool pool;
5566ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  ArenaAllocator arena(&pool);
5576ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  StackMapStream stream(&arena);
5586ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle
5596ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  ArenaBitVector sp_mask(&arena, 0, false);
5606ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  uint32_t number_of_dex_registers = 2;
5616ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  // First stack map.
5624f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
563b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInRegister, 0);  // Short location.
564b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, -2);   // Large location.
5654f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.EndStackMapEntry();
5666ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  // Second stack map, which should share the same dex register map.
5674f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
568b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInRegister, 0);  // Short location.
569b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, -2);   // Large location.
5704f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.EndStackMapEntry();
5716ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  // Third stack map (doesn't share the dex register map).
5724f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
573b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInRegister, 2);  // Short location.
574b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, -2);   // Large location.
5754f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.EndStackMapEntry();
5766ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle
5774f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  size_t size = stream.PrepareForFillIn();
5786ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  void* memory = arena.Alloc(size, kArenaAllocMisc);
5796ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  MemoryRegion region(memory, size);
5806ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  stream.FillIn(region);
5816ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle
5826ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  CodeInfo ci(region);
58309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  CodeInfoEncoding encoding = ci.ExtractEncoding();
584f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil
5856ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  // Verify first stack map.
586f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMap sm0 = ci.GetStackMapAt(0, encoding);
587f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, number_of_dex_registers);
588f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(0, dex_registers0.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
589f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(-2, dex_registers0.GetConstant(1, number_of_dex_registers, ci, encoding));
5906ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle
5916ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  // Verify second stack map.
592f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMap sm1 = ci.GetStackMapAt(1, encoding);
593f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1, encoding, number_of_dex_registers);
594f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(0, dex_registers1.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
595f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(-2, dex_registers1.GetConstant(1, number_of_dex_registers, ci, encoding));
5966ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle
5976ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  // Verify third stack map.
598f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMap sm2 = ci.GetStackMapAt(2, encoding);
599f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2, encoding, number_of_dex_registers);
600f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(2, dex_registers2.GetMachineRegister(0, number_of_dex_registers, ci, encoding));
601f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_EQ(-2, dex_registers2.GetConstant(1, number_of_dex_registers, ci, encoding));
6026ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle
6036ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle  // Verify dex register map offsets.
60409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(sm0.GetDexRegisterMapOffset(encoding.stack_map_encoding),
60509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky            sm1.GetDexRegisterMapOffset(encoding.stack_map_encoding));
60609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_NE(sm0.GetDexRegisterMapOffset(encoding.stack_map_encoding),
60709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky            sm2.GetDexRegisterMapOffset(encoding.stack_map_encoding));
60809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_NE(sm1.GetDexRegisterMapOffset(encoding.stack_map_encoding),
60909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky            sm2.GetDexRegisterMapOffset(encoding.stack_map_encoding));
6106ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle}
6116ae70962089e4af9718cc9b7c2b79a0c501c1844Calin Juravle
612a552e1c0584b8ab63150510286478c68cdbce13fRoland LevillainTEST(StackMapTest, TestNoDexRegisterMap) {
613a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ArenaPool pool;
614a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ArenaAllocator arena(&pool);
615a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  StackMapStream stream(&arena);
616a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
617a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ArenaBitVector sp_mask(&arena, 0, false);
618a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  uint32_t number_of_dex_registers = 0;
6194f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
6204f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  stream.EndStackMapEntry();
621a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
622012fc4e9d9b66b3ffb7838b0e29dadbb4863ee69Nicolas Geoffray  number_of_dex_registers = 1;
623012fc4e9d9b66b3ffb7838b0e29dadbb4863ee69Nicolas Geoffray  stream.BeginStackMapEntry(1, 67, 0x4, &sp_mask, number_of_dex_registers, 0);
624012fc4e9d9b66b3ffb7838b0e29dadbb4863ee69Nicolas Geoffray  stream.EndStackMapEntry();
625012fc4e9d9b66b3ffb7838b0e29dadbb4863ee69Nicolas Geoffray
6264f46ac5179967dda5966f2dcecf2cf08977951efCalin Juravle  size_t size = stream.PrepareForFillIn();
627a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  void* memory = arena.Alloc(size, kArenaAllocMisc);
628a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  MemoryRegion region(memory, size);
629a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  stream.FillIn(region);
630a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
631a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  CodeInfo code_info(region);
63209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  CodeInfoEncoding encoding = code_info.ExtractEncoding();
63309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(2u, code_info.GetNumberOfStackMaps(encoding));
634a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
63509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
63609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(0u, number_of_catalog_entries);
637f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
638a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  ASSERT_EQ(0u, location_catalog.Size());
639a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
640f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMap stack_map = code_info.GetStackMapAt(0, encoding);
641f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
642f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
64309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map_encoding));
64409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map_encoding));
64509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(0x3u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
646a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
64709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
64809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
649012fc4e9d9b66b3ffb7838b0e29dadbb4863ee69Nicolas Geoffray
650012fc4e9d9b66b3ffb7838b0e29dadbb4863ee69Nicolas Geoffray  stack_map = code_info.GetStackMapAt(1, encoding);
651012fc4e9d9b66b3ffb7838b0e29dadbb4863ee69Nicolas Geoffray  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1, encoding)));
652012fc4e9d9b66b3ffb7838b0e29dadbb4863ee69Nicolas Geoffray  ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(67, encoding)));
65309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(1u, stack_map.GetDexPc(encoding.stack_map_encoding));
65409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(67u, stack_map.GetNativePcOffset(encoding.stack_map_encoding));
65509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_EQ(0x4u, stack_map.GetRegisterMask(encoding.stack_map_encoding));
656012fc4e9d9b66b3ffb7838b0e29dadbb4863ee69Nicolas Geoffray
65709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding.stack_map_encoding));
65809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  ASSERT_FALSE(stack_map.HasInlineInfo(encoding.stack_map_encoding));
659a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain}
660a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
661b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas GeoffrayTEST(StackMapTest, InlineTest) {
662b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  ArenaPool pool;
663b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  ArenaAllocator arena(&pool);
664b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  StackMapStream stream(&arena);
665b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
666b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  ArenaBitVector sp_mask1(&arena, 0, true);
667b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  sp_mask1.SetBit(2);
668b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  sp_mask1.SetBit(4);
669b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
670b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  // First stack map.
671b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, 2, 2);
672b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInStack, 0);
673b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, 4);
674b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
675b176d7c6c8c01a50317f837a78de5da57ee84fb2Nicolas Geoffray  stream.BeginInlineInfoEntry(42, 2, kStatic, 1);
676b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInStack, 8);
677b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndInlineInfoEntry();
678b176d7c6c8c01a50317f837a78de5da57ee84fb2Nicolas Geoffray  stream.BeginInlineInfoEntry(82, 3, kStatic, 3);
679b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInStack, 16);
680b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, 20);
681b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInRegister, 15);
682b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndInlineInfoEntry();
683b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
684b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndStackMapEntry();
685b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
686b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  // Second stack map.
687b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.BeginStackMapEntry(2, 22, 0x3, &sp_mask1, 2, 3);
688b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInStack, 56);
689b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, 0);
690b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
691b176d7c6c8c01a50317f837a78de5da57ee84fb2Nicolas Geoffray  stream.BeginInlineInfoEntry(42, 2, kDirect, 1);
692b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInStack, 12);
693b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndInlineInfoEntry();
694b176d7c6c8c01a50317f837a78de5da57ee84fb2Nicolas Geoffray  stream.BeginInlineInfoEntry(82, 3, kStatic, 3);
695b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInStack, 80);
696b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, 10);
697b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInRegister, 5);
698b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndInlineInfoEntry();
699b176d7c6c8c01a50317f837a78de5da57ee84fb2Nicolas Geoffray  stream.BeginInlineInfoEntry(52, 5, kVirtual, 0);
700b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndInlineInfoEntry();
701b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
702b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndStackMapEntry();
703b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
704b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  // Third stack map.
705b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.BeginStackMapEntry(4, 56, 0x3, &sp_mask1, 2, 0);
706b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kNone, 0);
707b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, 4);
708b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndStackMapEntry();
709b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
710b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  // Fourth stack map.
711b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.BeginStackMapEntry(6, 78, 0x3, &sp_mask1, 2, 3);
712b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInStack, 56);
713b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kConstant, 0);
714b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
715b176d7c6c8c01a50317f837a78de5da57ee84fb2Nicolas Geoffray  stream.BeginInlineInfoEntry(42, 2, kVirtual, 0);
716b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndInlineInfoEntry();
717b176d7c6c8c01a50317f837a78de5da57ee84fb2Nicolas Geoffray  stream.BeginInlineInfoEntry(52, 5, kInterface, 1);
718b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInRegister, 2);
719b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndInlineInfoEntry();
720b176d7c6c8c01a50317f837a78de5da57ee84fb2Nicolas Geoffray  stream.BeginInlineInfoEntry(52, 10, kStatic, 2);
721b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kNone, 0);
722b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.AddDexRegisterEntry(Kind::kInRegister, 3);
723b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndInlineInfoEntry();
724b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
725b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.EndStackMapEntry();
726b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
727b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  size_t size = stream.PrepareForFillIn();
728b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  void* memory = arena.Alloc(size, kArenaAllocMisc);
729b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  MemoryRegion region(memory, size);
730b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  stream.FillIn(region);
731b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
732b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  CodeInfo ci(region);
73309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  CodeInfoEncoding encoding = ci.ExtractEncoding();
734b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
735b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  {
736b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    // Verify first stack map.
737f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    StackMap sm0 = ci.GetStackMapAt(0, encoding);
738b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
739f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0, encoding, 2);
740f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(0, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
741f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding));
742b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
743f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    InlineInfo if0 = ci.GetInlineInfoOf(sm0, encoding);
74461b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(2u, if0.GetDepth(encoding.inline_info_encoding));
74561b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(2u, if0.GetDexPcAtDepth(encoding.inline_info_encoding, 0));
74661b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(42u, if0.GetMethodIndexAtDepth(encoding.inline_info_encoding, 0));
74761b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 0));
74861b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(3u, if0.GetDexPcAtDepth(encoding.inline_info_encoding, 1));
74961b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(82u, if0.GetMethodIndexAtDepth(encoding.inline_info_encoding, 1));
75061b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 1));
751b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
752f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if0, encoding, 1);
753f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(8, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding));
754b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
755f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if0, encoding, 3);
756f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(16, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding));
757f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(20, dex_registers2.GetConstant(1, 3, ci, encoding));
758f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(15, dex_registers2.GetMachineRegister(2, 3, ci, encoding));
759b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  }
760b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
761b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  {
762b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    // Verify second stack map.
763f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    StackMap sm1 = ci.GetStackMapAt(1, encoding);
764b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
765f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm1, encoding, 2);
766f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
767f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding));
768b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
769f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    InlineInfo if1 = ci.GetInlineInfoOf(sm1, encoding);
77061b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(3u, if1.GetDepth(encoding.inline_info_encoding));
77161b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(2u, if1.GetDexPcAtDepth(encoding.inline_info_encoding, 0));
77261b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(42u, if1.GetMethodIndexAtDepth(encoding.inline_info_encoding, 0));
77361b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(kDirect, if1.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 0));
77461b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(3u, if1.GetDexPcAtDepth(encoding.inline_info_encoding, 1));
77561b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(82u, if1.GetMethodIndexAtDepth(encoding.inline_info_encoding, 1));
77661b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(kStatic, if1.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 1));
77761b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(5u, if1.GetDexPcAtDepth(encoding.inline_info_encoding, 2));
77861b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(52u, if1.GetMethodIndexAtDepth(encoding.inline_info_encoding, 2));
77961b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(kVirtual, if1.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 2));
780b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
781f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if1, encoding, 1);
782f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(12, dex_registers1.GetStackOffsetInBytes(0, 1, ci, encoding));
783b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
784f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, if1, encoding, 3);
785f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(80, dex_registers2.GetStackOffsetInBytes(0, 3, ci, encoding));
786f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(10, dex_registers2.GetConstant(1, 3, ci, encoding));
787f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(5, dex_registers2.GetMachineRegister(2, 3, ci, encoding));
788b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
78961b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_FALSE(if1.HasDexRegisterMapAtDepth(encoding.inline_info_encoding, 2));
790b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  }
791b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
792b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  {
793b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    // Verify third stack map.
794f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    StackMap sm2 = ci.GetStackMapAt(2, encoding);
795b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
796f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm2, encoding, 2);
797b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    ASSERT_FALSE(dex_registers0.IsDexRegisterLive(0));
798f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(4, dex_registers0.GetConstant(1, 2, ci, encoding));
79909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    ASSERT_FALSE(sm2.HasInlineInfo(encoding.stack_map_encoding));
800b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  }
801b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
802b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  {
803b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    // Verify fourth stack map.
804f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    StackMap sm3 = ci.GetStackMapAt(3, encoding);
805b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
806f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm3, encoding, 2);
807f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0, 2, ci, encoding));
808f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(0, dex_registers0.GetConstant(1, 2, ci, encoding));
809b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
810f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    InlineInfo if2 = ci.GetInlineInfoOf(sm3, encoding);
81161b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(3u, if2.GetDepth(encoding.inline_info_encoding));
81261b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(2u, if2.GetDexPcAtDepth(encoding.inline_info_encoding, 0));
81361b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(42u, if2.GetMethodIndexAtDepth(encoding.inline_info_encoding, 0));
81461b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(kVirtual, if2.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 0));
81561b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(5u, if2.GetDexPcAtDepth(encoding.inline_info_encoding, 1));
81661b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(52u, if2.GetMethodIndexAtDepth(encoding.inline_info_encoding, 1));
81761b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(kInterface, if2.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 1));
81861b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(10u, if2.GetDexPcAtDepth(encoding.inline_info_encoding, 2));
81961b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(52u, if2.GetMethodIndexAtDepth(encoding.inline_info_encoding, 2));
82061b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_EQ(kStatic, if2.GetInvokeTypeAtDepth(encoding.inline_info_encoding, 2));
82161b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky
82261b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    ASSERT_FALSE(if2.HasDexRegisterMapAtDepth(encoding.inline_info_encoding, 0));
823b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
824f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(1, if2, encoding, 1);
825f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(2, dex_registers1.GetMachineRegister(0, 1, ci, encoding));
826b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
827f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(2, if2, encoding, 2);
828b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    ASSERT_FALSE(dex_registers2.IsDexRegisterLive(0));
829f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    ASSERT_EQ(3, dex_registers2.GetMachineRegister(1, 2, ci, encoding));
830b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  }
831b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray}
832b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
83399ea58cc68b51837c065f4a2a54efbf208dd76faNicolas Geoffray}  // namespace art
834