Update Transaction for boot image extension.
And clean up transaction-related code to keep test code
out of the production binaries.
Test: Add TransactionTest#Constraints to transaction_test.
Test: m test-art-host-gtest
Test: testrunner.py --host
Test: aosp_taimen-userdebug boots.
Change-Id: Iefe5f1cfde95f564069249148f9e7d71564d7a10
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 9953743..e017b17 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -109,7 +109,7 @@
if (is_static) {
obj = f->GetDeclaringClass();
if (transaction_active) {
- if (Runtime::Current()->GetTransaction()->ReadConstraint(obj.Ptr(), f)) {
+ if (Runtime::Current()->GetTransaction()->ReadConstraint(self, obj, f)) {
Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Can't read static fields of "
+ obj->PrettyTypeOf() + " since it does not belong to clinit's class.");
return false;
@@ -321,14 +321,6 @@
ObjPtr<mirror::Object> obj;
if (is_static) {
obj = f->GetDeclaringClass();
- if (transaction_active) {
- if (Runtime::Current()->GetTransaction()->WriteConstraint(obj.Ptr(), f)) {
- Runtime::Current()->AbortTransactionAndThrowAbortError(
- self, "Can't set fields of " + obj->PrettyTypeOf());
- return false;
- }
- }
-
} else {
obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
if (UNLIKELY(obj == nullptr)) {
@@ -336,6 +328,22 @@
return false;
}
}
+ if (transaction_active) {
+ Runtime* runtime = Runtime::Current();
+ if (runtime->GetTransaction()->WriteConstraint(self, obj, f)) {
+ if (is_static) {
+ runtime->AbortTransactionAndThrowAbortError(
+ self, "Can't set fields of " + obj->PrettyTypeOf());
+ } else {
+ // This can happen only when compiling a boot image extension.
+ DCHECK(!runtime->GetTransaction()->IsStrict());
+ DCHECK(runtime->GetHeap()->ObjectIsInBootImageSpace(obj));
+ runtime->AbortTransactionAndThrowAbortError(
+ self, "Can't set fields of boot image objects");
+ }
+ return false;
+ }
+ }
uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
JValue value = GetFieldValue<field_type>(shadow_frame, vregA);
diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc
index 495039c..4429f63 100644
--- a/runtime/interpreter/unstarted_runtime_test.cc
+++ b/runtime/interpreter/unstarted_runtime_test.cc
@@ -785,19 +785,19 @@
{
JValue result;
tmp->SetVReg(0, static_cast<int32_t>(i));
- Runtime::Current()->EnterTransactionMode();
+ EnterTransactionMode();
UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
- ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
- Runtime::Current()->ExitTransactionMode();
+ ASSERT_TRUE(IsTransactionAborted());
+ ExitTransactionMode();
ASSERT_TRUE(self->IsExceptionPending());
}
{
JValue result;
tmp->SetVReg(0, static_cast<int32_t>(i));
- Runtime::Current()->EnterTransactionMode();
+ EnterTransactionMode();
UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
- ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
- Runtime::Current()->ExitTransactionMode();
+ ASSERT_TRUE(IsTransactionAborted());
+ ExitTransactionMode();
ASSERT_TRUE(self->IsExceptionPending());
}
}
@@ -805,19 +805,19 @@
{
JValue result;
tmp->SetVReg(0, static_cast<int32_t>(i));
- Runtime::Current()->EnterTransactionMode();
+ EnterTransactionMode();
UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
- ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
- Runtime::Current()->ExitTransactionMode();
+ ASSERT_TRUE(IsTransactionAborted());
+ ExitTransactionMode();
ASSERT_TRUE(self->IsExceptionPending());
}
{
JValue result;
tmp->SetVReg(0, static_cast<int32_t>(i));
- Runtime::Current()->EnterTransactionMode();
+ EnterTransactionMode();
UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
- ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
- Runtime::Current()->ExitTransactionMode();
+ ASSERT_TRUE(IsTransactionAborted());
+ ExitTransactionMode();
ASSERT_TRUE(self->IsExceptionPending());
}
}
@@ -980,10 +980,10 @@
UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
shadow_frame->SetLink(caller_frame.get());
- Runtime::Current()->EnterTransactionMode();
+ EnterTransactionMode();
UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
- ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
- Runtime::Current()->ExitTransactionMode();
+ ASSERT_TRUE(IsTransactionAborted());
+ ExitTransactionMode();
ASSERT_TRUE(self->IsExceptionPending());
self->ClearException();
@@ -1050,10 +1050,10 @@
PrepareForAborts();
{
- Runtime::Current()->EnterTransactionMode();
+ EnterTransactionMode();
UnstartedThreadCurrentThread(self, shadow_frame.get(), &result, 0);
- ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
- Runtime::Current()->ExitTransactionMode();
+ ASSERT_TRUE(IsTransactionAborted());
+ ExitTransactionMode();
ASSERT_TRUE(self->IsExceptionPending());
self->ClearException();
}
@@ -1120,7 +1120,7 @@
CHECK(name_string != nullptr);
if (in_transaction) {
- Runtime::Current()->EnterTransactionMode();
+ EnterTransactionMode();
}
CHECK(!self->IsExceptionPending());
@@ -1132,13 +1132,13 @@
} else {
CHECK(self->IsExceptionPending()) << name;
if (in_transaction) {
- ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
+ ASSERT_TRUE(IsTransactionAborted());
}
self->ClearException();
}
if (in_transaction) {
- Runtime::Current()->ExitTransactionMode();
+ ExitTransactionMode();
}
}
}