diff options
author | 2015-05-22 14:01:33 +0100 | |
---|---|---|
committer | 2015-05-22 14:01:33 +0100 | |
commit | e12997fbce8e22431be58cac9db2535f7b4a7ac3 (patch) | |
tree | ae167aa833e1ef249d121b179c95827fa4e7ec6c | |
parent | aa49c23d47e5fdfcf51380550ee864e9d30d082b (diff) |
Return an invalid StackMap when one cannot be found.
This avoids aborting when handling a crash.
Change-Id: Ie5b5d48061fa9258b349b0284f7b00c5855d9fbd
-rw-r--r-- | runtime/mirror/art_method.cc | 47 | ||||
-rw-r--r-- | runtime/stack.cc | 4 | ||||
-rw-r--r-- | runtime/stack_map.h | 9 | ||||
-rw-r--r-- | runtime/thread.cc | 1 |
4 files changed, 34 insertions, 27 deletions
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc index 9518c9d797..079a231d92 100644 --- a/runtime/mirror/art_method.cc +++ b/runtime/mirror/art_method.cc @@ -201,29 +201,32 @@ uint32_t ArtMethod::ToDexPc(const uintptr_t pc, bool abort_on_failure) { 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 6795516c83..f7b96eaf2e 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -109,6 +109,7 @@ InlineInfo StackVisitor::GetCurrentInlineInfo() const SHARED_LOCKS_REQUIRED(Lock 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 @@ bool StackVisitor::GetVRegFromOptimizedCode(mirror::ArtMethod* m, uint16_t vreg, 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 @@ void StackVisitor::WalkStack(bool include_transitions) { 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 f07fb74eb4..f710460d0f 100644 --- a/runtime/stack_map.h +++ b/runtime/stack_map.h @@ -641,6 +641,9 @@ class DexRegisterMap { 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 @@ class CodeInfo { return stack_map; } } - LOG(FATAL) << "Unreachable"; - UNREACHABLE(); + return StackMap(); } StackMap GetStackMapForNativePcOffset(uint32_t native_pc_offset) const { @@ -1041,8 +1043,7 @@ class CodeInfo { 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 2145c9c963..9b1600f7c7 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -2248,6 +2248,7 @@ class ReferenceMapVisitor : public StackVisitor { 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) { |