Use ClassStatus::kVisiblyInitialized for allocations.

And move the "intialized but not visibly initialized" check
to ClassLinker::EnsureIntialized().

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: aosp_taimen-userdebug boots.
Test: run-gtests.sh
Test: testrunner.py --target --optimizing
Bug: 36692143
Change-Id: Ib5e19326b1149b2aef586b905ce89470c3a8e405
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index fc32114..a79b87d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -5963,6 +5963,16 @@
   DCHECK(c != nullptr);
 
   if (c->IsInitialized()) {
+    // If we've seen an initialized but not visibly initialized class
+    // many times, request visible initialization.
+    if (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64) {
+      // Thanks to the x86 memory model classes skip the initialized status.
+      DCHECK(c->IsVisiblyInitialized());
+    } else if (UNLIKELY(!c->IsVisiblyInitialized())) {
+      if (self->IncrementMakeVisiblyInitializedCounter()) {
+        MakeInitializedClassesVisiblyInitialized(self, /*wait=*/ false);
+      }
+    }
     DCHECK(c->WasVerificationAttempted()) << c->PrettyClassAndClassLoader();
     return true;
   }