diff options
Diffstat (limited to 'runtime/debugger.cc')
| -rw-r--r-- | runtime/debugger.cc | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 904490aa8c..bc6589380c 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -28,6 +28,7 @@ #include "class_linker-inl.h" #include "dex_file-inl.h" #include "dex_instruction.h" +#include "entrypoints/runtime_asm_entrypoints.h" #include "gc/accounting/card_table-inl.h" #include "gc/allocation_record.h" #include "gc/scoped_gc_critical_section.h" @@ -570,6 +571,29 @@ bool Dbg::RequiresDeoptimization() { return !Runtime::Current()->GetInstrumentation()->IsForcedInterpretOnly(); } +// Used to patch boot image method entry point to interpreter bridge. +class UpdateEntryPointsClassVisitor : public ClassVisitor { + public: + explicit UpdateEntryPointsClassVisitor(instrumentation::Instrumentation* instrumentation) + : instrumentation_(instrumentation) {} + + bool operator()(mirror::Class* klass) OVERRIDE REQUIRES(Locks::mutator_lock_) { + auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); + for (auto& m : klass->GetMethods(pointer_size)) { + const void* code = m.GetEntryPointFromQuickCompiledCode(); + if (Runtime::Current()->GetHeap()->IsInBootImageOatFile(code) && + !m.IsNative() && + !m.IsProxyMethod()) { + instrumentation_->UpdateMethodsCode(&m, GetQuickToInterpreterBridge()); + } + } + return true; + } + + private: + instrumentation::Instrumentation* const instrumentation_; +}; + void Dbg::GoActive() { // Enable all debugging features, including scans for breakpoints. // This is a no-op if we're already active. @@ -598,6 +622,14 @@ void Dbg::GoActive() { } Runtime* runtime = Runtime::Current(); + // Since boot image code is AOT compiled as not debuggable, we need to patch + // entry points of methods in boot image to interpreter bridge. + if (!runtime->GetInstrumentation()->IsForcedInterpretOnly()) { + ScopedObjectAccess soa(self); + UpdateEntryPointsClassVisitor visitor(runtime->GetInstrumentation()); + runtime->GetClassLinker()->VisitClasses(&visitor); + } + ScopedSuspendAll ssa(__FUNCTION__); if (RequiresDeoptimization()) { runtime->GetInstrumentation()->EnableDeoptimization(); |