Don't send ClassFileLoadHook before JVMTI_PHASE_START.

All the classes we load prior to transitioning into JVMTI_PHASE_START
are tightly coupled into the runtime itself. For this reason
redefining them in the ways allowed by the ClassFileLoadHook during
first load could cause difficult to diagnose problems with the
runtime. Since there is no good way to determine if the new definition
is safe nor to report that the definition was ignored we instead
simply do not send this event during this stage of runtime
initialization.

Test: ./test/testrunner/testrunner.py --host -j40 -b
Change-Id: I813f2ced49a2a85e485a6f2cf94edb024799c5c0
diff --git a/runtime/openjdkjvmti/ti_class.cc b/runtime/openjdkjvmti/ti_class.cc
index 4282e38..2d1b25e 100644
--- a/runtime/openjdkjvmti/ti_class.cc
+++ b/runtime/openjdkjvmti/ti_class.cc
@@ -62,6 +62,7 @@
 #include "thread-inl.h"
 #include "thread_list.h"
 #include "ti_class_loader.h"
+#include "ti_phase.h"
 #include "ti_redefine.h"
 #include "utils.h"
 
@@ -142,6 +143,18 @@
       // It is a primitive or array. Just return
       return;
     }
+    jvmtiPhase phase = PhaseUtil::GetPhaseUnchecked();
+    if (UNLIKELY(phase != JVMTI_PHASE_START && phase != JVMTI_PHASE_LIVE)) {
+      // We want to wait until we are at least in the START phase so that all WellKnownClasses and
+      // mirror classes have been initialized and loaded. The runtime relies on these classes having
+      // specific fields and methods present. Since PreDefine hooks don't need to abide by this
+      // restriction we will simply not send the event for these classes.
+      LOG(WARNING) << "Ignoring load of class <" << descriptor << "> as it is being loaded during "
+                   << "runtime initialization.";
+      return;
+    }
+
+    // Strip the 'L' and ';' from the descriptor
     std::string name(std::string(descriptor).substr(1, strlen(descriptor) - 2));
 
     art::Thread* self = art::Thread::Current();