< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp

Print this page
*** 238,11 ***
  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
--- 238,18 ---
  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

*** 330,11 ***
      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);
--- 337,11 ---
      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);

*** 348,10 ***
--- 355,11 ---
      // 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 >