< prev index next >

src/hotspot/share/gc/shared/space.cpp

Print this page
*** 25,10 ***
--- 25,11 ---
  #include "precompiled.hpp"
  #include "classfile/vmClasses.hpp"
  #include "classfile/vmSymbols.hpp"
  #include "gc/shared/collectedHeap.inline.hpp"
  #include "gc/shared/genCollectedHeap.hpp"
+ #include "gc/shared/slidingForwarding.inline.hpp"
  #include "gc/shared/space.hpp"
  #include "gc/shared/space.inline.hpp"
  #include "gc/shared/spaceDecorator.inline.hpp"
  #include "memory/iterator.inline.hpp"
  #include "memory/universe.hpp"

*** 242,11 ***
  void ContiguousSpace::mangle_unused_area_complete() {
    mangler()->mangle_unused_area_complete();
  }
  #endif  // NOT_PRODUCT
  
! 
  HeapWord* ContiguousSpace::forward(oop q, size_t size,
                                      CompactPoint* cp, HeapWord* compact_top) {
    // q is alive
    // First check if we should switch compaction space
    assert(this == cp->space, "'this' should be current compaction space.");
--- 243,11 ---
  void ContiguousSpace::mangle_unused_area_complete() {
    mangler()->mangle_unused_area_complete();
  }
  #endif  // NOT_PRODUCT
  
! template <bool ALT_FWD>
  HeapWord* ContiguousSpace::forward(oop q, size_t size,
                                      CompactPoint* cp, HeapWord* compact_top) {
    // q is alive
    // First check if we should switch compaction space
    assert(this == cp->space, "'this' should be current compaction space.");

*** 267,17 ***
      compaction_max_size = pointer_delta(cp->space->end(), compact_top);
    }
  
    // store the forwarding pointer into the mark word
    if (cast_from_oop<HeapWord*>(q) != compact_top) {
!     q->forward_to(cast_to_oop(compact_top));
      assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
    } else {
      // if the object isn't moving we can just set the mark to the default
      // mark and handle it specially later on.
      q->init_mark();
!     assert(!q->is_forwarded(), "should not be forwarded");
    }
  
    compact_top += size;
  
    // We need to update the offset table so that the beginnings of objects can be
--- 268,17 ---
      compaction_max_size = pointer_delta(cp->space->end(), compact_top);
    }
  
    // store the forwarding pointer into the mark word
    if (cast_from_oop<HeapWord*>(q) != compact_top) {
!     SlidingForwarding::forward_to<ALT_FWD>(q, cast_to_oop(compact_top));
      assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
    } else {
      // if the object isn't moving we can just set the mark to the default
      // mark and handle it specially later on.
      q->init_mark();
!     assert(SlidingForwarding::is_not_forwarded(q), "should not be forwarded");
    }
  
    compact_top += size;
  
    // We need to update the offset table so that the beginnings of objects can be

*** 287,11 ***
    return compact_top;
  }
  
  #if INCLUDE_SERIALGC
  
! void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) {
    // Compute the new addresses for the live objects and store it in the mark
    // Used by universe::mark_sweep_phase2()
  
    // We're sure to be here before any objects are compacted into this
    // space, so this is a good time to initialize this:
--- 288,12 ---
    return compact_top;
  }
  
  #if INCLUDE_SERIALGC
  
! template <bool ALT_FWD>
+ void ContiguousSpace::prepare_for_compaction_impl(CompactPoint* cp) {
    // Compute the new addresses for the live objects and store it in the mark
    // Used by universe::mark_sweep_phase2()
  
    // We're sure to be here before any objects are compacted into this
    // space, so this is a good time to initialize this:

*** 320,11 ***
    while (cur_obj < scan_limit) {
      if (cast_to_oop(cur_obj)->is_gc_marked()) {
        // prefetch beyond cur_obj
        Prefetch::write(cur_obj, interval);
        size_t size = cast_to_oop(cur_obj)->size();
!       compact_top = cp->space->forward(cast_to_oop(cur_obj), size, cp, compact_top);
        cur_obj += size;
        end_of_live = cur_obj;
      } else {
        // run over all the contiguous dead objects
        HeapWord* end = cur_obj;
--- 322,11 ---
    while (cur_obj < scan_limit) {
      if (cast_to_oop(cur_obj)->is_gc_marked()) {
        // prefetch beyond cur_obj
        Prefetch::write(cur_obj, interval);
        size_t size = cast_to_oop(cur_obj)->size();
!       compact_top = cp->space->forward<ALT_FWD>(cast_to_oop(cur_obj), size, cp, compact_top);
        cur_obj += size;
        end_of_live = cur_obj;
      } else {
        // run over all the contiguous dead objects
        HeapWord* end = cur_obj;

*** 336,11 ***
  
        // see if we might want to pretend this object is alive so that
        // we don't have to compact quite as often.
        if (cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
          oop obj = cast_to_oop(cur_obj);
!         compact_top = cp->space->forward(obj, obj->size(), cp, compact_top);
          end_of_live = end;
        } else {
          // otherwise, it really is a free region.
  
          // cur_obj is a pointer to a dead object. Use this dead memory to store a pointer to the next live object.
--- 338,11 ---
  
        // see if we might want to pretend this object is alive so that
        // we don't have to compact quite as often.
        if (cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
          oop obj = cast_to_oop(cur_obj);
!         compact_top = cp->space->forward<ALT_FWD>(obj, obj->size(), cp, compact_top);
          end_of_live = end;
        } else {
          // otherwise, it really is a free region.
  
          // cur_obj is a pointer to a dead object. Use this dead memory to store a pointer to the next live object.

*** 367,11 ***
  
    // save the compaction_top of the compaction space.
    cp->space->set_compaction_top(compact_top);
  }
  
! void ContiguousSpace::adjust_pointers() {
    // Check first is there is any work to do.
    if (used() == 0) {
      return;   // Nothing to do.
    }
  
--- 369,20 ---
  
    // save the compaction_top of the compaction space.
    cp->space->set_compaction_top(compact_top);
  }
  
! void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) {
+   if (UseAltGCForwarding) {
+     prepare_for_compaction_impl<true>(cp);
+   } else {
+     prepare_for_compaction_impl<false>(cp);
+   }
+ }
+ 
+ template <bool ALT_FWD>
+ void ContiguousSpace::adjust_pointers_impl() {
    // Check first is there is any work to do.
    if (used() == 0) {
      return;   // Nothing to do.
    }
  

*** 390,11 ***
    while (cur_obj < end_of_live) {
      Prefetch::write(cur_obj, interval);
      if (cur_obj < first_dead || cast_to_oop(cur_obj)->is_gc_marked()) {
        // cur_obj is alive
        // point all the oops to the new location
!       size_t size = MarkSweep::adjust_pointers(cast_to_oop(cur_obj));
        debug_only(prev_obj = cur_obj);
        cur_obj += size;
      } else {
        debug_only(prev_obj = cur_obj);
        // cur_obj is not a live object, instead it points at the next live object
--- 401,11 ---
    while (cur_obj < end_of_live) {
      Prefetch::write(cur_obj, interval);
      if (cur_obj < first_dead || cast_to_oop(cur_obj)->is_gc_marked()) {
        // cur_obj is alive
        // point all the oops to the new location
!       size_t size = MarkSweep::adjust_pointers<ALT_FWD>(cast_to_oop(cur_obj));
        debug_only(prev_obj = cur_obj);
        cur_obj += size;
      } else {
        debug_only(prev_obj = cur_obj);
        // cur_obj is not a live object, instead it points at the next live object

*** 404,11 ***
    }
  
    assert(cur_obj == end_of_live, "just checking");
  }
  
! void ContiguousSpace::compact() {
    // Copy all live objects to their new location
    // Used by MarkSweep::mark_sweep_phase4()
  
    verify_up_to_first_dead(this);
  
--- 415,20 ---
    }
  
    assert(cur_obj == end_of_live, "just checking");
  }
  
! void ContiguousSpace::adjust_pointers() {
+   if (UseAltGCForwarding) {
+     adjust_pointers_impl<true>();
+   } else {
+     adjust_pointers_impl<false>();
+   }
+ }
+ 
+ template <bool ALT_FWD>
+ void ContiguousSpace::compact_impl() {
    // Copy all live objects to their new location
    // Used by MarkSweep::mark_sweep_phase4()
  
    verify_up_to_first_dead(this);
  

*** 433,22 ***
      cur_obj = *(HeapWord**)(_first_dead);
    }
  
    debug_only(HeapWord* prev_obj = nullptr);
    while (cur_obj < end_of_live) {
!     if (!cast_to_oop(cur_obj)->is_forwarded()) {
        debug_only(prev_obj = cur_obj);
        // The first word of the dead object contains a pointer to the next live object or end of space.
        cur_obj = *(HeapWord**)cur_obj;
        assert(cur_obj > prev_obj, "we should be moving forward through memory");
      } else {
        // prefetch beyond q
        Prefetch::read(cur_obj, scan_interval);
  
        // size and destination
        size_t size = cast_to_oop(cur_obj)->size();
!       HeapWord* compaction_top = cast_from_oop<HeapWord*>(cast_to_oop(cur_obj)->forwardee());
  
        // prefetch beyond compaction_top
        Prefetch::write(compaction_top, copy_interval);
  
        // copy object and reinit its mark
--- 453,22 ---
      cur_obj = *(HeapWord**)(_first_dead);
    }
  
    debug_only(HeapWord* prev_obj = nullptr);
    while (cur_obj < end_of_live) {
!     if (SlidingForwarding::is_not_forwarded(cast_to_oop(cur_obj))) {
        debug_only(prev_obj = cur_obj);
        // The first word of the dead object contains a pointer to the next live object or end of space.
        cur_obj = *(HeapWord**)cur_obj;
        assert(cur_obj > prev_obj, "we should be moving forward through memory");
      } else {
        // prefetch beyond q
        Prefetch::read(cur_obj, scan_interval);
  
        // size and destination
        size_t size = cast_to_oop(cur_obj)->size();
!       HeapWord* compaction_top = cast_from_oop<HeapWord*>(SlidingForwarding::forwardee<ALT_FWD>(cast_to_oop(cur_obj)));
  
        // prefetch beyond compaction_top
        Prefetch::write(compaction_top, copy_interval);
  
        // copy object and reinit its mark

*** 467,10 ***
--- 487,18 ---
    }
  
    clear_empty_region(this);
  }
  
+ void ContiguousSpace::compact() {
+   if (UseAltGCForwarding) {
+     compact_impl<true>();
+   } else {
+     compact_impl<false>();
+   }
+ }
+ 
  #endif // INCLUDE_SERIALGC
  
  void Space::print_short() const { print_short_on(tty); }
  
  void Space::print_short_on(outputStream* st) const {
< prev index next >