Support inlining with breakpoint

When installing/uninstalling a breakpoint in a method, we fully or selectively
deoptimize/undeoptimize depending on whether the method can be inlined. When
the method can be inlined, it requires full deoptimization. Otherwise, it only
requires selective deoptimization.

We add sanity check to control we are in a consistent state each time we add or
remove a breakpoint. We also add some comments to better describe the process
of deoptimization for breakpoint.

Bug: 12187616
Change-Id: Id15adc6e5e2fe783c83c925cbcd19ae02431b7e0
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index cf7271b..2a9c35f 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -115,10 +115,15 @@
       LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::classlinker_classes_lock_);
 
   // Deoptimization.
-  void EnableDeoptimization() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_)
+  void EnableDeoptimization()
+      EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_)
       LOCKS_EXCLUDED(deoptimized_methods_lock_);
-  void DisableDeoptimization() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_)
+  void DisableDeoptimization()
+      EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_)
       LOCKS_EXCLUDED(deoptimized_methods_lock_);
+  bool AreAllMethodsDeoptimized() const {
+    return interpreter_stubs_installed_;
+  }
   bool ShouldNotifyMethodEnterExitEvents() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Executes everything with interpreter.