Fix compiling boot image extension with assume-verified.
The change https://android-review.googlesource.com/1246288
enabled AOT initialization of classes for the compiler
filter "assume-verified". However, this was untested and
broken because aborted transactions would leave created
array classes with partially rolled-back state on the heap.
Note that for other compiler filters, the verification step
creates those array classes outside of a transaction.
We fix this problem by making sure that the initialization
of an array class does not create any transaction records
for the class fields (we are keeping the defined class).
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: aosp_taimen-userdebug boots.
Test: adb root && \
adb shell stop && \
adb shell setprop dalvik.vm.boot-image \
'boot.art:/nonx/boot-framework.art!/system/etc/boot-image.prof' && \
adb shell setprop dalvik.vm.image-dex2oat-filter \
assume-verified && \
adb shell start # Starts correctly.
Test: Extract the boot image extension compilation command
from the verbose log, change compiler filter to
"assume-verified" and execute with no crashes.
Bug: 119800099
Change-Id: Id57a01af0a015c75a16eea12fd19599ae76ce49a
diff --git a/runtime/transaction.h b/runtime/transaction.h
index f05bfee..184280f 100644
--- a/runtime/transaction.h
+++ b/runtime/transaction.h
@@ -320,10 +320,31 @@
const bool strict_;
std::string abort_message_ GUARDED_BY(log_lock_);
mirror::Class* root_ GUARDED_BY(log_lock_);
+ const char* assert_no_new_records_reason_ GUARDED_BY(log_lock_);
+
+ friend class ScopedAssertNoNewTransactionRecords;
DISALLOW_COPY_AND_ASSIGN(Transaction);
};
+class ScopedAssertNoNewTransactionRecords {
+ public:
+ explicit ScopedAssertNoNewTransactionRecords(const char* reason)
+ : transaction_(kIsDebugBuild ? InstallAssertion(reason) : nullptr) {}
+
+ ~ScopedAssertNoNewTransactionRecords() {
+ if (kIsDebugBuild && transaction_ != nullptr) {
+ RemoveAssertion(transaction_);
+ }
+ }
+
+ private:
+ static Transaction* InstallAssertion(const char* reason);
+ static void RemoveAssertion(Transaction* transaction);
+
+ Transaction* transaction_;
+};
+
} // namespace art
#endif // ART_RUNTIME_TRANSACTION_H_