8332683: G1: G1CardSetArray::EntryDataType [2] triggers ubsan runtime errors
Reviewed-by: tschatzl, ayang
This commit is contained in:
parent
f3d6fbf52e
commit
891d5aedf1
@ -163,7 +163,8 @@ public:
|
||||
private:
|
||||
EntryCountType _size;
|
||||
EntryCountType volatile _num_entries;
|
||||
EntryDataType _data[2];
|
||||
// VLA implementation.
|
||||
EntryDataType _data[1];
|
||||
|
||||
static const EntryCountType LockBitMask = (EntryCountType)1 << (sizeof(EntryCountType) * BitsPerByte - 1);
|
||||
static const EntryCountType EntryMask = LockBitMask - 1;
|
||||
@ -184,6 +185,14 @@ private:
|
||||
Atomic::release_store(_num_entries_addr, _local_num_entries);
|
||||
}
|
||||
};
|
||||
|
||||
EntryDataType const* base_addr() const;
|
||||
|
||||
EntryDataType const* entry_addr(EntryCountType index) const;
|
||||
|
||||
EntryDataType* entry_addr(EntryCountType index);
|
||||
|
||||
EntryDataType at(EntryCountType index) const;
|
||||
public:
|
||||
G1CardSetArray(uint const card_in_region, EntryCountType num_cards);
|
||||
|
||||
|
@ -145,7 +145,7 @@ inline G1CardSetArray::G1CardSetArray(uint card_in_region, EntryCountType num_ca
|
||||
_num_entries(1) {
|
||||
assert(_size > 0, "CardSetArray of size 0 not supported.");
|
||||
assert(_size < LockBitMask, "Only support CardSetArray of size %u or smaller.", LockBitMask - 1);
|
||||
_data[0] = checked_cast<EntryDataType>(card_in_region);
|
||||
*entry_addr(0) = checked_cast<EntryDataType>(card_in_region);
|
||||
}
|
||||
|
||||
inline G1CardSetArray::G1CardSetArrayLocker::G1CardSetArrayLocker(EntryCountType volatile* num_entries_addr) :
|
||||
@ -167,13 +167,31 @@ inline G1CardSetArray::G1CardSetArrayLocker::G1CardSetArrayLocker(EntryCountType
|
||||
}
|
||||
}
|
||||
|
||||
inline G1CardSetArray::EntryDataType const* G1CardSetArray::base_addr() const {
|
||||
const void* ptr = reinterpret_cast<const char*>(this) + header_size_in_bytes();
|
||||
return reinterpret_cast<EntryDataType const*>(ptr);
|
||||
}
|
||||
|
||||
inline G1CardSetArray::EntryDataType const* G1CardSetArray::entry_addr(EntryCountType index) const {
|
||||
assert(index < _num_entries, "precondition");
|
||||
return base_addr() + index;
|
||||
}
|
||||
|
||||
inline G1CardSetArray::EntryDataType* G1CardSetArray::entry_addr(EntryCountType index) {
|
||||
return const_cast<EntryDataType*>(const_cast<const G1CardSetArray*>(this)->entry_addr(index));
|
||||
}
|
||||
|
||||
inline G1CardSetArray::EntryDataType G1CardSetArray::at(EntryCountType index) const {
|
||||
return *entry_addr(index);
|
||||
}
|
||||
|
||||
inline G1AddCardResult G1CardSetArray::add(uint card_idx) {
|
||||
assert(card_idx < (1u << (sizeof(_data[0]) * BitsPerByte)),
|
||||
assert(card_idx < (1u << (sizeof(EntryDataType) * BitsPerByte)),
|
||||
"Card index %u does not fit allowed card value range.", card_idx);
|
||||
EntryCountType num_entries = Atomic::load_acquire(&_num_entries) & EntryMask;
|
||||
EntryCountType idx = 0;
|
||||
for (; idx < num_entries; idx++) {
|
||||
if (_data[idx] == card_idx) {
|
||||
if (at(idx) == card_idx) {
|
||||
return Found;
|
||||
}
|
||||
}
|
||||
@ -186,7 +204,7 @@ inline G1AddCardResult G1CardSetArray::add(uint card_idx) {
|
||||
num_entries = x.num_entries();
|
||||
// Look if the cards added while waiting for the lock are the same as our card.
|
||||
for (; idx < num_entries; idx++) {
|
||||
if (_data[idx] == card_idx) {
|
||||
if (at(idx) == card_idx) {
|
||||
return Found;
|
||||
}
|
||||
}
|
||||
@ -196,7 +214,7 @@ inline G1AddCardResult G1CardSetArray::add(uint card_idx) {
|
||||
return Overflow;
|
||||
}
|
||||
|
||||
_data[num_entries] = checked_cast<EntryDataType>(card_idx);
|
||||
*entry_addr(num_entries) = checked_cast<EntryDataType>(card_idx);
|
||||
|
||||
x.inc_num_entries();
|
||||
|
||||
@ -207,7 +225,7 @@ inline bool G1CardSetArray::contains(uint card_idx) {
|
||||
EntryCountType num_entries = Atomic::load_acquire(&_num_entries) & EntryMask;
|
||||
|
||||
for (EntryCountType idx = 0; idx < num_entries; idx++) {
|
||||
if (_data[idx] == card_idx) {
|
||||
if (at(idx) == card_idx) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -218,7 +236,7 @@ template <class CardVisitor>
|
||||
void G1CardSetArray::iterate(CardVisitor& found) {
|
||||
EntryCountType num_entries = Atomic::load_acquire(&_num_entries) & EntryMask;
|
||||
for (EntryCountType idx = 0; idx < num_entries; idx++) {
|
||||
found(_data[idx]);
|
||||
found(at(idx));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user