summaryrefslogtreecommitdiff
path: root/runtime/mirror/array.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/mirror/array.h')
-rw-r--r--runtime/mirror/array.h29
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;
}