From 3fd448a8b7903b00fceaed5853306e2d7eb31c72 Mon Sep 17 00:00:00 2001 From: Mingyao Yang Date: Tue, 10 May 2016 14:30:41 -0700 Subject: [PATCH] Fix an assert during jdwp debugging. When debugger attaches, we patch entry points of methods in framework code. During that process, it's possible that some method's declaring class isn't resolved yet. We need to relax one assert for that case. Bug: 28630805 Change-Id: I59fd488ad75417a64b52321677ffcac6ccdc5ce1 --- runtime/debugger.cc | 2 +- runtime/instrumentation.cc | 15 +++++++++++++-- runtime/instrumentation.h | 7 +++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 55f68d3f2..80056423a 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -582,7 +582,7 @@ class UpdateEntryPointsClassVisitor : public ClassVisitor { if (Runtime::Current()->GetHeap()->IsInBootImageOatFile(code) && !m.IsNative() && !m.IsProxyMethod()) { - instrumentation_->UpdateMethodsCode(&m, GetQuickToInterpreterBridge()); + instrumentation_->UpdateMethodsCodeFromDebugger(&m, GetQuickToInterpreterBridge()); } } return true; diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index 34bc45857..61119f849 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -687,8 +687,7 @@ void Instrumentation::ResetQuickAllocEntryPoints() { } } -void Instrumentation::UpdateMethodsCode(ArtMethod* method, const void* quick_code) { - DCHECK(method->GetDeclaringClass()->IsResolved()); +void Instrumentation::UpdateMethodsCodeImpl(ArtMethod* method, const void* quick_code) { const void* new_quick_code; if (LIKELY(!instrumentation_stubs_installed_)) { new_quick_code = quick_code; @@ -710,6 +709,18 @@ void Instrumentation::UpdateMethodsCode(ArtMethod* method, const void* quick_cod UpdateEntrypoints(method, new_quick_code); } +void Instrumentation::UpdateMethodsCode(ArtMethod* method, const void* quick_code) { + DCHECK(method->GetDeclaringClass()->IsResolved()); + UpdateMethodsCodeImpl(method, quick_code); +} + +void Instrumentation::UpdateMethodsCodeFromDebugger(ArtMethod* method, const void* quick_code) { + // When debugger attaches, we may update the entry points of all methods of a class + // to the interpreter bridge. A method's declaring class might not be in resolved + // state yet in that case. + UpdateMethodsCodeImpl(method, quick_code); +} + bool Instrumentation::AddDeoptimizedMethod(ArtMethod* method) { if (IsDeoptimizedMethod(method)) { // Already in the map. Return. diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h index a4c3d4153..ce6ead453 100644 --- a/runtime/instrumentation.h +++ b/runtime/instrumentation.h @@ -227,6 +227,10 @@ class Instrumentation { void UpdateMethodsCode(ArtMethod* method, const void* quick_code) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_); + // Update the code of a method respecting any installed stubs from debugger. + void UpdateMethodsCodeFromDebugger(ArtMethod* method, const void* quick_code) + SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_); + // Get the quick code for the given method. More efficient than asking the class linker as it // will short-cut to GetCode if instrumentation and static method resolution stubs aren't // installed. @@ -493,6 +497,9 @@ class Instrumentation { SHARED_REQUIRES(Locks::mutator_lock_, deoptimized_methods_lock_); bool IsDeoptimizedMethodsEmpty() const SHARED_REQUIRES(Locks::mutator_lock_, deoptimized_methods_lock_); + void UpdateMethodsCodeImpl(ArtMethod* method, const void* quick_code) + SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_); + // Have we hijacked ArtMethod::code_ so that it calls instrumentation/interpreter code? bool instrumentation_stubs_installed_; -- 2.11.0