stack_map.cc revision 1c1da4398cca9a828dea885ca1be12adf961d3a3
1004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray/*
2004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray * Copyright (C) 2015 The Android Open Source Project
3004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray *
4004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
5004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray * you may not use this file except in compliance with the License.
6004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray * You may obtain a copy of the License at
7004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray *
8004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
9004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray *
10004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software
11004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
12004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray * See the License for the specific language governing permissions and
14004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray * limitations under the License.
15004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray */
16004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
17004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray#include "stack_map.h"
18004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
19896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray#include <stdint.h>
20896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray
210396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain#include "indenter.h"
2212bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray#include "invoke_type.h"
230396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain
24004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffraynamespace art {
25004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
26a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillainconstexpr size_t DexRegisterLocationCatalog::kNoLocationEntryIndex;
27004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffrayconstexpr uint32_t StackMap::kNoDexRegisterMap;
28004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffrayconstexpr uint32_t StackMap::kNoInlineInfo;
29004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
301c1da4398cca9a828dea885ca1be12adf961d3a3Roland LevillainDexRegisterLocation::Kind DexRegisterMap::GetLocationInternalKind(
311c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain    uint16_t dex_register_number,
321c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain    uint16_t number_of_dex_registers,
331c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain    const CodeInfo& code_info,
341c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain    const StackMapEncoding& enc) const {
35a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterLocationCatalog dex_register_location_catalog =
36f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      code_info.GetDexRegisterLocationCatalog(enc);
37a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
38a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      dex_register_number,
39a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      number_of_dex_registers,
401c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain      code_info.GetNumberOfLocationCatalogEntries());
41a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  return dex_register_location_catalog.GetLocationInternalKind(location_catalog_entry_index);
42a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain}
43a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
44a552e1c0584b8ab63150510286478c68cdbce13fRoland LevillainDexRegisterLocation DexRegisterMap::GetDexRegisterLocation(uint16_t dex_register_number,
45a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                                           uint16_t number_of_dex_registers,
46f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                           const CodeInfo& code_info,
47f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                           const StackMapEncoding& enc) const {
48a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterLocationCatalog dex_register_location_catalog =
49f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      code_info.GetDexRegisterLocationCatalog(enc);
50a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
51a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      dex_register_number,
52a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      number_of_dex_registers,
531c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain      code_info.GetNumberOfLocationCatalogEntries());
54a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  return dex_register_location_catalog.GetDexRegisterLocation(location_catalog_entry_index);
55a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain}
56a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
57f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdiluint32_t StackMap::LoadAt(size_t number_of_bytes, size_t offset, bool check_max) const {
58896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  if (number_of_bytes == 0u) {
59896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    DCHECK(!check_max);
60896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    return 0;
61896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 1u) {
62f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    uint8_t value = region_.LoadUnaligned<uint8_t>(offset);
63f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    return (check_max && value == 0xFF) ? -1 : value;
64896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 2u) {
65f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    uint16_t value = region_.LoadUnaligned<uint16_t>(offset);
66f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    return (check_max && value == 0xFFFF) ? -1 : value;
67896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 3u) {
68f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    uint16_t low = region_.LoadUnaligned<uint16_t>(offset);
69f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    uint16_t high = region_.LoadUnaligned<uint8_t>(offset + sizeof(uint16_t));
70896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    uint32_t value = (high << 16) + low;
71f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    return (check_max && value == 0xFFFFFF) ? -1 : value;
72896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else {
73896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    DCHECK_EQ(number_of_bytes, 4u);
74f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    return region_.LoadUnaligned<uint32_t>(offset);
75896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  }
76896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray}
77896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray
78f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdilvoid StackMap::StoreAt(size_t number_of_bytes, size_t offset, uint32_t value) const {
79896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  if (number_of_bytes == 0u) {
80896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    DCHECK_EQ(value, 0u);
81896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 1u) {
82f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    region_.StoreUnaligned<uint8_t>(offset, value);
83896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 2u) {
84f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    region_.StoreUnaligned<uint16_t>(offset, value);
85896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 3u) {
86f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    region_.StoreUnaligned<uint16_t>(offset, Low16Bits(value));
87f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    region_.StoreUnaligned<uint8_t>(offset + sizeof(uint16_t), High16Bits(value));
88896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else {
89f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    region_.StoreUnaligned<uint32_t>(offset, value);
90896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    DCHECK_EQ(number_of_bytes, 4u);
91896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  }
92896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray}
93896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray
94a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillainstatic void DumpRegisterMapping(std::ostream& os,
95a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                size_t dex_register_num,
96a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                DexRegisterLocation location,
97a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                const std::string& prefix = "v",
98a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                const std::string& suffix = "") {
998f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  os << prefix << dex_register_num << ": "
1008f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko     << DexRegisterLocation::PrettyDescriptor(location.GetInternalKind())
1018f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko     << " (" << location.GetValue() << ")" << suffix << '\n';
1020396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain}
1030396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain
1048f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Markovoid CodeInfo::Dump(VariableIndentationOutputStream* vios,
105f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    uint32_t code_offset,
1060396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain                    uint16_t number_of_dex_registers,
1070396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain                    bool dump_stack_maps) const {
108f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMapEncoding encoding = ExtractEncoding();
109004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  uint32_t code_info_size = GetOverallSize();
110004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  size_t number_of_stack_maps = GetNumberOfStackMaps();
1118f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  vios->Stream()
1128f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << "Optimized CodeInfo (size=" << code_info_size
1138f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", number_of_dex_registers=" << number_of_dex_registers
1148f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", number_of_stack_maps=" << number_of_stack_maps
1158f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", has_inline_info=" << encoding.HasInlineInfo()
1168f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", number_of_bytes_for_inline_info=" << encoding.NumberOfBytesForInlineInfo()
1178f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", number_of_bytes_for_dex_register_map=" << encoding.NumberOfBytesForDexRegisterMap()
1188f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", number_of_bytes_for_dex_pc=" << encoding.NumberOfBytesForDexPc()
1198f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", number_of_bytes_for_native_pc=" << encoding.NumberOfBytesForNativePc()
1208f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", number_of_bytes_for_register_mask=" << encoding.NumberOfBytesForRegisterMask()
1218f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ")\n";
1228f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  ScopedIndentation indent1(vios);
123a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // Display the Dex register location catalog.
1248f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  GetDexRegisterLocationCatalog(encoding).Dump(vios, *this);
125a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // Display stack maps along with (live) Dex register maps.
1260396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  if (dump_stack_maps) {
1270396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain    for (size_t i = 0; i < number_of_stack_maps; ++i) {
128f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      StackMap stack_map = GetStackMapAt(i, encoding);
1298f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      stack_map.Dump(vios,
130f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     *this,
131f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     encoding,
132f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     code_offset,
133f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     number_of_dex_registers,
134f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     " " + std::to_string(i));
135b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    }
136b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  }
137b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  // TODO: Dump the stack map's inline information? We need to know more from the caller:
138b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  //       we need to know the number of dex registers for each inlined method.
139b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray}
140b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
1418f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Markovoid DexRegisterLocationCatalog::Dump(VariableIndentationOutputStream* vios,
1428f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko                                      const CodeInfo& code_info) {
143f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMapEncoding encoding = code_info.ExtractEncoding();
1441c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain  size_t number_of_location_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
145f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  size_t location_catalog_size_in_bytes = code_info.GetDexRegisterLocationCatalogSize(encoding);
1468f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  vios->Stream()
1470396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain      << "DexRegisterLocationCatalog (number_of_entries=" << number_of_location_catalog_entries
1480396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain      << ", size_in_bytes=" << location_catalog_size_in_bytes << ")\n";
1490396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  for (size_t i = 0; i < number_of_location_catalog_entries; ++i) {
1500396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain    DexRegisterLocation location = GetDexRegisterLocation(i);
1518f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    ScopedIndentation indent1(vios);
1528f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    DumpRegisterMapping(vios->Stream(), i, location, "entry ");
1530396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  }
1540396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain}
1550396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain
1568f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Markovoid DexRegisterMap::Dump(VariableIndentationOutputStream* vios,
157b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                          const CodeInfo& code_info,
158b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                          uint16_t number_of_dex_registers) const {
159f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMapEncoding encoding = code_info.ExtractEncoding();
1601c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain  size_t number_of_location_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
161b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  // TODO: Display the bit mask of live Dex registers.
162b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  for (size_t j = 0; j < number_of_dex_registers; ++j) {
163b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    if (IsDexRegisterLive(j)) {
164b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray      size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
165b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray          j, number_of_dex_registers, number_of_location_catalog_entries);
166f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      DexRegisterLocation location = GetDexRegisterLocation(j,
167f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                            number_of_dex_registers,
168f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                            code_info,
169f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                            encoding);
1708f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      ScopedIndentation indent1(vios);
171b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray      DumpRegisterMapping(
1728f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko          vios->Stream(), j, location, "v",
173b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray          "\t[entry " + std::to_string(static_cast<int>(location_catalog_entry_index)) + "]");
174b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    }
175b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  }
176b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray}
177b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
1788f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Markovoid StackMap::Dump(VariableIndentationOutputStream* vios,
179f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    const CodeInfo& code_info,
180f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                    const StackMapEncoding& encoding,
181f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    uint32_t code_offset,
182f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    uint16_t number_of_dex_registers,
183f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    const std::string& header_suffix) const {
1848f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  vios->Stream()
1858f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << "StackMap" << header_suffix
1868f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << std::hex
1878f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << " [native_pc=0x" << code_offset + GetNativePcOffset(encoding) << "]"
1888f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << " (dex_pc=0x" << GetDexPc(encoding)
1898f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", native_pc_offset=0x" << GetNativePcOffset(encoding)
1908f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", dex_register_map_offset=0x" << GetDexRegisterMapOffset(encoding)
1918f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", inline_info_offset=0x" << GetInlineDescriptorOffset(encoding)
1928f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", register_mask=0x" << GetRegisterMask(encoding)
1938f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << std::dec
1948f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", stack_mask=0b";
195f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  MemoryRegion stack_mask = GetStackMask(encoding);
196f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  for (size_t i = 0, e = stack_mask.size_in_bits(); i < e; ++i) {
1978f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    vios->Stream() << stack_mask.LoadBit(e - i - 1);
198f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  }
1998f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  vios->Stream() << ")\n";
200f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  if (HasDexRegisterMap(encoding)) {
201f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(
202f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil        *this, encoding, number_of_dex_registers);
2038f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    dex_register_map.Dump(vios, code_info, number_of_dex_registers);
204f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  }
20512bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray  if (HasInlineInfo(encoding)) {
20612bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray    InlineInfo inline_info = code_info.GetInlineInfoOf(*this, encoding);
20712bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray    // We do not know the length of the dex register maps of inlined frames
20812bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray    // at this level, so we just pass null to `InlineInfo::Dump` to tell
20912bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray    // it not to look at these maps.
2108f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    inline_info.Dump(vios, code_info, nullptr);
21112bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray  }
212f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain}
213f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain
2148f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Markovoid InlineInfo::Dump(VariableIndentationOutputStream* vios,
215b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                      const CodeInfo& code_info,
216b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                      uint16_t number_of_dex_registers[]) const {
2178f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  vios->Stream() << "InlineInfo with depth " << static_cast<uint32_t>(GetDepth()) << "\n";
218b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
219b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  for (size_t i = 0; i < GetDepth(); ++i) {
2208f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    vios->Stream()
2218f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << " At depth " << i
2228f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << std::hex
2238f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << " (dex_pc=0x" << GetDexPcAtDepth(i)
2248f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << std::dec
2258f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << ", method_index=" << GetMethodIndexAtDepth(i)
2268f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << ", invoke_type=" << static_cast<InvokeType>(GetInvokeTypeAtDepth(i))
2278f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << ")\n";
22812bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray    if (HasDexRegisterMapAtDepth(i) && (number_of_dex_registers != nullptr)) {
229f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      StackMapEncoding encoding = code_info.ExtractEncoding();
230b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray      DexRegisterMap dex_register_map =
231f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil          code_info.GetDexRegisterMapAtDepth(i, *this, encoding, number_of_dex_registers[i]);
2328f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      ScopedIndentation indent1(vios);
2338f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      dex_register_map.Dump(vios, code_info, number_of_dex_registers[i]);
234004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray    }
235004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  }
236004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray}
237004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
238004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray}  // namespace art
239