Prevent agents from delaying system daemon threads

The runtime starts several important daemon threads that are
responsible for various GC related tasks (i.e. FinalizerDaemon, etc).
The runtime cannot be considered fully started until these threads
have been started or will be started soon.

It was possible for agents to delay the startup of these daemons
arbitrarily (while calling arbitrary java code) by never leaving the
VMInit event or by never returning from the daemons ThreadStart
events. This could cause deadlocks or other errors when using some
agents, such as libjdwp.

In order to prevent these issues and more closely match other java
language runtimes we launch these threads before sending the VMInit
event and suppress their ThreadStart events. The openjdkjvmti plugin
then waits for the Daemon threads to actually begin executing before
calling the VMInit event or any other agent code. This prevents the
agents from seeing threads appear from nowhere.

Bug: 123696564
Test: while atest CtsJdwpTestCases; do; done;

Change-Id: I7e07187f3e8670f32df0490cb419585c13d81765
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 1465b14..7ecfdc7 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -869,15 +869,22 @@
                             GetInstructionSetString(kRuntimeISA));
   }
 
-  // Send the initialized phase event. Send it before starting daemons, as otherwise
-  // sending thread events becomes complicated.
+  StartDaemonThreads();
+
+  // Make sure the environment is still clean (no lingering local refs from starting daemon
+  // threads).
+  {
+    ScopedObjectAccess soa(self);
+    self->GetJniEnv()->AssertLocalsEmpty();
+  }
+
+  // Send the initialized phase event. Send it after starting the Daemon threads so that agents
+  // cannot delay the daemon threads from starting forever.
   {
     ScopedObjectAccess soa(self);
     callbacks_->NextRuntimePhase(RuntimePhaseCallback::RuntimePhase::kInit);
   }
 
-  StartDaemonThreads();
-
   {
     ScopedObjectAccess soa(self);
     self->GetJniEnv()->AssertLocalsEmpty();