diff options
author | Hiroshi Yamauchi <yamauchi@google.com> | 2015-04-23 16:12:40 -0700 |
---|---|---|
committer | Hiroshi Yamauchi <yamauchi@google.com> | 2015-04-23 21:11:40 -0700 |
commit | 60f63f53c01cb38ca18a815603282e802a6cf918 (patch) | |
tree | 4f18427401ead0c790e926672957189a0c0a39eb /runtime/mirror | |
parent | 633a37ece49c5afcf3fa9a89692f07d19c56229b (diff) | |
download | art-60f63f53c01cb38ca18a815603282e802a6cf918.tar.gz art-60f63f53c01cb38ca18a815603282e802a6cf918.tar.bz2 art-60f63f53c01cb38ca18a815603282e802a6cf918.zip |
Use the lock word bits for Baker-style read barrier.
This enables the standard object header to be used with the
Baker-style read barrier.
Bug: 19355854
Bug: 12687968
Change-Id: Ie552b6e1dfe30e96cb1d0895bd0dff25f9d7d015
Diffstat (limited to 'runtime/mirror')
-rw-r--r-- | runtime/mirror/object-inl.h | 40 | ||||
-rw-r--r-- | runtime/mirror/object.h | 9 |
2 files changed, 40 insertions, 9 deletions
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 2581fad740..95c1d110f2 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -115,8 +115,11 @@ inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { } inline Object* Object::GetReadBarrierPointer() { -#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER - DCHECK(kUseBakerOrBrooksReadBarrier); +#ifdef USE_BAKER_READ_BARRIER + DCHECK(kUseBakerReadBarrier); + return reinterpret_cast<Object*>(GetLockWord(false).ReadBarrierState()); +#elif USE_BROOKS_READ_BARRIER + DCHECK(kUseBrooksReadBarrier); return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>( OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_)); #else @@ -126,8 +129,14 @@ inline Object* Object::GetReadBarrierPointer() { } inline void Object::SetReadBarrierPointer(Object* rb_ptr) { -#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER - DCHECK(kUseBakerOrBrooksReadBarrier); +#ifdef USE_BAKER_READ_BARRIER + DCHECK(kUseBakerReadBarrier); + DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U); + LockWord lw = GetLockWord(false); + lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr))); + SetLockWord(lw, false); +#elif USE_BROOKS_READ_BARRIER + DCHECK(kUseBrooksReadBarrier); // We don't mark the card as this occurs as part of object allocation. Not all objects have // backing cards, such as large objects. SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>( @@ -140,8 +149,27 @@ inline void Object::SetReadBarrierPointer(Object* rb_ptr) { } inline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) { -#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER - DCHECK(kUseBakerOrBrooksReadBarrier); +#ifdef USE_BAKER_READ_BARRIER + DCHECK(kUseBakerReadBarrier); + DCHECK_EQ(reinterpret_cast<uint64_t>(expected_rb_ptr) >> 32, 0U); + DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U); + LockWord expected_lw; + LockWord new_lw; + do { + LockWord lw = GetLockWord(false); + if (UNLIKELY(reinterpret_cast<Object*>(lw.ReadBarrierState()) != expected_rb_ptr)) { + // Lost the race. + return false; + } + expected_lw = lw; + expected_lw.SetReadBarrierState( + static_cast<uint32_t>(reinterpret_cast<uintptr_t>(expected_rb_ptr))); + new_lw = lw; + new_lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr))); + } while (!CasLockWordWeakSequentiallyConsistent(expected_lw, new_lw)); + return true; +#elif USE_BROOKS_READ_BARRIER + DCHECK(kUseBrooksReadBarrier); MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_); uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + offset.SizeValue(); Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index 343c9bc8b6..7f162b7bdd 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -62,7 +62,7 @@ class Throwable; static constexpr bool kCheckFieldAssignments = false; // Size of Object. -static constexpr uint32_t kObjectHeaderSize = kUseBakerOrBrooksReadBarrier ? 16 : 8; +static constexpr uint32_t kObjectHeaderSize = kUseBrooksReadBarrier ? 16 : 8; // C++ mirror of java.lang.Object class MANAGED LOCKABLE Object { @@ -94,6 +94,9 @@ class MANAGED LOCKABLE Object { NO_RETURN #endif void SetReadBarrierPointer(Object* rb_ptr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); +#ifndef USE_BAKER_OR_BROOKS_READ_BARRIER + NO_RETURN +#endif bool AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void AssertReadBarrierPointer() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -502,11 +505,11 @@ class MANAGED LOCKABLE Object { // Monitor and hash code information. uint32_t monitor_; -#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER +#ifdef USE_BROOKS_READ_BARRIER // Note names use a 'x' prefix and the x_rb_ptr_ is of type int // instead of Object to go with the alphabetical/by-type field order // on the Java side. - uint32_t x_rb_ptr_; // For the Baker or Brooks pointer. + uint32_t x_rb_ptr_; // For the Brooks pointer. uint32_t x_xpadding_; // For 8-byte alignment. TODO: get rid of this. #endif |