Don't encode a DexRegisterMap if there is no live register.
Change-Id: I76a291e6a0ac37f0590d16c7f5b866115588bc55
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc
index c60a4ea..4784de1 100644
--- a/compiler/optimizing/stack_map_stream.cc
+++ b/compiler/optimizing/stack_map_stream.cc
@@ -270,7 +270,7 @@
stack_map.SetStackMask(stack_map_encoding_, *entry.sp_mask);
}
- if (entry.num_dex_registers == 0) {
+ if (entry.num_dex_registers == 0 || (entry.live_dex_registers_mask->NumSetBits() == 0)) {
// No dex map available.
stack_map.SetDexRegisterMapOffset(stack_map_encoding_, StackMap::kNoDexRegisterMap);
} else {
diff --git a/compiler/optimizing/stack_map_test.cc b/compiler/optimizing/stack_map_test.cc
index 560502f..604787f 100644
--- a/compiler/optimizing/stack_map_test.cc
+++ b/compiler/optimizing/stack_map_test.cc
@@ -614,6 +614,10 @@
stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask, number_of_dex_registers, 0);
stream.EndStackMapEntry();
+ number_of_dex_registers = 1;
+ stream.BeginStackMapEntry(1, 67, 0x4, &sp_mask, number_of_dex_registers, 0);
+ stream.EndStackMapEntry();
+
size_t size = stream.PrepareForFillIn();
void* memory = arena.Alloc(size, kArenaAllocMisc);
MemoryRegion region(memory, size);
@@ -622,7 +626,7 @@
CodeInfo code_info(region);
StackMapEncoding encoding = code_info.ExtractEncoding();
ASSERT_EQ(0u, encoding.NumberOfBytesForStackMask());
- ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
+ ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
uint32_t number_of_location_catalog_entries = code_info.GetNumberOfLocationCatalogEntries();
ASSERT_EQ(0u, number_of_location_catalog_entries);
@@ -638,6 +642,16 @@
ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding));
ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
+
+ stack_map = code_info.GetStackMapAt(1, encoding);
+ ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1, encoding)));
+ ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(67, encoding)));
+ ASSERT_EQ(1u, stack_map.GetDexPc(encoding));
+ ASSERT_EQ(67u, stack_map.GetNativePcOffset(encoding));
+ ASSERT_EQ(0x4u, stack_map.GetRegisterMask(encoding));
+
+ ASSERT_FALSE(stack_map.HasDexRegisterMap(encoding));
+ ASSERT_FALSE(stack_map.HasInlineInfo(encoding));
}
TEST(StackMapTest, InlineTest) {
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 9cb37ee..786cf06 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -221,18 +221,22 @@
CodeInfo code_info = handler_method_header_->GetOptimizedCodeInfo();
StackMapEncoding encoding = code_info.ExtractEncoding();
+ // Find stack map of the catch block.
+ StackMap catch_stack_map = code_info.GetCatchStackMapForDexPc(GetHandlerDexPc(), encoding);
+ DCHECK(catch_stack_map.IsValid());
+ DexRegisterMap catch_vreg_map =
+ code_info.GetDexRegisterMapOf(catch_stack_map, encoding, number_of_vregs);
+ if (!catch_vreg_map.IsValid()) {
+ return;
+ }
+
// Find stack map of the throwing instruction.
StackMap throw_stack_map =
code_info.GetStackMapForNativePcOffset(stack_visitor->GetNativePcOffset(), encoding);
DCHECK(throw_stack_map.IsValid());
DexRegisterMap throw_vreg_map =
code_info.GetDexRegisterMapOf(throw_stack_map, encoding, number_of_vregs);
-
- // Find stack map of the catch block.
- StackMap catch_stack_map = code_info.GetCatchStackMapForDexPc(GetHandlerDexPc(), encoding);
- DCHECK(catch_stack_map.IsValid());
- DexRegisterMap catch_vreg_map =
- code_info.GetDexRegisterMapOf(catch_stack_map, encoding, number_of_vregs);
+ DCHECK(throw_vreg_map.IsValid());
// Copy values between them.
for (uint16_t vreg = 0; vreg < number_of_vregs; ++vreg) {
@@ -387,6 +391,10 @@
number_of_vregs)
: code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_vregs);
+ if (!vreg_map.IsValid()) {
+ return;
+ }
+
for (uint16_t vreg = 0; vreg < number_of_vregs; ++vreg) {
if (updated_vregs != nullptr && updated_vregs[vreg]) {
// Keep the value set by debugger.
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 9098d38..5faff93 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -322,6 +322,9 @@
number_of_dex_registers)
: code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers);
+ if (!dex_register_map.IsValid()) {
+ return false;
+ }
DexRegisterLocation::Kind location_kind =
dex_register_map.GetLocationKind(vreg, number_of_dex_registers, code_info, encoding);
switch (location_kind) {
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index a15a081..aa23998 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -473,6 +473,9 @@
class DexRegisterMap {
public:
explicit DexRegisterMap(MemoryRegion region) : region_(region) {}
+ DexRegisterMap() {}
+
+ bool IsValid() const { return region_.pointer() != nullptr; }
// Get the surface kind of Dex register `dex_register_number`.
DexRegisterLocation::Kind GetLocationKind(uint16_t dex_register_number,
@@ -1136,11 +1139,15 @@
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));
+
+ if (!stack_map.HasDexRegisterMap(encoding)) {
+ return DexRegisterMap();
+ } else {
+ uint32_t offset = GetDexRegisterMapsOffset(encoding)
+ + stack_map.GetDexRegisterMapOffset(encoding);
+ size_t size = ComputeDexRegisterMapSizeOf(offset, number_of_dex_registers);
+ return DexRegisterMap(region_.Subregion(offset, size));
+ }
}
// Return the `DexRegisterMap` pointed by `inline_info` at depth `depth`.
@@ -1148,11 +1155,14 @@
InlineInfo inline_info,
const StackMapEncoding& encoding,
uint32_t number_of_dex_registers) const {
- DCHECK(inline_info.HasDexRegisterMapAtDepth(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));
+ if (!inline_info.HasDexRegisterMapAtDepth(depth)) {
+ return DexRegisterMap();
+ } else {
+ 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 StackMapEncoding& encoding) const {