summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2024-05-14 16:46:15 +0200
committer VladimĂ­r Marko <vmarko@google.com> 2024-05-17 05:52:24 +0000
commit382f0db56cb95d0f1062ce46c73bc21705c87cef (patch)
treeaf1ed12f59c3a8a90946560001a53a98ffdbce0a /runtime/class_linker.cc
parente6374e9c089c98729068fc25fc981e78b27d6a70 (diff)
Move transaction records from `Runtime` to `AotClassLinker`.
Keep a simple flag for active transaction in `Runtime` but move all other transaction data to `AotClassLinker`. Make `IsActiveTransaction()` a pre-requisite for calling `IsTransactionAborted()`. Eliminate `AbortTransactionAndThrowAbortError()` by inlining into `AbortTransactionV()` and rewriting other callers to use `AbortTransactionF()` instead. Separate transaction-related test code to its own files. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Change-Id: Ie6ee421fcfed1599049ab50ca692f19c71f395ce
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc144
1 files changed, 142 insertions, 2 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 03611ebc20..823d79e7d0 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -5857,13 +5857,13 @@ bool ClassLinker::InitializeClass(Thread* self,
WrapExceptionInInitializer(klass);
mirror::Class::SetStatus(klass, ClassStatus::kErrorResolved, self);
success = false;
- } else if (Runtime::Current()->IsTransactionAborted()) {
+ } else if (Runtime::Current()->IsActiveTransaction() && IsTransactionAborted()) {
// The exception thrown when the transaction aborted has been caught and cleared
// so we need to throw it again now.
VLOG(compiler) << "Return from class initializer of "
<< mirror::Class::PrettyDescriptor(klass.Get())
<< " without exception while transaction was aborted: re-throw it now.";
- runtime->ThrowTransactionAbortError(self);
+ ThrowTransactionAbortError(self);
mirror::Class::SetStatus(klass, ClassStatus::kErrorResolved, self);
success = false;
} else {
@@ -11188,6 +11188,146 @@ bool ClassLinker::TransactionAllocationConstraint(
UNREACHABLE();
}
+void ClassLinker::RecordWriteFieldBoolean([[maybe_unused]] mirror::Object* obj,
+ [[maybe_unused]] MemberOffset field_offset,
+ [[maybe_unused]] uint8_t value,
+ [[maybe_unused]] bool is_volatile) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordWriteFieldByte([[maybe_unused]] mirror::Object* obj,
+ [[maybe_unused]] MemberOffset field_offset,
+ [[maybe_unused]] int8_t value,
+ [[maybe_unused]] bool is_volatile) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordWriteFieldChar([[maybe_unused]] mirror::Object* obj,
+ [[maybe_unused]] MemberOffset field_offset,
+ [[maybe_unused]] uint16_t value,
+ [[maybe_unused]] bool is_volatile) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordWriteFieldShort([[maybe_unused]] mirror::Object* obj,
+ [[maybe_unused]] MemberOffset field_offset,
+ [[maybe_unused]] int16_t value,
+ [[maybe_unused]] bool is_volatile) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordWriteField32([[maybe_unused]] mirror::Object* obj,
+ [[maybe_unused]] MemberOffset field_offset,
+ [[maybe_unused]] uint32_t value,
+ [[maybe_unused]] bool is_volatile) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordWriteField64([[maybe_unused]] mirror::Object* obj,
+ [[maybe_unused]] MemberOffset field_offset,
+ [[maybe_unused]] uint64_t value,
+ [[maybe_unused]] bool is_volatile) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordWriteFieldReference([[maybe_unused]] mirror::Object* obj,
+ [[maybe_unused]] MemberOffset field_offset,
+ [[maybe_unused]] ObjPtr<mirror::Object> value,
+ [[maybe_unused]] bool is_volatile) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordWriteArray([[maybe_unused]] mirror::Array* array,
+ [[maybe_unused]] size_t index,
+ [[maybe_unused]] uint64_t value) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordStrongStringInsertion([[maybe_unused]] ObjPtr<mirror::String> s) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordWeakStringInsertion([[maybe_unused]] ObjPtr<mirror::String> s) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordStrongStringRemoval([[maybe_unused]] ObjPtr<mirror::String> s) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordWeakStringRemoval([[maybe_unused]] ObjPtr<mirror::String> s) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordResolveString([[maybe_unused]] ObjPtr<mirror::DexCache> dex_cache,
+ [[maybe_unused]] dex::StringIndex string_idx) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::RecordResolveMethodType([[maybe_unused]] ObjPtr<mirror::DexCache> dex_cache,
+ [[maybe_unused]] dex::ProtoIndex proto_idx) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::ThrowTransactionAbortError([[maybe_unused]] Thread* self) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::AbortTransactionF(
+ [[maybe_unused]] Thread* self, [[maybe_unused]] const char* fmt, ...) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::AbortTransactionV([[maybe_unused]] Thread* self,
+ [[maybe_unused]] const char* fmt,
+ [[maybe_unused]] va_list args) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+bool ClassLinker::IsTransactionAborted() const {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
+void ClassLinker::VisitTransactionRoots([[maybe_unused]] RootVisitor* visitor) {
+ // Nothing to do for normal `ClassLinker`, only `AotClassLinker` handles transactions.
+}
+
void ClassLinker::RemoveDexFromCaches(const DexFile& dex_file) {
ReaderMutexLock mu(Thread::Current(), *Locks::dex_lock_);