Revert^2 "Support clinit for app image during compilation"

Add some spot fixes for app image class initialization and re-enable
test 660 features.

Bug: 70735003
Test: test-art-host

This reverts commit abadf024efdc632f663d7fb503cd277b3f65fca2.

Change-Id: Id16fd3ada3eb1bd57ea60c3cdc4a0cf9835950d7
diff --git a/runtime/aot_class_linker.cc b/runtime/aot_class_linker.cc
index c9ca4c9..c151306 100644
--- a/runtime/aot_class_linker.cc
+++ b/runtime/aot_class_linker.cc
@@ -31,6 +31,16 @@
 
 AotClassLinker::~AotClassLinker() {}
 
+bool AotClassLinker::CanAllocClass() {
+  // AllocClass doesn't work under transaction, so we abort.
+  if (Runtime::Current()->IsActiveTransaction()) {
+    Runtime::Current()->AbortTransactionAndThrowAbortError(
+        Thread::Current(), "Can't resolve type within transaction.");
+    return false;
+  }
+  return ClassLinker::CanAllocClass();
+}
+
 // Wrap the original InitializeClass with creation of transaction when in strict mode.
 bool AotClassLinker::InitializeClass(Thread* self,
                                      Handle<mirror::Class> klass,
@@ -44,6 +54,13 @@
     return ClassLinker::InitializeClass(self, klass, can_init_statics, can_init_parents);
   }
 
+  // When in strict_mode, don't initialize a class if it belongs to boot but not initialized.
+  if (strict_mode_ && klass->IsBootStrapClassLoaded()) {
+    runtime->AbortTransactionAndThrowAbortError(self, "Can't resolve "
+        + klass->PrettyTypeOf() + " because it is an uninitialized boot class.");
+    return false;
+  }
+
   // Don't initialize klass if it's superclass is not initialized, because superclass might abort
   // the transaction and rolled back after klass's change is commited.
   if (strict_mode_ && !klass->IsInterface() && klass->HasSuperClass()) {
@@ -64,9 +81,8 @@
       // Exit Transaction if success.
       runtime->ExitTransactionMode();
     } else {
-      // If not successfully initialized, the last transaction must abort. Don't rollback
-      // immediately, leave the cleanup to compiler driver which needs abort message and exception.
-      DCHECK(runtime->IsTransactionAborted());
+      // If not successfully initialized, don't rollback immediately, leave the cleanup to compiler
+      // driver which needs abort message and exception.
       DCHECK(self->IsExceptionPending());
     }
   }
diff --git a/runtime/aot_class_linker.h b/runtime/aot_class_linker.h
index 6a8133e..74da33d 100644
--- a/runtime/aot_class_linker.h
+++ b/runtime/aot_class_linker.h
@@ -37,6 +37,13 @@
       override
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  // Override AllocClass because aot compiler will need to perform a transaction check to determine
+  // can we allocate class from heap.
+  bool CanAllocClass()
+      override
+      REQUIRES_SHARED(Locks::mutator_lock_)
+      REQUIRES(!Roles::uninterruptible_);
+
   bool InitializeClass(Thread *self,
                        Handle<mirror::Class> klass,
                        bool can_run_clinit,
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index c06e5e8..2bbcbb7 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3152,7 +3152,11 @@
     // Interface object should get the right size here. Regular class will
     // figure out the right size later and be replaced with one of the right
     // size when the class becomes resolved.
-    klass.Assign(AllocClass(self, SizeOfClassWithoutEmbeddedTables(dex_file, dex_class_def)));
+    if (CanAllocClass()) {
+      klass.Assign(AllocClass(self, SizeOfClassWithoutEmbeddedTables(dex_file, dex_class_def)));
+    } else {
+      return nullptr;
+    }
   }
   if (UNLIKELY(klass == nullptr)) {
     self->AssertPendingOOMException();
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 3605ffb..8269aaa 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -758,6 +758,10 @@
                                                          std::string* error_msg)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
+  virtual bool CanAllocClass() REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::dex_lock_) {
+    return true;
+  }
+
  private:
   class LinkInterfaceMethodsHelper;