Better inline instrumentation callbacks in interpreter.

While instrumentation callbacks (MethodEnterEvent, MethodExitEvent and
DexPcMovedEvent) are inlined, the given arguments (this object, method and
current dex pc) are "constructed" even if the callback results in a no-op
(because no listener is attached) and these arguments are not used.

This CL improves these parts of code by explicitely test whether a listener is
attached before calling the callback. Thus, parameters are only created if
a listener is attached. In the case no listener is attached, we prevent from
loading from memory the 'this' object and the method and prevent from computing
the dex pc (which is the difference between the code start address and the
current instruction address).

Change-Id: Ia93aeca1eaa6c1fc644e932eb67001d46b1cf429
diff --git a/src/instrumentation.h b/src/instrumentation.h
index e6fa251..e79c75e 100644
--- a/src/instrumentation.h
+++ b/src/instrumentation.h
@@ -137,12 +137,24 @@
     return instrumentation_stubs_installed_;
   }
 
+  bool HasMethodEntryListeners() const {
+    return have_method_entry_listeners_;
+  }
+
+  bool HasMethodExitListeners() const {
+    return have_method_exit_listeners_;
+  }
+
+  bool HasDexPcListeners() const {
+    return have_dex_pc_listeners_;
+  }
+
   // Inform listeners that a method has been entered. A dex PC is provided as we may install
   // listeners into executing code and get method enter events for methods already on the stack.
   void MethodEnterEvent(Thread* thread, mirror::Object* this_object,
                         const mirror::AbstractMethod* method, uint32_t dex_pc) const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    if (have_method_entry_listeners_) {
+    if (UNLIKELY(HasMethodEntryListeners())) {
       MethodEnterEventImpl(thread, this_object, method, dex_pc);
     }
   }
@@ -152,7 +164,7 @@
                        const mirror::AbstractMethod* method, uint32_t dex_pc,
                        const JValue& return_value) const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    if (have_method_exit_listeners_) {
+    if (UNLIKELY(HasMethodExitListeners())) {
       MethodExitEventImpl(thread, this_object, method, dex_pc, return_value);
     }
   }
@@ -166,7 +178,7 @@
   void DexPcMovedEvent(Thread* thread, mirror::Object* this_object,
                        const mirror::AbstractMethod* method, uint32_t dex_pc) const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    if (UNLIKELY(have_dex_pc_listeners_)) {
+    if (UNLIKELY(HasDexPcListeners())) {
       DexPcMovedEventImpl(thread, this_object, method, dex_pc);
     }
   }