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