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/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index 705e265..b185cf5 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -729,8 +729,10 @@
 
   const Instruction* inst = Instruction::At(insns + shadow_frame.GetDexPC());
   if (inst->GetDexPc(insns) == 0) {  // We are entering the method as opposed to deoptimizing..
-    instrumentation->MethodEnterEvent(self, this_object_ref.get(),
-                                      shadow_frame.GetMethod(), 0);
+    if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
+      instrumentation->MethodEnterEvent(self, this_object_ref.get(),
+                                        shadow_frame.GetMethod(), 0);
+    }
   }
   while (true) {
     if (UNLIKELY(self->TestAllFlags())) {
@@ -738,8 +740,10 @@
     }
     const uint32_t dex_pc = inst->GetDexPc(insns);
     shadow_frame.SetDexPC(dex_pc);
-    instrumentation->DexPcMovedEvent(self, this_object_ref.get(),
-                                     shadow_frame.GetMethod(), dex_pc);
+    if (instrumentation->HasDexPcListeners()) {
+      instrumentation->DexPcMovedEvent(self, this_object_ref.get(),
+                                       shadow_frame.GetMethod(), dex_pc);
+    }
     const bool kTracing = false;
     if (kTracing) {
 #define TRACE_LOG std::cerr
@@ -847,8 +851,11 @@
       case Instruction::RETURN_VOID: {
         PREAMBLE();
         JValue result;
-        instrumentation->MethodExitEvent(self, this_object_ref.get(),
-                                         shadow_frame.GetMethod(), inst->GetDexPc(insns), result);
+        if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
+          instrumentation->MethodExitEvent(self, this_object_ref.get(),
+                                           shadow_frame.GetMethod(), inst->GetDexPc(insns),
+                                           result);
+        }
         return result;
       }
       case Instruction::RETURN: {
@@ -856,16 +863,22 @@
         JValue result;
         result.SetJ(0);
         result.SetI(shadow_frame.GetVReg(inst->VRegA_11x()));
-        instrumentation->MethodExitEvent(self, this_object_ref.get(),
-                                         shadow_frame.GetMethod(), inst->GetDexPc(insns), result);
+        if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
+          instrumentation->MethodExitEvent(self, this_object_ref.get(),
+                                           shadow_frame.GetMethod(), inst->GetDexPc(insns),
+                                           result);
+        }
         return result;
       }
       case Instruction::RETURN_WIDE: {
         PREAMBLE();
         JValue result;
         result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x()));
-        instrumentation->MethodExitEvent(self, this_object_ref.get(),
-                                         shadow_frame.GetMethod(), inst->GetDexPc(insns), result);
+        if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
+          instrumentation->MethodExitEvent(self, this_object_ref.get(),
+                                           shadow_frame.GetMethod(), inst->GetDexPc(insns),
+                                           result);
+        }
         return result;
       }
       case Instruction::RETURN_OBJECT: {
@@ -873,8 +886,11 @@
         JValue result;
         result.SetJ(0);
         result.SetL(shadow_frame.GetVRegReference(inst->VRegA_11x()));
-        instrumentation->MethodExitEvent(self, this_object_ref.get(),
-                                         shadow_frame.GetMethod(), inst->GetDexPc(insns), result);
+        if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
+          instrumentation->MethodExitEvent(self, this_object_ref.get(),
+                                           shadow_frame.GetMethod(), inst->GetDexPc(insns),
+                                           result);
+        }
         return result;
       }
       case Instruction::CONST_4: {