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_;