summaryrefslogtreecommitdiffstats
path: root/runtime/instrumentation.h
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2013-09-19 14:47:09 +0200
committerSebastien Hertz <shertz@google.com>2013-10-17 11:15:43 +0200
commitee1997a3b83334985e757f369c09e111b121661b (patch)
tree8745229cde52990208b27af54d7e80ea2fc274c4 /runtime/instrumentation.h
parent9f69b62e6b009b29e6420c49e7444e91466a6a33 (diff)
downloadart-ee1997a3b83334985e757f369c09e111b121661b.zip
art-ee1997a3b83334985e757f369c09e111b121661b.tar.gz
art-ee1997a3b83334985e757f369c09e111b121661b.tar.bz2
Improve interpreter handler table management.
We still have two handlers table: - the "main" table which holds execution handlers of each instruction, - the "alternative" table which holds handlers supporting instrumentation before jumping to the corresponding instruction handler from the "main" table. Instrumentation holds the index of the handler table the interpreter must use. This index is represented by the InterpreterHandlerTable enum and is stored in the Instrumentation::interpreter_handler_table_ field. Interpreter's current handler table update happens: - on backward branch - after invoke - when throwing exception. In the case of the backward branch and exception, we only update the table if any thread's flags is set. This allows to only do one test for handling thread suspension and handler table update. This CL also removes the local variable "instrumentation". Every handler which needs it will get it from Runtime::Current()->GetInstrumentation(). Change-Id: Id886ea7ebf3dac1285f0ca701c098aee7ebaab8d
Diffstat (limited to 'runtime/instrumentation.h')
-rw-r--r--runtime/instrumentation.h27
1 files changed, 26 insertions, 1 deletions
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index 28f9555..7a0aaf7 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -38,6 +38,14 @@ namespace instrumentation {
const bool kVerboseInstrumentation = false;
+// Interpreter handler tables.
+enum InterpreterHandlerTable {
+ kMainHandlerTable = 0, // Main handler table: no suspend check, no instrumentation.
+ kAlternativeHandlerTable = 1, // Alternative handler table: suspend check and/or instrumentation
+ // enabled.
+ kNumHandlerTables
+};
+
// Instrumentation event listener API. Registered listeners will get the appropriate call back for
// the events they are listening for. The call backs supply the thread, method and dex_pc the event
// occurred upon. The thread may or may not be Thread::Current().
@@ -95,7 +103,8 @@ class Instrumentation {
interpret_only_(false), forced_interpret_only_(false),
have_method_entry_listeners_(false), have_method_exit_listeners_(false),
have_method_unwind_listeners_(false), have_dex_pc_listeners_(false),
- have_exception_caught_listeners_(false) {}
+ have_exception_caught_listeners_(false),
+ interpreter_handler_table_(kMainHandlerTable) {}
// Add a listener to be notified of the masked together sent of instrumentation events. This
// suspend the runtime to install stubs. You are expected to hold the mutator lock as a proxy
@@ -110,6 +119,10 @@ class Instrumentation {
EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_)
LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::classlinker_classes_lock_);
+ InterpreterHandlerTable GetInterpreterHandlerTable() const {
+ return interpreter_handler_table_;
+ }
+
// Update the code of a method respecting any installed stubs.
void UpdateMethodsCode(mirror::ArtMethod* method, const void* code) const;
@@ -149,6 +162,11 @@ class Instrumentation {
return have_dex_pc_listeners_;
}
+ bool IsActive() const {
+ return have_dex_pc_listeners_ || have_method_entry_listeners_ || have_method_exit_listeners_ ||
+ have_exception_caught_listeners_ || have_method_unwind_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,
@@ -215,6 +233,10 @@ class Instrumentation {
EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_)
LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::classlinker_classes_lock_);
+ void UpdateInterpreterHandlerTable() {
+ interpreter_handler_table_ = IsActive() ? kAlternativeHandlerTable : kMainHandlerTable;
+ }
+
void MethodEnterEventImpl(Thread* thread, mirror::Object* this_object,
const mirror::ArtMethod* method, uint32_t dex_pc) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -267,6 +289,9 @@ class Instrumentation {
std::list<InstrumentationListener*> dex_pc_listeners_ GUARDED_BY(Locks::mutator_lock_);
std::list<InstrumentationListener*> exception_caught_listeners_ GUARDED_BY(Locks::mutator_lock_);
+ // Current interpreter handler table. This is updated each time the thread state flags are modified.
+ InterpreterHandlerTable interpreter_handler_table_;
+
DISALLOW_COPY_AND_ASSIGN(Instrumentation);
};