Skip to content

Commit

Permalink
8321216: SerialGC attempts to access the card table beyond the end of…
Browse files Browse the repository at this point in the history
… the heap during card table scan

Co-authored-by: Albert Mingkun Yang <ayang@openjdk.org>
Reviewed-by: ayang, iwalulya
  • Loading branch information
Thomas Schatzl and albertnetymk committed Dec 5, 2023
1 parent a1fe16b commit 800f347
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
13 changes: 12 additions & 1 deletion src/hotspot/share/gc/serial/cardTableRS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
Expand All @@ -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;
}
Expand Down
15 changes: 10 additions & 5 deletions src/hotspot/share/gc/shared/cardTable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ class CardTable: public CHeapObj<mtGC> {
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);

Expand Down Expand Up @@ -144,16 +152,13 @@ class CardTable: public CHeapObj<mtGC> {
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 ")",
Expand Down

1 comment on commit 800f347

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.