< prev index next >

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

Print this page
*** 46,10 ***
--- 46,11 ---
  #include "gc/shared/gcTraceTime.inline.hpp"
  #include "gc/shared/modRefBarrierSet.hpp"
  #include "gc/shared/preservedMarks.inline.hpp"
  #include "gc/shared/referencePolicy.hpp"
  #include "gc/shared/referenceProcessorPhaseTimes.hpp"
+ #include "gc/shared/slidingForwarding.inline.hpp"
  #include "gc/shared/space.inline.hpp"
  #include "gc/shared/strongRootsScope.hpp"
  #include "gc/shared/weakProcessor.hpp"
  #include "memory/universe.hpp"
  #include "oops/instanceRefKlass.hpp"

*** 193,14 ***
      if (PrefetchCopyIntervalInBytes >= 0) {
        Prefetch::write(p, PrefetchCopyIntervalInBytes);
      }
    }
  
    static void forward_obj(oop obj, HeapWord* new_addr) {
      prefetch_write_scan(obj);
      if (cast_from_oop<HeapWord*>(obj) != new_addr) {
!       obj->forward_to(cast_to_oop(new_addr));
      } else {
        assert(obj->is_gc_marked(), "inv");
        // This obj will stay in-place. Fix the markword.
        obj->init_mark();
      }
--- 194,15 ---
      if (PrefetchCopyIntervalInBytes >= 0) {
        Prefetch::write(p, PrefetchCopyIntervalInBytes);
      }
    }
  
+   template <bool ALT_FWD>
    static void forward_obj(oop obj, HeapWord* new_addr) {
      prefetch_write_scan(obj);
      if (cast_from_oop<HeapWord*>(obj) != new_addr) {
!       SlidingForwarding::forward_to<ALT_FWD>(obj, cast_to_oop(new_addr));
      } else {
        assert(obj->is_gc_marked(), "inv");
        // This obj will stay in-place. Fix the markword.
        obj->init_mark();
      }

*** 216,16 ***
        i_addr += obj->size();
      }
      return end;
    };
  
    static size_t relocate(HeapWord* addr) {
      // Prefetch source and destination
      prefetch_read_scan(addr);
  
      oop obj = cast_to_oop(addr);
!     oop new_obj = obj->forwardee();
      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();
--- 218,17 ---
        i_addr += obj->size();
      }
      return end;
    };
  
+   template <bool ALT_FWD>
    static size_t relocate(HeapWord* addr) {
      // Prefetch source and destination
      prefetch_read_scan(addr);
  
      oop obj = cast_to_oop(addr);
!     oop new_obj = SlidingForwarding::forwardee<ALT_FWD>(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();

*** 250,10 ***
--- 253,11 ---
        _num_spaces = 3;
      }
      _index = 0;
    }
  
+   template <bool ALT_FWD>
    void phase2_calculate_new_addr() {
      for (uint i = 0; i < _num_spaces; ++i) {
        ContiguousSpace* space = get_space(i);
        HeapWord* cur_addr = space->bottom();
        HeapWord* top = space->top();

*** 265,11 ***
        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)) {
--- 269,11 ---
        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<ALT_FWD>(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)) {

*** 290,57 ***
          record_first_dead(i, top);
        }
      }
    }
  
    void phase3_adjust_pointers() {
      for (uint i = 0; i < _num_spaces; ++i) {
        ContiguousSpace* space = get_space(i);
        HeapWord* cur_addr = space->bottom();
        HeapWord* const top = space->top();
        HeapWord* const first_dead = get_first_dead(i);
  
        while (cur_addr < top) {
          prefetch_write_scan(cur_addr);
          if (cur_addr < first_dead || cast_to_oop(cur_addr)->is_gc_marked()) {
!           size_t size = MarkSweep::adjust_pointers(cast_to_oop(cur_addr));
            cur_addr += size;
          } else {
            assert(*(HeapWord**)cur_addr > cur_addr, "forward progress");
            cur_addr = *(HeapWord**)cur_addr;
          }
        }
      }
    }
  
    void phase4_compact() {
      for (uint i = 0; i < _num_spaces; ++i) {
        ContiguousSpace* space = get_space(i);
        HeapWord* cur_addr = space->bottom();
        HeapWord* top = space->top();
  
        // Check if the first obj inside this space is forwarded.
!       if (!cast_to_oop(cur_addr)->is_forwarded()) {
          // Jump over consecutive (in-place) live-objs-chunk
          cur_addr = get_first_dead(i);
        }
  
        while (cur_addr < top) {
!         if (!cast_to_oop(cur_addr)->is_forwarded()) {
            cur_addr = *(HeapWord**) cur_addr;
            continue;
          }
!         cur_addr += relocate(cur_addr);
        }
  
        // Reset top and unused memory
        space->set_top(get_compaction_top(i));
        if (ZapUnusedHeapArea) {
          space->mangle_unused_area();
        }
      }
    }
  };
  
  void GenMarkSweep::phase1_mark(bool clear_all_softrefs) {
    // Recursively traverse all live objects and mark them
    GCTraceTime(Info, gc, phases) tm("Phase 1: Mark live objects", _gc_timer);
--- 294,83 ---
          record_first_dead(i, top);
        }
      }
    }
  
+   void phase2_calculate_new_addr() {
+     if (UseAltGCForwarding) {
+       phase2_calculate_new_addr<true>();
+     } else {
+       phase2_calculate_new_addr<false>();
+     }
+   }
+ 
+   template <bool ALT_FWD>
    void phase3_adjust_pointers() {
      for (uint i = 0; i < _num_spaces; ++i) {
        ContiguousSpace* space = get_space(i);
        HeapWord* cur_addr = space->bottom();
        HeapWord* const top = space->top();
        HeapWord* const first_dead = get_first_dead(i);
  
        while (cur_addr < top) {
          prefetch_write_scan(cur_addr);
          if (cur_addr < first_dead || cast_to_oop(cur_addr)->is_gc_marked()) {
!           size_t size = MarkSweep::adjust_pointers<ALT_FWD>(cast_to_oop(cur_addr));
            cur_addr += size;
          } else {
            assert(*(HeapWord**)cur_addr > cur_addr, "forward progress");
            cur_addr = *(HeapWord**)cur_addr;
          }
        }
      }
    }
  
+   void phase3_adjust_pointers() {
+     if (UseAltGCForwarding) {
+       phase3_adjust_pointers<true>();
+     } else {
+       phase3_adjust_pointers<false>();
+     }
+   }
+ 
+   template <bool ALT_FWD>
    void phase4_compact() {
      for (uint i = 0; i < _num_spaces; ++i) {
        ContiguousSpace* space = get_space(i);
        HeapWord* cur_addr = space->bottom();
        HeapWord* top = space->top();
  
        // Check if the first obj inside this space is forwarded.
!       if (SlidingForwarding::is_not_forwarded(cast_to_oop(cur_addr))) {
          // Jump over consecutive (in-place) live-objs-chunk
          cur_addr = get_first_dead(i);
        }
  
        while (cur_addr < top) {
!         if (SlidingForwarding::is_not_forwarded(cast_to_oop(cur_addr))) {
            cur_addr = *(HeapWord**) cur_addr;
            continue;
          }
!         cur_addr += relocate<ALT_FWD>(cur_addr);
        }
  
        // Reset top and unused memory
        space->set_top(get_compaction_top(i));
        if (ZapUnusedHeapArea) {
          space->mangle_unused_area();
        }
      }
    }
+ 
+   void phase4_compact() {
+     if (UseAltGCForwarding) {
+       phase4_compact<true>();
+     } else {
+       phase4_compact<false>();
+     }
+   }
  };
  
  void GenMarkSweep::phase1_mark(bool clear_all_softrefs) {
    // Recursively traverse all live objects and mark them
    GCTraceTime(Info, gc, phases) tm("Phase 1: Mark live objects", _gc_timer);

*** 446,10 ***
--- 476,12 ---
  
    allocate_stacks();
  
    phase1_mark(clear_all_softrefs);
  
+   SlidingForwarding::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);

*** 467,18 ***
      // Adjust the pointers to reflect the new locations
      GCTraceTime(Info, gc, phases) tm("Phase 3: Adjust pointers", gc_timer());
  
      ClassLoaderDataGraph::verify_claimed_marks_cleared(ClassLoaderData::_claim_stw_fullgc_adjust);
  
!     CodeBlobToOopClosure code_closure(&adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations);
!     gch->process_roots(SerialHeap::SO_AllCodeCache,
!                        &adjust_pointer_closure,
!                        &adjust_cld_closure,
!                        &adjust_cld_closure,
!                        &code_closure);
! 
!     WeakProcessor::oops_do(&adjust_pointer_closure);
  
      adjust_marks();
      compacter.phase3_adjust_pointers();
    }
  
--- 499,33 ---
      // Adjust the pointers to reflect the new locations
      GCTraceTime(Info, gc, phases) tm("Phase 3: Adjust pointers", gc_timer());
  
      ClassLoaderDataGraph::verify_claimed_marks_cleared(ClassLoaderData::_claim_stw_fullgc_adjust);
  
!     if (UseAltGCForwarding) {
!       AdjustPointerClosure<true> adjust_pointer_closure;
!       CLDToOopClosure adjust_cld_closure(&adjust_pointer_closure, ClassLoaderData::_claim_stw_fullgc_adjust);
!       CodeBlobToOopClosure code_closure(&adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations);
!       gch->process_roots(SerialHeap::SO_AllCodeCache,
!                          &adjust_pointer_closure,
!                          &adjust_cld_closure,
!                          &adjust_cld_closure,
+                          &code_closure);
+ 
+       WeakProcessor::oops_do(&adjust_pointer_closure);
+     } else {
+       AdjustPointerClosure<false> adjust_pointer_closure;
+       CLDToOopClosure adjust_cld_closure(&adjust_pointer_closure, ClassLoaderData::_claim_stw_fullgc_adjust);
+       CodeBlobToOopClosure code_closure(&adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations);
+       gch->process_roots(SerialHeap::SO_AllCodeCache,
+                          &adjust_pointer_closure,
+                          &adjust_cld_closure,
+                          &adjust_cld_closure,
+                          &code_closure);
+ 
+       WeakProcessor::oops_do(&adjust_pointer_closure);
+     }
  
      adjust_marks();
      compacter.phase3_adjust_pointers();
    }
  

*** 487,10 ***
--- 534,12 ---
      GCTraceTime(Info, gc, phases) tm("Phase 4: Move objects", _gc_timer);
  
      compacter.phase4_compact();
    }
  
+   SlidingForwarding::end();
+ 
    restore_marks();
  
    // Set saved marks for allocation profiler (and other things? -- dld)
    // (Should this be in general part?)
    gch->save_marks();
< prev index next >