Support using adbconnection and openjdkjvmti without JAVA_DEBUGGABLE

We need to support using a best-effort JDWP when we have the
ENABLE_JDWP attribute without the JAVA_DEBUGGABLE attribute. This is
used on eng and userdebug builds. We do this by making the plugin try
to change the runtime to debuggable if possible and to allow getting
an ArtTiEnv which is a best-effort version of JVMTI by calling GetEnv
with (JVMTI_VERSION_1_2 | 0x4000000). This is needed since if the
runtime isn't debuggable we cannot guarantee compatibility with the
JVMTI specification in all cases due to compiler optimizations such as
inlining. By creating this special version agents are able to
positively signal that they are able to deal with this uncertainty.

We also support using openjdkjvmti without being JAVA_DEBUGGABLE. This
is done by either only allowing the best effort ArtTiEnvs or by
changing the environment to be debuggable if we are loaded early
enough.

Moving the runtime to debuggable state involves deoptimizing the boot
image and throwing out any image files associated with non-debuggable
oat-files.

Bug: 62821960
Test: ./test.py --host -j50
Test: Manual
Test: Build, Test debugging system_server and other processes.
Change-Id: I2233299fceb83c76785e5de09e51eaf18b7922e8
diff --git a/openjdkjvmti/deopt_manager.cc b/openjdkjvmti/deopt_manager.cc
index aced769..53d8483 100644
--- a/openjdkjvmti/deopt_manager.cc
+++ b/openjdkjvmti/deopt_manager.cc
@@ -68,7 +68,9 @@
 }
 
 DeoptManager::DeoptManager()
-  : deoptimization_status_lock_("JVMTI_DeoptimizationStatusLock"),
+  : deoptimization_status_lock_("JVMTI_DeoptimizationStatusLock",
+                                static_cast<art::LockLevel>(
+                                    art::LockLevel::kClassLinkerClassesLock + 1)),
     deoptimization_condition_("JVMTI_DeoptimizationCondition", deoptimization_status_lock_),
     performing_deoptimization_(false),
     global_deopt_count_(0),
@@ -91,6 +93,33 @@
   callbacks->RemoveMethodInspectionCallback(&inspection_callback_);
 }
 
+void DeoptManager::FinishSetup() {
+  art::Thread* self = art::Thread::Current();
+  art::MutexLock mu(self, deoptimization_status_lock_);
+
+  art::Runtime* runtime = art::Runtime::Current();
+  // See if we need to do anything.
+  if (!runtime->IsJavaDebuggable()) {
+    // See if we can enable all JVMTI functions. If this is false, only kArtTiVersion agents can be
+    // retrieved and they will all be best-effort.
+    if (PhaseUtil::GetPhaseUnchecked() == JVMTI_PHASE_ONLOAD) {
+      // We are still early enough to change the compiler options and get full JVMTI support.
+      LOG(INFO) << "Openjdkjvmti plugin loaded on a non-debuggable runtime. Changing runtime to "
+                << "debuggable state. Please pass '--debuggable' to dex2oat and "
+                << "'-Xcompiler-option --debuggable' to dalvikvm in the future.";
+      DCHECK(runtime->GetJit() == nullptr) << "Jit should not be running yet!";
+      runtime->AddCompilerOption("--debuggable");
+      runtime->SetJavaDebuggable(true);
+    } else {
+      LOG(WARNING) << "Openjdkjvmti plugin was loaded on a non-debuggable Runtime. Plugin was "
+                   << "loaded too late to change runtime state to DEBUGGABLE. Only kArtTiVersion "
+                   << "(0x" << std::hex << kArtTiVersion << ") environments are available. Some "
+                   << "functionality might not work properly.";
+    }
+    runtime->DeoptimizeBootImage();
+  }
+}
+
 bool DeoptManager::MethodHasBreakpoints(art::ArtMethod* method) {
   art::MutexLock lk(art::Thread::Current(), deoptimization_status_lock_);
   return MethodHasBreakpointsLocked(method);