stack_map.cc revision f677ebfd832c9c614fea5e6735725fec2f7a3f2a
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"
220396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain
23004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffraynamespace art {
24004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
25a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillainconstexpr size_t DexRegisterLocationCatalog::kNoLocationEntryIndex;
26004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffrayconstexpr uint32_t StackMap::kNoDexRegisterMap;
27004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffrayconstexpr uint32_t StackMap::kNoInlineInfo;
28004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
29a552e1c0584b8ab63150510286478c68cdbce13fRoland LevillainDexRegisterLocation::Kind DexRegisterMap::GetLocationInternalKind(uint16_t dex_register_number,
30a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                                                  uint16_t number_of_dex_registers,
31f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                                  const CodeInfo& code_info,
32f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                                  const StackMapEncoding& enc) const {
33a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterLocationCatalog dex_register_location_catalog =
34f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      code_info.GetDexRegisterLocationCatalog(enc);
35a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
36a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      dex_register_number,
37a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      number_of_dex_registers,
38a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      code_info.GetNumberOfDexRegisterLocationCatalogEntries());
39a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  return dex_register_location_catalog.GetLocationInternalKind(location_catalog_entry_index);
40a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain}
41a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
42a552e1c0584b8ab63150510286478c68cdbce13fRoland LevillainDexRegisterLocation DexRegisterMap::GetDexRegisterLocation(uint16_t dex_register_number,
43a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                                           uint16_t number_of_dex_registers,
44f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                           const CodeInfo& code_info,
45f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                           const StackMapEncoding& enc) const {
46a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterLocationCatalog dex_register_location_catalog =
47f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      code_info.GetDexRegisterLocationCatalog(enc);
48a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
49a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      dex_register_number,
50a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      number_of_dex_registers,
51a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      code_info.GetNumberOfDexRegisterLocationCatalogEntries());
52a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  return dex_register_location_catalog.GetDexRegisterLocation(location_catalog_entry_index);
53a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain}
54a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
55f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdiluint32_t StackMap::LoadAt(size_t number_of_bytes, size_t offset, bool check_max) const {
56896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  if (number_of_bytes == 0u) {
57896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    DCHECK(!check_max);
58896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    return 0;
59896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 1u) {
60f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    uint8_t value = region_.LoadUnaligned<uint8_t>(offset);
61f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    return (check_max && value == 0xFF) ? -1 : value;
62896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 2u) {
63f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    uint16_t value = region_.LoadUnaligned<uint16_t>(offset);
64f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    return (check_max && value == 0xFFFF) ? -1 : value;
65896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 3u) {
66f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    uint16_t low = region_.LoadUnaligned<uint16_t>(offset);
67f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    uint16_t high = region_.LoadUnaligned<uint8_t>(offset + sizeof(uint16_t));
68896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    uint32_t value = (high << 16) + low;
69f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    return (check_max && value == 0xFFFFFF) ? -1 : value;
70896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else {
71896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    DCHECK_EQ(number_of_bytes, 4u);
72f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    return region_.LoadUnaligned<uint32_t>(offset);
73896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  }
74896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray}
75896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray
76f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdilvoid StackMap::StoreAt(size_t number_of_bytes, size_t offset, uint32_t value) const {
77896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  if (number_of_bytes == 0u) {
78896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    DCHECK_EQ(value, 0u);
79896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 1u) {
80f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    region_.StoreUnaligned<uint8_t>(offset, value);
81896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 2u) {
82f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    region_.StoreUnaligned<uint16_t>(offset, value);
83896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else if (number_of_bytes == 3u) {
84f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    region_.StoreUnaligned<uint16_t>(offset, Low16Bits(value));
85f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    region_.StoreUnaligned<uint8_t>(offset + sizeof(uint16_t), High16Bits(value));
86896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  } else {
87f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    region_.StoreUnaligned<uint32_t>(offset, value);
88896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray    DCHECK_EQ(number_of_bytes, 4u);
89896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray  }
90896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray}
91896f8f7fe562f6e59119cb32531da9f0a5f13d18Nicolas Geoffray
92a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillainstatic void DumpRegisterMapping(std::ostream& os,
93a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                size_t dex_register_num,
94a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                DexRegisterLocation location,
95a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                const std::string& prefix = "v",
96a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                const std::string& suffix = "") {
970396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
980396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  std::ostream indented_os(&indent_filter);
990396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  indented_os << prefix << dex_register_num << ": "
1000396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain              << DexRegisterLocation::PrettyDescriptor(location.GetInternalKind())
1010396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain              << " (" << location.GetValue() << ")" << suffix << '\n';
1020396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain}
1030396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain
1040396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillainvoid CodeInfo::Dump(std::ostream& os,
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();
1110396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
1120396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  std::ostream indented_os(&indent_filter);
1130396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  indented_os << "Optimized CodeInfo (size=" << code_info_size
1140396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain              << ", number_of_dex_registers=" << number_of_dex_registers
1150396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain              << ", number_of_stack_maps=" << number_of_stack_maps
116f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << ", has_inline_info=" << encoding.HasInlineInfo()
117f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << ", number_of_bytes_for_inline_info=" << encoding.NumberOfBytesForInlineInfo()
118f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << ", number_of_bytes_for_dex_register_map="
119f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                  << encoding.NumberOfBytesForDexRegisterMap()
120f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << ", number_of_bytes_for_dex_pc=" << encoding.NumberOfBytesForDexPc()
121f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << ", number_of_bytes_for_native_pc=" << encoding.NumberOfBytesForNativePc()
122f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << ", number_of_bytes_for_register_mask=" << encoding.NumberOfBytesForRegisterMask()
1230396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain              << ")\n";
124a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // Display the Dex register location catalog.
125f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  GetDexRegisterLocationCatalog(encoding).Dump(indented_os, *this);
126a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // Display stack maps along with (live) Dex register maps.
1270396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  if (dump_stack_maps) {
1280396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain    for (size_t i = 0; i < number_of_stack_maps; ++i) {
129f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      StackMap stack_map = GetStackMapAt(i, encoding);
130f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      stack_map.Dump(indented_os,
131f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     *this,
132f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     encoding,
133f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     code_offset,
134f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     number_of_dex_registers,
135f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     " " + std::to_string(i));
136b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    }
137b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  }
138b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  // TODO: Dump the stack map's inline information? We need to know more from the caller:
139b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  //       we need to know the number of dex registers for each inlined method.
140b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray}
141b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
1420396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillainvoid DexRegisterLocationCatalog::Dump(std::ostream& os, const CodeInfo& code_info) {
143f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMapEncoding encoding = code_info.ExtractEncoding();
1440396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  size_t number_of_location_catalog_entries =
1450396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain      code_info.GetNumberOfDexRegisterLocationCatalogEntries();
146f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  size_t location_catalog_size_in_bytes = code_info.GetDexRegisterLocationCatalogSize(encoding);
1470396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
1480396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  std::ostream indented_os(&indent_filter);
1490396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  indented_os
1500396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain      << "DexRegisterLocationCatalog (number_of_entries=" << number_of_location_catalog_entries
1510396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain      << ", size_in_bytes=" << location_catalog_size_in_bytes << ")\n";
1520396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  for (size_t i = 0; i < number_of_location_catalog_entries; ++i) {
1530396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain    DexRegisterLocation location = GetDexRegisterLocation(i);
1540396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain    DumpRegisterMapping(indented_os, i, location, "entry ");
1550396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  }
1560396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain}
1570396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain
158b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffrayvoid DexRegisterMap::Dump(std::ostream& os,
159b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                          const CodeInfo& code_info,
160b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                          uint16_t number_of_dex_registers) const {
161f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  StackMapEncoding encoding = code_info.ExtractEncoding();
162b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  size_t number_of_location_catalog_entries =
163b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray      code_info.GetNumberOfDexRegisterLocationCatalogEntries();
1640396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
1650396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  std::ostream indented_os(&indent_filter);
166b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  // TODO: Display the bit mask of live Dex registers.
167b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  for (size_t j = 0; j < number_of_dex_registers; ++j) {
168b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    if (IsDexRegisterLive(j)) {
169b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray      size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
170b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray          j, number_of_dex_registers, number_of_location_catalog_entries);
171f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      DexRegisterLocation location = GetDexRegisterLocation(j,
172f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                            number_of_dex_registers,
173f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                            code_info,
174f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                            encoding);
175b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray      DumpRegisterMapping(
1760396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain          indented_os, j, location, "v",
177b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray          "\t[entry " + std::to_string(static_cast<int>(location_catalog_entry_index)) + "]");
178b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    }
179b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  }
180b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray}
181b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
182f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillainvoid StackMap::Dump(std::ostream& os,
183f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    const CodeInfo& code_info,
184f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                    const StackMapEncoding& encoding,
185f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    uint32_t code_offset,
186f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    uint16_t number_of_dex_registers,
187f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    const std::string& header_suffix) const {
188f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
189f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  std::ostream indented_os(&indent_filter);
190f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  indented_os << "StackMap" << header_suffix
191f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain              << std::hex
192f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << " [native_pc=0x" << code_offset + GetNativePcOffset(encoding) << "]"
193f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << " (dex_pc=0x" << GetDexPc(encoding)
194f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << ", native_pc_offset=0x" << GetNativePcOffset(encoding)
195f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << ", dex_register_map_offset=0x" << GetDexRegisterMapOffset(encoding)
196f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << ", inline_info_offset=0x" << GetInlineDescriptorOffset(encoding)
197f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil              << ", register_mask=0x" << GetRegisterMask(encoding)
198f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain              << std::dec
199f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain              << ", stack_mask=0b";
200f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  MemoryRegion stack_mask = GetStackMask(encoding);
201f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  for (size_t i = 0, e = stack_mask.size_in_bits(); i < e; ++i) {
202f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain    indented_os << stack_mask.LoadBit(e - i - 1);
203f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  }
204f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  indented_os << ")\n";
205f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  if (HasDexRegisterMap(encoding)) {
206f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(
207f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil        *this, encoding, number_of_dex_registers);
208f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain    dex_register_map.Dump(os, code_info, number_of_dex_registers);
209f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  }
210f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain}
211f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain
212b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffrayvoid InlineInfo::Dump(std::ostream& os,
213b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                      const CodeInfo& code_info,
214b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                      uint16_t number_of_dex_registers[]) const {
2150396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
2160396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  std::ostream indented_os(&indent_filter);
2170396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  indented_os << "InlineInfo with depth " << static_cast<uint32_t>(GetDepth()) << "\n";
218b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
219b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  for (size_t i = 0; i < GetDepth(); ++i) {
2200396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain    indented_os << " At depth " << i
2210396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain                << std::hex
2220396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain                << " (dex_pc=0x" << GetDexPcAtDepth(i)
2230396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain                << ", method_index=0x" << GetMethodIndexAtDepth(i)
2240396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain                << ")\n";
225b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    if (HasDexRegisterMapAtDepth(i)) {
226f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      StackMapEncoding encoding = code_info.ExtractEncoding();
227b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray      DexRegisterMap dex_register_map =
228f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil          code_info.GetDexRegisterMapAtDepth(i, *this, encoding, number_of_dex_registers[i]);
2290396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain      dex_register_map.Dump(indented_os, code_info, number_of_dex_registers[i]);
230004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray    }
231004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  }
232004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray}
233004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
234004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray}  // namespace art
235