Merge "Fix an assert during jdwp debugging."
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 55f68d3..8005642 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -582,7 +582,7 @@
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 34bc458..61119f8 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -687,8 +687,7 @@
}
}
-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 @@
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 a4c3d41..ce6ead4 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -227,6 +227,10 @@
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 @@
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_;