8343460: ZGC: Crash in ZRemembered::scan_page_and_clear_remset

Reviewed-by: jsikstro, eosterlund, stefank
This commit is contained in:
Axel Boldt-Christmas 2024-11-14 06:13:19 +00:00
parent 95a00f8a18
commit e7d90b941f
2 changed files with 9 additions and 20 deletions

View File

@ -248,10 +248,6 @@ void ZHeap::free_page(ZPage* page, bool allow_defragment) {
// Remove page table entry // Remove page table entry
_page_table.remove(page); _page_table.remove(page);
if (page->is_old()) {
page->remset_delete();
}
// Free page // Free page
_page_allocator.free_page(page, allow_defragment); _page_allocator.free_page(page, allow_defragment);
} }
@ -262,9 +258,6 @@ size_t ZHeap::free_empty_pages(const ZArray<ZPage*>* pages) {
ZArrayIterator<ZPage*> iter(pages); ZArrayIterator<ZPage*> iter(pages);
for (ZPage* page; iter.next(&page);) { for (ZPage* page; iter.next(&page);) {
_page_table.remove(page); _page_table.remove(page);
if (page->is_old()) {
page->remset_delete();
}
freed += page->size(); freed += page->size();
} }

View File

@ -809,6 +809,11 @@ ZPage* ZPageAllocator::prepare_to_recycle(ZPage* page, bool allow_defragment) {
return defragment_page(to_recycle); return defragment_page(to_recycle);
} }
// Remove the remset before recycling
if (to_recycle->is_old() && to_recycle == page) {
to_recycle->remset_delete();
}
return to_recycle; return to_recycle;
} }
@ -880,18 +885,9 @@ void ZPageAllocator::free_pages(const ZArray<ZPage*>* pages) {
} }
void ZPageAllocator::free_pages_alloc_failed(ZPageAllocation* allocation) { void ZPageAllocator::free_pages_alloc_failed(ZPageAllocation* allocation) {
ZArray<ZPage*> to_recycle_pages; // The page(s) in the allocation are either taken from the cache or a newly
// created, mapped and commited ZPage. These page(s) have not been inserted in
// Prepare pages for recycling before taking the lock // the page table, nor allocated a remset, so prepare_to_recycle is not required.
ZListRemoveIterator<ZPage> allocation_pages_iter(allocation->pages());
for (ZPage* page; allocation_pages_iter.next(&page);) {
// Prepare to recycle
ZPage* const to_recycle = prepare_to_recycle(page, false /* allow_defragment */);
// Register for recycling
to_recycle_pages.push(to_recycle);
}
ZLocker<ZLock> locker(&_lock); ZLocker<ZLock> locker(&_lock);
// Only decrease the overall used and not the generation used, // Only decrease the overall used and not the generation used,
@ -901,7 +897,7 @@ void ZPageAllocator::free_pages_alloc_failed(ZPageAllocation* allocation) {
size_t freed = 0; size_t freed = 0;
// Free any allocated/flushed pages // Free any allocated/flushed pages
ZArrayIterator<ZPage*> iter(&to_recycle_pages); ZListRemoveIterator<ZPage> iter(allocation->pages());
for (ZPage* page; iter.next(&page);) { for (ZPage* page; iter.next(&page);) {
freed += page->size(); freed += page->size();
recycle_page(page); recycle_page(page);