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
307dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbeckystd::ostream& operator<<(std::ostream& stream, const DexRegisterLocation::Kind& kind) {
317dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky  using Kind = DexRegisterLocation::Kind;
327dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky  switch (kind) {
337dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky    case Kind::kNone:
347dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky      return stream << "none";
357dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky    case Kind::kInStack:
367dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky      return stream << "in stack";
377dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky    case Kind::kInRegister:
387dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky      return stream << "in register";
397dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky    case Kind::kInRegisterHigh:
407dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky      return stream << "in register high";
417dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky    case Kind::kInFpuRegister:
427dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky      return stream << "in fpu register";
437dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky    case Kind::kInFpuRegisterHigh:
447dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky      return stream << "in fpu register high";
457dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky    case Kind::kConstant:
467dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky      return stream << "as constant";
477dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky    case Kind::kInStackLargeOffset:
487dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky      return stream << "in stack (large offset)";
497dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky    case Kind::kConstantLargeValue:
507dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky      return stream << "as constant (large value)";
517dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky  }
527dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky  return stream << "Kind<" << static_cast<uint32_t>(kind) << ">";
537dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky}
547dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky
551c1da4398cca9a828dea885ca1be12adf961d3a3Roland LevillainDexRegisterLocation::Kind DexRegisterMap::GetLocationInternalKind(
561c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain    uint16_t dex_register_number,
571c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain    uint16_t number_of_dex_registers,
581c1da4398cca9a828dea885ca1be12adf961d3a3Roland Levillain    const CodeInfo& code_info,
5909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    const CodeInfoEncoding& enc) const {
60a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterLocationCatalog dex_register_location_catalog =
61f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      code_info.GetDexRegisterLocationCatalog(enc);
62a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
63a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      dex_register_number,
64a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      number_of_dex_registers,
6509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      code_info.GetNumberOfLocationCatalogEntries(enc));
66a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  return dex_register_location_catalog.GetLocationInternalKind(location_catalog_entry_index);
67a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain}
68a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
69a552e1c0584b8ab63150510286478c68cdbce13fRoland LevillainDexRegisterLocation DexRegisterMap::GetDexRegisterLocation(uint16_t dex_register_number,
70a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                                           uint16_t number_of_dex_registers,
71f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                           const CodeInfo& code_info,
7209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky                                                           const CodeInfoEncoding& enc) const {
73a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  DexRegisterLocationCatalog dex_register_location_catalog =
74f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      code_info.GetDexRegisterLocationCatalog(enc);
75a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
76a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      dex_register_number,
77a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain      number_of_dex_registers,
7809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      code_info.GetNumberOfLocationCatalogEntries(enc));
79a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  return dex_register_location_catalog.GetDexRegisterLocation(location_catalog_entry_index);
80a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain}
81a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain
82a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillainstatic void DumpRegisterMapping(std::ostream& os,
83a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                size_t dex_register_num,
84a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                DexRegisterLocation location,
85a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                const std::string& prefix = "v",
86a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain                                const std::string& suffix = "") {
878f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  os << prefix << dex_register_num << ": "
887dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky     << location.GetInternalKind()
898f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko     << " (" << location.GetValue() << ")" << suffix << '\n';
900396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain}
910396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain
9209ed09866da6d8c7448ef297c148bfa577a247c2David Srbeckyvoid StackMapEncoding::Dump(VariableIndentationOutputStream* vios) const {
9309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  vios->Stream()
9409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << "StackMapEncoding"
9509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << " (native_pc_bit_offset=" << static_cast<uint32_t>(kNativePcBitOffset)
9609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << ", dex_pc_bit_offset=" << static_cast<uint32_t>(dex_pc_bit_offset_)
9709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << ", dex_register_map_bit_offset=" << static_cast<uint32_t>(dex_register_map_bit_offset_)
9809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << ", inline_info_bit_offset=" << static_cast<uint32_t>(inline_info_bit_offset_)
9909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << ", register_mask_bit_offset=" << static_cast<uint32_t>(register_mask_bit_offset_)
10009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << ", stack_mask_bit_offset=" << static_cast<uint32_t>(stack_mask_bit_offset_)
10109ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << ")\n";
10209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky}
10309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky
10461b28a17d9b6e8e998103646e98e4a9772e11927David Srbeckyvoid InlineInfoEncoding::Dump(VariableIndentationOutputStream* vios) const {
10561b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky  vios->Stream()
10661b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky      << "InlineInfoEncoding"
10761b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky      << " (method_index_bit_offset=" << static_cast<uint32_t>(kMethodIndexBitOffset)
10861b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky      << ", dex_pc_bit_offset=" << static_cast<uint32_t>(dex_pc_bit_offset_)
10961b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky      << ", invoke_type_bit_offset=" << static_cast<uint32_t>(invoke_type_bit_offset_)
11061b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky      << ", dex_register_map_bit_offset=" << static_cast<uint32_t>(dex_register_map_bit_offset_)
11161b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky      << ", total_bit_size=" << static_cast<uint32_t>(total_bit_size_)
11261b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky      << ")\n";
11361b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky}
11461b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky
1158f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Markovoid CodeInfo::Dump(VariableIndentationOutputStream* vios,
116f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    uint32_t code_offset,
1170396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain                    uint16_t number_of_dex_registers,
1180396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain                    bool dump_stack_maps) const {
11909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  CodeInfoEncoding encoding = ExtractEncoding();
12009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  size_t number_of_stack_maps = GetNumberOfStackMaps(encoding);
1218f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  vios->Stream()
12209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << "Optimized CodeInfo (number_of_dex_registers=" << number_of_dex_registers
1238f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", number_of_stack_maps=" << number_of_stack_maps
1248f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ")\n";
1258f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  ScopedIndentation indent1(vios);
12609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  encoding.stack_map_encoding.Dump(vios);
12761b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky  if (HasInlineInfo(encoding)) {
12861b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    encoding.inline_info_encoding.Dump(vios);
12961b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky  }
130a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // Display the Dex register location catalog.
1318f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  GetDexRegisterLocationCatalog(encoding).Dump(vios, *this);
132a552e1c0584b8ab63150510286478c68cdbce13fRoland Levillain  // Display stack maps along with (live) Dex register maps.
1330396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  if (dump_stack_maps) {
1340396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain    for (size_t i = 0; i < number_of_stack_maps; ++i) {
135f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      StackMap stack_map = GetStackMapAt(i, encoding);
1368f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      stack_map.Dump(vios,
137f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     *this,
138f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     encoding,
139f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     code_offset,
140f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     number_of_dex_registers,
141f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                     " " + std::to_string(i));
142b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    }
143b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  }
144b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  // TODO: Dump the stack map's inline information? We need to know more from the caller:
145b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  //       we need to know the number of dex registers for each inlined method.
146b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray}
147b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
1488f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Markovoid DexRegisterLocationCatalog::Dump(VariableIndentationOutputStream* vios,
1498f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko                                      const CodeInfo& code_info) {
15009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  CodeInfoEncoding encoding = code_info.ExtractEncoding();
15109ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  size_t number_of_location_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
152f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil  size_t location_catalog_size_in_bytes = code_info.GetDexRegisterLocationCatalogSize(encoding);
1538f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  vios->Stream()
1540396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain      << "DexRegisterLocationCatalog (number_of_entries=" << number_of_location_catalog_entries
1550396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain      << ", size_in_bytes=" << location_catalog_size_in_bytes << ")\n";
1560396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  for (size_t i = 0; i < number_of_location_catalog_entries; ++i) {
1570396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain    DexRegisterLocation location = GetDexRegisterLocation(i);
1588f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    ScopedIndentation indent1(vios);
1598f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    DumpRegisterMapping(vios->Stream(), i, location, "entry ");
1600396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain  }
1610396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain}
1620396ed7d3ad30778cb4af19e7086bea0deace9b9Roland Levillain
1638f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Markovoid DexRegisterMap::Dump(VariableIndentationOutputStream* vios,
164b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                          const CodeInfo& code_info,
165b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                          uint16_t number_of_dex_registers) const {
16609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  CodeInfoEncoding encoding = code_info.ExtractEncoding();
16709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  size_t number_of_location_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
168b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  // TODO: Display the bit mask of live Dex registers.
169b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  for (size_t j = 0; j < number_of_dex_registers; ++j) {
170b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    if (IsDexRegisterLive(j)) {
171b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray      size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
172b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray          j, number_of_dex_registers, number_of_location_catalog_entries);
173f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil      DexRegisterLocation location = GetDexRegisterLocation(j,
174f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                            number_of_dex_registers,
175f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                            code_info,
176f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil                                                            encoding);
1778f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      ScopedIndentation indent1(vios);
178b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray      DumpRegisterMapping(
1798f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko          vios->Stream(), j, location, "v",
180b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray          "\t[entry " + std::to_string(static_cast<int>(location_catalog_entry_index)) + "]");
181b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray    }
182b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray  }
183b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray}
184b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
1858f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Markovoid StackMap::Dump(VariableIndentationOutputStream* vios,
186f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    const CodeInfo& code_info,
18709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky                    const CodeInfoEncoding& encoding,
188f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    uint32_t code_offset,
189f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    uint16_t number_of_dex_registers,
190f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain                    const std::string& header_suffix) const {
19109ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  StackMapEncoding stack_map_encoding = encoding.stack_map_encoding;
1928f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  vios->Stream()
1938f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << "StackMap" << header_suffix
1948f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << std::hex
19509ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << " [native_pc=0x" << code_offset + GetNativePcOffset(stack_map_encoding) << "]"
19609ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << " (dex_pc=0x" << GetDexPc(stack_map_encoding)
19709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << ", native_pc_offset=0x" << GetNativePcOffset(stack_map_encoding)
19809ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << ", dex_register_map_offset=0x" << GetDexRegisterMapOffset(stack_map_encoding)
19909ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << ", inline_info_offset=0x" << GetInlineDescriptorOffset(stack_map_encoding)
20009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      << ", register_mask=0x" << GetRegisterMask(stack_map_encoding)
2018f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << std::dec
2028f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      << ", stack_mask=0b";
20309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  for (size_t i = 0, e = GetNumberOfStackMaskBits(stack_map_encoding); i < e; ++i) {
20409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky    vios->Stream() << GetStackMaskBit(stack_map_encoding, e - i - 1);
205f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  }
2068f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko  vios->Stream() << ")\n";
20709ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  if (HasDexRegisterMap(stack_map_encoding)) {
208f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil    DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(
209f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil        *this, encoding, number_of_dex_registers);
2108f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    dex_register_map.Dump(vios, code_info, number_of_dex_registers);
211f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain  }
21209ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky  if (HasInlineInfo(stack_map_encoding)) {
21312bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray    InlineInfo inline_info = code_info.GetInlineInfoOf(*this, encoding);
21412bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray    // We do not know the length of the dex register maps of inlined frames
21512bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray    // at this level, so we just pass null to `InlineInfo::Dump` to tell
21612bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray    // it not to look at these maps.
2178f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    inline_info.Dump(vios, code_info, nullptr);
21812bdb72221f344ba0d86f338cc0feb49799c37f0Nicolas Geoffray  }
219f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain}
220f2650d1f957b158496de8016bc43fb575e81d6bcRoland Levillain
2218f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Markovoid InlineInfo::Dump(VariableIndentationOutputStream* vios,
222b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                      const CodeInfo& code_info,
223b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray                      uint16_t number_of_dex_registers[]) const {
22461b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky  InlineInfoEncoding inline_info_encoding = code_info.ExtractEncoding().inline_info_encoding;
22561b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky  vios->Stream() << "InlineInfo with depth "
22661b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky                 << static_cast<uint32_t>(GetDepth(inline_info_encoding))
22761b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky                 << "\n";
228b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray
22961b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky  for (size_t i = 0; i < GetDepth(inline_info_encoding); ++i) {
2308f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko    vios->Stream()
2318f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << " At depth " << i
2328f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << std::hex
23361b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky        << " (dex_pc=0x" << GetDexPcAtDepth(inline_info_encoding, i)
2348f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << std::dec
23561b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky        << ", method_index=" << GetMethodIndexAtDepth(inline_info_encoding, i)
23661b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky        << ", invoke_type=" << static_cast<InvokeType>(GetInvokeTypeAtDepth(inline_info_encoding,
23761b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky                                                                            i))
2388f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko        << ")\n";
23961b28a17d9b6e8e998103646e98e4a9772e11927David Srbecky    if (HasDexRegisterMapAtDepth(inline_info_encoding, i) && (number_of_dex_registers != nullptr)) {
24009ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky      CodeInfoEncoding encoding = code_info.ExtractEncoding();
241b1d0f3f7e92fdcc92fe2d4c48cbb1262c005583fNicolas Geoffray      DexRegisterMap dex_register_map =
242f677ebfd832c9c614fea5e6735725fec2f7a3f2aDavid Brazdil          code_info.GetDexRegisterMapAtDepth(i, *this, encoding, number_of_dex_registers[i]);
2438f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      ScopedIndentation indent1(vios);
2448f1e08af6172781f91a17fce0a5a4183a9f70aa9Vladimir Marko      dex_register_map.Dump(vios, code_info, number_of_dex_registers[i]);
245004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray    }
246004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray  }
247004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray}
248004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray
249004c230b4cfc856690c61faabc41864061813c88Nicolas Geoffray}  // namespace art
250