8321216: SerialGC attempts to access the card table beyond the end of the heap during card table scan

Co-authored-by: Albert Mingkun Yang <ayang@openjdk.org>
Reviewed-by: ayang, iwalulya
This commit is contained in:
Thomas Schatzl 2023-12-05 15:08:37 +00:00
parent a1fe16b5ec
commit 800f347c32
2 changed files with 22 additions and 6 deletions

View File

@ -392,6 +392,10 @@ CardTable::CardValue* CardTableRS::find_first_clean_card(CardValue* const start_
CardValue* const end_card,
CardTableRS* ct,
Func& object_start) {
// end_card might be just beyond the heap, so need to use the _raw variant.
HeapWord* end_address = ct->addr_for_raw(end_card);
for (CardValue* current_card = start_card; current_card < end_card; /* empty */) {
if (is_dirty(current_card)) {
current_card++;
@ -414,8 +418,15 @@ CardTable::CardValue* CardTableRS::find_first_clean_card(CardValue* const start_
return current_card;
}
// This might be the last object in this area, avoid trying to access the
// card beyond the allowed area.
HeapWord* next_address = obj_start_addr + obj->size();
if (next_address >= end_address) {
break;
}
// Card occupied by next obj.
CardValue* next_obj_card = ct->byte_for(obj_start_addr + obj->size());
CardValue* next_obj_card = ct->byte_for(next_address);
if (is_clean(next_obj_card)) {
return next_obj_card;
}

View File

@ -83,6 +83,14 @@ protected:
return cards_required(_whole_heap.word_size()) - 1;
}
// Mapping from card marking array entry to address of first word without checks.
HeapWord* addr_for_raw(const CardValue* p) const {
// As _byte_map_base may be "negative" (the card table has been allocated before
// the heap in memory), do not use pointer_delta() to avoid the assertion failure.
size_t delta = p - _byte_map_base;
return (HeapWord*) (delta << _card_shift);
}
private:
void initialize_covered_region(void* region0_start, void* region1_start);
@ -144,16 +152,13 @@ public:
return byte_after(p);
}
// Mapping from card marking array entry to address of first word
// Mapping from card marking array entry to address of first word.
HeapWord* addr_for(const CardValue* p) const {
assert(p >= _byte_map && p < _byte_map + _byte_map_size,
"out of bounds access to card marking array. p: " PTR_FORMAT
" _byte_map: " PTR_FORMAT " _byte_map + _byte_map_size: " PTR_FORMAT,
p2i(p), p2i(_byte_map), p2i(_byte_map + _byte_map_size));
// As _byte_map_base may be "negative" (the card table has been allocated before
// the heap in memory), do not use pointer_delta() to avoid the assertion failure.
size_t delta = p - _byte_map_base;
HeapWord* result = (HeapWord*) (delta << _card_shift);
HeapWord* result = addr_for_raw(p);
assert(_whole_heap.contains(result),
"Returning result = " PTR_FORMAT " out of bounds of "
" card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",