Remove locking from `Transaction`.
Multi-threaded execution of transaction has never been fully
supported, so remove the unnecessary locking as it is pure
overhead. (And implementing it would require a lot of effort
on transactions interfering with each other.)
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 181943478
Change-Id: Ibdbc335738d34ea1398f50f0cc763f3b3f5838b9
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 959df00..3bbfc55 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -499,7 +499,7 @@
if (is_static) {
obj = f->GetDeclaringClass();
if (transaction_active) {
- if (Runtime::Current()->GetTransaction()->ReadConstraint(self, obj)) {
+ if (Runtime::Current()->GetTransaction()->ReadConstraint(obj)) {
Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Can't read static fields of "
+ obj->PrettyTypeOf() + " since it does not belong to clinit's class.");
return false;
@@ -552,7 +552,7 @@
static inline bool CheckWriteConstraint(Thread* self, ObjPtr<mirror::Object> obj)
REQUIRES_SHARED(Locks::mutator_lock_) {
Runtime* runtime = Runtime::Current();
- if (runtime->GetTransaction()->WriteConstraint(self, obj)) {
+ if (runtime->GetTransaction()->WriteConstraint(obj)) {
DCHECK(runtime->GetHeap()->ObjectIsInBootImageSpace(obj) || obj->IsClass());
const char* base_msg = runtime->GetHeap()->ObjectIsInBootImageSpace(obj)
? "Can't set fields of boot image "
@@ -566,7 +566,7 @@
static inline bool CheckWriteValueConstraint(Thread* self, ObjPtr<mirror::Object> value)
REQUIRES_SHARED(Locks::mutator_lock_) {
Runtime* runtime = Runtime::Current();
- if (runtime->GetTransaction()->WriteValueConstraint(self, value)) {
+ if (runtime->GetTransaction()->WriteValueConstraint(value)) {
DCHECK(value != nullptr);
std::string msg = value->IsClass()
? "Can't store reference to class " + value->AsClass()->PrettyDescriptor()
diff --git a/runtime/transaction.cc b/runtime/transaction.cc
index 0ad7a78..0aec48c 100644
--- a/runtime/transaction.cc
+++ b/runtime/transaction.cc
@@ -41,8 +41,7 @@
static constexpr bool kEnableTransactionStats = false;
Transaction::Transaction(bool strict, mirror::Class* root)
- : log_lock_("transaction log lock", kTransactionLogLock),
- aborted_(false),
+ : aborted_(false),
rolling_back_(false),
heap_(Runtime::Current()->GetHeap()),
strict_(strict),
@@ -53,7 +52,6 @@
Transaction::~Transaction() {
if (kEnableTransactionStats) {
- MutexLock mu(Thread::Current(), log_lock_);
size_t objects_count = object_logs_.size();
size_t field_values_count = 0;
for (const auto& it : object_logs_) {
@@ -77,7 +75,6 @@
}
void Transaction::Abort(const std::string& abort_message) {
- MutexLock mu(Thread::Current(), log_lock_);
// We may abort more than once if the exception thrown at the time of the
// previous abort has been caught during execution of a class initializer.
// We just keep the message of the first abort because it will cause the
@@ -105,23 +102,12 @@
}
}
-bool Transaction::IsAborted() {
- MutexLock mu(Thread::Current(), log_lock_);
- return aborted_;
-}
-
-bool Transaction::IsRollingBack() {
- return rolling_back_;
-}
-
-const std::string& Transaction::GetAbortMessage() {
- MutexLock mu(Thread::Current(), log_lock_);
+const std::string& Transaction::GetAbortMessage() const {
return abort_message_;
}
-bool Transaction::WriteConstraint(Thread* self, ObjPtr<mirror::Object> obj) {
+bool Transaction::WriteConstraint(ObjPtr<mirror::Object> obj) const {
DCHECK(obj != nullptr);
- MutexLock mu(self, log_lock_);
// Prevent changes in boot image spaces for app or boot image extension.
// For boot image there are no boot image spaces and this condition evaluates to false.
@@ -135,12 +121,11 @@
obj != root_; // modifying other classes' static field, fail
}
-bool Transaction::WriteValueConstraint(Thread* self, ObjPtr<mirror::Object> value) {
+bool Transaction::WriteValueConstraint(ObjPtr<mirror::Object> value) const {
if (value == nullptr) {
return false; // We can always store null values.
}
gc::Heap* heap = Runtime::Current()->GetHeap();
- MutexLock mu(self, log_lock_);
if (IsStrict()) {
// TODO: Should we restrict writes the same way as for boot image extension?
return false;
@@ -153,11 +138,10 @@
}
}
-bool Transaction::ReadConstraint(Thread* self, ObjPtr<mirror::Object> obj) {
+bool Transaction::ReadConstraint(ObjPtr<mirror::Object> obj) const {
// Read constraints are checked only for static field reads as there are
// no constraints on reading instance fields and array elements.
DCHECK(obj->IsClass());
- MutexLock mu(self, log_lock_);
if (IsStrict()) {
return obj != root_; // fail if not self-updating
} else {
@@ -171,7 +155,6 @@
uint8_t value,
bool is_volatile) {
DCHECK(obj != nullptr);
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
ObjectLog& object_log = object_logs_[obj];
object_log.LogBooleanValue(field_offset, value, is_volatile);
@@ -182,7 +165,6 @@
int8_t value,
bool is_volatile) {
DCHECK(obj != nullptr);
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
ObjectLog& object_log = object_logs_[obj];
object_log.LogByteValue(field_offset, value, is_volatile);
@@ -193,7 +175,6 @@
uint16_t value,
bool is_volatile) {
DCHECK(obj != nullptr);
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
ObjectLog& object_log = object_logs_[obj];
object_log.LogCharValue(field_offset, value, is_volatile);
@@ -205,7 +186,6 @@
int16_t value,
bool is_volatile) {
DCHECK(obj != nullptr);
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
ObjectLog& object_log = object_logs_[obj];
object_log.LogShortValue(field_offset, value, is_volatile);
@@ -217,7 +197,6 @@
uint32_t value,
bool is_volatile) {
DCHECK(obj != nullptr);
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
ObjectLog& object_log = object_logs_[obj];
object_log.Log32BitsValue(field_offset, value, is_volatile);
@@ -228,7 +207,6 @@
uint64_t value,
bool is_volatile) {
DCHECK(obj != nullptr);
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
ObjectLog& object_log = object_logs_[obj];
object_log.Log64BitsValue(field_offset, value, is_volatile);
@@ -239,7 +217,6 @@
mirror::Object* value,
bool is_volatile) {
DCHECK(obj != nullptr);
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
ObjectLog& object_log = object_logs_[obj];
object_log.LogReferenceValue(field_offset, value, is_volatile);
@@ -249,7 +226,6 @@
DCHECK(array != nullptr);
DCHECK(array->IsArrayInstance());
DCHECK(!array->IsObjectArray());
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
auto it = array_logs_.find(array);
if (it == array_logs_.end()) {
@@ -263,7 +239,6 @@
dex::StringIndex string_idx) {
DCHECK(dex_cache != nullptr);
DCHECK_LT(string_idx.index_, dex_cache->GetDexFile()->NumStringIds());
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
resolve_string_logs_.emplace_back(dex_cache, string_idx);
}
@@ -272,7 +247,6 @@
dex::ProtoIndex proto_idx) {
DCHECK(dex_cache != nullptr);
DCHECK_LT(proto_idx.index_, dex_cache->GetDexFile()->NumProtoIds());
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
resolve_method_type_logs_.emplace_back(dex_cache, proto_idx);
}
@@ -299,7 +273,6 @@
void Transaction::LogInternedString(InternStringLog&& log) {
Locks::intern_table_lock_->AssertExclusiveHeld(Thread::Current());
- MutexLock mu(Thread::Current(), log_lock_);
DCHECK(assert_no_new_records_reason_ == nullptr) << assert_no_new_records_reason_;
intern_string_logs_.push_front(std::move(log));
}
@@ -307,8 +280,7 @@
void Transaction::Rollback() {
Thread* self = Thread::Current();
self->AssertNoPendingException();
- MutexLock mu1(self, *Locks::intern_table_lock_);
- MutexLock mu2(self, log_lock_);
+ MutexLock mu(self, *Locks::intern_table_lock_);
rolling_back_ = true;
CHECK(!Runtime::Current()->IsActiveTransaction());
UndoObjectModifications();
@@ -362,7 +334,6 @@
}
void Transaction::VisitRoots(RootVisitor* visitor) {
- MutexLock mu(Thread::Current(), log_lock_);
visitor->VisitRoot(reinterpret_cast<mirror::Object**>(&root_), RootInfo(kRootUnknown));
VisitObjectLogs(visitor);
VisitArrayLogs(visitor);
@@ -755,7 +726,6 @@
if (kIsDebugBuild && Runtime::Current()->IsActiveTransaction()) {
transaction = Runtime::Current()->GetTransaction().get();
if (transaction != nullptr) {
- MutexLock mu(Thread::Current(), transaction->log_lock_);
CHECK(transaction->assert_no_new_records_reason_ == nullptr)
<< "old: " << transaction->assert_no_new_records_reason_ << " new: " << reason;
transaction->assert_no_new_records_reason_ = reason;
@@ -767,7 +737,6 @@
void ScopedAssertNoNewTransactionRecords::RemoveAssertion(Transaction* transaction) {
if (kIsDebugBuild) {
CHECK(Runtime::Current()->GetTransaction().get() == transaction);
- MutexLock mu(Thread::Current(), transaction->log_lock_);
CHECK(transaction->assert_no_new_records_reason_ != nullptr);
transaction->assert_no_new_records_reason_ = nullptr;
}
diff --git a/runtime/transaction.h b/runtime/transaction.h
index ece548c..8ee922f 100644
--- a/runtime/transaction.h
+++ b/runtime/transaction.h
@@ -51,21 +51,23 @@
~Transaction();
void Abort(const std::string& abort_message)
- REQUIRES(!log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void ThrowAbortError(Thread* self, const std::string* abort_message)
- REQUIRES(!log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- bool IsAborted() REQUIRES(!log_lock_);
+ bool IsAborted() const {
+ return aborted_;
+ }
// If the transaction is rollbacking. Transactions will set this flag when they start rollbacking,
// because the nested transaction should be disabled when rollbacking to restore the memory.
- bool IsRollingBack();
+ bool IsRollingBack() const {
+ return rolling_back_;
+ }
// If the transaction is in strict mode, then all access of static fields will be constrained,
// one class's clinit will not be allowed to read or modify another class's static fields, unless
// the transaction is aborted.
- bool IsStrict() {
+ bool IsStrict() const {
return strict_;
}
@@ -73,87 +75,68 @@
void RecordWriteFieldBoolean(mirror::Object* obj,
MemberOffset field_offset,
uint8_t value,
- bool is_volatile)
- REQUIRES(!log_lock_);
+ bool is_volatile);
void RecordWriteFieldByte(mirror::Object* obj,
MemberOffset field_offset,
int8_t value,
- bool is_volatile)
- REQUIRES(!log_lock_);
+ bool is_volatile);
void RecordWriteFieldChar(mirror::Object* obj,
MemberOffset field_offset,
uint16_t value,
- bool is_volatile)
- REQUIRES(!log_lock_);
+ bool is_volatile);
void RecordWriteFieldShort(mirror::Object* obj,
MemberOffset field_offset,
int16_t value,
- bool is_volatile)
- REQUIRES(!log_lock_);
+ bool is_volatile);
void RecordWriteField32(mirror::Object* obj,
MemberOffset field_offset,
uint32_t value,
- bool is_volatile)
- REQUIRES(!log_lock_);
+ bool is_volatile);
void RecordWriteField64(mirror::Object* obj,
MemberOffset field_offset,
uint64_t value,
- bool is_volatile)
- REQUIRES(!log_lock_);
+ bool is_volatile);
void RecordWriteFieldReference(mirror::Object* obj,
MemberOffset field_offset,
mirror::Object* value,
- bool is_volatile)
- REQUIRES(!log_lock_);
+ bool is_volatile);
// Record array change.
void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
- REQUIRES(!log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Record intern string table changes.
void RecordStrongStringInsertion(ObjPtr<mirror::String> s)
- REQUIRES(Locks::intern_table_lock_)
- REQUIRES(!log_lock_);
+ REQUIRES(Locks::intern_table_lock_);
void RecordWeakStringInsertion(ObjPtr<mirror::String> s)
- REQUIRES(Locks::intern_table_lock_)
- REQUIRES(!log_lock_);
+ REQUIRES(Locks::intern_table_lock_);
void RecordStrongStringRemoval(ObjPtr<mirror::String> s)
- REQUIRES(Locks::intern_table_lock_)
- REQUIRES(!log_lock_);
+ REQUIRES(Locks::intern_table_lock_);
void RecordWeakStringRemoval(ObjPtr<mirror::String> s)
- REQUIRES(Locks::intern_table_lock_)
- REQUIRES(!log_lock_);
+ REQUIRES(Locks::intern_table_lock_);
// Record resolve string.
void RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, dex::StringIndex string_idx)
- REQUIRES_SHARED(Locks::mutator_lock_)
- REQUIRES(!log_lock_);
+ REQUIRES_SHARED(Locks::mutator_lock_);
// Record resolve method type.
void RecordResolveMethodType(ObjPtr<mirror::DexCache> dex_cache, dex::ProtoIndex proto_idx)
- REQUIRES_SHARED(Locks::mutator_lock_)
- REQUIRES(!log_lock_);
+ REQUIRES_SHARED(Locks::mutator_lock_);
// Abort transaction by undoing all recorded changes.
void Rollback()
- REQUIRES_SHARED(Locks::mutator_lock_)
- REQUIRES(!log_lock_);
+ REQUIRES_SHARED(Locks::mutator_lock_);
void VisitRoots(RootVisitor* visitor)
- REQUIRES(!log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- bool ReadConstraint(Thread* self, ObjPtr<mirror::Object> obj)
- REQUIRES(!log_lock_)
+ bool ReadConstraint(ObjPtr<mirror::Object> obj) const
REQUIRES_SHARED(Locks::mutator_lock_);
- bool WriteConstraint(Thread* self, ObjPtr<mirror::Object> obj)
- REQUIRES(!log_lock_)
+ bool WriteConstraint(ObjPtr<mirror::Object> obj) const
REQUIRES_SHARED(Locks::mutator_lock_);
- bool WriteValueConstraint(Thread* self, ObjPtr<mirror::Object> value)
- REQUIRES(!log_lock_)
+ bool WriteValueConstraint(ObjPtr<mirror::Object> value) const
REQUIRES_SHARED(Locks::mutator_lock_);
private:
@@ -296,57 +279,45 @@
};
void LogInternedString(InternStringLog&& log)
- REQUIRES(Locks::intern_table_lock_)
- REQUIRES(!log_lock_);
+ REQUIRES(Locks::intern_table_lock_);
void UndoObjectModifications()
- REQUIRES(log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void UndoArrayModifications()
- REQUIRES(log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void UndoInternStringTableModifications()
REQUIRES(Locks::intern_table_lock_)
- REQUIRES(log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void UndoResolveStringModifications()
- REQUIRES(log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void UndoResolveMethodTypeModifications()
- REQUIRES(log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void VisitObjectLogs(RootVisitor* visitor)
- REQUIRES(log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void VisitArrayLogs(RootVisitor* visitor)
- REQUIRES(log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void VisitInternStringLogs(RootVisitor* visitor)
- REQUIRES(log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void VisitResolveStringLogs(RootVisitor* visitor)
- REQUIRES(log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
void VisitResolveMethodTypeLogs(RootVisitor* visitor)
- REQUIRES(log_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- const std::string& GetAbortMessage() REQUIRES(!log_lock_);
+ const std::string& GetAbortMessage() const;
- Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_);
- std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_);
- std::map<mirror::Array*, ArrayLog> array_logs_ GUARDED_BY(log_lock_);
- std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_);
- std::list<ResolveStringLog> resolve_string_logs_ GUARDED_BY(log_lock_);
- std::list<ResolveMethodTypeLog> resolve_method_type_logs_ GUARDED_BY(log_lock_);
- bool aborted_ GUARDED_BY(log_lock_);
+ std::map<mirror::Object*, ObjectLog> object_logs_;
+ std::map<mirror::Array*, ArrayLog> array_logs_ ;
+ std::list<InternStringLog> intern_string_logs_;
+ std::list<ResolveStringLog> resolve_string_logs_;
+ std::list<ResolveMethodTypeLog> resolve_method_type_logs_;
+ bool aborted_;
bool rolling_back_; // Single thread, no race.
gc::Heap* const heap_;
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_);
+ std::string abort_message_;
+ mirror::Class* root_;
+ const char* assert_no_new_records_reason_;
friend class ScopedAssertNoNewTransactionRecords;
diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc
index 4c2c4c2..5c78505 100644
--- a/runtime/transaction_test.cc
+++ b/runtime/transaction_test.cc
@@ -732,55 +732,54 @@
// Test non-strict transaction.
Transaction transaction(/*strict=*/ false, /*root=*/ nullptr);
// Static field in boot image.
- EXPECT_TRUE(transaction.WriteConstraint(soa.Self(), boolean_class.Get()));
- EXPECT_FALSE(transaction.ReadConstraint(soa.Self(), boolean_class.Get()));
+ EXPECT_TRUE(transaction.WriteConstraint(boolean_class.Get()));
+ EXPECT_FALSE(transaction.ReadConstraint(boolean_class.Get()));
// Instance field or array element in boot image.
// Do not check ReadConstraint(), it expects only static fields (checks for class object).
- EXPECT_TRUE(transaction.WriteConstraint(soa.Self(), true_value.Get()));
- EXPECT_TRUE(transaction.WriteConstraint(soa.Self(), array_iftable.Get()));
+ EXPECT_TRUE(transaction.WriteConstraint(true_value.Get()));
+ EXPECT_TRUE(transaction.WriteConstraint(array_iftable.Get()));
// Static field not in boot image.
- EXPECT_FALSE(transaction.WriteConstraint(soa.Self(), static_fields_test_class.Get()));
- EXPECT_FALSE(transaction.ReadConstraint(soa.Self(), static_fields_test_class.Get()));
+ EXPECT_FALSE(transaction.WriteConstraint(static_fields_test_class.Get()));
+ EXPECT_FALSE(transaction.ReadConstraint(static_fields_test_class.Get()));
// Instance field or array element not in boot image.
// Do not check ReadConstraint(), it expects only static fields (checks for class object).
- EXPECT_FALSE(transaction.WriteConstraint(soa.Self(), instance_fields_test_object.Get()));
- EXPECT_FALSE(transaction.WriteConstraint(soa.Self(), long_array_dim3.Get()));
+ EXPECT_FALSE(transaction.WriteConstraint(instance_fields_test_object.Get()));
+ EXPECT_FALSE(transaction.WriteConstraint(long_array_dim3.Get()));
// Write value constraints.
- EXPECT_FALSE(transaction.WriteValueConstraint(soa.Self(), static_fields_test_class.Get()));
- EXPECT_FALSE(transaction.WriteValueConstraint(soa.Self(), instance_fields_test_object.Get()));
- EXPECT_TRUE(transaction.WriteValueConstraint(soa.Self(), long_array_dim3->GetClass()));
- EXPECT_TRUE(transaction.WriteValueConstraint(soa.Self(), long_array_dim3.Get()));
- EXPECT_FALSE(transaction.WriteValueConstraint(soa.Self(), long_array->GetClass()));
- EXPECT_FALSE(transaction.WriteValueConstraint(soa.Self(), long_array.Get()));
+ EXPECT_FALSE(transaction.WriteValueConstraint(static_fields_test_class.Get()));
+ EXPECT_FALSE(transaction.WriteValueConstraint(instance_fields_test_object.Get()));
+ EXPECT_TRUE(transaction.WriteValueConstraint(long_array_dim3->GetClass()));
+ EXPECT_TRUE(transaction.WriteValueConstraint(long_array_dim3.Get()));
+ EXPECT_FALSE(transaction.WriteValueConstraint(long_array->GetClass()));
+ EXPECT_FALSE(transaction.WriteValueConstraint(long_array.Get()));
// Test strict transaction.
Transaction strict_transaction(/*strict=*/ true, /*root=*/ static_field_class.Get());
// Static field in boot image.
- EXPECT_TRUE(strict_transaction.WriteConstraint(soa.Self(), boolean_class.Get()));
- EXPECT_TRUE(strict_transaction.ReadConstraint(soa.Self(), boolean_class.Get()));
+ EXPECT_TRUE(strict_transaction.WriteConstraint(boolean_class.Get()));
+ EXPECT_TRUE(strict_transaction.ReadConstraint(boolean_class.Get()));
// Instance field or array element in boot image.
// Do not check ReadConstraint(), it expects only static fields (checks for class object).
- EXPECT_TRUE(strict_transaction.WriteConstraint(soa.Self(), true_value.Get()));
- EXPECT_TRUE(strict_transaction.WriteConstraint(soa.Self(), array_iftable.Get()));
+ EXPECT_TRUE(strict_transaction.WriteConstraint(true_value.Get()));
+ EXPECT_TRUE(strict_transaction.WriteConstraint(array_iftable.Get()));
// Static field in another class not in boot image.
- EXPECT_TRUE(strict_transaction.WriteConstraint(soa.Self(), static_fields_test_class.Get()));
- EXPECT_TRUE(strict_transaction.ReadConstraint(soa.Self(), static_fields_test_class.Get()));
+ EXPECT_TRUE(strict_transaction.WriteConstraint(static_fields_test_class.Get()));
+ EXPECT_TRUE(strict_transaction.ReadConstraint(static_fields_test_class.Get()));
// Instance field or array element not in boot image.
// Do not check ReadConstraint(), it expects only static fields (checks for class object).
- EXPECT_FALSE(strict_transaction.WriteConstraint(soa.Self(), instance_fields_test_object.Get()));
- EXPECT_FALSE(strict_transaction.WriteConstraint(soa.Self(), long_array_dim3.Get()));
+ EXPECT_FALSE(strict_transaction.WriteConstraint(instance_fields_test_object.Get()));
+ EXPECT_FALSE(strict_transaction.WriteConstraint(long_array_dim3.Get()));
// Static field in the same class.
- EXPECT_FALSE(strict_transaction.WriteConstraint(soa.Self(), static_field_class.Get()));
- EXPECT_FALSE(strict_transaction.ReadConstraint(soa.Self(), static_field_class.Get()));
+ EXPECT_FALSE(strict_transaction.WriteConstraint(static_field_class.Get()));
+ EXPECT_FALSE(strict_transaction.ReadConstraint(static_field_class.Get()));
// Write value constraints.
- EXPECT_FALSE(strict_transaction.WriteValueConstraint(soa.Self(), static_fields_test_class.Get()));
- EXPECT_FALSE(
- strict_transaction.WriteValueConstraint(soa.Self(), instance_fields_test_object.Get()));
+ EXPECT_FALSE(strict_transaction.WriteValueConstraint(static_fields_test_class.Get()));
+ EXPECT_FALSE(strict_transaction.WriteValueConstraint(instance_fields_test_object.Get()));
// TODO: The following may be revised, see a TODO in Transaction::WriteValueConstraint().
- EXPECT_FALSE(strict_transaction.WriteValueConstraint(soa.Self(), long_array_dim3->GetClass()));
- EXPECT_FALSE(strict_transaction.WriteValueConstraint(soa.Self(), long_array_dim3.Get()));
- EXPECT_FALSE(strict_transaction.WriteValueConstraint(soa.Self(), long_array->GetClass()));
- EXPECT_FALSE(strict_transaction.WriteValueConstraint(soa.Self(), long_array.Get()));
+ EXPECT_FALSE(strict_transaction.WriteValueConstraint(long_array_dim3->GetClass()));
+ EXPECT_FALSE(strict_transaction.WriteValueConstraint(long_array_dim3.Get()));
+ EXPECT_FALSE(strict_transaction.WriteValueConstraint(long_array->GetClass()));
+ EXPECT_FALSE(strict_transaction.WriteValueConstraint(long_array.Get()));
}
} // namespace art