Reduce the number of fences needed for monitors
Add the necessary CasWeakAcquire primitives for LockWords.
Have MonitorEnter initially read the lockword using a
memory_order_relaxed operation. In the unlikely case we need more,
compensate with an explicit fence.
In the uncontended case, install the thin lock with Acquire,
rather than SequentiallyConsistent semantics.
Have MonitorExit use a Release instead of SequentiallyConsistent
CAS in the ReadBarrier case. Add TODO for the other case.
Together, these should usually eliminate 3 fences (or acq/rel)
per critical section.
Have Install() only use Release ordering.
Add TODO for inflation spinning, which looks to me like it could be
improved appreciably.
Drive-by fix:
GetMaxSpinsBeforeThinLockInflation spelling
Test: Build for several targets, boot, m art-test-host art-test-target
Change-Id: I2cab09723252065f6365e4234ee3249c69ece888
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 6d29ed3..354410e 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -97,6 +97,12 @@
OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
}
+inline bool Object::CasLockWordWeakAcquire(LockWord old_val, LockWord new_val) {
+ // Force use of non-transactional mode and do not check.
+ return CasFieldWeakAcquire32<false, false>(
+ OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
+}
+
inline bool Object::CasLockWordWeakRelease(LockWord old_val, LockWord new_val) {
// Force use of non-transactional mode and do not check.
return CasFieldWeakRelease32<false, false>(
@@ -759,6 +765,24 @@
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
+inline bool Object::CasFieldWeakAcquire32(MemberOffset field_offset,
+ int32_t old_value, int32_t new_value) {
+ if (kCheckTransaction) {
+ DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
+ }
+ if (kTransactionActive) {
+ Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
+ }
+ if (kVerifyFlags & kVerifyThis) {
+ VerifyObject(this);
+ }
+ uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
+ AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
+
+ return atomic_addr->CompareExchangeWeakAcquire(old_value, new_value);
+}
+
+template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
inline bool Object::CasFieldWeakRelease32(MemberOffset field_offset,
int32_t old_value, int32_t new_value) {
if (kCheckTransaction) {