Skip to content

Commit

Permalink
avoid UB
Browse files Browse the repository at this point in the history
  • Loading branch information
kimbarrett committed Jan 10, 2025
1 parent 12752b0 commit 374add7
Showing 1 changed file with 35 additions and 6 deletions.
41 changes: 35 additions & 6 deletions src/hotspot/share/gc/parallel/psCardTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,38 @@ class PSStripeShadowCardTable {
const uint _card_shift;
const uint _card_size;
CardValue _table[PSCardTable::num_cards_in_stripe];
const CardValue* _table_base;
uintptr_t _table_base;

// Avoid UB pointer operations by using integers internally.

static_assert(sizeof(intptr_t) == sizeof(CardValue*), "simplifying assumption");
static_assert(sizeof(CardValue) == 1, "simplifying assumption");

static uintptr_t iaddr(const void* p) {
return reinterpret_cast<uintptr_t>(p);
}

uintptr_t compute_table_base(HeapWord* start) const {
uintptr_t offset = iaddr(start) >> _card_shift;
return iaddr(_table) - offset;
}

void check_card_inclusive(const CardValue* card) const {
assert(iaddr(card) >= iaddr(_table), "out of bounds");
assert(iaddr(card) <= (iaddr(_table) + sizeof(_table)), "out of bounds");
}

void check_card_exclusive(const CardValue* card) const {
assert(iaddr(card) >= iaddr(_table), "out of bounds");
assert(iaddr(card) <= (iaddr(_table) + sizeof(_table)), "out of bounds");
}

public:
PSStripeShadowCardTable(PSCardTable* pst, HeapWord* const start, HeapWord* const end) :
_card_shift(CardTable::card_shift()),
_card_size(CardTable::card_size()),
_table_base(_table - (uintptr_t(start) >> _card_shift)) {
_table_base(compute_table_base(start))
{
size_t stripe_byte_size = pointer_delta(end, start) * HeapWordSize;
size_t copy_length = align_up(stripe_byte_size, _card_size) >> _card_shift;
// The end of the last stripe may not be card aligned as it is equal to old
Expand All @@ -143,20 +168,24 @@ class PSStripeShadowCardTable {
}

HeapWord* addr_for(const CardValue* const card) {
assert(card >= _table && card <= &_table[PSCardTable::num_cards_in_stripe], "out of bounds");
return (HeapWord*) ((card - _table_base) << _card_shift);
check_card_inclusive(card);
uintptr_t addr = (iaddr(card) - _table_base) << _card_shift;
return reinterpret_cast<HeapWord*>(addr);
}

const CardValue* card_for(HeapWord* addr) {
return &_table_base[uintptr_t(addr) >> _card_shift];
uintptr_t icard = _table_base + (iaddr(addr) >> _card_shift);
const CardValue* card = reinterpret_cast<const CardValue*>(icard);
check_card_inclusive(card);
return card;
}

bool is_dirty(const CardValue* const card) {
return !is_clean(card);
}

bool is_clean(const CardValue* const card) {
assert(card >= _table && card < &_table[PSCardTable::num_cards_in_stripe], "out of bounds");
check_card_exclusive(card);
return *card == PSCardTable::clean_card_val();
}

Expand Down

0 comments on commit 374add7

Please sign in to comment.