< prev index next > src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp
Print this page
oop ShenandoahGenerationalHeap::try_evacuate_object(oop p, Thread* thread, ShenandoahHeapRegion* from_region,
ShenandoahAffiliation target_gen) {
bool alloc_from_lab = true;
bool has_plab = false;
HeapWord* copy = nullptr;
! size_t size = ShenandoahForwarding::size(p);
bool is_promotion = (target_gen == OLD_GENERATION) && from_region->is_young();
#ifdef ASSERT
if (ShenandoahOOMDuringEvacALot &&
(os::random() & 1) == 0) { // Simulate OOM every ~2nd slow-path call
oop ShenandoahGenerationalHeap::try_evacuate_object(oop p, Thread* thread, ShenandoahHeapRegion* from_region,
ShenandoahAffiliation target_gen) {
bool alloc_from_lab = true;
bool has_plab = false;
HeapWord* copy = nullptr;
!
+ markWord mark = p->mark();
+ if (ShenandoahForwarding::is_forwarded(mark)) {
+ return ShenandoahForwarding::get_forwardee(p);
+ }
+ size_t old_size = ShenandoahForwarding::size(p);
+ size_t size = p->copy_size(old_size, mark);
+
bool is_promotion = (target_gen == OLD_GENERATION) && from_region->is_young();
#ifdef ASSERT
if (ShenandoahOOMDuringEvacALot &&
(os::random() & 1) == 0) { // Simulate OOM every ~2nd slow-path call
return ShenandoahBarrierSet::resolve_forwarded(p);
}
// Copy the object:
NOT_PRODUCT(evac_tracker()->begin_evacuation(thread, size * HeapWordSize));
! Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(p), copy, size);
oop copy_val = cast_to_oop(copy);
// Update the age of the evacuated object
if (target_gen == YOUNG_GENERATION && is_aging_cycle()) {
ShenandoahHeap::increase_object_age(copy_val, from_region->age() + 1);
return ShenandoahBarrierSet::resolve_forwarded(p);
}
// Copy the object:
NOT_PRODUCT(evac_tracker()->begin_evacuation(thread, size * HeapWordSize));
! Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(p), copy, old_size);
oop copy_val = cast_to_oop(copy);
// Update the age of the evacuated object
if (target_gen == YOUNG_GENERATION && is_aging_cycle()) {
ShenandoahHeap::increase_object_age(copy_val, from_region->age() + 1);
// This is necessary for virtual thread support. This uses the mark word without
// considering that it may now be a forwarding pointer (and could therefore crash).
// Secondarily, we do not want to spend cycles relativizing stack chunks for oops
// that lost the evacuation race (and will therefore not become visible). It is
// safe to do this on the public copy (this is also done during concurrent mark).
+ copy_val->initialize_hash_if_necessary(p);
ContinuationGCSupport::relativize_stack_chunk(copy_val);
// Record that the evacuation succeeded
NOT_PRODUCT(evac_tracker()->end_evacuation(thread, size * HeapWordSize));
< prev index next >