diff options
| author | 2021-07-06 14:04:30 +0100 | |
|---|---|---|
| committer | 2021-07-07 08:01:57 +0000 | |
| commit | 24c080f628e7df51460332374f4ebcae2762d155 (patch) | |
| tree | cbb0231518ce4afc94310b13edb1b87e5f14600b | |
| parent | 4dc6589f392d46800a3b64625245bdfe4bbbfc2f (diff) | |
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
| -rw-r--r-- | runtime/interpreter/interpreter_common.h | 6 | ||||
| -rw-r--r-- | runtime/transaction.cc | 43 | ||||
| -rw-r--r-- | runtime/transaction.h | 99 | ||||
| -rw-r--r-- | runtime/transaction_test.cc | 61 |
4 files changed, 74 insertions, 135 deletions
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 959df0010d..3bbfc55179 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -499,7 +499,7 @@ ALWAYS_INLINE bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, const Ins 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 @@ ALWAYS_INLINE bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, const Ins 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 CheckWriteConstraint(Thread* self, ObjPtr<mirror::Object> obj 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 0ad7a78258..0aec48cabd 100644 --- a/runtime/transaction.cc +++ b/runtime/transaction.cc @@ -41,8 +41,7 @@ namespace art { 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(bool strict, mirror::Class* root) 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 @@ Transaction::~Transaction() { } 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 @@ void Transaction::ThrowAbortError(Thread* self, const std::string* abort_message } } -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 @@ bool Transaction::WriteConstraint(Thread* self, ObjPtr<mirror::Object> obj) { 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::WriteValueConstraint(Thread* self, ObjPtr<mirror::Object> valu } } -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 @@ void Transaction::RecordWriteFieldBoolean(mirror::Object* obj, 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 @@ void Transaction::RecordWriteFieldByte(mirror::Object* obj, 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 @@ void Transaction::RecordWriteFieldChar(mirror::Object* obj, 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 @@ void Transaction::RecordWriteFieldShort(mirror::Object* obj, 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 @@ void Transaction::RecordWriteField32(mirror::Object* obj, 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 @@ void Transaction::RecordWriteField64(mirror::Object* obj, 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 @@ void Transaction::RecordWriteFieldReference(mirror::Object* obj, 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 @@ void Transaction::RecordWriteArray(mirror::Array* array, size_t index, uint64_t 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 @@ void Transaction::RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, 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 @@ void Transaction::RecordResolveMethodType(ObjPtr<mirror::DexCache> dex_cache, 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::RecordWeakStringRemoval(ObjPtr<mirror::String> s) { 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::LogInternedString(InternStringLog&& log) { 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::UndoResolveMethodTypeModifications() { } 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 @@ Transaction* ScopedAssertNoNewTransactionRecords::InstallAssertion(const char* r 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 @@ Transaction* ScopedAssertNoNewTransactionRecords::InstallAssertion(const char* r 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 ece548c15a..8ee922f468 100644 --- a/runtime/transaction.h +++ b/runtime/transaction.h @@ -51,21 +51,23 @@ class Transaction final { ~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 @@ class Transaction final { 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 @@ class Transaction final { }; 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 4c2c4c22d8..5c78505da7 100644 --- a/runtime/transaction_test.cc +++ b/runtime/transaction_test.cc @@ -732,55 +732,54 @@ TEST_F(TransactionTest, Constraints) { // 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 |