Use bit-level packing for InlineInfo in stackmaps as well.
Use the same approach as we do for stackmaps to reduce the size.
It saves 4.0 MB from non-debuggable boot.oat (AOSP).
It does not affect debuggable boot.oat.
It saves 3.6 MB (of 96.6 MB) from /system/framework/arm/ (GOOG).
It saves 0.6 MB (of 26.7 MB) from /system/framework/oat/arm/ (GOOG).
Field loads from inline-info get around 5% slower.
(based on the time it takes to load all inline-infos from boot.oat)
Change-Id: I67b0fa5eef74c1fdb013680d0231fd44ea696176
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 116261b..16fbfaa 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -42,11 +42,12 @@
template <bool kResolve = true>
inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method,
const InlineInfo& inline_info,
+ const InlineInfoEncoding& encoding,
uint8_t inlining_depth)
SHARED_REQUIRES(Locks::mutator_lock_) {
- uint32_t method_index = inline_info.GetMethodIndexAtDepth(inlining_depth);
+ uint32_t method_index = inline_info.GetMethodIndexAtDepth(encoding, inlining_depth);
InvokeType invoke_type = static_cast<InvokeType>(
- inline_info.GetInvokeTypeAtDepth(inlining_depth));
+ inline_info.GetInvokeTypeAtDepth(encoding, inlining_depth));
ArtMethod* caller = outer_method->GetDexCacheResolvedMethod(method_index, sizeof(void*));
if (!caller->IsRuntimeMethod()) {
return caller;
@@ -68,7 +69,10 @@
if (inlining_depth == 0) {
class_loader.Assign(outer_method->GetClassLoader());
} else {
- caller = GetResolvedMethod<kResolve>(outer_method, inline_info, inlining_depth - 1);
+ caller = GetResolvedMethod<kResolve>(outer_method,
+ inline_info,
+ encoding,
+ inlining_depth - 1);
class_loader.Assign(caller->GetClassLoader());
}
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index 3368411..e46576e 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -280,7 +280,10 @@
DCHECK(stack_map.IsValid());
if (stack_map.HasInlineInfo(encoding.stack_map_encoding)) {
InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
- caller = GetResolvedMethod(outer_method, inline_info, inline_info.GetDepth() - 1);
+ caller = GetResolvedMethod(outer_method,
+ inline_info,
+ encoding.inline_info_encoding,
+ inline_info.GetDepth(encoding.inline_info_encoding) - 1);
}
}
}
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 27926e0..aba1694 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -332,7 +332,8 @@
DCHECK(stack_map.IsValid());
if (stack_map.HasInlineInfo(encoding.stack_map_encoding)) {
InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
- return inline_info.GetDexPcAtDepth(inline_info.GetDepth() - 1);
+ return inline_info.GetDexPcAtDepth(encoding.inline_info_encoding,
+ inline_info.GetDepth(encoding.inline_info_encoding)-1);
} else {
return stack_map.GetDexPc(encoding.stack_map_encoding);
}
diff --git a/runtime/oat.h b/runtime/oat.h
index 68e71c4..469a65f 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,7 +32,7 @@
class PACKED(4) OatHeader {
public:
static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
- static constexpr uint8_t kOatVersion[] = { '0', '7', '7', '\0' };
+ static constexpr uint8_t kOatVersion[] = { '0', '7', '8', '\0' };
static constexpr const char* kImageLocationKey = "image-location";
static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 2336365..c22eb92 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -130,11 +130,19 @@
if (IsInInlinedFrame()) {
size_t depth_in_stack_map = current_inlining_depth_ - 1;
InlineInfo inline_info = GetCurrentInlineInfo();
+ const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
+ CodeInfoEncoding encoding = method_header->GetOptimizedCodeInfo().ExtractEncoding();
DCHECK(walk_kind_ != StackWalkKind::kSkipInlinedFrames);
bool allow_resolve = walk_kind_ != StackWalkKind::kIncludeInlinedFramesNoResolve;
return allow_resolve
- ? GetResolvedMethod<true>(*GetCurrentQuickFrame(), inline_info, depth_in_stack_map)
- : GetResolvedMethod<false>(*GetCurrentQuickFrame(), inline_info, depth_in_stack_map);
+ ? GetResolvedMethod<true>(*GetCurrentQuickFrame(),
+ inline_info,
+ encoding.inline_info_encoding,
+ depth_in_stack_map)
+ : GetResolvedMethod<false>(*GetCurrentQuickFrame(),
+ inline_info,
+ encoding.inline_info_encoding,
+ depth_in_stack_map);
} else {
return *cur_quick_frame_;
}
@@ -148,7 +156,10 @@
} else if (cur_quick_frame_ != nullptr) {
if (IsInInlinedFrame()) {
size_t depth_in_stack_map = current_inlining_depth_ - 1;
- return GetCurrentInlineInfo().GetDexPcAtDepth(depth_in_stack_map);
+ const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
+ CodeInfoEncoding encoding = method_header->GetOptimizedCodeInfo().ExtractEncoding();
+ return GetCurrentInlineInfo().GetDexPcAtDepth(encoding.inline_info_encoding,
+ depth_in_stack_map);
} else if (cur_oat_quick_method_header_ == nullptr) {
return DexFile::kDexNoIndex;
} else {
@@ -875,7 +886,7 @@
if (stack_map.IsValid() && stack_map.HasInlineInfo(encoding.stack_map_encoding)) {
InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
DCHECK_EQ(current_inlining_depth_, 0u);
- for (current_inlining_depth_ = inline_info.GetDepth();
+ for (current_inlining_depth_ = inline_info.GetDepth(encoding.inline_info_encoding);
current_inlining_depth_ != 0;
--current_inlining_depth_) {
bool should_continue = VisitFrame();
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index b51baf1..a7e7c21 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -101,6 +101,17 @@
<< ")\n";
}
+void InlineInfoEncoding::Dump(VariableIndentationOutputStream* vios) const {
+ vios->Stream()
+ << "InlineInfoEncoding"
+ << " (method_index_bit_offset=" << static_cast<uint32_t>(kMethodIndexBitOffset)
+ << ", dex_pc_bit_offset=" << static_cast<uint32_t>(dex_pc_bit_offset_)
+ << ", invoke_type_bit_offset=" << static_cast<uint32_t>(invoke_type_bit_offset_)
+ << ", dex_register_map_bit_offset=" << static_cast<uint32_t>(dex_register_map_bit_offset_)
+ << ", total_bit_size=" << static_cast<uint32_t>(total_bit_size_)
+ << ")\n";
+}
+
void CodeInfo::Dump(VariableIndentationOutputStream* vios,
uint32_t code_offset,
uint16_t number_of_dex_registers,
@@ -113,6 +124,9 @@
<< ")\n";
ScopedIndentation indent1(vios);
encoding.stack_map_encoding.Dump(vios);
+ if (HasInlineInfo(encoding)) {
+ encoding.inline_info_encoding.Dump(vios);
+ }
// Display the Dex register location catalog.
GetDexRegisterLocationCatalog(encoding).Dump(vios, *this);
// Display stack maps along with (live) Dex register maps.
@@ -207,18 +221,22 @@
void InlineInfo::Dump(VariableIndentationOutputStream* vios,
const CodeInfo& code_info,
uint16_t number_of_dex_registers[]) const {
- vios->Stream() << "InlineInfo with depth " << static_cast<uint32_t>(GetDepth()) << "\n";
+ InlineInfoEncoding inline_info_encoding = code_info.ExtractEncoding().inline_info_encoding;
+ vios->Stream() << "InlineInfo with depth "
+ << static_cast<uint32_t>(GetDepth(inline_info_encoding))
+ << "\n";
- for (size_t i = 0; i < GetDepth(); ++i) {
+ for (size_t i = 0; i < GetDepth(inline_info_encoding); ++i) {
vios->Stream()
<< " At depth " << i
<< std::hex
- << " (dex_pc=0x" << GetDexPcAtDepth(i)
+ << " (dex_pc=0x" << GetDexPcAtDepth(inline_info_encoding, i)
<< std::dec
- << ", method_index=" << GetMethodIndexAtDepth(i)
- << ", invoke_type=" << static_cast<InvokeType>(GetInvokeTypeAtDepth(i))
+ << ", method_index=" << GetMethodIndexAtDepth(inline_info_encoding, i)
+ << ", invoke_type=" << static_cast<InvokeType>(GetInvokeTypeAtDepth(inline_info_encoding,
+ i))
<< ")\n";
- if (HasDexRegisterMapAtDepth(i) && (number_of_dex_registers != nullptr)) {
+ if (HasDexRegisterMapAtDepth(inline_info_encoding, i) && (number_of_dex_registers != nullptr)) {
CodeInfoEncoding encoding = code_info.ExtractEncoding();
DexRegisterMap dex_register_map =
code_info.GetDexRegisterMapAtDepth(i, *this, encoding, number_of_dex_registers[i]);
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index 9e8884e..7c50f97 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -24,12 +24,6 @@
namespace art {
-#define ELEMENT_BYTE_OFFSET_AFTER(PreviousElement) \
- k ## PreviousElement ## Offset + sizeof(PreviousElement ## Type)
-
-#define ELEMENT_BIT_OFFSET_AFTER(PreviousElement) \
- k ## PreviousElement ## BitOffset + PreviousElement ## BitSize
-
class VariableIndentationOutputStream;
// Size of a frame slot, in bytes. This constant is a signed value,
@@ -888,102 +882,139 @@
friend class StackMapStream;
};
+class InlineInfoEncoding {
+ public:
+ void SetFromSizes(size_t method_index_max,
+ size_t dex_pc_max,
+ size_t invoke_type_max,
+ size_t dex_register_map_size) {
+ total_bit_size_ = kMethodIndexBitOffset;
+ total_bit_size_ += MinimumBitsToStore(method_index_max);
+
+ dex_pc_bit_offset_ = dchecked_integral_cast<uint8_t>(total_bit_size_);
+ total_bit_size_ += MinimumBitsToStore(1 /* kNoDexPc */ + dex_pc_max);
+
+ invoke_type_bit_offset_ = dchecked_integral_cast<uint8_t>(total_bit_size_);
+ total_bit_size_ += MinimumBitsToStore(invoke_type_max);
+
+ // We also need +1 for kNoDexRegisterMap, but since the size is strictly
+ // greater than any offset we might try to encode, we already implicitly have it.
+ dex_register_map_bit_offset_ = dchecked_integral_cast<uint8_t>(total_bit_size_);
+ total_bit_size_ += MinimumBitsToStore(dex_register_map_size);
+ }
+
+ ALWAYS_INLINE FieldEncoding GetMethodIndexEncoding() const {
+ return FieldEncoding(kMethodIndexBitOffset, dex_pc_bit_offset_);
+ }
+ ALWAYS_INLINE FieldEncoding GetDexPcEncoding() const {
+ return FieldEncoding(dex_pc_bit_offset_, invoke_type_bit_offset_, -1 /* min_value */);
+ }
+ ALWAYS_INLINE FieldEncoding GetInvokeTypeEncoding() const {
+ return FieldEncoding(invoke_type_bit_offset_, dex_register_map_bit_offset_);
+ }
+ ALWAYS_INLINE FieldEncoding GetDexRegisterMapEncoding() const {
+ return FieldEncoding(dex_register_map_bit_offset_, total_bit_size_, -1 /* min_value */);
+ }
+ ALWAYS_INLINE size_t GetEntrySize() const {
+ return RoundUp(total_bit_size_, kBitsPerByte) / kBitsPerByte;
+ }
+
+ void Dump(VariableIndentationOutputStream* vios) const;
+
+ private:
+ static constexpr uint8_t kIsLastBitOffset = 0;
+ static constexpr uint8_t kMethodIndexBitOffset = 1;
+ uint8_t dex_pc_bit_offset_;
+ uint8_t invoke_type_bit_offset_;
+ uint8_t dex_register_map_bit_offset_;
+ uint8_t total_bit_size_;
+};
+
/**
* Inline information for a specific PC. The information is of the form:
*
- * [inlining_depth, entry+]
- *
- * where `entry` is of the form:
- *
- * [dex_pc, method_index, dex_register_map_offset].
+ * [is_last, method_index, dex_pc, invoke_type, dex_register_map_offset]+.
*/
class InlineInfo {
public:
- // Memory layout: fixed contents.
- typedef uint8_t DepthType;
- // Memory layout: single entry contents.
- typedef uint32_t MethodIndexType;
- typedef uint32_t DexPcType;
- typedef uint8_t InvokeTypeType;
- typedef uint32_t DexRegisterMapType;
-
- explicit InlineInfo(MemoryRegion region) : region_(region) {}
-
- DepthType GetDepth() const {
- return region_.LoadUnaligned<DepthType>(kDepthOffset);
+ explicit InlineInfo(MemoryRegion region) : region_(region) {
}
- void SetDepth(DepthType depth) {
- region_.StoreUnaligned<DepthType>(kDepthOffset, depth);
+ ALWAYS_INLINE uint32_t GetDepth(const InlineInfoEncoding& encoding) const {
+ size_t depth = 0;
+ while (!GetRegionAtDepth(encoding, depth++).LoadBit(0)) { } // Check is_last bit.
+ return depth;
}
- MethodIndexType GetMethodIndexAtDepth(DepthType depth) const {
- return region_.LoadUnaligned<MethodIndexType>(
- kFixedSize + depth * SingleEntrySize() + kMethodIndexOffset);
+ ALWAYS_INLINE void SetDepth(const InlineInfoEncoding& encoding, uint32_t depth) {
+ DCHECK_GT(depth, 0u);
+ for (size_t d = 0; d < depth; ++d) {
+ GetRegionAtDepth(encoding, d).StoreBit(0, d == depth - 1); // Set is_last bit.
+ }
}
- void SetMethodIndexAtDepth(DepthType depth, MethodIndexType index) {
- region_.StoreUnaligned<MethodIndexType>(
- kFixedSize + depth * SingleEntrySize() + kMethodIndexOffset, index);
+ ALWAYS_INLINE uint32_t GetMethodIndexAtDepth(const InlineInfoEncoding& encoding,
+ uint32_t depth) const {
+ return encoding.GetMethodIndexEncoding().Load(GetRegionAtDepth(encoding, depth));
}
- DexPcType GetDexPcAtDepth(DepthType depth) const {
- return region_.LoadUnaligned<DexPcType>(
- kFixedSize + depth * SingleEntrySize() + kDexPcOffset);
+ ALWAYS_INLINE void SetMethodIndexAtDepth(const InlineInfoEncoding& encoding,
+ uint32_t depth,
+ uint32_t index) {
+ encoding.GetMethodIndexEncoding().Store(GetRegionAtDepth(encoding, depth), index);
}
- void SetDexPcAtDepth(DepthType depth, DexPcType dex_pc) {
- region_.StoreUnaligned<DexPcType>(
- kFixedSize + depth * SingleEntrySize() + kDexPcOffset, dex_pc);
+ ALWAYS_INLINE uint32_t GetDexPcAtDepth(const InlineInfoEncoding& encoding,
+ uint32_t depth) const {
+ return encoding.GetDexPcEncoding().Load(GetRegionAtDepth(encoding, depth));
}
- InvokeTypeType GetInvokeTypeAtDepth(DepthType depth) const {
- return region_.LoadUnaligned<InvokeTypeType>(
- kFixedSize + depth * SingleEntrySize() + kInvokeTypeOffset);
+ ALWAYS_INLINE void SetDexPcAtDepth(const InlineInfoEncoding& encoding,
+ uint32_t depth,
+ uint32_t dex_pc) {
+ encoding.GetDexPcEncoding().Store(GetRegionAtDepth(encoding, depth), dex_pc);
}
- void SetInvokeTypeAtDepth(DepthType depth, InvokeTypeType invoke_type) {
- region_.StoreUnaligned<InvokeTypeType>(
- kFixedSize + depth * SingleEntrySize() + kInvokeTypeOffset, invoke_type);
+ ALWAYS_INLINE uint32_t GetInvokeTypeAtDepth(const InlineInfoEncoding& encoding,
+ uint32_t depth) const {
+ return encoding.GetInvokeTypeEncoding().Load(GetRegionAtDepth(encoding, depth));
}
- DexRegisterMapType GetDexRegisterMapOffsetAtDepth(DepthType depth) const {
- return region_.LoadUnaligned<DexRegisterMapType>(
- kFixedSize + depth * SingleEntrySize() + kDexRegisterMapOffset);
+ ALWAYS_INLINE void SetInvokeTypeAtDepth(const InlineInfoEncoding& encoding,
+ uint32_t depth,
+ uint32_t invoke_type) {
+ encoding.GetInvokeTypeEncoding().Store(GetRegionAtDepth(encoding, depth), invoke_type);
}
- void SetDexRegisterMapOffsetAtDepth(DepthType depth, DexRegisterMapType offset) {
- region_.StoreUnaligned<DexRegisterMapType>(
- kFixedSize + depth * SingleEntrySize() + kDexRegisterMapOffset, offset);
+ ALWAYS_INLINE uint32_t GetDexRegisterMapOffsetAtDepth(const InlineInfoEncoding& encoding,
+ uint32_t depth) const {
+ return encoding.GetDexRegisterMapEncoding().Load(GetRegionAtDepth(encoding, depth));
}
- bool HasDexRegisterMapAtDepth(DepthType depth) const {
- return GetDexRegisterMapOffsetAtDepth(depth) != StackMap::kNoDexRegisterMap;
+ ALWAYS_INLINE void SetDexRegisterMapOffsetAtDepth(const InlineInfoEncoding& encoding,
+ uint32_t depth,
+ uint32_t offset) {
+ encoding.GetDexRegisterMapEncoding().Store(GetRegionAtDepth(encoding, depth), offset);
}
- static size_t SingleEntrySize() {
- return kFixedEntrySize;
+ ALWAYS_INLINE bool HasDexRegisterMapAtDepth(const InlineInfoEncoding& encoding,
+ uint32_t depth) const {
+ return GetDexRegisterMapOffsetAtDepth(encoding, depth) != StackMap::kNoDexRegisterMap;
}
void Dump(VariableIndentationOutputStream* vios,
- const CodeInfo& info, uint16_t* number_of_dex_registers) const;
-
+ const CodeInfo& info,
+ uint16_t* number_of_dex_registers) const;
private:
- static constexpr int kDepthOffset = 0;
- static constexpr int kFixedSize = ELEMENT_BYTE_OFFSET_AFTER(Depth);
-
- static constexpr int kMethodIndexOffset = 0;
- static constexpr int kDexPcOffset = ELEMENT_BYTE_OFFSET_AFTER(MethodIndex);
- static constexpr int kInvokeTypeOffset = ELEMENT_BYTE_OFFSET_AFTER(DexPc);
- static constexpr int kDexRegisterMapOffset = ELEMENT_BYTE_OFFSET_AFTER(InvokeType);
- static constexpr int kFixedEntrySize = ELEMENT_BYTE_OFFSET_AFTER(DexRegisterMap);
+ ALWAYS_INLINE MemoryRegion GetRegionAtDepth(const InlineInfoEncoding& encoding,
+ uint32_t depth) const {
+ size_t entry_size = encoding.GetEntrySize();
+ DCHECK_GT(entry_size, 0u);
+ return region_.Subregion(depth * entry_size, entry_size);
+ }
MemoryRegion region_;
-
- friend class CodeInfo;
- friend class StackMap;
- friend class StackMapStream;
};
// Most of the fields are encoded as ULEB128 to save space.
@@ -993,6 +1024,7 @@
uint32_t stack_map_size_in_bytes;
uint32_t number_of_location_catalog_entries;
StackMapEncoding stack_map_encoding;
+ InlineInfoEncoding inline_info_encoding;
uint8_t header_size;
CodeInfoEncoding() { }
@@ -1003,9 +1035,18 @@
number_of_stack_maps = DecodeUnsignedLeb128(&ptr);
stack_map_size_in_bytes = DecodeUnsignedLeb128(&ptr);
number_of_location_catalog_entries = DecodeUnsignedLeb128(&ptr);
- static_assert(alignof(StackMapEncoding) == 1, "StackMapEncoding should not require alignment");
+ static_assert(alignof(StackMapEncoding) == 1,
+ "StackMapEncoding should not require alignment");
stack_map_encoding = *reinterpret_cast<const StackMapEncoding*>(ptr);
ptr += sizeof(StackMapEncoding);
+ if (stack_map_encoding.GetInlineInfoEncoding().BitSize() > 0) {
+ static_assert(alignof(InlineInfoEncoding) == 1,
+ "InlineInfoEncoding should not require alignment");
+ inline_info_encoding = *reinterpret_cast<const InlineInfoEncoding*>(ptr);
+ ptr += sizeof(InlineInfoEncoding);
+ } else {
+ inline_info_encoding = InlineInfoEncoding{}; // NOLINT.
+ }
header_size = dchecked_integral_cast<uint8_t>(ptr - reinterpret_cast<const uint8_t*>(data));
}
@@ -1015,8 +1056,12 @@
EncodeUnsignedLeb128(dest, number_of_stack_maps);
EncodeUnsignedLeb128(dest, stack_map_size_in_bytes);
EncodeUnsignedLeb128(dest, number_of_location_catalog_entries);
- const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&stack_map_encoding);
- dest->insert(dest->end(), ptr, ptr + sizeof(stack_map_encoding));
+ const uint8_t* stack_map_ptr = reinterpret_cast<const uint8_t*>(&stack_map_encoding);
+ dest->insert(dest->end(), stack_map_ptr, stack_map_ptr + sizeof(StackMapEncoding));
+ if (stack_map_encoding.GetInlineInfoEncoding().BitSize() > 0) {
+ const uint8_t* inline_info_ptr = reinterpret_cast<const uint8_t*>(&inline_info_encoding);
+ dest->insert(dest->end(), inline_info_ptr, inline_info_ptr + sizeof(InlineInfoEncoding));
+ }
}
};
@@ -1110,11 +1155,11 @@
InlineInfo inline_info,
const CodeInfoEncoding& encoding,
uint32_t number_of_dex_registers) const {
- if (!inline_info.HasDexRegisterMapAtDepth(depth)) {
+ if (!inline_info.HasDexRegisterMapAtDepth(encoding.inline_info_encoding, depth)) {
return DexRegisterMap();
} else {
- uint32_t offset = GetDexRegisterMapsOffset(encoding)
- + inline_info.GetDexRegisterMapOffsetAtDepth(depth);
+ uint32_t offset = GetDexRegisterMapsOffset(encoding) +
+ inline_info.GetDexRegisterMapOffsetAtDepth(encoding.inline_info_encoding, depth);
size_t size = ComputeDexRegisterMapSizeOf(encoding, offset, number_of_dex_registers);
return DexRegisterMap(region_.Subregion(offset, size));
}
@@ -1124,9 +1169,7 @@
DCHECK(stack_map.HasInlineInfo(encoding.stack_map_encoding));
uint32_t offset = stack_map.GetInlineDescriptorOffset(encoding.stack_map_encoding)
+ GetDexRegisterMapsOffset(encoding);
- uint8_t depth = region_.LoadUnaligned<uint8_t>(offset);
- return InlineInfo(region_.Subregion(offset,
- InlineInfo::kFixedSize + depth * InlineInfo::SingleEntrySize()));
+ return InlineInfo(region_.Subregion(offset, region_.size() - offset));
}
StackMap GetStackMapForDexPc(uint32_t dex_pc, const CodeInfoEncoding& encoding) const {