< prev index next >

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

Print this page
@@ -25,10 +25,11 @@
  #include "precompiled.hpp"
  
  #include "compiler/oopMap.hpp"
  #include "gc/shared/gcTraceTime.inline.hpp"
  #include "gc/shared/preservedMarks.inline.hpp"
+ #include "gc/shared/slidingForwarding.inline.hpp"
  #include "gc/shared/tlab_globals.hpp"
  #include "gc/shared/workerThread.hpp"
  #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
  #include "gc/shenandoah/shenandoahConcurrentGC.hpp"
  #include "gc/shenandoah/shenandoahCollectionSet.hpp"

@@ -180,10 +181,11 @@
      // f. Sync pinned region status from the CP marks
      heap->sync_pinned_region_status();
  
      // The rest of prologue:
      _preserved_marks->init(heap->workers()->active_workers());
+     heap->forwarding()->clear();
  
      assert(heap->has_forwarded_objects() == has_forwarded_objects, "This should not change");
    }
  
    if (UseTLAB) {

@@ -290,12 +292,13 @@
    heap->parallel_cleaning(true /* full_gc */);
  }
  
  class ShenandoahPrepareForCompactionObjectClosure : public ObjectClosure {
  private:
-   PreservedMarks*          const _preserved_marks;
-   ShenandoahHeap*          const _heap;
+   PreservedMarks*    const _preserved_marks;
+   SlidingForwarding* const _forwarding;
+   ShenandoahHeap*    const _heap;
    GrowableArray<ShenandoahHeapRegion*>& _empty_regions;
    int _empty_regions_pos;
    ShenandoahHeapRegion*          _to_region;
    ShenandoahHeapRegion*          _from_region;
    HeapWord* _compact_point;

@@ -303,10 +306,11 @@
  public:
    ShenandoahPrepareForCompactionObjectClosure(PreservedMarks* preserved_marks,
                                                GrowableArray<ShenandoahHeapRegion*>& empty_regions,
                                                ShenandoahHeapRegion* to_region) :
      _preserved_marks(preserved_marks),
+     _forwarding(ShenandoahHeap::heap()->forwarding()),
      _heap(ShenandoahHeap::heap()),
      _empty_regions(empty_regions),
      _empty_regions_pos(0),
      _to_region(to_region),
      _from_region(NULL),

@@ -356,11 +360,11 @@
  
      // Object fits into current region, record new location:
      assert(_compact_point + obj_size <= _to_region->end(), "must fit");
      shenandoah_assert_not_forwarded(NULL, p);
      _preserved_marks->push_if_necessary(p, p->mark());
-     p->forward_to(cast_to_oop(_compact_point));
+     _forwarding->forward_to(p, cast_to_oop(_compact_point));
      _compact_point += obj_size;
    }
  };
  
  class ShenandoahPrepareForCompactionTask : public WorkerTask {

@@ -430,10 +434,11 @@
    }
  };
  
  void ShenandoahFullGC::calculate_target_humongous_objects() {
    ShenandoahHeap* heap = ShenandoahHeap::heap();
+   SlidingForwarding* forwarding = heap->forwarding();
  
    // Compute the new addresses for humongous objects. We need to do this after addresses
    // for regular objects are calculated, and we know what regions in heap suffix are
    // available for humongous moves.
    //

@@ -464,11 +469,11 @@
        size_t start = to_end - num_regions;
  
        if (start >= to_begin && start != r->index()) {
          // Fits into current window, and the move is non-trivial. Record the move then, and continue scan.
          _preserved_marks->get(0)->push_if_necessary(old_obj, old_obj->mark());
-         old_obj->forward_to(cast_to_oop(heap->get_region(start)->bottom()));
+         forwarding->forward_to(old_obj, cast_to_oop(heap->get_region(start)->bottom()));
          to_end = start;
          continue;
        }
      }
  

@@ -715,29 +720,31 @@
    }
  }
  
  class ShenandoahAdjustPointersClosure : public MetadataVisitingOopIterateClosure {
  private:
-   ShenandoahHeap* const _heap;
+   ShenandoahHeap*           const _heap;
+   const SlidingForwarding*  const _forwarding;
    ShenandoahMarkingContext* const _ctx;
  
    template <class T>
    inline void do_oop_work(T* p) {
      T o = RawAccess<>::oop_load(p);
      if (!CompressedOops::is_null(o)) {
        oop obj = CompressedOops::decode_not_null(o);
        assert(_ctx->is_marked(obj), "must be marked");
        if (obj->is_forwarded()) {
-         oop forw = obj->forwardee();
+         oop forw = _forwarding->forwardee(obj);
          RawAccess<IS_NOT_NULL>::oop_store(p, forw);
        }
      }
    }
  
  public:
    ShenandoahAdjustPointersClosure() :
      _heap(ShenandoahHeap::heap()),
+     _forwarding(_heap->forwarding()),
      _ctx(ShenandoahHeap::heap()->complete_marking_context()) {}
  
    void do_oop(oop* p)       { do_oop_work(p); }
    void do_oop(narrowOop* p) { do_oop_work(p); }
  };

@@ -793,11 +800,12 @@
  
    void work(uint worker_id) {
      ShenandoahParallelWorkerSession worker_session(worker_id);
      ShenandoahAdjustPointersClosure cl;
      _rp->roots_do(worker_id, &cl);
-     _preserved_marks->get(worker_id)->adjust_during_full_gc();
+     const SlidingForwarding* const forwarding = ShenandoahHeap::heap()->forwarding();
+     _preserved_marks->get(worker_id)->adjust_during_full_gc(forwarding);
    }
  };
  
  void ShenandoahFullGC::phase3_update_references() {
    GCTraceTime(Info, gc, phases) time("Phase 3: Adjust pointers", _gc_timer);

@@ -823,23 +831,24 @@
    workers->run_task(&adjust_pointers_task);
  }
  
  class ShenandoahCompactObjectsClosure : public ObjectClosure {
  private:
-   ShenandoahHeap* const _heap;
-   uint            const _worker_id;
+   ShenandoahHeap*          const _heap;
+   const SlidingForwarding* const _forwarding;
+   uint                     const _worker_id;
  
  public:
    ShenandoahCompactObjectsClosure(uint worker_id) :
-     _heap(ShenandoahHeap::heap()), _worker_id(worker_id) {}
+     _heap(ShenandoahHeap::heap()), _forwarding(_heap->forwarding()), _worker_id(worker_id) {}
  
    void do_object(oop p) {
      assert(_heap->complete_marking_context()->is_marked(p), "must be marked");
      size_t size = p->size();
      if (p->is_forwarded()) {
        HeapWord* compact_from = cast_from_oop<HeapWord*>(p);
-       HeapWord* compact_to = cast_from_oop<HeapWord*>(p->forwardee());
+       HeapWord* compact_to = cast_from_oop<HeapWord*>(_forwarding->forwardee(p));
        Copy::aligned_conjoint_words(compact_from, compact_to, size);
        oop new_obj = cast_to_oop(compact_to);
        new_obj->init_mark();
      }
    }

@@ -930,10 +939,11 @@
    // This code is serial, because doing the in-slice parallel sliding is tricky. In most cases,
    // humongous regions are already compacted, and do not require further moves, which alleviates
    // sliding costs. We may consider doing this in parallel in future.
  
    ShenandoahHeap* heap = ShenandoahHeap::heap();
+   const SlidingForwarding* const forwarding = heap->forwarding();
  
    for (size_t c = heap->num_regions(); c > 0; c--) {
      ShenandoahHeapRegion* r = heap->get_region(c - 1);
      if (r->is_humongous_start()) {
        oop old_obj = cast_to_oop(r->bottom());

@@ -944,11 +954,11 @@
        size_t words_size = old_obj->size();
        size_t num_regions = ShenandoahHeapRegion::required_regions(words_size * HeapWordSize);
  
        size_t old_start = r->index();
        size_t old_end   = old_start + num_regions - 1;
-       size_t new_start = heap->heap_region_index_containing(old_obj->forwardee());
+       size_t new_start = heap->heap_region_index_containing(forwarding->forwardee(old_obj));
        size_t new_end   = new_start + num_regions - 1;
        assert(old_start != new_start, "must be real move");
        assert(r->is_stw_move_allowed(), "Region " SIZE_FORMAT " should be movable", r->index());
  
        Copy::aligned_conjoint_words(heap->get_region(old_start)->bottom(),
< prev index next >