8372540: SerialGC: Remove race between allocation and expansion before is_init_completed

Reviewed-by: ayang, sjohanss, eosterlund
This commit is contained in:
Axel Boldt-Christmas 2025-12-02 10:59:04 +00:00
parent f636fcadd7
commit e27abe8a97

View File

@ -304,9 +304,12 @@ HeapWord* SerialHeap::mem_allocate_work(size_t size, bool is_tlab) {
HeapWord* result = nullptr;
for (uint try_count = 1; /* break */; try_count++) {
result = mem_allocate_cas_noexpand(size, is_tlab);
if (result != nullptr) {
break;
{
ConditionalMutexLocker locker(Heap_lock, !is_init_completed());
result = mem_allocate_cas_noexpand(size, is_tlab);
if (result != nullptr) {
break;
}
}
uint gc_count_before; // Read inside the Heap_lock locked region.
{
@ -320,10 +323,15 @@ HeapWord* SerialHeap::mem_allocate_work(size_t size, bool is_tlab) {
}
if (!is_init_completed()) {
// Can't do GC; try heap expansion to satisfy the request.
result = expand_heap_and_allocate(size, is_tlab);
if (result != nullptr) {
return result;
// Double checked locking, this ensure that is_init_completed() does not
// transition while expanding the heap.
MonitorLocker ml(InitCompleted_lock, Monitor::_no_safepoint_check_flag);
if (!is_init_completed()) {
// Can't do GC; try heap expansion to satisfy the request.
result = expand_heap_and_allocate(size, is_tlab);
if (result != nullptr) {
return result;
}
}
}