Cache stack map encoding
Operations on CodeInfo and StackMap objects repeatedly read encoding
information from the MemoryRegion. Since these are 3-bit-loads of
values that never change, caching them can measurably reduce compile
times.
According to benchmarks, this patch saves 1-3% on armv7, 2-4% on x86,
and 0-1% on x64.
Change-Id: I46b197513601325d8bab562cc80100c00ec28a3b
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 349013c..fe26438 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -182,9 +182,10 @@
uint32_t sought_offset = pc - reinterpret_cast<uintptr_t>(entry_point);
if (IsOptimized(sizeof(void*))) {
CodeInfo code_info = GetOptimizedCodeInfo();
- StackMap stack_map = code_info.GetStackMapForNativePcOffset(sought_offset);
+ StackMapEncoding encoding = code_info.ExtractEncoding();
+ StackMap stack_map = code_info.GetStackMapForNativePcOffset(sought_offset, encoding);
if (stack_map.IsValid()) {
- return stack_map.GetDexPc(code_info);
+ return stack_map.GetDexPc(encoding);
}
} else {
MappingTable table(entry_point != nullptr ?
diff --git a/runtime/check_reference_map_visitor.h b/runtime/check_reference_map_visitor.h
index d323379..504b753 100644
--- a/runtime/check_reference_map_visitor.h
+++ b/runtime/check_reference_map_visitor.h
@@ -65,17 +65,18 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
CodeInfo code_info = m->GetOptimizedCodeInfo();
- StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+ StackMapEncoding encoding = code_info.ExtractEncoding();
+ StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
uint16_t number_of_dex_registers = m->GetCodeItem()->registers_size_;
DexRegisterMap dex_register_map =
- code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
- MemoryRegion stack_mask = stack_map.GetStackMask(code_info);
- uint32_t register_mask = stack_map.GetRegisterMask(code_info);
+ code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
+ MemoryRegion stack_mask = stack_map.GetStackMask(encoding);
+ uint32_t register_mask = stack_map.GetRegisterMask(encoding);
for (int i = 0; i < number_of_references; ++i) {
int reg = registers[i];
CHECK(reg < m->GetCodeItem()->registers_size_);
- DexRegisterLocation location =
- dex_register_map.GetDexRegisterLocation(reg, number_of_dex_registers, code_info);
+ DexRegisterLocation location = dex_register_map.GetDexRegisterLocation(
+ reg, number_of_dex_registers, code_info, encoding);
switch (location.GetKind()) {
case DexRegisterLocation::Kind::kNone:
// Not set, should not be a reference.
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index dbd24a2..b0cbd02 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -77,10 +77,11 @@
(reinterpret_cast<uint8_t*>(sp) + callee_return_pc_offset));
uintptr_t native_pc_offset = outer_method->NativeQuickPcOffset(caller_pc);
CodeInfo code_info = outer_method->GetOptimizedCodeInfo();
- StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+ StackMapEncoding encoding = code_info.ExtractEncoding();
+ StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
DCHECK(stack_map.IsValid());
- if (stack_map.HasInlineInfo(code_info)) {
- InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
+ if (stack_map.HasInlineInfo(encoding)) {
+ InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
uint32_t method_index = inline_info.GetMethodIndexAtDepth(inline_info.GetDepth() - 1);
InvokeType invoke_type = static_cast<InvokeType>(
inline_info.GetInvokeTypeAtDepth(inline_info.GetDepth() - 1));
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 042c33f..cc83db1 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -314,13 +314,14 @@
if (outer_method->IsOptimized(sizeof(void*))) {
CodeInfo code_info = outer_method->GetOptimizedCodeInfo();
- StackMap stack_map = code_info.GetStackMapForNativePcOffset(outer_pc_offset);
+ StackMapEncoding encoding = code_info.ExtractEncoding();
+ StackMap stack_map = code_info.GetStackMapForNativePcOffset(outer_pc_offset, encoding);
DCHECK(stack_map.IsValid());
- if (stack_map.HasInlineInfo(code_info)) {
- InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
+ if (stack_map.HasInlineInfo(encoding)) {
+ InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
return inline_info.GetDexPcAtDepth(inline_info.GetDepth() - 1);
} else {
- return stack_map.GetDexPc(code_info);
+ return stack_map.GetDexPc(encoding);
}
} else {
return outer_method->ToDexPc(outer_pc);
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 4110887..5aeca98 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -113,9 +113,10 @@
ArtMethod* outer_method = *GetCurrentQuickFrame();
uint32_t native_pc_offset = outer_method->NativeQuickPcOffset(cur_quick_frame_pc_);
CodeInfo code_info = outer_method->GetOptimizedCodeInfo();
- StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+ StackMapEncoding encoding = code_info.ExtractEncoding();
+ StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
DCHECK(stack_map.IsValid());
- return code_info.GetInlineInfoOf(stack_map);
+ return code_info.GetInlineInfoOf(stack_map, encoding);
}
ArtMethod* StackVisitor::GetMethod() const {
@@ -274,34 +275,40 @@
const void* code_pointer = outer_method->GetQuickOatCodePointer(sizeof(void*));
DCHECK(code_pointer != nullptr);
CodeInfo code_info = outer_method->GetOptimizedCodeInfo();
+ StackMapEncoding encoding = code_info.ExtractEncoding();
uint32_t native_pc_offset = outer_method->NativeQuickPcOffset(cur_quick_frame_pc_);
- StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+ StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
DCHECK(stack_map.IsValid());
size_t depth_in_stack_map = current_inlining_depth_ - 1;
DexRegisterMap dex_register_map = IsInInlinedFrame()
- ? code_info.GetDexRegisterMapAtDepth(
- depth_in_stack_map, code_info.GetInlineInfoOf(stack_map), number_of_dex_registers)
- : code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+ ? code_info.GetDexRegisterMapAtDepth(depth_in_stack_map,
+ code_info.GetInlineInfoOf(stack_map, encoding),
+ encoding,
+ number_of_dex_registers)
+ : code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
DexRegisterLocation::Kind location_kind =
- dex_register_map.GetLocationKind(vreg, number_of_dex_registers, code_info);
+ dex_register_map.GetLocationKind(vreg, number_of_dex_registers, code_info, encoding);
switch (location_kind) {
case DexRegisterLocation::Kind::kInStack: {
- const int32_t offset =
- dex_register_map.GetStackOffsetInBytes(vreg, number_of_dex_registers, code_info);
+ const int32_t offset = dex_register_map.GetStackOffsetInBytes(vreg,
+ number_of_dex_registers,
+ code_info,
+ encoding);
const uint8_t* addr = reinterpret_cast<const uint8_t*>(cur_quick_frame_) + offset;
*val = *reinterpret_cast<const uint32_t*>(addr);
return true;
}
case DexRegisterLocation::Kind::kInRegister:
case DexRegisterLocation::Kind::kInFpuRegister: {
- uint32_t reg = dex_register_map.GetMachineRegister(vreg, number_of_dex_registers, code_info);
+ uint32_t reg =
+ dex_register_map.GetMachineRegister(vreg, number_of_dex_registers, code_info, encoding);
return GetRegisterIfAccessible(reg, kind, val);
}
case DexRegisterLocation::Kind::kConstant:
- *val = dex_register_map.GetConstant(vreg, number_of_dex_registers, code_info);
+ *val = dex_register_map.GetConstant(vreg, number_of_dex_registers, code_info, encoding);
return true;
case DexRegisterLocation::Kind::kNone:
return false;
@@ -309,7 +316,10 @@
LOG(FATAL)
<< "Unexpected location kind"
<< DexRegisterLocation::PrettyDescriptor(
- dex_register_map.GetLocationInternalKind(vreg, number_of_dex_registers, code_info));
+ dex_register_map.GetLocationInternalKind(vreg,
+ number_of_dex_registers,
+ code_info,
+ encoding));
UNREACHABLE();
}
}
@@ -782,10 +792,11 @@
if ((walk_kind_ == StackWalkKind::kIncludeInlinedFrames)
&& method->IsOptimized(sizeof(void*))) {
CodeInfo code_info = method->GetOptimizedCodeInfo();
+ StackMapEncoding encoding = code_info.ExtractEncoding();
uint32_t native_pc_offset = method->NativeQuickPcOffset(cur_quick_frame_pc_);
- StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
- if (stack_map.IsValid() && stack_map.HasInlineInfo(code_info)) {
- InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
+ StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
+ if (stack_map.IsValid() && stack_map.HasInlineInfo(encoding)) {
+ InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
DCHECK_EQ(current_inlining_depth_, 0u);
for (current_inlining_depth_ = inline_info.GetDepth();
current_inlining_depth_ != 0;
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index a64071f..f8fc2a9 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -28,9 +28,10 @@
DexRegisterLocation::Kind DexRegisterMap::GetLocationInternalKind(uint16_t dex_register_number,
uint16_t number_of_dex_registers,
- const CodeInfo& code_info) const {
+ const CodeInfo& code_info,
+ const StackMapEncoding& enc) const {
DexRegisterLocationCatalog dex_register_location_catalog =
- code_info.GetDexRegisterLocationCatalog();
+ code_info.GetDexRegisterLocationCatalog(enc);
size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
dex_register_number,
number_of_dex_registers,
@@ -40,9 +41,10 @@
DexRegisterLocation DexRegisterMap::GetDexRegisterLocation(uint16_t dex_register_number,
uint16_t number_of_dex_registers,
- const CodeInfo& code_info) const {
+ const CodeInfo& code_info,
+ const StackMapEncoding& enc) const {
DexRegisterLocationCatalog dex_register_location_catalog =
- code_info.GetDexRegisterLocationCatalog();
+ code_info.GetDexRegisterLocationCatalog(enc);
size_t location_catalog_entry_index = GetLocationCatalogEntryIndex(
dex_register_number,
number_of_dex_registers,
@@ -50,156 +52,43 @@
return dex_register_location_catalog.GetDexRegisterLocation(location_catalog_entry_index);
}
-// Loads `number_of_bytes` at the given `offset` and assemble a uint32_t. If `check_max` is true,
-// this method converts a maximum value of size `number_of_bytes` into a uint32_t 0xFFFFFFFF.
-static uint32_t LoadAt(MemoryRegion region,
- size_t number_of_bytes,
- size_t offset,
- bool check_max = false) {
+uint32_t StackMap::LoadAt(size_t number_of_bytes, size_t offset, bool check_max) const {
if (number_of_bytes == 0u) {
DCHECK(!check_max);
return 0;
} else if (number_of_bytes == 1u) {
- uint8_t value = region.LoadUnaligned<uint8_t>(offset);
- if (check_max && value == 0xFF) {
- return -1;
- } else {
- return value;
- }
+ uint8_t value = region_.LoadUnaligned<uint8_t>(offset);
+ return (check_max && value == 0xFF) ? -1 : value;
} else if (number_of_bytes == 2u) {
- uint16_t value = region.LoadUnaligned<uint16_t>(offset);
- if (check_max && value == 0xFFFF) {
- return -1;
- } else {
- return value;
- }
+ uint16_t value = region_.LoadUnaligned<uint16_t>(offset);
+ return (check_max && value == 0xFFFF) ? -1 : value;
} else if (number_of_bytes == 3u) {
- uint16_t low = region.LoadUnaligned<uint16_t>(offset);
- uint16_t high = region.LoadUnaligned<uint8_t>(offset + sizeof(uint16_t));
+ uint16_t low = region_.LoadUnaligned<uint16_t>(offset);
+ uint16_t high = region_.LoadUnaligned<uint8_t>(offset + sizeof(uint16_t));
uint32_t value = (high << 16) + low;
- if (check_max && value == 0xFFFFFF) {
- return -1;
- } else {
- return value;
- }
+ return (check_max && value == 0xFFFFFF) ? -1 : value;
} else {
DCHECK_EQ(number_of_bytes, 4u);
- return region.LoadUnaligned<uint32_t>(offset);
+ return region_.LoadUnaligned<uint32_t>(offset);
}
}
-static void StoreAt(MemoryRegion region, size_t number_of_bytes, size_t offset, uint32_t value) {
+void StackMap::StoreAt(size_t number_of_bytes, size_t offset, uint32_t value) const {
if (number_of_bytes == 0u) {
DCHECK_EQ(value, 0u);
} else if (number_of_bytes == 1u) {
- region.StoreUnaligned<uint8_t>(offset, value);
+ region_.StoreUnaligned<uint8_t>(offset, value);
} else if (number_of_bytes == 2u) {
- region.StoreUnaligned<uint16_t>(offset, value);
+ region_.StoreUnaligned<uint16_t>(offset, value);
} else if (number_of_bytes == 3u) {
- region.StoreUnaligned<uint16_t>(offset, Low16Bits(value));
- region.StoreUnaligned<uint8_t>(offset + sizeof(uint16_t), High16Bits(value));
+ region_.StoreUnaligned<uint16_t>(offset, Low16Bits(value));
+ region_.StoreUnaligned<uint8_t>(offset + sizeof(uint16_t), High16Bits(value));
} else {
- region.StoreUnaligned<uint32_t>(offset, value);
+ region_.StoreUnaligned<uint32_t>(offset, value);
DCHECK_EQ(number_of_bytes, 4u);
}
}
-uint32_t StackMap::GetDexPc(const CodeInfo& info) const {
- return LoadAt(region_, info.NumberOfBytesForDexPc(), info.ComputeStackMapDexPcOffset());
-}
-
-void StackMap::SetDexPc(const CodeInfo& info, uint32_t dex_pc) {
- StoreAt(region_, info.NumberOfBytesForDexPc(), info.ComputeStackMapDexPcOffset(), dex_pc);
-}
-
-uint32_t StackMap::GetNativePcOffset(const CodeInfo& info) const {
- return LoadAt(region_, info.NumberOfBytesForNativePc(), info.ComputeStackMapNativePcOffset());
-}
-
-void StackMap::SetNativePcOffset(const CodeInfo& info, uint32_t native_pc_offset) {
- StoreAt(region_, info.NumberOfBytesForNativePc(), info.ComputeStackMapNativePcOffset(), native_pc_offset);
-}
-
-uint32_t StackMap::GetDexRegisterMapOffset(const CodeInfo& info) const {
- return LoadAt(region_,
- info.NumberOfBytesForDexRegisterMap(),
- info.ComputeStackMapDexRegisterMapOffset(),
- /* check_max */ true);
-}
-
-void StackMap::SetDexRegisterMapOffset(const CodeInfo& info, uint32_t offset) {
- StoreAt(region_,
- info.NumberOfBytesForDexRegisterMap(),
- info.ComputeStackMapDexRegisterMapOffset(),
- offset);
-}
-
-uint32_t StackMap::GetInlineDescriptorOffset(const CodeInfo& info) const {
- if (!info.HasInlineInfo()) return kNoInlineInfo;
- return LoadAt(region_,
- info.NumberOfBytesForInlineInfo(),
- info.ComputeStackMapInlineInfoOffset(),
- /* check_max */ true);
-}
-
-void StackMap::SetInlineDescriptorOffset(const CodeInfo& info, uint32_t offset) {
- DCHECK(info.HasInlineInfo());
- StoreAt(region_,
- info.NumberOfBytesForInlineInfo(),
- info.ComputeStackMapInlineInfoOffset(),
- offset);
-}
-
-uint32_t StackMap::GetRegisterMask(const CodeInfo& info) const {
- return LoadAt(region_,
- info.NumberOfBytesForRegisterMask(),
- info.ComputeStackMapRegisterMaskOffset());
-}
-
-void StackMap::SetRegisterMask(const CodeInfo& info, uint32_t mask) {
- StoreAt(region_,
- info.NumberOfBytesForRegisterMask(),
- info.ComputeStackMapRegisterMaskOffset(),
- mask);
-}
-
-size_t StackMap::ComputeStackMapSizeInternal(size_t stack_mask_size,
- size_t number_of_bytes_for_inline_info,
- size_t number_of_bytes_for_dex_map,
- size_t number_of_bytes_for_dex_pc,
- size_t number_of_bytes_for_native_pc,
- size_t number_of_bytes_for_register_mask) {
- return stack_mask_size
- + number_of_bytes_for_inline_info
- + number_of_bytes_for_dex_map
- + number_of_bytes_for_dex_pc
- + number_of_bytes_for_native_pc
- + number_of_bytes_for_register_mask;
-}
-
-size_t StackMap::ComputeStackMapSize(size_t stack_mask_size,
- size_t inline_info_size,
- size_t dex_register_map_size,
- size_t dex_pc_max,
- size_t native_pc_max,
- size_t register_mask_max) {
- return ComputeStackMapSizeInternal(
- stack_mask_size,
- inline_info_size == 0
- ? 0
- // + 1 to also encode kNoInlineInfo.
- : CodeInfo::EncodingSizeInBytes(inline_info_size + dex_register_map_size + 1),
- // + 1 to also encode kNoDexRegisterMap.
- CodeInfo::EncodingSizeInBytes(dex_register_map_size + 1),
- CodeInfo::EncodingSizeInBytes(dex_pc_max),
- CodeInfo::EncodingSizeInBytes(native_pc_max),
- CodeInfo::EncodingSizeInBytes(register_mask_max));
-}
-
-MemoryRegion StackMap::GetStackMask(const CodeInfo& info) const {
- return region_.Subregion(info.ComputeStackMapStackMaskOffset(), info.GetStackMaskSize());
-}
-
static void DumpRegisterMapping(std::ostream& os,
size_t dex_register_num,
DexRegisterLocation location,
@@ -216,6 +105,7 @@
uint32_t code_offset,
uint16_t number_of_dex_registers,
bool dump_stack_maps) const {
+ StackMapEncoding encoding = ExtractEncoding();
uint32_t code_info_size = GetOverallSize();
size_t number_of_stack_maps = GetNumberOfStackMaps();
Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
@@ -223,21 +113,26 @@
indented_os << "Optimized CodeInfo (size=" << code_info_size
<< ", number_of_dex_registers=" << number_of_dex_registers
<< ", number_of_stack_maps=" << number_of_stack_maps
- << ", has_inline_info=" << HasInlineInfo()
- << ", number_of_bytes_for_inline_info=" << NumberOfBytesForInlineInfo()
- << ", number_of_bytes_for_dex_register_map=" << NumberOfBytesForDexRegisterMap()
- << ", number_of_bytes_for_dex_pc=" << NumberOfBytesForDexPc()
- << ", number_of_bytes_for_native_pc=" << NumberOfBytesForNativePc()
- << ", number_of_bytes_for_register_mask=" << NumberOfBytesForRegisterMask()
+ << ", has_inline_info=" << encoding.HasInlineInfo()
+ << ", number_of_bytes_for_inline_info=" << encoding.NumberOfBytesForInlineInfo()
+ << ", number_of_bytes_for_dex_register_map="
+ << encoding.NumberOfBytesForDexRegisterMap()
+ << ", number_of_bytes_for_dex_pc=" << encoding.NumberOfBytesForDexPc()
+ << ", number_of_bytes_for_native_pc=" << encoding.NumberOfBytesForNativePc()
+ << ", number_of_bytes_for_register_mask=" << encoding.NumberOfBytesForRegisterMask()
<< ")\n";
// Display the Dex register location catalog.
- GetDexRegisterLocationCatalog().Dump(indented_os, *this);
+ GetDexRegisterLocationCatalog(encoding).Dump(indented_os, *this);
// Display stack maps along with (live) Dex register maps.
if (dump_stack_maps) {
for (size_t i = 0; i < number_of_stack_maps; ++i) {
- StackMap stack_map = GetStackMapAt(i);
- stack_map.Dump(
- indented_os, *this, code_offset, number_of_dex_registers, " " + std::to_string(i));
+ StackMap stack_map = GetStackMapAt(i, encoding);
+ stack_map.Dump(indented_os,
+ *this,
+ encoding,
+ code_offset,
+ number_of_dex_registers,
+ " " + std::to_string(i));
}
}
// TODO: Dump the stack map's inline information? We need to know more from the caller:
@@ -245,9 +140,10 @@
}
void DexRegisterLocationCatalog::Dump(std::ostream& os, const CodeInfo& code_info) {
+ StackMapEncoding encoding = code_info.ExtractEncoding();
size_t number_of_location_catalog_entries =
code_info.GetNumberOfDexRegisterLocationCatalogEntries();
- size_t location_catalog_size_in_bytes = code_info.GetDexRegisterLocationCatalogSize();
+ size_t location_catalog_size_in_bytes = code_info.GetDexRegisterLocationCatalogSize(encoding);
Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
std::ostream indented_os(&indent_filter);
indented_os
@@ -262,6 +158,7 @@
void DexRegisterMap::Dump(std::ostream& os,
const CodeInfo& code_info,
uint16_t number_of_dex_registers) const {
+ StackMapEncoding encoding = code_info.ExtractEncoding();
size_t number_of_location_catalog_entries =
code_info.GetNumberOfDexRegisterLocationCatalogEntries();
Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
@@ -271,7 +168,10 @@
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);
+ DexRegisterLocation location = GetDexRegisterLocation(j,
+ number_of_dex_registers,
+ code_info,
+ encoding);
DumpRegisterMapping(
indented_os, j, location, "v",
"\t[entry " + std::to_string(static_cast<int>(location_catalog_entry_index)) + "]");
@@ -281,6 +181,7 @@
void StackMap::Dump(std::ostream& os,
const CodeInfo& code_info,
+ const StackMapEncoding& encoding,
uint32_t code_offset,
uint16_t number_of_dex_registers,
const std::string& header_suffix) const {
@@ -288,21 +189,22 @@
std::ostream indented_os(&indent_filter);
indented_os << "StackMap" << header_suffix
<< std::hex
- << " [native_pc=0x" << code_offset + GetNativePcOffset(code_info) << "]"
- << " (dex_pc=0x" << GetDexPc(code_info)
- << ", native_pc_offset=0x" << GetNativePcOffset(code_info)
- << ", dex_register_map_offset=0x" << GetDexRegisterMapOffset(code_info)
- << ", inline_info_offset=0x" << GetInlineDescriptorOffset(code_info)
- << ", register_mask=0x" << GetRegisterMask(code_info)
+ << " [native_pc=0x" << code_offset + GetNativePcOffset(encoding) << "]"
+ << " (dex_pc=0x" << GetDexPc(encoding)
+ << ", native_pc_offset=0x" << GetNativePcOffset(encoding)
+ << ", dex_register_map_offset=0x" << GetDexRegisterMapOffset(encoding)
+ << ", inline_info_offset=0x" << GetInlineDescriptorOffset(encoding)
+ << ", register_mask=0x" << GetRegisterMask(encoding)
<< std::dec
<< ", stack_mask=0b";
- MemoryRegion stack_mask = GetStackMask(code_info);
+ MemoryRegion stack_mask = GetStackMask(encoding);
for (size_t i = 0, e = stack_mask.size_in_bits(); i < e; ++i) {
indented_os << stack_mask.LoadBit(e - i - 1);
}
indented_os << ")\n";
- if (HasDexRegisterMap(code_info)) {
- DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(*this, number_of_dex_registers);
+ if (HasDexRegisterMap(encoding)) {
+ DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(
+ *this, encoding, number_of_dex_registers);
dex_register_map.Dump(os, code_info, number_of_dex_registers);
}
}
@@ -321,8 +223,9 @@
<< ", method_index=0x" << GetMethodIndexAtDepth(i)
<< ")\n";
if (HasDexRegisterMapAtDepth(i)) {
+ StackMapEncoding encoding = code_info.ExtractEncoding();
DexRegisterMap dex_register_map =
- code_info.GetDexRegisterMapAtDepth(i, *this, number_of_dex_registers[i]);
+ code_info.GetDexRegisterMapAtDepth(i, *this, encoding, number_of_dex_registers[i]);
dex_register_map.Dump(indented_os, code_info, number_of_dex_registers[i]);
}
}
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index 7f33e6d..4e42008 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -32,6 +32,7 @@
static constexpr size_t kVRegSize = 4;
class CodeInfo;
+class StackMapEncoding;
/**
* Classes in the following file are wrapper on stack map information backed
@@ -437,26 +438,30 @@
// Get the surface kind of Dex register `dex_register_number`.
DexRegisterLocation::Kind GetLocationKind(uint16_t dex_register_number,
uint16_t number_of_dex_registers,
- const CodeInfo& code_info) const {
+ const CodeInfo& code_info,
+ const StackMapEncoding& enc) const {
return DexRegisterLocation::ConvertToSurfaceKind(
- GetLocationInternalKind(dex_register_number, number_of_dex_registers, code_info));
+ GetLocationInternalKind(dex_register_number, number_of_dex_registers, code_info, enc));
}
// Get the internal kind of Dex register `dex_register_number`.
DexRegisterLocation::Kind GetLocationInternalKind(uint16_t dex_register_number,
uint16_t number_of_dex_registers,
- const CodeInfo& code_info) const;
+ const CodeInfo& code_info,
+ const StackMapEncoding& enc) const;
// Get the Dex register location `dex_register_number`.
DexRegisterLocation GetDexRegisterLocation(uint16_t dex_register_number,
uint16_t number_of_dex_registers,
- const CodeInfo& code_info) const;
+ const CodeInfo& code_info,
+ const StackMapEncoding& enc) const;
int32_t GetStackOffsetInBytes(uint16_t dex_register_number,
uint16_t number_of_dex_registers,
- const CodeInfo& code_info) const {
+ const CodeInfo& code_info,
+ const StackMapEncoding& enc) const {
DexRegisterLocation location =
- GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info);
+ GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info, enc);
DCHECK(location.GetKind() == DexRegisterLocation::Kind::kInStack);
// GetDexRegisterLocation returns the offset in bytes.
return location.GetValue();
@@ -464,9 +469,10 @@
int32_t GetConstant(uint16_t dex_register_number,
uint16_t number_of_dex_registers,
- const CodeInfo& code_info) const {
+ const CodeInfo& code_info,
+ const StackMapEncoding& enc) const {
DexRegisterLocation location =
- GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info);
+ GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info, enc);
DCHECK(location.GetKind() == DexRegisterLocation::Kind::kConstant)
<< DexRegisterLocation::PrettyDescriptor(location.GetKind());
return location.GetValue();
@@ -474,9 +480,10 @@
int32_t GetMachineRegister(uint16_t dex_register_number,
uint16_t number_of_dex_registers,
- const CodeInfo& code_info) const {
+ const CodeInfo& code_info,
+ const StackMapEncoding& enc) const {
DexRegisterLocation location =
- GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info);
+ GetDexRegisterLocation(dex_register_number, number_of_dex_registers, code_info, enc);
DCHECK(location.GetInternalKind() == DexRegisterLocation::Kind::kInRegister
|| location.GetInternalKind() == DexRegisterLocation::Kind::kInFpuRegister)
<< DexRegisterLocation::PrettyDescriptor(location.GetInternalKind());
@@ -628,6 +635,111 @@
friend class StackMapStream;
};
+class StackMapEncoding {
+ public:
+ StackMapEncoding() {}
+
+ StackMapEncoding(size_t stack_mask_size,
+ size_t bytes_for_inline_info,
+ size_t bytes_for_dex_register_map,
+ size_t bytes_for_dex_pc,
+ size_t bytes_for_native_pc,
+ size_t bytes_for_register_mask)
+ : bytes_for_stack_mask_(stack_mask_size),
+ bytes_for_inline_info_(bytes_for_inline_info),
+ bytes_for_dex_register_map_(bytes_for_dex_register_map),
+ bytes_for_dex_pc_(bytes_for_dex_pc),
+ bytes_for_native_pc_(bytes_for_native_pc),
+ bytes_for_register_mask_(bytes_for_register_mask) {}
+
+ static StackMapEncoding CreateFromSizes(size_t stack_mask_size,
+ size_t inline_info_size,
+ size_t dex_register_map_size,
+ size_t dex_pc_max,
+ size_t native_pc_max,
+ size_t register_mask_max) {
+ return StackMapEncoding(
+ stack_mask_size,
+ // + 1 to also encode kNoInlineInfo: if an inline info offset
+ // is at 0xFF, we want to overflow to a larger encoding, because it will
+ // conflict with kNoInlineInfo.
+ // The offset is relative to the dex register map. TODO: Change this.
+ inline_info_size == 0
+ ? 0
+ : EncodingSizeInBytes(dex_register_map_size + inline_info_size + 1),
+ // + 1 to also encode kNoDexRegisterMap: if a dex register map offset
+ // is at 0xFF, we want to overflow to a larger encoding, because it will
+ // conflict with kNoDexRegisterMap.
+ EncodingSizeInBytes(dex_register_map_size + 1),
+ EncodingSizeInBytes(dex_pc_max),
+ EncodingSizeInBytes(native_pc_max),
+ EncodingSizeInBytes(register_mask_max));
+ }
+
+ // Get the size of one stack map of this CodeInfo object, in bytes.
+ // All stack maps of a CodeInfo have the same size.
+ size_t ComputeStackMapSize() const {
+ return bytes_for_register_mask_
+ + bytes_for_stack_mask_
+ + bytes_for_inline_info_
+ + bytes_for_dex_register_map_
+ + bytes_for_dex_pc_
+ + bytes_for_native_pc_;
+ }
+
+ bool HasInlineInfo() const { return bytes_for_inline_info_ > 0; }
+
+ size_t NumberOfBytesForStackMask() const { return bytes_for_stack_mask_; }
+ size_t NumberOfBytesForInlineInfo() const { return bytes_for_inline_info_; }
+ size_t NumberOfBytesForDexRegisterMap() const { return bytes_for_dex_register_map_; }
+ size_t NumberOfBytesForDexPc() const { return bytes_for_dex_pc_; }
+ size_t NumberOfBytesForNativePc() const { return bytes_for_native_pc_; }
+ size_t NumberOfBytesForRegisterMask() const { return bytes_for_register_mask_; }
+
+ size_t ComputeStackMapRegisterMaskOffset() const {
+ return kRegisterMaskOffset;
+ }
+
+ size_t ComputeStackMapStackMaskOffset() const {
+ return ComputeStackMapRegisterMaskOffset() + bytes_for_register_mask_;
+ }
+
+ size_t ComputeStackMapDexPcOffset() const {
+ return ComputeStackMapStackMaskOffset() + bytes_for_stack_mask_;
+ }
+
+ size_t ComputeStackMapNativePcOffset() const {
+ return ComputeStackMapDexPcOffset() + bytes_for_dex_pc_;
+ }
+
+ size_t ComputeStackMapDexRegisterMapOffset() const {
+ return ComputeStackMapNativePcOffset() + bytes_for_native_pc_;
+ }
+
+ size_t ComputeStackMapInlineInfoOffset() const {
+ return ComputeStackMapDexRegisterMapOffset() + bytes_for_dex_register_map_;
+ }
+
+ private:
+ static size_t EncodingSizeInBytes(size_t max_element) {
+ DCHECK(IsUint<32>(max_element));
+ return (max_element == 0) ? 0
+ : IsUint<8>(max_element) ? 1
+ : IsUint<16>(max_element) ? 2
+ : IsUint<24>(max_element) ? 3
+ : 4;
+ }
+
+ static constexpr int kRegisterMaskOffset = 0;
+
+ size_t bytes_for_stack_mask_;
+ size_t bytes_for_inline_info_;
+ size_t bytes_for_dex_register_map_;
+ size_t bytes_for_dex_pc_;
+ size_t bytes_for_native_pc_;
+ size_t bytes_for_register_mask_;
+};
+
/**
* A Stack Map holds compilation information for a specific PC necessary for:
* - Mapping it to a dex PC,
@@ -642,44 +754,82 @@
*/
class StackMap {
public:
- explicit StackMap(MemoryRegion region) : region_(region) {}
StackMap() {}
+ explicit StackMap(MemoryRegion region) : region_(region) {}
bool IsValid() const { return region_.pointer() != nullptr; }
- uint32_t GetDexPc(const CodeInfo& info) const;
+ uint32_t GetDexPc(const StackMapEncoding& encoding) const {
+ return LoadAt(encoding.NumberOfBytesForDexPc(), encoding.ComputeStackMapDexPcOffset());
+ }
- void SetDexPc(const CodeInfo& info, uint32_t dex_pc);
+ void SetDexPc(const StackMapEncoding& encoding, uint32_t dex_pc) {
+ StoreAt(encoding.NumberOfBytesForDexPc(), encoding.ComputeStackMapDexPcOffset(), dex_pc);
+ }
- uint32_t GetNativePcOffset(const CodeInfo& info) const;
+ uint32_t GetNativePcOffset(const StackMapEncoding& encoding) const {
+ return LoadAt(encoding.NumberOfBytesForNativePc(), encoding.ComputeStackMapNativePcOffset());
+ }
- void SetNativePcOffset(const CodeInfo& info, uint32_t native_pc_offset);
+ void SetNativePcOffset(const StackMapEncoding& encoding, uint32_t native_pc_offset) {
+ StoreAt(encoding.NumberOfBytesForNativePc(),
+ encoding.ComputeStackMapNativePcOffset(),
+ native_pc_offset);
+ }
- uint32_t GetDexRegisterMapOffset(const CodeInfo& info) const;
+ uint32_t GetDexRegisterMapOffset(const StackMapEncoding& encoding) const {
+ return LoadAt(encoding.NumberOfBytesForDexRegisterMap(),
+ encoding.ComputeStackMapDexRegisterMapOffset(),
+ /* check_max */ true);
+ }
- void SetDexRegisterMapOffset(const CodeInfo& info, uint32_t offset);
+ void SetDexRegisterMapOffset(const StackMapEncoding& encoding, uint32_t offset) {
+ StoreAt(encoding.NumberOfBytesForDexRegisterMap(),
+ encoding.ComputeStackMapDexRegisterMapOffset(),
+ offset);
+ }
- uint32_t GetInlineDescriptorOffset(const CodeInfo& info) const;
+ uint32_t GetInlineDescriptorOffset(const StackMapEncoding& encoding) const {
+ if (!encoding.HasInlineInfo()) return kNoInlineInfo;
+ return LoadAt(encoding.NumberOfBytesForInlineInfo(),
+ encoding.ComputeStackMapInlineInfoOffset(),
+ /* check_max */ true);
+ }
- void SetInlineDescriptorOffset(const CodeInfo& info, uint32_t offset);
+ void SetInlineDescriptorOffset(const StackMapEncoding& encoding, uint32_t offset) {
+ DCHECK(encoding.HasInlineInfo());
+ StoreAt(encoding.NumberOfBytesForInlineInfo(),
+ encoding.ComputeStackMapInlineInfoOffset(),
+ offset);
+ }
- uint32_t GetRegisterMask(const CodeInfo& info) const;
+ uint32_t GetRegisterMask(const StackMapEncoding& encoding) const {
+ return LoadAt(encoding.NumberOfBytesForRegisterMask(),
+ encoding.ComputeStackMapRegisterMaskOffset());
+ }
- void SetRegisterMask(const CodeInfo& info, uint32_t mask);
+ void SetRegisterMask(const StackMapEncoding& encoding, uint32_t mask) {
+ StoreAt(encoding.NumberOfBytesForRegisterMask(),
+ encoding.ComputeStackMapRegisterMaskOffset(),
+ mask);
+ }
- MemoryRegion GetStackMask(const CodeInfo& info) const;
+ MemoryRegion GetStackMask(const StackMapEncoding& encoding) const {
+ return region_.Subregion(encoding.ComputeStackMapStackMaskOffset(),
+ encoding.NumberOfBytesForStackMask());
+ }
- void SetStackMask(const CodeInfo& info, const BitVector& sp_map) {
- MemoryRegion region = GetStackMask(info);
+ void SetStackMask(const StackMapEncoding& encoding, const BitVector& sp_map) {
+ MemoryRegion region = GetStackMask(encoding);
sp_map.CopyTo(region.start(), region.size());
}
- bool HasDexRegisterMap(const CodeInfo& info) const {
- return GetDexRegisterMapOffset(info) != kNoDexRegisterMap;
+ bool HasDexRegisterMap(const StackMapEncoding& encoding) const {
+ return GetDexRegisterMapOffset(encoding) != kNoDexRegisterMap;
}
- bool HasInlineInfo(const CodeInfo& info) const {
- return GetInlineDescriptorOffset(info) != kNoInlineInfo;
+ bool HasInlineInfo(const StackMapEncoding& encoding) const {
+ return GetInlineDescriptorOffset(encoding) != kNoInlineInfo;
}
bool Equals(const StackMap& other) const {
@@ -687,15 +837,9 @@
&& region_.size() == other.region_.size();
}
- static size_t ComputeStackMapSize(size_t stack_mask_size,
- size_t inline_info_size,
- size_t dex_register_map_size,
- size_t dex_pc_max,
- size_t native_pc_max,
- size_t register_mask_max);
-
void Dump(std::ostream& os,
const CodeInfo& code_info,
+ const StackMapEncoding& encoding,
uint32_t code_offset,
uint16_t number_of_dex_registers,
const std::string& header_suffix = "") const;
@@ -709,21 +853,17 @@
static constexpr uint32_t kNoInlineInfo = -1;
private:
- static size_t ComputeStackMapSizeInternal(size_t stack_mask_size,
- size_t number_of_bytes_for_inline_info,
- size_t number_of_bytes_for_dex_map,
- size_t number_of_bytes_for_dex_pc,
- size_t number_of_bytes_for_native_pc,
- size_t number_of_bytes_for_register_mask);
-
// TODO: Instead of plain types such as "uint32_t", introduce
// typedefs (and document the memory layout of StackMap).
- static constexpr int kRegisterMaskOffset = 0;
static constexpr int kFixedSize = 0;
+ // Loads `number_of_bytes` at the given `offset` and assemble a uint32_t. If `check_max` is true,
+ // this method converts a maximum value of size `number_of_bytes` into a uint32_t 0xFFFFFFFF.
+ uint32_t LoadAt(size_t number_of_bytes, size_t offset, bool check_max = false) const;
+ void StoreAt(size_t number_of_bytes, size_t offset, uint32_t value) const;
+
MemoryRegion region_;
- friend class CodeInfo;
friend class StackMapStream;
};
@@ -827,39 +967,23 @@
region_ = MemoryRegion(const_cast<void*>(data), size);
}
- static size_t EncodingSizeInBytes(size_t max_element) {
- DCHECK(IsUint<32>(max_element));
- return (max_element == 0) ? 0
- : IsUint<8>(max_element) ? 1
- : IsUint<16>(max_element) ? 2
- : IsUint<24>(max_element) ? 3
- : 4;
+ StackMapEncoding ExtractEncoding() const {
+ return StackMapEncoding(region_.LoadUnaligned<uint32_t>(kStackMaskSizeOffset),
+ GetNumberOfBytesForEncoding(kInlineInfoBitOffset),
+ GetNumberOfBytesForEncoding(kDexRegisterMapBitOffset),
+ GetNumberOfBytesForEncoding(kDexPcBitOffset),
+ GetNumberOfBytesForEncoding(kNativePcBitOffset),
+ GetNumberOfBytesForEncoding(kRegisterMaskBitOffset));
}
- void SetEncoding(size_t inline_info_size,
- size_t dex_register_map_size,
- size_t dex_pc_max,
- size_t native_pc_max,
- size_t register_mask_max) {
- if (inline_info_size != 0) {
- region_.StoreBit(kHasInlineInfoBitOffset, 1);
- // + 1 to also encode kNoInlineInfo: if an inline info offset
- // is at 0xFF, we want to overflow to a larger encoding, because it will
- // conflict with kNoInlineInfo.
- // The offset is relative to the dex register map. TODO: Change this.
- SetEncodingAt(kInlineInfoBitOffset,
- EncodingSizeInBytes(dex_register_map_size + inline_info_size + 1));
- } else {
- region_.StoreBit(kHasInlineInfoBitOffset, 0);
- SetEncodingAt(kInlineInfoBitOffset, 0);
- }
- // + 1 to also encode kNoDexRegisterMap: if a dex register map offset
- // is at 0xFF, we want to overflow to a larger encoding, because it will
- // conflict with kNoDexRegisterMap.
- SetEncodingAt(kDexRegisterMapBitOffset, EncodingSizeInBytes(dex_register_map_size + 1));
- SetEncodingAt(kDexPcBitOffset, EncodingSizeInBytes(dex_pc_max));
- SetEncodingAt(kNativePcBitOffset, EncodingSizeInBytes(native_pc_max));
- SetEncodingAt(kRegisterMaskBitOffset, EncodingSizeInBytes(register_mask_max));
+ void SetEncoding(const StackMapEncoding& encoding) {
+ region_.StoreUnaligned<uint32_t>(kStackMaskSizeOffset, encoding.NumberOfBytesForStackMask());
+ region_.StoreBit(kHasInlineInfoBitOffset, encoding.NumberOfBytesForInlineInfo() != 0);
+ SetEncodingAt(kInlineInfoBitOffset, encoding.NumberOfBytesForInlineInfo());
+ SetEncodingAt(kDexRegisterMapBitOffset, encoding.NumberOfBytesForDexRegisterMap());
+ SetEncodingAt(kDexPcBitOffset, encoding.NumberOfBytesForDexPc());
+ SetEncodingAt(kNativePcBitOffset, encoding.NumberOfBytesForNativePc());
+ SetEncodingAt(kRegisterMaskBitOffset, encoding.NumberOfBytesForRegisterMask());
}
void SetEncodingAt(size_t bit_offset, size_t number_of_bytes) {
@@ -880,64 +1004,15 @@
return region_.LoadBit(kHasInlineInfoBitOffset);
}
- size_t NumberOfBytesForInlineInfo() const {
- return GetNumberOfBytesForEncoding(kInlineInfoBitOffset);
- }
-
- size_t NumberOfBytesForDexRegisterMap() const {
- return GetNumberOfBytesForEncoding(kDexRegisterMapBitOffset);
- }
-
- size_t NumberOfBytesForRegisterMask() const {
- return GetNumberOfBytesForEncoding(kRegisterMaskBitOffset);
- }
-
- size_t NumberOfBytesForNativePc() const {
- return GetNumberOfBytesForEncoding(kNativePcBitOffset);
- }
-
- size_t NumberOfBytesForDexPc() const {
- return GetNumberOfBytesForEncoding(kDexPcBitOffset);
- }
-
- size_t ComputeStackMapRegisterMaskOffset() const {
- return StackMap::kRegisterMaskOffset;
- }
-
- size_t ComputeStackMapStackMaskOffset() const {
- return ComputeStackMapRegisterMaskOffset()
- + (NumberOfBytesForRegisterMask() * sizeof(uint8_t));
- }
-
- size_t ComputeStackMapDexPcOffset() const {
- return ComputeStackMapStackMaskOffset() + GetStackMaskSize();
- }
-
- size_t ComputeStackMapNativePcOffset() const {
- return ComputeStackMapDexPcOffset()
- + (NumberOfBytesForDexPc() * sizeof(uint8_t));
- }
-
- size_t ComputeStackMapDexRegisterMapOffset() const {
- return ComputeStackMapNativePcOffset()
- + (NumberOfBytesForNativePc() * sizeof(uint8_t));
- }
-
- size_t ComputeStackMapInlineInfoOffset() const {
- CHECK(HasInlineInfo());
- return ComputeStackMapDexRegisterMapOffset()
- + (NumberOfBytesForDexRegisterMap() * sizeof(uint8_t));
- }
-
- DexRegisterLocationCatalog GetDexRegisterLocationCatalog() const {
+ DexRegisterLocationCatalog GetDexRegisterLocationCatalog(const StackMapEncoding& encoding) const {
return DexRegisterLocationCatalog(region_.Subregion(
- GetDexRegisterLocationCatalogOffset(),
- GetDexRegisterLocationCatalogSize()));
+ GetDexRegisterLocationCatalogOffset(encoding),
+ GetDexRegisterLocationCatalogSize(encoding)));
}
- StackMap GetStackMapAt(size_t i) const {
- size_t size = StackMapSize();
- return StackMap(GetStackMaps().Subregion(i * size, size));
+ StackMap GetStackMapAt(size_t i, const StackMapEncoding& encoding) const {
+ size_t stack_map_size = encoding.ComputeStackMapSize();
+ return StackMap(GetStackMaps(encoding).Subregion(i * stack_map_size, stack_map_size));
}
uint32_t GetOverallSize() const {
@@ -956,19 +1031,11 @@
region_.StoreUnaligned<uint32_t>(kNumberOfDexRegisterLocationCatalogEntriesOffset, num_entries);
}
- uint32_t GetDexRegisterLocationCatalogSize() const {
- return ComputeDexRegisterLocationCatalogSize(GetDexRegisterLocationCatalogOffset(),
+ uint32_t GetDexRegisterLocationCatalogSize(const StackMapEncoding& encoding) const {
+ return ComputeDexRegisterLocationCatalogSize(GetDexRegisterLocationCatalogOffset(encoding),
GetNumberOfDexRegisterLocationCatalogEntries());
}
- uint32_t GetStackMaskSize() const {
- return region_.LoadUnaligned<uint32_t>(kStackMaskSizeOffset);
- }
-
- void SetStackMaskSize(uint32_t size) {
- region_.StoreUnaligned<uint32_t>(kStackMaskSizeOffset, size);
- }
-
size_t GetNumberOfStackMaps() const {
return region_.LoadUnaligned<uint32_t>(kNumberOfStackMapsOffset);
}
@@ -977,37 +1044,30 @@
region_.StoreUnaligned<uint32_t>(kNumberOfStackMapsOffset, number_of_stack_maps);
}
- // Get the size of one stack map of this CodeInfo object, in bytes.
- // All stack maps of a CodeInfo have the same size.
- size_t StackMapSize() const {
- return StackMap::ComputeStackMapSizeInternal(GetStackMaskSize(),
- NumberOfBytesForInlineInfo(),
- NumberOfBytesForDexRegisterMap(),
- NumberOfBytesForDexPc(),
- NumberOfBytesForNativePc(),
- NumberOfBytesForRegisterMask());
- }
-
// Get the size all the stack maps of this CodeInfo object, in bytes.
- size_t GetStackMapsSize() const {
- return StackMapSize() * GetNumberOfStackMaps();
+ size_t GetStackMapsSize(const StackMapEncoding& encoding) const {
+ return encoding.ComputeStackMapSize() * GetNumberOfStackMaps();
}
- uint32_t GetDexRegisterLocationCatalogOffset() const {
- return GetStackMapsOffset() + GetStackMapsSize();
+ uint32_t GetDexRegisterLocationCatalogOffset(const StackMapEncoding& encoding) const {
+ return GetStackMapsOffset() + GetStackMapsSize(encoding);
}
- size_t GetDexRegisterMapsOffset() const {
- return GetDexRegisterLocationCatalogOffset() + GetDexRegisterLocationCatalogSize();
+ size_t GetDexRegisterMapsOffset(const StackMapEncoding& encoding) const {
+ return GetDexRegisterLocationCatalogOffset(encoding)
+ + GetDexRegisterLocationCatalogSize(encoding);
}
uint32_t GetStackMapsOffset() const {
return kFixedSize;
}
- DexRegisterMap GetDexRegisterMapOf(StackMap stack_map, uint32_t number_of_dex_registers) const {
- DCHECK(stack_map.HasDexRegisterMap(*this));
- uint32_t offset = GetDexRegisterMapsOffset() + stack_map.GetDexRegisterMapOffset(*this);
+ DexRegisterMap GetDexRegisterMapOf(StackMap stack_map,
+ const StackMapEncoding& encoding,
+ uint32_t number_of_dex_registers) const {
+ DCHECK(stack_map.HasDexRegisterMap(encoding));
+ uint32_t offset = GetDexRegisterMapsOffset(encoding)
+ + stack_map.GetDexRegisterMapOffset(encoding);
size_t size = ComputeDexRegisterMapSizeOf(offset, number_of_dex_registers);
return DexRegisterMap(region_.Subregion(offset, size));
}
@@ -1015,37 +1075,40 @@
// Return the `DexRegisterMap` pointed by `inline_info` at depth `depth`.
DexRegisterMap GetDexRegisterMapAtDepth(uint8_t depth,
InlineInfo inline_info,
+ const StackMapEncoding& encoding,
uint32_t number_of_dex_registers) const {
DCHECK(inline_info.HasDexRegisterMapAtDepth(depth));
- uint32_t offset =
- GetDexRegisterMapsOffset() + inline_info.GetDexRegisterMapOffsetAtDepth(depth);
+ uint32_t offset = GetDexRegisterMapsOffset(encoding)
+ + 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();
+ InlineInfo GetInlineInfoOf(StackMap stack_map, const StackMapEncoding& encoding) const {
+ DCHECK(stack_map.HasInlineInfo(encoding));
+ uint32_t offset = stack_map.GetInlineDescriptorOffset(encoding)
+ + GetDexRegisterMapsOffset(encoding);
uint8_t depth = region_.LoadUnaligned<uint8_t>(offset);
return InlineInfo(region_.Subregion(offset,
InlineInfo::kFixedSize + depth * InlineInfo::SingleEntrySize()));
}
- StackMap GetStackMapForDexPc(uint32_t dex_pc) const {
+ StackMap GetStackMapForDexPc(uint32_t dex_pc, const StackMapEncoding& encoding) const {
for (size_t i = 0, e = GetNumberOfStackMaps(); i < e; ++i) {
- StackMap stack_map = GetStackMapAt(i);
- if (stack_map.GetDexPc(*this) == dex_pc) {
+ StackMap stack_map = GetStackMapAt(i, encoding);
+ if (stack_map.GetDexPc(encoding) == dex_pc) {
return stack_map;
}
}
return StackMap();
}
- StackMap GetStackMapForNativePcOffset(uint32_t native_pc_offset) const {
+ StackMap GetStackMapForNativePcOffset(uint32_t native_pc_offset,
+ const StackMapEncoding& encoding) const {
// TODO: stack maps are sorted by native pc, we can do a binary search.
for (size_t i = 0, e = GetNumberOfStackMaps(); i < e; ++i) {
- StackMap stack_map = GetStackMapAt(i);
- if (stack_map.GetNativePcOffset(*this) == native_pc_offset) {
+ StackMap stack_map = GetStackMapAt(i, encoding);
+ if (stack_map.GetNativePcOffset(encoding) == native_pc_offset) {
return stack_map;
}
}
@@ -1081,10 +1144,10 @@
static constexpr int kNativePcBitOffset = kDexPcBitOffset + 3;
static constexpr int kRegisterMaskBitOffset = kNativePcBitOffset + 3;
- MemoryRegion GetStackMaps() const {
+ MemoryRegion GetStackMaps(const StackMapEncoding& encoding) const {
return region_.size() == 0
? MemoryRegion()
- : region_.Subregion(GetStackMapsOffset(), GetStackMapsSize());
+ : region_.Subregion(GetStackMapsOffset(), GetStackMapsSize(encoding));
}
// Compute the size of the Dex register map associated to the stack map at
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 67f611e..4203b96 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2273,9 +2273,10 @@
const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(m, sizeof(void*));
uintptr_t native_pc_offset = m->NativeQuickPcOffset(GetCurrentQuickFramePc(), entry_point);
CodeInfo code_info = m->GetOptimizedCodeInfo();
- StackMap map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+ StackMapEncoding encoding = code_info.ExtractEncoding();
+ StackMap map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding);
DCHECK(map.IsValid());
- MemoryRegion mask = map.GetStackMask(code_info);
+ MemoryRegion mask = map.GetStackMask(encoding);
// Visit stack entries that hold pointers.
for (size_t i = 0; i < mask.size_in_bits(); ++i) {
if (mask.LoadBit(i)) {
@@ -2291,7 +2292,7 @@
}
}
// Visit callee-save registers that hold pointers.
- uint32_t register_mask = map.GetRegisterMask(code_info);
+ uint32_t register_mask = map.GetRegisterMask(encoding);
for (size_t i = 0; i < BitSizeOf<uint32_t>(); ++i) {
if (register_mask & (1 << i)) {
mirror::Object** ref_addr = reinterpret_cast<mirror::Object**>(GetGPRAddress(i));