Merge "Fix instrumentation frame check with inlining"
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index deada4c..432119e7 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -960,6 +960,15 @@
   }
 }
 
+// Computes a frame ID by ignoring inlined frames.
+size_t Instrumentation::ComputeFrameId(Thread* self,
+                                       size_t frame_depth,
+                                       size_t inlined_frames_before_frame) {
+  CHECK_GT(frame_depth, inlined_frames_before_frame);
+  size_t no_inline_depth = frame_depth - inlined_frames_before_frame;
+  return StackVisitor::ComputeNumFrames(self, kInstrumentationStackWalk) - no_inline_depth;
+}
+
 static void CheckStackDepth(Thread* self, const InstrumentationStackFrame& instrumentation_frame,
                             int delta)
     SHARED_REQUIRES(Locks::mutator_lock_) {
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index 612ca14..8dd2357 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -397,6 +397,11 @@
       SHARED_REQUIRES(Locks::mutator_lock_)
       REQUIRES(!Locks::thread_list_lock_);
 
+  static size_t ComputeFrameId(Thread* self,
+                               size_t frame_depth,
+                               size_t inlined_frames_before_frame)
+      SHARED_REQUIRES(Locks::mutator_lock_);
+
  private:
   InstrumentationLevel GetCurrentInstrumentationLevel() const;
 
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 1d21a64..840c0cb 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -891,6 +891,7 @@
   CHECK_EQ(cur_depth_, 0U);
   bool exit_stubs_installed = Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled();
   uint32_t instrumentation_stack_depth = 0;
+  size_t inlined_frames_count = 0;
 
   for (const ManagedStack* current_fragment = thread_->GetManagedStack();
        current_fragment != nullptr; current_fragment = current_fragment->GetLink()) {
@@ -922,6 +923,7 @@
                 return;
               }
               cur_depth_++;
+              inlined_frames_count++;
             }
           }
         }
@@ -952,16 +954,19 @@
               ArtMethod* callee = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs);
               CHECK_EQ(GetMethod(), callee) << "Expected: " << PrettyMethod(callee) << " Found: "
                                             << PrettyMethod(GetMethod());
-            } else if (instrumentation_frame.method_ != GetMethod()) {
-              LOG(FATAL)  << "Expected: " << PrettyMethod(instrumentation_frame.method_)
-                          << " Found: " << PrettyMethod(GetMethod());
+            } else {
+              CHECK_EQ(instrumentation_frame.method_, GetMethod())
+                  << "Expected: " << PrettyMethod(instrumentation_frame.method_)
+                  << " Found: " << PrettyMethod(GetMethod());
             }
             if (num_frames_ != 0) {
               // Check agreement of frame Ids only if num_frames_ is computed to avoid infinite
               // recursion.
-              CHECK(instrumentation_frame.frame_id_ == GetFrameId())
-                    << "Expected: " << instrumentation_frame.frame_id_
-                    << " Found: " << GetFrameId();
+              size_t frame_id = instrumentation::Instrumentation::ComputeFrameId(
+                  thread_,
+                  cur_depth_,
+                  inlined_frames_count);
+              CHECK_EQ(instrumentation_frame.frame_id_, frame_id);
             }
             return_pc = instrumentation_frame.return_pc_;
           }