summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-07-10 17:35:57 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-07-10 16:05:36 +0000
commitadce33da293b0eeaaf52673338770f22be71ca5d (patch)
treeb2d65f4668793fab5652dfe41dcf13c913fee3a8 /runtime
parentcba6b1fc88fd54c35211fd49a7a7501cfcdaa170 (diff)
parent228602f562f1d130d06e60a98752d99c2d467d6a (diff)
downloadart-adce33da293b0eeaaf52673338770f22be71ca5d.zip
art-adce33da293b0eeaaf52673338770f22be71ca5d.tar.gz
art-adce33da293b0eeaaf52673338770f22be71ca5d.tar.bz2
Merge "Make CAS operations in Object use art::Atomic."
Diffstat (limited to 'runtime')
-rw-r--r--runtime/interpreter/interpreter.cc6
-rw-r--r--runtime/mirror/object-inl.h47
-rw-r--r--runtime/mirror/object.cc2
-rw-r--r--runtime/mirror/object.h12
-rw-r--r--runtime/monitor.cc4
-rw-r--r--runtime/native/sun_misc_Unsafe.cc9
6 files changed, 45 insertions, 35 deletions
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index cb4d444..729444e 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -95,9 +95,11 @@ static void UnstartedRuntimeJni(Thread* self, ArtMethod* method,
jint newValue = args[4];
bool success;
if (Runtime::Current()->IsActiveTransaction()) {
- success = obj->CasField32<true>(MemberOffset(offset), expectedValue, newValue);
+ success = obj->CasFieldWeakSequentiallyConsistent32<true>(MemberOffset(offset),
+ expectedValue, newValue);
} else {
- success = obj->CasField32<false>(MemberOffset(offset), expectedValue, newValue);
+ success = obj->CasFieldWeakSequentiallyConsistent32<false>(MemberOffset(offset),
+ expectedValue, newValue);
}
result->SetZ(success ? JNI_TRUE : JNI_FALSE);
} else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") {
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 62c1162..089ef57 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -69,10 +69,10 @@ inline void Object::SetLockWord(LockWord new_val, bool as_volatile) {
}
}
-inline bool Object::CasLockWord(LockWord old_val, LockWord new_val) {
+inline bool Object::CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) {
// Force use of non-transactional mode and do not check.
- return CasField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(),
- new_val.GetValue());
+ return CasFieldWeakSequentiallyConsistent32<false, false>(
+ OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
}
inline uint32_t Object::GetLockOwnerThreadId() {
@@ -131,21 +131,17 @@ inline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object*
DCHECK(kUseBakerOrBrooksReadBarrier);
MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_);
byte* raw_addr = reinterpret_cast<byte*>(this) + offset.SizeValue();
- HeapReference<Object>* ref = reinterpret_cast<HeapReference<Object>*>(raw_addr);
+ Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr));
HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr));
- uint32_t expected_val = expected_ref.reference_;
- uint32_t new_val;
do {
- uint32_t old_val = ref->reference_;
- if (old_val != expected_val) {
+ if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) {
// Lost the race.
return false;
}
- new_val = new_ref.reference_;
- } while (!__sync_bool_compare_and_swap(
- reinterpret_cast<uint32_t*>(raw_addr), expected_val, new_val));
- DCHECK_EQ(new_val, ref->reference_);
+ } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_,
+ new_ref.reference_));
+ DCHECK_EQ(new_ref.reference_, atomic_rb_ptr->LoadRelaxed());
return true;
#else
LOG(FATAL) << "Unreachable";
@@ -448,7 +444,8 @@ inline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_va
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value) {
+inline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset,
+ int32_t old_value, int32_t new_value) {
if (kCheckTransaction) {
DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
}
@@ -459,9 +456,9 @@ inline bool Object::CasField32(MemberOffset field_offset, int32_t old_value, int
VerifyObject(this);
}
byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
- volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr);
+ AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
- return __sync_bool_compare_and_swap(addr, old_value, new_value);
+ return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
}
template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
@@ -513,7 +510,8 @@ inline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_va
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value) {
+inline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset,
+ int64_t old_value, int64_t new_value) {
if (kCheckTransaction) {
DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
}
@@ -524,8 +522,8 @@ inline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int
VerifyObject(this);
}
byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
- volatile int64_t* addr = reinterpret_cast<volatile int64_t*>(raw_addr);
- return QuasiAtomic::Cas64(old_value, new_value, addr);
+ Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
+ return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
}
template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption,
@@ -615,8 +613,8 @@ inline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset f
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value,
- Object* new_value) {
+inline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
+ Object* old_value, Object* new_value) {
if (kCheckTransaction) {
DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
}
@@ -632,11 +630,14 @@ inline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value,
if (kTransactionActive) {
Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
}
- byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
- volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr);
HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
- bool success = __sync_bool_compare_and_swap(addr, old_ref.reference_, new_ref.reference_);
+ byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
+ Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
+
+ bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_,
+ new_ref.reference_);
+
if (success) {
Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
}
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index 422a88b..e58091f 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -156,7 +156,7 @@ int32_t Object::IdentityHashCode() const {
// loop iteration.
LockWord hash_word(LockWord::FromHashCode(GenerateIdentityHashCode()));
DCHECK_EQ(hash_word.GetState(), LockWord::kHashCode);
- if (const_cast<Object*>(this)->CasLockWord(lw, hash_word)) {
+ if (const_cast<Object*>(this)->CasLockWordWeakSequentiallyConsistent(lw, hash_word)) {
return hash_word.GetHashCode();
}
break;
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index c082443..d29011a 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -110,7 +110,8 @@ class MANAGED LOCKABLE Object {
// have C++11 "strong" semantics.
// TODO: In most, possibly all, cases, these assumptions are too strong.
// Confirm and weaken the implementation.
- bool CasLockWord(LockWord old_val, LockWord new_val) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
uint32_t GetLockOwnerThreadId();
mirror::Object* MonitorEnter(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
@@ -226,7 +227,8 @@ class MANAGED LOCKABLE Object {
template<bool kTransactionActive, bool kCheckTransaction = true,
VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldObject(MemberOffset field_offset, Object* old_value, Object* new_value)
+ bool CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset, Object* old_value,
+ Object* new_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -252,7 +254,8 @@ class MANAGED LOCKABLE Object {
template<bool kTransactionActive, bool kCheckTransaction = true,
VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value) ALWAYS_INLINE
+ bool CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset, int32_t old_value,
+ int32_t new_value) ALWAYS_INLINE
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
@@ -275,7 +278,8 @@ class MANAGED LOCKABLE Object {
template<bool kTransactionActive, bool kCheckTransaction = true,
VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value)
+ bool CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset, int64_t old_value,
+ int64_t new_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<bool kTransactionActive, bool kCheckTransaction = true,
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index c3ec38d..5633a77 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -163,7 +163,7 @@ bool Monitor::Install(Thread* self) {
}
LockWord fat(this);
// Publish the updated lock word, which may race with other threads.
- bool success = GetObject()->CasLockWord(lw, fat);
+ bool success = GetObject()->CasLockWordWeakSequentiallyConsistent(lw, fat);
// Lock profiling.
if (success && owner_ != nullptr && lock_profiling_threshold_ != 0) {
locking_method_ = owner_->GetCurrentMethod(&locking_dex_pc_);
@@ -722,7 +722,7 @@ mirror::Object* Monitor::MonitorEnter(Thread* self, mirror::Object* obj) {
switch (lock_word.GetState()) {
case LockWord::kUnlocked: {
LockWord thin_locked(LockWord::FromThinLockId(thread_id, 0));
- if (h_obj->CasLockWord(lock_word, thin_locked)) {
+ if (h_obj->CasLockWordWeakSequentiallyConsistent(lock_word, thin_locked)) {
// CasLockWord enforces more than the acquire ordering we need here.
return h_obj.Get(); // Success!
}
diff --git a/runtime/native/sun_misc_Unsafe.cc b/runtime/native/sun_misc_Unsafe.cc
index d23cfff..7cc4cac 100644
--- a/runtime/native/sun_misc_Unsafe.cc
+++ b/runtime/native/sun_misc_Unsafe.cc
@@ -28,7 +28,8 @@ static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj,
ScopedFastNativeObjectAccess soa(env);
mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
// JNI must use non transactional mode.
- bool success = obj->CasField32<false>(MemberOffset(offset), expectedValue, newValue);
+ bool success = obj->CasFieldWeakSequentiallyConsistent32<false>(MemberOffset(offset),
+ expectedValue, newValue);
return success ? JNI_TRUE : JNI_FALSE;
}
@@ -37,7 +38,8 @@ static jboolean Unsafe_compareAndSwapLong(JNIEnv* env, jobject, jobject javaObj,
ScopedFastNativeObjectAccess soa(env);
mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
// JNI must use non transactional mode.
- bool success = obj->CasField64<false>(MemberOffset(offset), expectedValue, newValue);
+ bool success = obj->CasFieldWeakSequentiallyConsistent64<false>(MemberOffset(offset),
+ expectedValue, newValue);
return success ? JNI_TRUE : JNI_FALSE;
}
@@ -48,7 +50,8 @@ static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaOb
mirror::Object* expectedValue = soa.Decode<mirror::Object*>(javaExpectedValue);
mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
// JNI must use non transactional mode.
- bool success = obj->CasFieldObject<false>(MemberOffset(offset), expectedValue, newValue);
+ bool success = obj->CasFieldWeakSequentiallyConsistentObject<false>(MemberOffset(offset),
+ expectedValue, newValue);
return success ? JNI_TRUE : JNI_FALSE;
}