From 74109f6683096de494b1457fa6d5b0ac33b4c98c Mon Sep 17 00:00:00 2001 From: Sebastien Hertz Date: Fri, 7 Jun 2013 17:40:09 +0200 Subject: 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 --- src/instrumentation.h | 18 +++++++++++++++--- src/interpreter/interpreter.cc | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 43 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/instrumentation.h b/src/instrumentation.h index e6fa251076..e79c75efac 100644 --- a/src/instrumentation.h +++ b/src/instrumentation.h @@ -137,12 +137,24 @@ class Instrumentation { 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 @@ class Instrumentation { 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 @@ class Instrumentation { 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); } } diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc index 705e265090..b185cf5ea8 100644 --- a/src/interpreter/interpreter.cc +++ b/src/interpreter/interpreter.cc @@ -729,8 +729,10 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c 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 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c } 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 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c 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 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c 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 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c 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: { -- cgit v1.2.3-59-g8ed1b