8276047: G1: refactor G1CardSetArrayLocker

Reviewed-by: tschatzl, sjohanss
This commit is contained in:
Albert Mingkun Yang 2021-10-29 09:06:36 +00:00
parent e922023ec9
commit 24cf48000a
2 changed files with 17 additions and 18 deletions

@ -196,19 +196,19 @@ private:
static const EntryCountType EntryMask = LockBitMask - 1;
class G1CardSetArrayLocker : public StackObj {
EntryCountType volatile* _value;
EntryCountType volatile _original_value;
bool _success;
EntryCountType volatile* _num_entries_addr;
EntryCountType _local_num_entries;
public:
G1CardSetArrayLocker(EntryCountType volatile* value);
EntryCountType num_entries() const { return _original_value; }
void inc_num_entries() { _success = true; }
EntryCountType num_entries() const { return _local_num_entries; }
void inc_num_entries() {
assert(((_local_num_entries + 1) & EntryMask) == (EntryCountType)(_local_num_entries + 1), "no overflow" );
_local_num_entries++;
}
~G1CardSetArrayLocker() {
assert(((_original_value + _success) & EntryMask) == (EntryCountType)(_original_value + _success), "precondition!" );
Atomic::release_store(_value, (EntryCountType)(_original_value + _success));
Atomic::release_store(_num_entries_addr, _local_num_entries);
}
};

@ -145,22 +145,21 @@ inline G1CardSetArray::G1CardSetArray(uint card_in_region, EntryCountType num_el
_data[0] = card_in_region;
}
inline G1CardSetArray::G1CardSetArrayLocker::G1CardSetArrayLocker(EntryCountType volatile* value) :
_value(value),
_success(false) {
inline G1CardSetArray::G1CardSetArrayLocker::G1CardSetArrayLocker(EntryCountType volatile* num_entries_addr) :
_num_entries_addr(num_entries_addr) {
SpinYield s;
EntryCountType original_value = (*_value) & EntryMask;
EntryCountType num_entries = Atomic::load(_num_entries_addr) & EntryMask;
while (true) {
EntryCountType old_value = Atomic::cmpxchg(_value,
original_value,
(EntryCountType)(original_value | LockBitMask));
if (old_value == original_value) {
EntryCountType old_value = Atomic::cmpxchg(_num_entries_addr,
num_entries,
(EntryCountType)(num_entries | LockBitMask));
if (old_value == num_entries) {
// Succeeded locking the array.
_original_value = original_value;
_local_num_entries = num_entries;
break;
}
// Failed. Retry (with the lock bit stripped again).
original_value = old_value & EntryMask;
num_entries = old_value & EntryMask;
s.wait();
}
}