Fix missing single-step event

During debugging, we used to suspend too lately after a step. It occurred when
we were stepping out of an interpreted method into a compiled "caller" method.
The issue is we did not deoptimize when returning from the interpreted method
but only did it when returning from the compiled method. Therefore we were not
executing the rest of the compiled method's code with interpreter which
prevents from debugging it.

This CL fixes this issue by using instrumentation entry/exit stubs when calling
interpreted method from compiled code. Therefore, we execute instrumentation
exit stub when returning from interpreter and are able to deoptimize from this
point. This allows to execute compiled method's code with interpreter and to
debug it.

We now also prevent from reporting method entry/exit twice while instrumenting
interpreted methods. We report method entry/exit events only from interpreter.

Bug: 14422182
Bug: 11705760
Change-Id: Ia1175d36202239273083c4e9733c7e9290244090
diff --git a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
index d161d0b..2edcb78 100644
--- a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
@@ -32,10 +32,15 @@
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
   instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
-  const void* result = instrumentation->GetQuickCodeFor(method);
+  const void* result;
+  if (instrumentation->IsDeoptimized(method)) {
+    result = GetQuickToInterpreterBridge();
+  } else {
+    result = instrumentation->GetQuickCodeFor(method);
+  }
   DCHECK(result != GetQuickToInterpreterBridgeTrampoline(Runtime::Current()->GetClassLinker()));
   bool interpreter_entry = (result == GetQuickToInterpreterBridge());
-  instrumentation->PushInstrumentationStackFrame(self, method->IsStatic() ? NULL : this_object,
+  instrumentation->PushInstrumentationStackFrame(self, method->IsStatic() ? nullptr : this_object,
                                                  method, lr, interpreter_entry);
   CHECK(result != NULL) << PrettyMethod(method);
   return result;