Return an invalid StackMap when one cannot be found.
This avoids aborting when handling a crash.
Change-Id: Ie5b5d48061fa9258b349b0284f7b00c5855d9fbd
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index 9518c9d..079a231 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -201,29 +201,32 @@
uint32_t sought_offset = pc - reinterpret_cast<uintptr_t>(entry_point);
if (IsOptimized(sizeof(void*))) {
CodeInfo code_info = GetOptimizedCodeInfo();
- return code_info.GetStackMapForNativePcOffset(sought_offset).GetDexPc(code_info);
- }
-
- MappingTable table(entry_point != nullptr ?
- GetMappingTable(EntryPointToCodePointer(entry_point), sizeof(void*)) : nullptr);
- if (table.TotalSize() == 0) {
- // NOTE: Special methods (see Mir2Lir::GenSpecialCase()) have an empty mapping
- // but they have no suspend checks and, consequently, we never call ToDexPc() for them.
- DCHECK(IsNative() || IsCalleeSaveMethod() || IsProxyMethod()) << PrettyMethod(this);
- return DexFile::kDexNoIndex; // Special no mapping case
- }
- // Assume the caller wants a pc-to-dex mapping so check here first.
- typedef MappingTable::PcToDexIterator It;
- for (It cur = table.PcToDexBegin(), end = table.PcToDexEnd(); cur != end; ++cur) {
- if (cur.NativePcOffset() == sought_offset) {
- return cur.DexPc();
+ StackMap stack_map = code_info.GetStackMapForNativePcOffset(sought_offset);
+ if (stack_map.IsValid()) {
+ return stack_map.GetDexPc(code_info);
}
- }
- // Now check dex-to-pc mappings.
- typedef MappingTable::DexToPcIterator It2;
- for (It2 cur = table.DexToPcBegin(), end = table.DexToPcEnd(); cur != end; ++cur) {
- if (cur.NativePcOffset() == sought_offset) {
- return cur.DexPc();
+ } else {
+ MappingTable table(entry_point != nullptr ?
+ GetMappingTable(EntryPointToCodePointer(entry_point), sizeof(void*)) : nullptr);
+ if (table.TotalSize() == 0) {
+ // NOTE: Special methods (see Mir2Lir::GenSpecialCase()) have an empty mapping
+ // but they have no suspend checks and, consequently, we never call ToDexPc() for them.
+ DCHECK(IsNative() || IsCalleeSaveMethod() || IsProxyMethod()) << PrettyMethod(this);
+ return DexFile::kDexNoIndex; // Special no mapping case
+ }
+ // Assume the caller wants a pc-to-dex mapping so check here first.
+ typedef MappingTable::PcToDexIterator It;
+ for (It cur = table.PcToDexBegin(), end = table.PcToDexEnd(); cur != end; ++cur) {
+ if (cur.NativePcOffset() == sought_offset) {
+ return cur.DexPc();
+ }
+ }
+ // Now check dex-to-pc mappings.
+ typedef MappingTable::DexToPcIterator It2;
+ for (It2 cur = table.DexToPcBegin(), end = table.DexToPcEnd(); cur != end; ++cur) {
+ if (cur.NativePcOffset() == sought_offset) {
+ return cur.DexPc();
+ }
}
}
if (abort_on_failure) {
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 6795516..f7b96ea 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -109,6 +109,7 @@
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);
+ DCHECK(stack_map.IsValid());
return code_info.GetInlineInfoOf(stack_map);
}
@@ -269,6 +270,7 @@
uint32_t native_pc_offset = outer_method->NativeQuickPcOffset(cur_quick_frame_pc_);
StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+ DCHECK(stack_map.IsValid());
size_t depth_in_stack_map = current_inlining_depth_ - 1;
DexRegisterMap dex_register_map = IsInInlinedFrame()
@@ -749,7 +751,7 @@
CodeInfo code_info = method->GetOptimizedCodeInfo();
uint32_t native_pc_offset = method->NativeQuickPcOffset(cur_quick_frame_pc_);
StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
- if (stack_map.HasInlineInfo(code_info)) {
+ if (stack_map.IsValid() && stack_map.HasInlineInfo(code_info)) {
InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
DCHECK_EQ(current_inlining_depth_, 0u);
for (current_inlining_depth_ = inline_info.GetDepth();
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index f07fb74..f710460 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -641,6 +641,9 @@
class StackMap {
public:
explicit StackMap(MemoryRegion region) : region_(region) {}
+ StackMap() {}
+
+ bool IsValid() const { return region_.pointer() != nullptr; }
uint32_t GetDexPc(const CodeInfo& info) const;
@@ -1029,8 +1032,7 @@
return stack_map;
}
}
- LOG(FATAL) << "Unreachable";
- UNREACHABLE();
+ return StackMap();
}
StackMap GetStackMapForNativePcOffset(uint32_t native_pc_offset) const {
@@ -1041,8 +1043,7 @@
return stack_map;
}
}
- LOG(FATAL) << "Unreachable";
- UNREACHABLE();
+ return StackMap();
}
void Dump(std::ostream& os, uint16_t number_of_dex_registers) const;
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 2145c9c..9b1600f 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2248,6 +2248,7 @@
uintptr_t native_pc_offset = m->NativeQuickPcOffset(GetCurrentQuickFramePc(), entry_point);
CodeInfo code_info = m->GetOptimizedCodeInfo();
StackMap map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
+ DCHECK(map.IsValid());
MemoryRegion mask = map.GetStackMask(code_info);
// Visit stack entries that hold pointers.
for (size_t i = 0; i < mask.size_in_bits(); ++i) {