diff options
author | Sebastien Hertz <shertz@google.com> | 2015-04-10 12:12:33 +0200 |
---|---|---|
committer | Sebastien Hertz <shertz@google.com> | 2015-05-07 22:20:26 +0200 |
commit | c3cde2c00bcbe97c9b0c119919500fcbbe824baa (patch) | |
tree | 0818cd13edb117f5c5f1513aea20c560277768be /runtime/interpreter/interpreter_goto_table_impl.cc | |
parent | 5260d14566d13b1767ca63d2768d9b0e0a1bba33 (diff) | |
download | android_art-c3cde2c00bcbe97c9b0c119919500fcbbe824baa.tar.gz android_art-c3cde2c00bcbe97c9b0c119919500fcbbe824baa.tar.bz2 android_art-c3cde2c00bcbe97c9b0c119919500fcbbe824baa.zip |
JDWP: properly combine location events
This CL properly groups JDWP events at the same location: Breakpoint,
Single-step, Method Entry and Method Exit. This is necessary if the
debugger is not the only instrumentation listener. This matches the
behavior of Dalvik, especially for methods with a single return
instruction.
The interpreter was tuned so the instrumentation callbacks were
called to satisfy the debugger with the idea the debugger was the
only instrumentation listener. This is not true when method tracing
is enabled at the same time.
When tracing is enabled, there is always a listener for MethodEntry
and MethodExit events (art::Trace class). However, if the debugger
is only listening to DexPcMoved event (to manage JDWP Breakpoint
event), it will not be notified of this event.
We now properly call all the instrumentation callbacks in the
interpreter and move the logic specific to debugging into the class
DebugInstrumentationListener. This allows to properly group JDWP
location events together depending on the sequence of instrumentation
callbacks.
We add Thread::tls_32bit_sized_values::debug_method_entry_ flag to
remember we just entered a method. It replaces the local variable
notified_method_entry_event in the interpreter and simplifies the
code.
Bump oat version to force recompilation because the layout of the
Thread class is modified.
Bug: 19829329
Bug: 20205350
(cherry picked from commit 9d6bf69ad3012a9d843268fdd5325b6719b6d5f2)
Change-Id: I204af9112e37d2eebc86661fb7c961a41c74e598
Diffstat (limited to 'runtime/interpreter/interpreter_goto_table_impl.cc')
-rw-r--r-- | runtime/interpreter/interpreter_goto_table_impl.cc | 47 |
1 files changed, 10 insertions, 37 deletions
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc index 878efba1a5..dd1f55e6b2 100644 --- a/runtime/interpreter/interpreter_goto_table_impl.cc +++ b/runtime/interpreter/interpreter_goto_table_impl.cc @@ -156,7 +156,6 @@ JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowF const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc); uint16_t inst_data; const void* const* currentHandlersTable; - bool notified_method_entry_event = false; UPDATE_HANDLER_TABLE(); if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing. if (kIsDebugBuild) { @@ -166,7 +165,6 @@ JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowF if (UNLIKELY(instrumentation->HasMethodEntryListeners())) { instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), shadow_frame.GetMethod(), 0); - notified_method_entry_event = true; } } @@ -264,9 +262,6 @@ JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowF instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), shadow_frame.GetMethod(), dex_pc, result); - } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { - instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), - shadow_frame.GetMethod(), dex_pc); } return result; } @@ -281,9 +276,6 @@ JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowF instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), shadow_frame.GetMethod(), dex_pc, result); - } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { - instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), - shadow_frame.GetMethod(), dex_pc); } return result; } @@ -299,9 +291,6 @@ JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowF instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), shadow_frame.GetMethod(), dex_pc, result); - } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { - instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), - shadow_frame.GetMethod(), dex_pc); } return result; } @@ -316,9 +305,6 @@ JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowF instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), shadow_frame.GetMethod(), dex_pc, result); - } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { - instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), - shadow_frame.GetMethod(), dex_pc); } return result; } @@ -352,9 +338,6 @@ JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowF instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), shadow_frame.GetMethod(), dex_pc, result); - } else if (UNLIKELY(instrumentation->HasDexPcListeners())) { - instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), - shadow_frame.GetMethod(), dex_pc); } return result; } @@ -2510,26 +2493,16 @@ JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowF // Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The // compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to // a constant condition that would remove the "if" statement so the test is free. -#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \ - alt_op_##code: { \ - if (Instruction::code != Instruction::RETURN_VOID && \ - Instruction::code != Instruction::RETURN_VOID_NO_BARRIER && \ - Instruction::code != Instruction::RETURN && \ - Instruction::code != Instruction::RETURN_WIDE && \ - Instruction::code != Instruction::RETURN_OBJECT) { \ - if (LIKELY(!notified_method_entry_event)) { \ - Runtime* runtime = Runtime::Current(); \ - const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \ - if (UNLIKELY(instrumentation->HasDexPcListeners())) { \ - Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \ - instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \ - } \ - } else { \ - notified_method_entry_event = false; \ - } \ - } \ - UPDATE_HANDLER_TABLE(); \ - goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \ +#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \ + alt_op_##code: { \ + Runtime* const runtime = Runtime::Current(); \ + const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \ + if (UNLIKELY(instrumentation->HasDexPcListeners())) { \ + Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \ + instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \ + } \ + UPDATE_HANDLER_TABLE(); \ + goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \ } #include "dex_instruction_list.h" DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER) |