mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-02 14:38:28 +00:00
8332257: Shenandoah: Move evacuation methods to implementation file
Reviewed-by: shade, kdnilsen
This commit is contained in:
parent
da9c23ace9
commit
de57d4b2e0
@ -1119,6 +1119,83 @@ void ShenandoahHeap::evacuate_collection_set(bool concurrent) {
|
||||
workers()->run_task(&task);
|
||||
}
|
||||
|
||||
oop ShenandoahHeap::evacuate_object(oop p, Thread* thread) {
|
||||
if (ShenandoahThreadLocalData::is_oom_during_evac(Thread::current())) {
|
||||
// This thread went through the OOM during evac protocol and it is safe to return
|
||||
// the forward pointer. It must not attempt to evacuate any more.
|
||||
return ShenandoahBarrierSet::resolve_forwarded(p);
|
||||
}
|
||||
|
||||
assert(ShenandoahThreadLocalData::is_evac_allowed(thread), "must be enclosed in oom-evac scope");
|
||||
|
||||
size_t size = p->size();
|
||||
|
||||
assert(!heap_region_containing(p)->is_humongous(), "never evacuate humongous objects");
|
||||
|
||||
bool alloc_from_gclab = true;
|
||||
HeapWord* copy = nullptr;
|
||||
|
||||
#ifdef ASSERT
|
||||
if (ShenandoahOOMDuringEvacALot &&
|
||||
(os::random() & 1) == 0) { // Simulate OOM every ~2nd slow-path call
|
||||
copy = nullptr;
|
||||
} else {
|
||||
#endif
|
||||
if (UseTLAB) {
|
||||
copy = allocate_from_gclab(thread, size);
|
||||
}
|
||||
if (copy == nullptr) {
|
||||
ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared_gc(size);
|
||||
copy = allocate_memory(req);
|
||||
alloc_from_gclab = false;
|
||||
}
|
||||
#ifdef ASSERT
|
||||
}
|
||||
#endif
|
||||
|
||||
if (copy == nullptr) {
|
||||
control_thread()->handle_alloc_failure_evac(size);
|
||||
|
||||
_oom_evac_handler.handle_out_of_memory_during_evacuation();
|
||||
|
||||
return ShenandoahBarrierSet::resolve_forwarded(p);
|
||||
}
|
||||
|
||||
// Copy the object:
|
||||
Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(p), copy, size);
|
||||
|
||||
// Try to install the new forwarding pointer.
|
||||
oop copy_val = cast_to_oop(copy);
|
||||
ContinuationGCSupport::relativize_stack_chunk(copy_val);
|
||||
|
||||
oop result = ShenandoahForwarding::try_update_forwardee(p, copy_val);
|
||||
if (result == copy_val) {
|
||||
// Successfully evacuated. Our copy is now the public one!
|
||||
shenandoah_assert_correct(nullptr, copy_val);
|
||||
return copy_val;
|
||||
} else {
|
||||
// Failed to evacuate. We need to deal with the object that is left behind. Since this
|
||||
// new allocation is certainly after TAMS, it will be considered live in the next cycle.
|
||||
// But if it happens to contain references to evacuated regions, those references would
|
||||
// not get updated for this stale copy during this cycle, and we will crash while scanning
|
||||
// it the next cycle.
|
||||
//
|
||||
// For GCLAB allocations, it is enough to rollback the allocation ptr. Either the next
|
||||
// object will overwrite this stale copy, or the filler object on LAB retirement will
|
||||
// do this. For non-GCLAB allocations, we have no way to retract the allocation, and
|
||||
// have to explicitly overwrite the copy with the filler object. With that overwrite,
|
||||
// we have to keep the fwdptr initialized and pointing to our (stale) copy.
|
||||
if (alloc_from_gclab) {
|
||||
ShenandoahThreadLocalData::gclab(thread)->undo_allocation(copy, size);
|
||||
} else {
|
||||
fill_with_object(copy, size);
|
||||
shenandoah_assert_correct(nullptr, copy_val);
|
||||
}
|
||||
shenandoah_assert_correct(nullptr, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahHeap::trash_cset_regions() {
|
||||
ShenandoahHeapLocker locker(lock());
|
||||
|
||||
|
||||
@ -639,7 +639,7 @@ public:
|
||||
|
||||
// Evacuates object src. Returns the evacuated object, either evacuated
|
||||
// by this thread, or by some other thread.
|
||||
inline oop evacuate_object(oop src, Thread* thread);
|
||||
oop evacuate_object(oop src, Thread* thread);
|
||||
|
||||
// Call before/after evacuation.
|
||||
inline void enter_evacuation(Thread* t);
|
||||
|
||||
@ -287,83 +287,6 @@ inline HeapWord* ShenandoahHeap::allocate_from_gclab(Thread* thread, size_t size
|
||||
return allocate_from_gclab_slow(thread, size);
|
||||
}
|
||||
|
||||
inline oop ShenandoahHeap::evacuate_object(oop p, Thread* thread) {
|
||||
if (ShenandoahThreadLocalData::is_oom_during_evac(Thread::current())) {
|
||||
// This thread went through the OOM during evac protocol and it is safe to return
|
||||
// the forward pointer. It must not attempt to evacuate any more.
|
||||
return ShenandoahBarrierSet::resolve_forwarded(p);
|
||||
}
|
||||
|
||||
assert(ShenandoahThreadLocalData::is_evac_allowed(thread), "must be enclosed in oom-evac scope");
|
||||
|
||||
size_t size = p->size();
|
||||
|
||||
assert(!heap_region_containing(p)->is_humongous(), "never evacuate humongous objects");
|
||||
|
||||
bool alloc_from_gclab = true;
|
||||
HeapWord* copy = nullptr;
|
||||
|
||||
#ifdef ASSERT
|
||||
if (ShenandoahOOMDuringEvacALot &&
|
||||
(os::random() & 1) == 0) { // Simulate OOM every ~2nd slow-path call
|
||||
copy = nullptr;
|
||||
} else {
|
||||
#endif
|
||||
if (UseTLAB) {
|
||||
copy = allocate_from_gclab(thread, size);
|
||||
}
|
||||
if (copy == nullptr) {
|
||||
ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared_gc(size);
|
||||
copy = allocate_memory(req);
|
||||
alloc_from_gclab = false;
|
||||
}
|
||||
#ifdef ASSERT
|
||||
}
|
||||
#endif
|
||||
|
||||
if (copy == nullptr) {
|
||||
control_thread()->handle_alloc_failure_evac(size);
|
||||
|
||||
_oom_evac_handler.handle_out_of_memory_during_evacuation();
|
||||
|
||||
return ShenandoahBarrierSet::resolve_forwarded(p);
|
||||
}
|
||||
|
||||
// Copy the object:
|
||||
Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(p), copy, size);
|
||||
|
||||
// Try to install the new forwarding pointer.
|
||||
oop copy_val = cast_to_oop(copy);
|
||||
ContinuationGCSupport::relativize_stack_chunk(copy_val);
|
||||
|
||||
oop result = ShenandoahForwarding::try_update_forwardee(p, copy_val);
|
||||
if (result == copy_val) {
|
||||
// Successfully evacuated. Our copy is now the public one!
|
||||
shenandoah_assert_correct(nullptr, copy_val);
|
||||
return copy_val;
|
||||
} else {
|
||||
// Failed to evacuate. We need to deal with the object that is left behind. Since this
|
||||
// new allocation is certainly after TAMS, it will be considered live in the next cycle.
|
||||
// But if it happens to contain references to evacuated regions, those references would
|
||||
// not get updated for this stale copy during this cycle, and we will crash while scanning
|
||||
// it the next cycle.
|
||||
//
|
||||
// For GCLAB allocations, it is enough to rollback the allocation ptr. Either the next
|
||||
// object will overwrite this stale copy, or the filler object on LAB retirement will
|
||||
// do this. For non-GCLAB allocations, we have no way to retract the allocation, and
|
||||
// have to explicitly overwrite the copy with the filler object. With that overwrite,
|
||||
// we have to keep the fwdptr initialized and pointing to our (stale) copy.
|
||||
if (alloc_from_gclab) {
|
||||
ShenandoahThreadLocalData::gclab(thread)->undo_allocation(copy, size);
|
||||
} else {
|
||||
fill_with_object(copy, size);
|
||||
shenandoah_assert_correct(nullptr, copy_val);
|
||||
}
|
||||
shenandoah_assert_correct(nullptr, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool ShenandoahHeap::requires_marking(const void* entry) const {
|
||||
oop obj = cast_to_oop(entry);
|
||||
return !_marking_context->is_marked_strong(obj);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user