Support InlineInfo in StackMap.
Change-Id: I9956091775cedc609fdae7dec1433fcb8858a477
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index 11e7e44..6a0c07d 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -257,21 +257,48 @@
DumpStackMapHeader(os, i);
if (stack_map.HasDexRegisterMap(*this)) {
DexRegisterMap dex_register_map = GetDexRegisterMapOf(stack_map, number_of_dex_registers);
- // TODO: Display the bit mask of live Dex registers.
- for (size_t j = 0; j < number_of_dex_registers; ++j) {
- if (dex_register_map.IsDexRegisterLive(j)) {
- size_t location_catalog_entry_index = dex_register_map.GetLocationCatalogEntryIndex(
- j, number_of_dex_registers, number_of_location_catalog_entries);
- DexRegisterLocation location =
- dex_register_map.GetDexRegisterLocation(j, number_of_dex_registers, *this);
- DumpRegisterMapping(
- os, j, location, "v",
- "\t[entry " + std::to_string(static_cast<int>(location_catalog_entry_index)) + "]");
- }
- }
+ dex_register_map.Dump(os, *this, number_of_dex_registers);
}
}
- // TODO: Dump the stack map's inline information.
+ // TODO: Dump the stack map's inline information? We need to know more from the caller:
+ // we need to know the number of dex registers for each inlined method.
+}
+
+void DexRegisterMap::Dump(std::ostream& os,
+ const CodeInfo& code_info,
+ uint16_t number_of_dex_registers) const {
+ size_t number_of_location_catalog_entries =
+ code_info.GetNumberOfDexRegisterLocationCatalogEntries();
+ // TODO: Display the bit mask of live Dex registers.
+ for (size_t j = 0; j < number_of_dex_registers; ++j) {
+ if (IsDexRegisterLive(j)) {
+ size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
+ j, number_of_dex_registers, number_of_location_catalog_entries);
+ DexRegisterLocation location = GetDexRegisterLocation(j, number_of_dex_registers, code_info);
+ DumpRegisterMapping(
+ os, j, location, "v",
+ "\t[entry " + std::to_string(static_cast<int>(location_catalog_entry_index)) + "]");
+ }
+ }
+}
+
+void InlineInfo::Dump(std::ostream& os,
+ const CodeInfo& code_info,
+ uint16_t number_of_dex_registers[]) const {
+ os << "InlineInfo with depth " << static_cast<uint32_t>(GetDepth()) << "\n";
+
+ for (size_t i = 0; i < GetDepth(); ++i) {
+ os << " At depth " << i
+ << std::hex
+ << " (dex_pc=0x" << GetDexPcAtDepth(i)
+ << ", method_index=0x" << GetMethodIndexAtDepth(i)
+ << ")\n";
+ if (HasDexRegisterMapAtDepth(i)) {
+ DexRegisterMap dex_register_map =
+ code_info.GetDexRegisterMapAtDepth(i, *this, number_of_dex_registers[i]);
+ dex_register_map.Dump(os, code_info, number_of_dex_registers[i]);
+ }
+ }
}
} // namespace art
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index f68cafe..16ae772 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -39,47 +39,6 @@
* their own fields.
*/
-/**
- * Inline information for a specific PC. The information is of the form:
- * [inlining_depth, [method_dex reference]+]
- */
-class InlineInfo {
- public:
- explicit InlineInfo(MemoryRegion region) : region_(region) {}
-
- uint8_t GetDepth() const {
- return region_.LoadUnaligned<uint8_t>(kDepthOffset);
- }
-
- void SetDepth(uint8_t depth) {
- region_.StoreUnaligned<uint8_t>(kDepthOffset, depth);
- }
-
- uint32_t GetMethodReferenceIndexAtDepth(uint8_t depth) const {
- return region_.LoadUnaligned<uint32_t>(kFixedSize + depth * SingleEntrySize());
- }
-
- void SetMethodReferenceIndexAtDepth(uint8_t depth, uint32_t index) {
- region_.StoreUnaligned<uint32_t>(kFixedSize + depth * SingleEntrySize(), index);
- }
-
- static size_t SingleEntrySize() {
- return sizeof(uint32_t);
- }
-
- private:
- // TODO: Instead of plain types such as "uint8_t", introduce
- // typedefs (and document the memory layout of InlineInfo).
- static constexpr int kDepthOffset = 0;
- static constexpr int kFixedSize = kDepthOffset + sizeof(uint8_t);
-
- MemoryRegion region_;
-
- friend class CodeInfo;
- friend class StackMap;
- friend class StackMapStream;
-};
-
// Dex register location container used by DexRegisterMap and StackMapStream.
class DexRegisterLocation {
public:
@@ -506,7 +465,8 @@
const CodeInfo& code_info) const {
DexRegisterLocation location =
GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info);
- DCHECK(location.GetKind() == DexRegisterLocation::Kind::kConstant);
+ DCHECK(location.GetKind() == DexRegisterLocation::Kind::kConstant)
+ << DexRegisterLocation::PrettyDescriptor(location.GetKind());
return location.GetValue();
}
@@ -641,6 +601,8 @@
return region_.size();
}
+ void Dump(std::ostream& o, const CodeInfo& code_info, uint16_t number_of_dex_registers) const;
+
private:
// Return the index in the Dex register map corresponding to the Dex
// register number `dex_register_number`.
@@ -675,9 +637,6 @@
* The information is of the form:
* [dex_pc, native_pc_offset, dex_register_map_offset, inlining_info_offset, register_mask,
* stack_mask].
- *
- * Note that register_mask is fixed size, but stack_mask is variable size, depending on the
- * stack size of a method.
*/
class StackMap {
public:
@@ -759,6 +718,72 @@
friend class StackMapStream;
};
+/**
+ * Inline information for a specific PC. The information is of the form:
+ * [inlining_depth, [dex_pc, method_index, dex_register_map_offset]+]
+ */
+class InlineInfo {
+ public:
+ explicit InlineInfo(MemoryRegion region) : region_(region) {}
+
+ uint8_t GetDepth() const {
+ return region_.LoadUnaligned<uint8_t>(kDepthOffset);
+ }
+
+ void SetDepth(uint8_t depth) {
+ region_.StoreUnaligned<uint8_t>(kDepthOffset, depth);
+ }
+
+ uint32_t GetMethodIndexAtDepth(uint8_t depth) const {
+ return region_.LoadUnaligned<uint32_t>(kFixedSize + depth * SingleEntrySize());
+ }
+
+ void SetMethodIndexAtDepth(uint8_t depth, uint32_t index) {
+ region_.StoreUnaligned<uint32_t>(kFixedSize + depth * SingleEntrySize(), index);
+ }
+
+ uint32_t GetDexPcAtDepth(uint8_t depth) const {
+ return region_.LoadUnaligned<uint32_t>(
+ kFixedSize + depth * SingleEntrySize() + sizeof(uint32_t));
+ }
+
+ void SetDexPcAtDepth(uint8_t depth, uint32_t dex_pc) {
+ region_.StoreUnaligned<uint32_t>(
+ kFixedSize + depth * SingleEntrySize() + sizeof(uint32_t), dex_pc);
+ }
+
+ uint32_t GetDexRegisterMapOffsetAtDepth(uint8_t depth) const {
+ return region_.LoadUnaligned<uint32_t>(
+ kFixedSize + depth * SingleEntrySize() + sizeof(uint32_t) + sizeof(uint32_t));
+ }
+
+ void SetDexRegisterMapOffsetAtDepth(uint8_t depth, uint32_t offset) {
+ region_.StoreUnaligned<uint32_t>(
+ kFixedSize + depth * SingleEntrySize() + sizeof(uint32_t) + sizeof(uint32_t), offset);
+ }
+
+ bool HasDexRegisterMapAtDepth(uint8_t depth) const {
+ return GetDexRegisterMapOffsetAtDepth(depth) != StackMap::kNoDexRegisterMap;
+ }
+
+ static size_t SingleEntrySize() {
+ return sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t);
+ }
+
+ void Dump(std::ostream& os, const CodeInfo& info, uint16_t* number_of_dex_registers) const;
+
+ private:
+ // TODO: Instead of plain types such as "uint8_t", introduce
+ // typedefs (and document the memory layout of InlineInfo).
+ static constexpr int kDepthOffset = 0;
+ static constexpr int kFixedSize = kDepthOffset + sizeof(uint8_t);
+
+ MemoryRegion region_;
+
+ friend class CodeInfo;
+ friend class StackMap;
+ friend class StackMapStream;
+};
/**
* Wrapper around all compiler information collected for a method.
@@ -960,6 +985,17 @@
return DexRegisterMap(region_.Subregion(offset, size));
}
+ // Return the `DexRegisterMap` pointed by `inline_info` at depth `depth`.
+ DexRegisterMap GetDexRegisterMapAtDepth(uint8_t depth,
+ InlineInfo inline_info,
+ uint32_t number_of_dex_registers) const {
+ DCHECK(inline_info.HasDexRegisterMapAtDepth(depth));
+ uint32_t offset =
+ GetDexRegisterMapsOffset() + inline_info.GetDexRegisterMapOffsetAtDepth(depth);
+ size_t size = ComputeDexRegisterMapSizeOf(offset, number_of_dex_registers);
+ return DexRegisterMap(region_.Subregion(offset, size));
+ }
+
InlineInfo GetInlineInfoOf(StackMap stack_map) const {
DCHECK(stack_map.HasInlineInfo(*this));
uint32_t offset = stack_map.GetInlineDescriptorOffset(*this) + GetDexRegisterMapsOffset();