Combine JDWP location events

The runtime now sends location events BREAKPOINT, SINGLE_STEP, METHOD_ENTRY,
METHOD_EXIT and METHOD_EXIT_WITH_RETURN_VALUE in the same JDWP event packet
when they relate to the same location.

We update the Dbg::UpdateDebugger method to take initial event flags and
returned value. It allows to call this method from DebugInstrumentationListener
so we can treat method entry/exit events with breakpoint and single-step.

In the interpreter, we ensure we do not call Instrumentation::DexPcMovedEvent
when Instrumentation::MethodEnterEvent has just been called or when we're about
to call Instrumentation::MethodExitEvent. This prevents from sending duplicated
events.

I measured the average performance impact on some benchmarks with a Nexus 4
without a debugger attached:
* 1%-2% for the computed-goto-based interpreter (default interpreter)
* 5%-10% for the switch-based interpreter.
This is mostly due to the test of the boolean flag for the method entry event.

Bug: https://code.google.com/p/android/issues/detail?id=68427
Bug: 11874828
Change-Id: Ic4ff61375ff6b4ed5825adeac09f61f97b4be619
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 22a0e22..b7564e1 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -139,7 +139,7 @@
       // TODO: post location events is a suspension point and native method entry stubs aren't.
       return;
     }
-    Dbg::PostLocationEvent(method, 0, this_object, Dbg::kMethodEntry, nullptr);
+    Dbg::UpdateDebugger(thread, this_object, method, 0, Dbg::kMethodEntry, nullptr);
   }
 
   void MethodExited(Thread* thread, mirror::Object* this_object, mirror::ArtMethod* method,
@@ -149,7 +149,7 @@
       // TODO: post location events is a suspension point and native method entry stubs aren't.
       return;
     }
-    Dbg::PostLocationEvent(method, dex_pc, this_object, Dbg::kMethodExit, &return_value);
+    Dbg::UpdateDebugger(thread, this_object, method, dex_pc, Dbg::kMethodExit, &return_value);
   }
 
   void MethodUnwind(Thread* thread, mirror::Object* this_object, mirror::ArtMethod* method,
@@ -163,7 +163,7 @@
   void DexPcMoved(Thread* thread, mirror::Object* this_object, mirror::ArtMethod* method,
                   uint32_t new_dex_pc)
       OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    Dbg::UpdateDebugger(thread, this_object, method, new_dex_pc);
+    Dbg::UpdateDebugger(thread, this_object, method, new_dex_pc, 0, nullptr);
   }
 
   void FieldRead(Thread* thread, mirror::Object* this_object, mirror::ArtMethod* method,
@@ -2586,13 +2586,12 @@
 }
 
 void Dbg::UpdateDebugger(Thread* thread, mirror::Object* this_object,
-                         mirror::ArtMethod* m, uint32_t dex_pc) {
+                         mirror::ArtMethod* m, uint32_t dex_pc,
+                         int event_flags, const JValue* return_value) {
   if (!IsDebuggerActive() || dex_pc == static_cast<uint32_t>(-2) /* fake method exit */) {
     return;
   }
 
-  int event_flags = 0;
-
   if (IsBreakpoint(m, dex_pc)) {
     event_flags |= kBreakpoint;
   }
@@ -2660,7 +2659,7 @@
   // If there's something interesting going on, see if it matches one
   // of the debugger filters.
   if (event_flags != 0) {
-    Dbg::PostLocationEvent(m, dex_pc, this_object, event_flags, nullptr);
+    Dbg::PostLocationEvent(m, dex_pc, this_object, event_flags, return_value);
   }
 }