diff options
Diffstat (limited to 'runtime/mirror/array.h')
-rw-r--r-- | runtime/mirror/array.h | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h index 2e123ef215..7555975c41 100644 --- a/runtime/mirror/array.h +++ b/runtime/mirror/array.h @@ -20,6 +20,7 @@ #include "object.h" #include "object_callbacks.h" #include "gc/heap.h" +#include "runtime.h" #include "thread.h" namespace art { @@ -60,7 +61,9 @@ class MANAGED Array : public Object { void SetLength(int32_t length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { CHECK_GE(length, 0); - SetField32(OFFSET_OF_OBJECT_MEMBER(Array, length_), length, false, false); + // We use non transactional version since we can't undo this write. We also disable checking + // since it would fail during a transaction. + SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Array, length_), length, false, false); } static MemberOffset LengthOffset() { @@ -144,14 +147,34 @@ class MANAGED PrimitiveArray : public Array { } void Set(int32_t i, T value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + if (Runtime::Current()->IsActiveTransaction()) { + Set<true>(i, value); + } else { + Set<false>(i, value); + } + } + + // TODO fix thread safety analysis broken by the use of template. This should be + // SHARED_LOCKS_REQUIRED(Locks::mutator_lock_). + template<bool kTransactionActive, bool kCheckTransaction = true> + void Set(int32_t i, T value) NO_THREAD_SAFETY_ANALYSIS { if (LIKELY(CheckIsValidIndex(i))) { - SetWithoutChecks(i, value); + SetWithoutChecks<kTransactionActive, kCheckTransaction>(i, value); } else { DCHECK(Thread::Current()->IsExceptionPending()); } } - void SetWithoutChecks(int32_t i, T value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + // TODO fix thread safety analysis broken by the use of template. This should be + // SHARED_LOCKS_REQUIRED(Locks::mutator_lock_). + template<bool kTransactionActive, bool kCheckTransaction = true> + void SetWithoutChecks(int32_t i, T value) NO_THREAD_SAFETY_ANALYSIS { + if (kCheckTransaction) { + DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); + } + if (kTransactionActive) { + Runtime::Current()->RecordWriteArray(this, i, GetWithoutChecks(i)); + } DCHECK(CheckIsValidIndex(i)); GetData()[i] = value; } |