OSDN Git Service

Add way to disable resolving for stack walk
authorMathieu Chartier <mathieuc@google.com>
Thu, 31 Mar 2016 18:07:09 +0000 (11:07 -0700)
committerMathieu Chartier <mathieuc@google.com>
Thu, 31 Mar 2016 21:00:44 +0000 (14:00 -0700)
Only occurs for walking the inlined frames case.

Bug: 27857910

Change-Id: Idb90254879ebae4c756ee1a3d235999ae589a2a8

runtime/entrypoints/entrypoint_utils-inl.h
runtime/gc/allocation_record.cc
runtime/stack.cc
runtime/stack.h

index 5344cdd..116261b 100644 (file)
@@ -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 @@ inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method,
   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 @@ inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method,
   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());
   }
 
index 44059b1..bd023b3 100644 (file)
@@ -187,7 +187,7 @@ class AllocRecordStackVisitor : public StackVisitor {
  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 @@ class AllocRecordStackVisitor : public StackVisitor {
       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()));
     }
index ee5da8e..57ce07d 100644 (file)
@@ -130,7 +130,11 @@ ArtMethod* StackVisitor::GetMethod() const {
     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 @@ void StackVisitor::WalkStack(bool include_transitions) {
         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();
index 4fa1a4f..3659560 100644 (file)
@@ -569,6 +569,7 @@ class StackVisitor {
   // when walking the stack.
   enum class StackWalkKind {
     kIncludeInlinedFrames,
+    kIncludeInlinedFramesNoResolve,
     kSkipInlinedFrames,
   };