Merge "Add marks for instrumentation frames that get interpreted." into dalvik-dev
diff --git a/src/instrumentation.cc b/src/instrumentation.cc
index 8af0885..f36cb8c 100644
--- a/src/instrumentation.cc
+++ b/src/instrumentation.cc
@@ -131,7 +131,8 @@
       uintptr_t return_pc = GetReturnPc();
       CHECK_NE(return_pc, instrumentation_exit_pc_);
       CHECK_NE(return_pc, 0U);
-      InstrumentationStackFrame instrumentation_frame(GetThisObject(), m, return_pc, GetFrameId());
+      InstrumentationStackFrame instrumentation_frame(GetThisObject(), m, return_pc, GetFrameId(),
+                                                      false);
       if (kVerboseInstrumentation) {
         LOG(INFO) << "Pushing frame " << instrumentation_frame.Dump();
       }
@@ -209,7 +210,11 @@
           if (kVerboseInstrumentation) {
             LOG(INFO) << "  Removing exit stub in " << DescribeLocation();
           }
-          CHECK(m == instrumentation_frame.method_) << PrettyMethod(m);
+          if (instrumentation_frame.interpreter_entry_) {
+            CHECK(m == Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs));
+          } else {
+            CHECK(m == instrumentation_frame.method_) << PrettyMethod(m);
+          }
           SetReturnPc(instrumentation_frame.return_pc_);
           // Create the method exit events. As the methods didn't really exit the result is 0.
           instrumentation_->MethodExitEvent(thread_, instrumentation_frame.this_object_, m,
@@ -222,7 +227,6 @@
       if (!removed_stub) {
         if (kVerboseInstrumentation) {
           LOG(INFO) << "  No exit stub in " << DescribeLocation();
-          DescribeStack(thread_);
         }
       }
       return true;  // Continue.
@@ -463,7 +467,7 @@
 
 void Instrumentation::PushInstrumentationStackFrame(Thread* self, mirror::Object* this_object,
                                                     mirror::AbstractMethod* method,
-                                                    uintptr_t lr) {
+                                                    uintptr_t lr, bool interpreter_entry) {
   // We have a callee-save frame meaning this value is guaranteed to never be 0.
   size_t frame_id = StackVisitor::ComputeNumFrames(self);
   std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
@@ -471,7 +475,7 @@
     LOG(INFO) << "Entering " << PrettyMethod(method) << " from PC " << (void*)lr;
   }
   instrumentation::InstrumentationStackFrame instrumentation_frame(this_object, method, lr,
-                                                                   frame_id);
+                                                                   frame_id, interpreter_entry);
   stack->push_front(instrumentation_frame);
 
   MethodEnterEvent(self, this_object, method, 0);
diff --git a/src/instrumentation.h b/src/instrumentation.h
index e79c75e..5fea34f 100644
--- a/src/instrumentation.h
+++ b/src/instrumentation.h
@@ -192,7 +192,8 @@
   // Called when an instrumented method is entered. The intended link register (lr) is saved so
   // that returning causes a branch to the method exit stub. Generates method enter events.
   void PushInstrumentationStackFrame(Thread* self, mirror::Object* this_object,
-                                     mirror::AbstractMethod* method, uintptr_t lr)
+                                     mirror::AbstractMethod* method, uintptr_t lr,
+                                     bool interpreter_entry)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Called when an instrumented method is exited. Removes the pushed instrumentation frame
@@ -272,8 +273,9 @@
 // An element in the instrumentation side stack maintained in art::Thread.
 struct InstrumentationStackFrame {
   InstrumentationStackFrame(mirror::Object* this_object, mirror::AbstractMethod* method,
-                            uintptr_t return_pc, size_t frame_id)
-      : this_object_(this_object), method_(method), return_pc_(return_pc), frame_id_(frame_id) {
+                            uintptr_t return_pc, size_t frame_id, bool interpreter_entry)
+      : this_object_(this_object), method_(method), return_pc_(return_pc), frame_id_(frame_id),
+        interpreter_entry_(interpreter_entry) {
   }
 
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -282,6 +284,7 @@
   mirror::AbstractMethod* method_;
   const uintptr_t return_pc_;
   const size_t frame_id_;
+  bool interpreter_entry_;
 };
 
 }  // namespace instrumentation
diff --git a/src/oat/runtime/support_instrumentation.cc b/src/oat/runtime/support_instrumentation.cc
index 8f56ce3..1f1b952 100644
--- a/src/oat/runtime/support_instrumentation.cc
+++ b/src/oat/runtime/support_instrumentation.cc
@@ -31,9 +31,10 @@
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
   instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
-  instrumentation->PushInstrumentationStackFrame(self, method->IsStatic() ? NULL : this_object,
-                                                 method, lr);
   const void* result = instrumentation->GetQuickCodeFor(method);
+  bool interpreter_entry = (result == GetInterpreterEntryPoint());
+  instrumentation->PushInstrumentationStackFrame(self, method->IsStatic() ? NULL : this_object,
+                                                 method, lr, interpreter_entry);
   CHECK(result != NULL) << PrettyMethod(method);
   return result;
 }
diff --git a/src/object_utils.h b/src/object_utils.h
index 6a07425..4af5d4c 100644
--- a/src/object_utils.h
+++ b/src/object_utils.h
@@ -439,8 +439,7 @@
     return GetClassLinker()->ResolveString(dex_file, method_id.name_idx_, GetDexCache());
   }
 
-  const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const char* result = shorty_;
     if (result == NULL) {
       const DexFile& dex_file = GetDexFile();
diff --git a/src/stack.cc b/src/stack.cc
index 8672975..fcd0f2d 100644
--- a/src/stack.cc
+++ b/src/stack.cc
@@ -310,7 +310,12 @@
             instrumentation::InstrumentationStackFrame instrumentation_frame =
                 GetInstrumentationStackFrame(instrumentation_stack_depth);
             instrumentation_stack_depth++;
-            if (instrumentation_frame.method_ != GetMethod()) {
+            if (instrumentation_frame.interpreter_entry_) {
+              mirror::AbstractMethod* callee = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs);
+              if (GetMethod() != callee) {
+                LOG(FATAL) << "Expected: " << callee << " Found: " << PrettyMethod(GetMethod());
+              }
+            } else if (instrumentation_frame.method_ != GetMethod()) {
               LOG(FATAL)  << "Expected: " << PrettyMethod(instrumentation_frame.method_)
                 << " Found: " << PrettyMethod(GetMethod());
             }
diff --git a/src/thread_list.cc b/src/thread_list.cc
index eacd848..59c38b4 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -140,14 +140,6 @@
   ss << "Thread suspend timeout\n";
   runtime->DumpLockHolders(ss);
   ss << "\n";
-  Locks::mutator_lock_->SharedTryLock(self);
-  if (!Locks::mutator_lock_->IsSharedHeld(self)) {
-    LOG(WARNING) << "Dumping thread list without holding mutator_lock_";
-  }
-  Locks::thread_list_lock_->TryLock(self);
-  if (!Locks::thread_list_lock_->IsExclusiveHeld(self)) {
-    LOG(WARNING) << "Dumping thread list without holding thread_list_lock_";
-  }
   runtime->GetThreadList()->DumpLocked(ss);
   LOG(FATAL) << ss.str();
 }