< prev index next >

src/hotspot/share/gc/serial/serialFullGC.cpp

Print this page
*** 189,11 ***
    void record_first_dead(uint index, HeapWord* first_dead) {
      assert(_spaces[index]._first_dead == nullptr, "should write only once");
      _spaces[index]._first_dead = first_dead;
    }
  
!   HeapWord* alloc(size_t words) {
      while (true) {
        if (words <= pointer_delta(_spaces[_index]._space->end(),
                                   _spaces[_index]._compaction_top)) {
          HeapWord* result = _spaces[_index]._compaction_top;
          _spaces[_index]._compaction_top += words;
--- 189,12 ---
    void record_first_dead(uint index, HeapWord* first_dead) {
      assert(_spaces[index]._first_dead == nullptr, "should write only once");
      _spaces[index]._first_dead = first_dead;
    }
  
!   HeapWord* alloc(size_t old_size, size_t new_size, HeapWord* old_obj) {
+     size_t words = (old_obj == _spaces[_index]._compaction_top) ? old_size : new_size;
      while (true) {
        if (words <= pointer_delta(_spaces[_index]._space->end(),
                                   _spaces[_index]._compaction_top)) {
          HeapWord* result = _spaces[_index]._compaction_top;
          _spaces[_index]._compaction_top += words;

*** 205,10 ***
--- 206,11 ---
        }
  
        // out-of-memory in this space
        _index++;
        assert(_index < max_num_spaces - 1, "the last space should not be used");
+       words = (old_obj == _spaces[_index]._compaction_top) ? old_size : new_size;
      }
    }
  
    static void prefetch_read_scan(void* p) {
      if (PrefetchScanIntervalInBytes >= 0) {

*** 256,16 ***
      prefetch_read_scan(addr);
  
      oop obj = cast_to_oop(addr);
      oop new_obj = FullGCForwarding::forwardee(obj);
      HeapWord* new_addr = cast_from_oop<HeapWord*>(new_obj);
-     assert(addr != new_addr, "inv");
-     prefetch_write_copy(new_addr);
  
      size_t obj_size = obj->size();
!     Copy::aligned_conjoint_words(addr, new_addr, obj_size);
      new_obj->init_mark();
  
      return obj_size;
    }
  
  public:
--- 258,20 ---
      prefetch_read_scan(addr);
  
      oop obj = cast_to_oop(addr);
      oop new_obj = FullGCForwarding::forwardee(obj);
      HeapWord* new_addr = cast_from_oop<HeapWord*>(new_obj);
  
      size_t obj_size = obj->size();
!     if (addr != new_addr) {
+       prefetch_write_copy(new_addr);
+       Copy::aligned_conjoint_words(addr, new_addr, obj_size);
+     }
      new_obj->init_mark();
+     if (addr != new_addr) {
+       new_obj->initialize_hash_if_necessary(obj);
+     }
  
      return obj_size;
    }
  
  public:

*** 297,20 ***
        DeadSpacer dead_spacer(space);
  
        while (cur_addr < top) {
          oop obj = cast_to_oop(cur_addr);
          size_t obj_size = obj->size();
          if (obj->is_gc_marked()) {
!           HeapWord* new_addr = alloc(obj_size);
            forward_obj(obj, new_addr);
            cur_addr += obj_size;
          } else {
            // Skipping the current known-unmarked obj
            HeapWord* next_live_addr = find_next_live_addr(cur_addr + obj_size, top);
            if (dead_spacer.insert_deadspace(cur_addr, next_live_addr)) {
              // Register space for the filler obj
!             alloc(pointer_delta(next_live_addr, cur_addr));
            } else {
              if (!record_first_dead_done) {
                record_first_dead(i, cur_addr);
                record_first_dead_done = true;
              }
--- 303,23 ---
        DeadSpacer dead_spacer(space);
  
        while (cur_addr < top) {
          oop obj = cast_to_oop(cur_addr);
          size_t obj_size = obj->size();
+         size_t new_size = obj->copy_size(obj_size, obj->mark());
          if (obj->is_gc_marked()) {
!           HeapWord* new_addr = alloc(obj_size, new_size, cur_addr);
            forward_obj(obj, new_addr);
+           assert(obj->size() == obj_size, "size must not change after forwarding");
            cur_addr += obj_size;
          } else {
            // Skipping the current known-unmarked obj
            HeapWord* next_live_addr = find_next_live_addr(cur_addr + obj_size, top);
            if (dead_spacer.insert_deadspace(cur_addr, next_live_addr)) {
              // Register space for the filler obj
!             size_t size = pointer_delta(next_live_addr, cur_addr);
+             alloc(size, size, cur_addr);
            } else {
              if (!record_first_dead_done) {
                record_first_dead(i, cur_addr);
                record_first_dead_done = true;
              }

*** 592,11 ***
    }
  
    // some marks may contain information we need to preserve so we store them away
    // and overwrite the mark.  We'll restore it at the end of serial full GC.
    markWord mark = obj->mark();
!   obj->set_mark(obj->prototype_mark().set_marked());
  
    ContinuationGCSupport::transform_stack_chunk(obj);
  
    if (obj->mark_must_be_preserved(mark)) {
      preserve_mark(obj, mark);
--- 601,11 ---
    }
  
    // some marks may contain information we need to preserve so we store them away
    // and overwrite the mark.  We'll restore it at the end of serial full GC.
    markWord mark = obj->mark();
!   obj->set_mark(mark.set_marked());
  
    ContinuationGCSupport::transform_stack_chunk(obj);
  
    if (obj->mark_must_be_preserved(mark)) {
      preserve_mark(obj, mark);

*** 695,10 ***
--- 704,12 ---
  
    allocate_stacks();
  
    phase1_mark(clear_all_softrefs);
  
+   FullGCForwarding::begin();
+ 
    Compacter compacter{gch};
  
    {
      // Now all live objects are marked, compute the new object addresses.
      GCTraceTime(Info, gc, phases) tm("Phase 2: Compute new object addresses", _gc_timer);

*** 738,10 ***
--- 749,12 ---
      compacter.phase4_compact();
    }
  
    restore_marks();
  
+   FullGCForwarding::end();
+ 
    deallocate_stacks();
  
    SerialFullGC::_string_dedup_requests->flush();
  
    bool is_young_gen_empty = (gch->young_gen()->used() == 0);
< prev index next >