inlinebool Object::CasLockWord(LockWord old_val,
LockWord new_val,
CASMode mode,
std::memory_order memory_order) { // Force use of non-transactional mode and do not check. return CasField32<false, false>(MonitorOffset(),
old_val.GetValue(),
new_val.GetValue(),
mode,
memory_order);
}
inline uint32_t Object::GetReadBarrierState(uintptr_t* fake_address_dependency) { if (!kUseBakerReadBarrier) {
LOG(FATAL) << "Unreachable";
UNREACHABLE();
} #ifdefined(__arm__)
uintptr_t obj = reinterpret_cast<uintptr_t>(this);
uintptr_t result;
DCHECK_EQ(OFFSETOF_MEMBER(Object, monitor_), 4U); // Use inline assembly to prevent the compiler from optimizing away the false dependency.
__asm__ __volatile__( "ldr %[result], [%[obj], #4]\n\t" // This instruction is enough to "fool the compiler and the CPU" by having `fad` always be // null, without them being able to assume that fact. "eor %[fad], %[result], %[result]\n\t"
: [result] "+r" (result), [fad] "=r" (*fake_address_dependency)
: [obj] "r" (obj));
DCHECK_EQ(*fake_address_dependency, 0U);
LockWord lw(static_cast<uint32_t>(result));
uint32_t rb_state = lw.ReadBarrierState(); return rb_state; #elifdefined(__aarch64__)
uintptr_t obj = reinterpret_cast<uintptr_t>(this);
uintptr_t result;
DCHECK_EQ(OFFSETOF_MEMBER(Object, monitor_), 4U); // Use inline assembly to prevent the compiler from optimizing away the false dependency.
__asm__ __volatile__( "ldr %w[result], [%[obj], #4]\n\t" // This instruction is enough to "fool the compiler and the CPU" by having `fad` always be // null, without them being able to assume that fact. "eor %[fad], %[result], %[result]\n\t"
: [result] "+r" (result), [fad] "=r" (*fake_address_dependency)
: [obj] "r" (obj));
DCHECK_EQ(*fake_address_dependency, 0U);
LockWord lw(static_cast<uint32_t>(result));
uint32_t rb_state = lw.ReadBarrierState(); return rb_state; #elifdefined(__i386__) || defined(__x86_64__) || defined(__riscv) // TODO(riscv64): add arch-specific implementation
LockWord lw = GetLockWord(false); // i386/x86_64 don't need fake address dependency. Use a compiler fence to avoid compiler // reordering.
*fake_address_dependency = 0;
std::atomic_signal_fence(std::memory_order_acquire);
uint32_t rb_state = lw.ReadBarrierState(); return rb_state; #else
UNUSED(fake_address_dependency);
LOG(FATAL) << "Unsupported architecture.";
UNREACHABLE(); #endif
}
inlinebool Object::AtomicSetReadBarrierState(uint32_t expected_rb_state,
uint32_t rb_state,
std::memory_order order) { if (!kUseBakerReadBarrier) {
LOG(FATAL) << "Unreachable";
UNREACHABLE();
}
DCHECK(ReadBarrier::IsValidReadBarrierState(expected_rb_state)) << expected_rb_state;
DCHECK(ReadBarrier::IsValidReadBarrierState(rb_state)) << rb_state;
LockWord expected_lw;
LockWord new_lw; do {
LockWord lw = GetLockWord(false); if (UNLIKELY(lw.ReadBarrierState() != expected_rb_state)) { // Lost the race. returnfalse;
}
expected_lw = lw;
expected_lw.SetReadBarrierState(expected_rb_state);
new_lw = lw;
new_lw.SetReadBarrierState(rb_state); // ConcurrentCopying::ProcessMarkStackRef uses this with // `kMemoryOrder` == `std::memory_order_release`. // If `kMemoryOrder` == `std::memory_order_release`, use a CAS release so that when GC updates // all the fields of an object and then changes the object from gray to black (non-gray), the // field updates (stores) will be visible (won't be reordered after this CAS.)
} while (!CasLockWord(expected_lw, new_lw, CASMode::kWeak, order)); returntrue;
}
inlinebool Object::AtomicSetMarkBit(uint32_t expected_mark_bit, uint32_t mark_bit) {
LockWord expected_lw;
LockWord new_lw; do {
LockWord lw = GetLockWord(false); if (UNLIKELY(lw.MarkBitState() != expected_mark_bit)) { // Lost the race. returnfalse;
}
expected_lw = lw;
new_lw = lw;
new_lw.SetMarkBitState(mark_bit); // Since this is only set from the mutator, we can use the non-release CAS.
} while (!CasLockWord(expected_lw, new_lw, CASMode::kWeak, std::memory_order_relaxed)); returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.