diff options
author | Jeff Hao <jeffhao@google.com> | 2013-07-16 16:39:33 -0700 |
---|---|---|
committer | Jeff Hao <jeffhao@google.com> | 2013-07-17 13:40:51 -0700 |
commit | 65d15d985a27be01e1d64f473af0e9d8eb19051d (patch) | |
tree | 211dfad2d50cd42a1d5418941da44abeb1d2d16c /runtime/instrumentation.cc | |
parent | 82f9f02d89ea859bd04514bd28bb6cac0409c7b2 (diff) | |
download | art-65d15d985a27be01e1d64f473af0e9d8eb19051d.zip art-65d15d985a27be01e1d64f473af0e9d8eb19051d.tar.gz art-65d15d985a27be01e1d64f473af0e9d8eb19051d.tar.bz2 |
Fixes to instrumentation for debug build and interpreter.
- Stub uninstall will put back the interpreter entry point if Xint
mode is specified.
- Copy method entry and exit listeners before iterating over them
to prevent problems that occur when they are modified during
iteration.
- Corrected checks from WalkStack and AssertPcIsWithinCode to
handle instrumented code since they are used to remove the stubs.
Change-Id: Ib0e2b421e6b56d520e4643699624dd80ee5148e3
Diffstat (limited to 'runtime/instrumentation.cc')
-rw-r--r-- | runtime/instrumentation.cc | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index 8598d6d..091f66a 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -59,7 +59,9 @@ bool Instrumentation::InstallStubsForClass(mirror::Class* klass) { if (!method->IsAbstract()) { const void* new_code; if (uninstall) { - if (is_initialized || !method->IsStatic() || method->IsConstructor()) { + if (forced_interpret_only_ && !method->IsNative() && !method->IsProxyMethod()) { + new_code = GetInterpreterEntryPoint(); + } else if (is_initialized || !method->IsStatic() || method->IsConstructor()) { new_code = class_linker->GetOatCodeFor(method); } else { new_code = GetResolutionTrampoline(class_linker); @@ -79,7 +81,11 @@ bool Instrumentation::InstallStubsForClass(mirror::Class* klass) { if (!method->IsAbstract()) { const void* new_code; if (uninstall) { - new_code = class_linker->GetOatCodeFor(method); + if (forced_interpret_only_ && !method->IsNative() && !method->IsProxyMethod()) { + new_code = GetInterpreterEntryPoint(); + } else { + new_code = class_linker->GetOatCodeFor(method); + } } else { // !uninstall if (!interpreter_stubs_installed_ || method->IsNative()) { new_code = GetInstrumentationEntryPoint(); @@ -376,6 +382,12 @@ void Instrumentation::ConfigureStubs(bool require_entry_exit_stubs, bool require void Instrumentation::UpdateMethodsCode(mirror::AbstractMethod* method, const void* code) const { if (LIKELY(!instrumentation_stubs_installed_)) { method->SetEntryPointFromCompiledCode(code); + } else { + if (!interpreter_stubs_installed_ || method->IsNative()) { + method->SetEntryPointFromCompiledCode(GetInstrumentationEntryPoint()); + } else { + method->SetEntryPointFromCompiledCode(GetInterpreterEntryPoint()); + } } } @@ -396,9 +408,14 @@ void Instrumentation::MethodEnterEventImpl(Thread* thread, mirror::Object* this_ const mirror::AbstractMethod* method, uint32_t dex_pc) const { typedef std::list<InstrumentationListener*>::const_iterator It; // TODO: C++0x auto - for (It it = method_entry_listeners_.begin(), end = method_entry_listeners_.end(); it != end; - ++it) { - (*it)->MethodEntered(thread, this_object, method, dex_pc); + It it = method_entry_listeners_.begin(); + bool is_end = (it == method_entry_listeners_.end()); + // Implemented this way to prevent problems caused by modification of the list while iterating. + while (!is_end) { + InstrumentationListener* cur = *it; + ++it; + is_end = (it == method_entry_listeners_.end()); + cur->MethodEntered(thread, this_object, method, dex_pc); } } @@ -406,9 +423,14 @@ void Instrumentation::MethodExitEventImpl(Thread* thread, mirror::Object* this_o const mirror::AbstractMethod* method, uint32_t dex_pc, const JValue& return_value) const { typedef std::list<InstrumentationListener*>::const_iterator It; // TODO: C++0x auto - for (It it = method_exit_listeners_.begin(), end = method_exit_listeners_.end(); it != end; - ++it) { - (*it)->MethodExited(thread, this_object, method, dex_pc, return_value); + It it = method_exit_listeners_.begin(); + bool is_end = (it == method_exit_listeners_.end()); + // Implemented this way to prevent problems caused by modification of the list while iterating. + while (!is_end) { + InstrumentationListener* cur = *it; + ++it; + is_end = (it == method_exit_listeners_.end()); + cur->MethodExited(thread, this_object, method, dex_pc, return_value); } } |