mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-15 13:49:42 +02:00
8364628: Serial: Refactor SerialHeap::mem_allocate_work
Reviewed-by: phh, kbarrett
This commit is contained in:
parent
41520998aa
commit
dd113c8df0
4 changed files with 28 additions and 37 deletions
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue