Add way to disable resolving for stack walk
Only occurs for walking the inlined frames case.
Bug: 27857910
(cherry picked from commit be2892bf771435eb451c74297b553f7dc9fea4ca)
Change-Id: Ied92be96f2f74ba02c02168f704443b95e7a4b04
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 5344cdd..116261b 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -39,6 +39,7 @@
namespace art {
+template <bool kResolve = true>
inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method,
const InlineInfo& inline_info,
uint8_t inlining_depth)
@@ -50,6 +51,9 @@
if (!caller->IsRuntimeMethod()) {
return caller;
}
+ if (!kResolve) {
+ return nullptr;
+ }
// The method in the dex cache can be the runtime method responsible for invoking
// the stub that will then update the dex cache. Therefore, we need to do the
@@ -64,7 +68,7 @@
if (inlining_depth == 0) {
class_loader.Assign(outer_method->GetClassLoader());
} else {
- caller = GetResolvedMethod(outer_method, inline_info, inlining_depth - 1);
+ caller = GetResolvedMethod<kResolve>(outer_method, inline_info, inlining_depth - 1);
class_loader.Assign(caller->GetClassLoader());
}
diff --git a/runtime/gc/allocation_record.cc b/runtime/gc/allocation_record.cc
index 44059b1..bd023b3 100644
--- a/runtime/gc/allocation_record.cc
+++ b/runtime/gc/allocation_record.cc
@@ -187,7 +187,7 @@
public:
AllocRecordStackVisitor(Thread* thread, size_t max_depth, AllocRecordStackTrace* trace_out)
SHARED_REQUIRES(Locks::mutator_lock_)
- : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
+ : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFramesNoResolve),
max_depth_(max_depth),
trace_(trace_out) {}
@@ -198,7 +198,8 @@
return false;
}
ArtMethod* m = GetMethod();
- if (!m->IsRuntimeMethod()) {
+ // m may be null if we have inlined methods of unresolved classes. b/27858645
+ if (m != nullptr && !m->IsRuntimeMethod()) {
m = m->GetInterfaceMethodIfProxy(sizeof(void*));
trace_->AddStackElement(AllocRecordStackTraceElement(m, GetDexPc()));
}
diff --git a/runtime/stack.cc b/runtime/stack.cc
index ee5da8e..57ce07d 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -130,7 +130,11 @@
if (IsInInlinedFrame()) {
size_t depth_in_stack_map = current_inlining_depth_ - 1;
InlineInfo inline_info = GetCurrentInlineInfo();
- return GetResolvedMethod(*GetCurrentQuickFrame(), inline_info, depth_in_stack_map);
+ 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);
} else {
return *cur_quick_frame_;
}
@@ -859,7 +863,8 @@
cur_oat_quick_method_header_ = method->GetOatQuickMethodHeader(cur_quick_frame_pc_);
SanityCheckFrame();
- if ((walk_kind_ == StackWalkKind::kIncludeInlinedFrames)
+ if ((walk_kind_ == StackWalkKind::kIncludeInlinedFrames ||
+ walk_kind_ == StackWalkKind::kIncludeInlinedFramesNoResolve)
&& (cur_oat_quick_method_header_ != nullptr)
&& cur_oat_quick_method_header_->IsOptimized()) {
CodeInfo code_info = cur_oat_quick_method_header_->GetOptimizedCodeInfo();
diff --git a/runtime/stack.h b/runtime/stack.h
index ec653e7..a25874e 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -595,6 +595,7 @@
// when walking the stack.
enum class StackWalkKind {
kIncludeInlinedFrames,
+ kIncludeInlinedFramesNoResolve,
kSkipInlinedFrames,
};