8364628: Serial: Refactor SerialHeap::mem_allocate_work

Reviewed-by: phh, kbarrett
This commit is contained in:
Albert Mingkun Yang 2025-08-14 14:50:56 +00:00
parent 41520998aa
commit dd113c8df0
4 changed files with 28 additions and 37 deletions

View file

@ -281,15 +281,6 @@ size_t SerialHeap::max_capacity() const {
return _young_gen->max_capacity() + _old_gen->max_capacity();
}
// Return true if any of the following is true:
// . the allocation won't fit into the current young gen heap
// . heap memory is tight
bool SerialHeap::should_try_older_generation_allocation(size_t word_size) const {
size_t young_capacity = _young_gen->capacity_before_gc();
return (word_size > heap_word_size(young_capacity))
|| _is_heap_almost_full;
}
HeapWord* SerialHeap::expand_heap_and_allocate(size_t size, bool is_tlab) {
HeapWord* result = nullptr;
if (_old_gen->should_allocate(size, is_tlab)) {
@ -308,32 +299,26 @@ HeapWord* SerialHeap::expand_heap_and_allocate(size_t size, bool is_tlab) {
HeapWord* SerialHeap::mem_allocate_work(size_t size, bool is_tlab) {
HeapWord* result = nullptr;
// Loop until the allocation is satisfied, or unsatisfied after GC.
for (uint try_count = 1; /* return or throw */; try_count += 1) {
// First allocation attempt is lock-free.
DefNewGeneration *young = _young_gen;
if (young->should_allocate(size, is_tlab)) {
result = young->par_allocate(size);
for (uint try_count = 1; /* break */; try_count++) {
if (_young_gen->should_allocate(size, is_tlab)) {
result = _young_gen->par_allocate(size);
if (result != nullptr) {
assert(is_in_reserved(result), "result not in heap");
return result;
break;
}
}
// Try old-gen allocation for non-TLAB.
if (!is_tlab) {
// If it's too large for young-gen or heap is too full.
if (size > heap_word_size(_young_gen->capacity_before_gc()) || _is_heap_almost_full) {
result = _old_gen->par_allocate(size);
if (result != nullptr) {
break;
}
}
}
uint gc_count_before; // Read inside the Heap_lock locked region.
{
MutexLocker ml(Heap_lock);
log_trace(gc, alloc)("SerialHeap::mem_allocate_work: attempting locked slow path allocation");
// Note that only large objects get a shot at being
// allocated in later generations.
bool first_only = !should_try_older_generation_allocation(size);
result = attempt_allocation(size, is_tlab, first_only);
if (result != nullptr) {
assert(is_in_reserved(result), "result not in heap");
return result;
}
// Read the gc count while the heap lock is held.
gc_count_before = total_collections();
}
@ -341,10 +326,7 @@ HeapWord* SerialHeap::mem_allocate_work(size_t size, bool is_tlab) {
VMThread::execute(&op);
if (op.gc_succeeded()) {
result = op.result();
assert(result == nullptr || is_in_reserved(result),
"result not in heap");
return result;
break;
}
// Give a warning if we seem to be looping forever.
@ -354,6 +336,9 @@ HeapWord* SerialHeap::mem_allocate_work(size_t size, bool is_tlab) {
" size=%zu %s", try_count, size, is_tlab ? "(TLAB)" : "");
}
}
assert(result == nullptr || is_in_reserved(result), "postcondition");
return result;
}
HeapWord* SerialHeap::attempt_allocation(size_t size,

View file

@ -229,10 +229,6 @@ public:
void save_marks();
private:
// Return true if an allocation should be attempted in the older generation
// if it fails in the younger generation. Return false, otherwise.
bool should_try_older_generation_allocation(size_t word_size) const;
// Try to allocate space by expanding the heap.
HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);

View file

@ -126,6 +126,8 @@ public:
// Allocate and returns a block of the requested size, or returns "null".
// Assumes the caller has done any necessary locking.
inline HeapWord* allocate(size_t word_size);
// Multi-threaded version.
inline HeapWord* par_allocate(size_t word_size);
// Expand the old-gen then invoke allocate above.
HeapWord* expand_and_allocate(size_t size);

View file

@ -57,4 +57,12 @@ HeapWord* TenuredGeneration::allocate(size_t word_size) {
return res;
}
HeapWord* TenuredGeneration::par_allocate(size_t word_size) {
HeapWord* res = _the_space->par_allocate(word_size);
if (res != nullptr) {
_bts->update_for_block(res, res + word_size);
}
return res;
}
#endif // SHARE_GC_SERIAL_TENUREDGENERATION_INLINE_HPP