namespace art {
+template <bool kResolve = true>
inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method,
const InlineInfo& inline_info,
uint8_t inlining_depth)
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
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());
}
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) {}
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()));
}
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_;
}
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();
// when walking the stack.
enum class StackWalkKind {
kIncludeInlinedFrames,
+ kIncludeInlinedFramesNoResolve,
kSkipInlinedFrames,
};