changeset 48073:5caa1d5f74c1

8186571: Implementation: JEP 307: Parallel Full GC for G1 Summary: Improve G1 worst-case latencies by making the full GC parallel. Reviewed-by: tschatzl, sangheki, ehelin
author sjohanss
date Tue, 14 Nov 2017 11:33:23 +0100
parents 3cfab71d6c81
children 95363d2f2c13
files src/hotspot/share/gc/g1/collectionSetChooser.cpp src/hotspot/share/gc/g1/g1CardLiveData.cpp src/hotspot/share/gc/g1/g1CollectedHeap.cpp src/hotspot/share/gc/g1/g1CollectedHeap.hpp src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp src/hotspot/share/gc/g1/g1ConcurrentMark.cpp src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.cpp src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.hpp src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.inline.hpp src/hotspot/share/gc/g1/g1FullCollector.cpp src/hotspot/share/gc/g1/g1FullCollector.hpp src/hotspot/share/gc/g1/g1FullCollector_ext.cpp src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp src/hotspot/share/gc/g1/g1FullGCAdjustTask.hpp src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp src/hotspot/share/gc/g1/g1FullGCCompactTask.hpp src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp src/hotspot/share/gc/g1/g1FullGCMarkTask.hpp src/hotspot/share/gc/g1/g1FullGCMarker.cpp src/hotspot/share/gc/g1/g1FullGCMarker.hpp src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp src/hotspot/share/gc/g1/g1FullGCOopClosures.cpp src/hotspot/share/gc/g1/g1FullGCOopClosures.hpp src/hotspot/share/gc/g1/g1FullGCOopClosures.inline.hpp src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.cpp src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.hpp src/hotspot/share/gc/g1/g1FullGCScope.cpp src/hotspot/share/gc/g1/g1FullGCScope.hpp src/hotspot/share/gc/g1/g1FullGCTask.cpp src/hotspot/share/gc/g1/g1FullGCTask.hpp src/hotspot/share/gc/g1/g1HeapVerifier.cpp src/hotspot/share/gc/g1/g1HeapVerifier.hpp src/hotspot/share/gc/g1/g1HotCardCache.cpp src/hotspot/share/gc/g1/g1HotCardCache.hpp src/hotspot/share/gc/g1/g1MarkSweep.cpp src/hotspot/share/gc/g1/g1MarkSweep.hpp src/hotspot/share/gc/g1/g1MarkSweep_ext.cpp src/hotspot/share/gc/g1/g1OopClosures.inline.hpp src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp src/hotspot/share/gc/g1/g1RemSet.cpp src/hotspot/share/gc/g1/g1RemSet.hpp src/hotspot/share/gc/g1/g1RemSet.inline.hpp src/hotspot/share/gc/g1/g1RemSetSummary.cpp src/hotspot/share/gc/g1/g1RootProcessor.cpp src/hotspot/share/gc/g1/g1RootProcessor.hpp src/hotspot/share/gc/g1/g1SerialFullCollector.cpp src/hotspot/share/gc/g1/g1SerialFullCollector.hpp src/hotspot/share/gc/g1/g1StringDedup.cpp src/hotspot/share/gc/g1/g1StringDedup.hpp src/hotspot/share/gc/g1/g1_specialized_oop_closures.hpp src/hotspot/share/gc/g1/heapRegion.cpp src/hotspot/share/gc/g1/heapRegion.hpp src/hotspot/share/gc/g1/heapRegion.inline.hpp src/hotspot/share/gc/g1/heapRegionManager.cpp src/hotspot/share/gc/g1/heapRegionManager.hpp src/hotspot/share/gc/serial/markSweep.cpp src/hotspot/share/gc/shared/gcName.hpp src/hotspot/share/gc/shared/gcTrace.hpp src/hotspot/share/gc/shared/preservedMarks.cpp src/hotspot/share/gc/shared/preservedMarks.hpp src/hotspot/share/gc/shared/specialized_oop_closures.hpp src/hotspot/share/gc/shared/taskqueue.hpp src/hotspot/share/gc/shared/taskqueue.inline.hpp src/hotspot/share/memory/universe.hpp src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCName.java test/hotspot/gtest/gc/g1/test_heapRegion.cpp test/hotspot/gtest/gc/shared/test_preservedMarks.cpp test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java
diffstat 73 files changed, 2856 insertions(+), 960 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/g1/collectionSetChooser.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/collectionSetChooser.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -247,8 +247,8 @@
       _g1(G1CollectedHeap::heap()), _hrclaimer(n_workers) {}
 
   void work(uint worker_id) {
-    ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted, _chunk_size);
-    _g1->heap_region_par_iterate(&parKnownGarbageCl, worker_id, &_hrclaimer);
+    ParKnownGarbageHRClosure par_known_garbage_cl(_hrSorted, _chunk_size);
+    _g1->heap_region_par_iterate_from_worker_offset(&par_known_garbage_cl, &_hrclaimer, worker_id);
   }
 };
 
--- a/src/hotspot/share/gc/g1/g1CardLiveData.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1CardLiveData.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -314,7 +314,7 @@
     G1CollectedHeap* g1h = G1CollectedHeap::heap();
     G1ConcurrentMark* cm = g1h->concurrent_mark();
     G1CreateLiveDataClosure cl(g1h, cm, cm->next_mark_bitmap(), _live_data);
-    g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
+    g1h->heap_region_par_iterate_from_worker_offset(&cl, &_hr_claimer, worker_id);
   }
 };
 
@@ -381,7 +381,7 @@
   void work(uint worker_id) {
     G1FinalizeCardLiveDataClosure cl(G1CollectedHeap::heap(), _bitmap, _live_data);
 
-    G1CollectedHeap::heap()->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
+    G1CollectedHeap::heap()->heap_region_par_iterate_from_worker_offset(&cl, &_hr_claimer, worker_id);
   }
 };
 
@@ -560,7 +560,7 @@
                                    _mark_bitmap,
                                    _act_live_data,
                                    &_exp_live_data);
-    _g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
+    _g1h->heap_region_par_iterate_from_worker_offset(&cl, &_hr_claimer, worker_id);
 
     Atomic::add(cl.failures(), &_failures);
   }
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -38,6 +38,7 @@
 #include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/g1ConcurrentRefineThread.hpp"
 #include "gc/g1/g1EvacStats.inline.hpp"
+#include "gc/g1/g1FullCollector.hpp"
 #include "gc/g1/g1FullGCScope.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
 #include "gc/g1/g1HeapSizingPolicy.hpp"
@@ -48,10 +49,9 @@
 #include "gc/g1/g1ParScanThreadState.inline.hpp"
 #include "gc/g1/g1Policy.hpp"
 #include "gc/g1/g1RegionToSpaceMapper.hpp"
-#include "gc/g1/g1RemSet.inline.hpp"
+#include "gc/g1/g1RemSet.hpp"
 #include "gc/g1/g1RootClosures.hpp"
 #include "gc/g1/g1RootProcessor.hpp"
-#include "gc/g1/g1SerialFullCollector.hpp"
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/g1/g1YCTypes.hpp"
 #include "gc/g1/g1YoungRemSetSamplingThread.hpp"
@@ -143,6 +143,12 @@
   reset_from_card_cache(start_idx, num_regions);
 }
 
+
+HeapRegion* G1CollectedHeap::new_heap_region(uint hrs_index,
+                                             MemRegion mr) {
+  return new HeapRegion(hrs_index, bot(), mr);
+}
+
 // Private methods.
 
 HeapRegion*
@@ -1155,7 +1161,6 @@
 
 void G1CollectedHeap::abort_refinement() {
   if (_hot_card_cache->use_cache()) {
-    _hot_card_cache->reset_card_counts();
     _hot_card_cache->reset_hot_cache();
   }
 
@@ -1199,6 +1204,10 @@
 }
 
 void G1CollectedHeap::print_heap_after_full_collection(G1HeapTransition* heap_transition) {
+  // Post collection logging.
+  // We should do this after we potentially resize the heap so
+  // that all the COMMIT / UNCOMMIT events are generated before
+  // the compaction events.
   print_hrm_post_compaction();
   heap_transition->print();
   print_heap_after_gc();
@@ -1221,23 +1230,18 @@
   gc_prologue(true);
   prepare_heap_for_full_collection();
 
-  G1SerialFullCollector serial(scope, ref_processor_stw());
-  serial.prepare_collection();
-  serial.collect();
-  serial.complete_collection();
+  G1FullCollector collector(scope, ref_processor_stw(), concurrent_mark()->next_mark_bitmap(), workers()->active_workers());
+  collector.prepare_collection();
+  collector.collect();
+  collector.complete_collection();
 
   prepare_heap_for_mutators();
 
   g1_policy()->record_full_collection_end();
   gc_epilogue(true);
 
-  // Post collection verification.
   verify_after_full_collection();
 
-  // Post collection logging.
-  // We should do this after we potentially resize the heap so
-  // that all the COMMIT / UNCOMMIT events are generated before
-  // the compaction events.
   print_heap_after_full_collection(scope->heap_transition());
 }
 
@@ -1269,10 +1273,10 @@
 }
 
 void G1CollectedHeap::resize_if_necessary_after_full_collection() {
-  // Include bytes that will be pre-allocated to support collections, as "used".
-  const size_t used_after_gc = used();
+  // Capacity, free and used after the GC counted as full regions to
+  // include the waste in the following calculations.
   const size_t capacity_after_gc = capacity();
-  const size_t free_after_gc = capacity_after_gc - used_after_gc;
+  const size_t used_after_gc = capacity_after_gc - unused_committed_regions_in_bytes();
 
   // This is enforced in arguments.cpp.
   assert(MinHeapFreeRatio <= MaxHeapFreeRatio,
@@ -1326,8 +1330,9 @@
     size_t expand_bytes = minimum_desired_capacity - capacity_after_gc;
 
     log_debug(gc, ergo, heap)("Attempt heap expansion (capacity lower than min desired capacity after Full GC). "
-                              "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)",
-                              capacity_after_gc, used_after_gc, minimum_desired_capacity, MinHeapFreeRatio);
+                              "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B live: " SIZE_FORMAT "B "
+                              "min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)",
+                              capacity_after_gc, used_after_gc, used(), minimum_desired_capacity, MinHeapFreeRatio);
 
     expand(expand_bytes, _workers);
 
@@ -1337,8 +1342,9 @@
     size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity;
 
     log_debug(gc, ergo, heap)("Attempt heap shrinking (capacity higher than max desired capacity after Full GC). "
-                              "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)",
-                              capacity_after_gc, used_after_gc, minimum_desired_capacity, MinHeapFreeRatio);
+                              "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B live: " SIZE_FORMAT "B "
+                              "maximum_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)",
+                              capacity_after_gc, used_after_gc, used(), maximum_desired_capacity, MaxHeapFreeRatio);
 
     shrink(shrink_bytes);
   }
@@ -1959,6 +1965,10 @@
   return _hrm.length() * HeapRegion::GrainBytes;
 }
 
+size_t G1CollectedHeap::unused_committed_regions_in_bytes() const {
+  return _hrm.total_free_bytes();
+}
+
 void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) {
   hr->reset_gc_time_stamp();
 }
@@ -2262,10 +2272,15 @@
   _hrm.iterate(cl);
 }
 
-void G1CollectedHeap::heap_region_par_iterate(HeapRegionClosure* cl,
-                                              uint worker_id,
-                                              HeapRegionClaimer *hrclaimer) const {
-  _hrm.par_iterate(cl, worker_id, hrclaimer);
+void G1CollectedHeap::heap_region_par_iterate_from_worker_offset(HeapRegionClosure* cl,
+                                                                 HeapRegionClaimer *hrclaimer,
+                                                                 uint worker_id) const {
+  _hrm.par_iterate(cl, hrclaimer, hrclaimer->offset_for_worker(worker_id));
+}
+
+void G1CollectedHeap::heap_region_par_iterate_from_start(HeapRegionClosure* cl,
+                                                         HeapRegionClaimer *hrclaimer) const {
+  _hrm.par_iterate(cl, hrclaimer, 0);
 }
 
 void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) {
@@ -2276,14 +2291,6 @@
   _collection_set.iterate_from(cl, worker_id, workers()->active_workers());
 }
 
-HeapRegion* G1CollectedHeap::next_compaction_region(const HeapRegion* from) const {
-  HeapRegion* result = _hrm.next_region_in_heap(from);
-  while (result != NULL && result->is_pinned()) {
-    result = _hrm.next_region_in_heap(result);
-  }
-  return result;
-}
-
 HeapWord* G1CollectedHeap::block_start(const void* addr) const {
   HeapRegion* hr = heap_region_containing(addr);
   return hr->block_start(addr);
@@ -2375,7 +2382,7 @@
   switch (vo) {
   case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj, hr);
   case VerifyOption_G1UseNextMarking: return is_obj_ill(obj, hr);
-  case VerifyOption_G1UseMarkWord:    return !obj->is_gc_marked() && !hr->is_archive();
+  case VerifyOption_G1UseFullMarking: return is_obj_dead_full(obj, hr);
   default:                            ShouldNotReachHere();
   }
   return false; // keep some compilers happy
@@ -2386,10 +2393,7 @@
   switch (vo) {
   case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj);
   case VerifyOption_G1UseNextMarking: return is_obj_ill(obj);
-  case VerifyOption_G1UseMarkWord: {
-    HeapRegion* hr = _hrm.addr_to_region((HeapWord*)obj);
-    return !obj->is_gc_marked() && !hr->is_archive();
-  }
+  case VerifyOption_G1UseFullMarking: return is_obj_dead_full(obj);
   default:                            ShouldNotReachHere();
   }
   return false; // keep some compilers happy
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -1046,6 +1046,7 @@
   // The Concurrent Marking reference processor...
   ReferenceProcessor* ref_processor_cm() const { return _ref_processor_cm; }
 
+  size_t unused_committed_regions_in_bytes() const;
   virtual size_t capacity() const;
   virtual size_t used() const;
   // This should be called when we're not holding the heap lock. The
@@ -1181,6 +1182,8 @@
     return barrier_set_cast<G1SATBCardTableLoggingModRefBS>(barrier_set());
   }
 
+  G1HotCardCache* g1_hot_card_cache() const { return _hot_card_cache; }
+
   // Iteration functions.
 
   // Iterate over all objects, calling "cl.do_object" on each.
@@ -1207,15 +1210,18 @@
 
   inline HeapWord* bottom_addr_for_region(uint index) const;
 
-  // Iterate over the heap regions in parallel. Assumes that this will be called
-  // in parallel by a number of worker threads with distinct worker ids
-  // in the range passed to the HeapRegionClaimer. Applies "blk->doHeapRegion"
-  // to each of the regions, by attempting to claim the region using the
-  // HeapRegionClaimer and, if successful, applying the closure to the claimed
-  // region.
-  void heap_region_par_iterate(HeapRegionClosure* cl,
-                               uint worker_id,
-                               HeapRegionClaimer* hrclaimer) const;
+  // Two functions to iterate over the heap regions in parallel. Threads
+  // compete using the HeapRegionClaimer to claim the regions before
+  // applying the closure on them.
+  // The _from_worker_offset version uses the HeapRegionClaimer and
+  // the worker id to calculate a start offset to prevent all workers to
+  // start from the point.
+  void heap_region_par_iterate_from_worker_offset(HeapRegionClosure* cl,
+                                                  HeapRegionClaimer* hrclaimer,
+                                                  uint worker_id) const;
+
+  void heap_region_par_iterate_from_start(HeapRegionClosure* cl,
+                                          HeapRegionClaimer* hrclaimer) const;
 
   // Iterate over the regions (if any) in the current collection set.
   void collection_set_iterate(HeapRegionClosure* blk);
@@ -1226,8 +1232,6 @@
   // collection set regions.
   void collection_set_iterate_from(HeapRegionClosure *blk, uint worker_id);
 
-  HeapRegion* next_compaction_region(const HeapRegion* from) const;
-
   // Returns the HeapRegion that contains addr. addr must not be NULL.
   template <class T>
   inline HeapRegion* heap_region_containing(const T addr) const;
@@ -1391,6 +1395,9 @@
 
   inline bool is_obj_ill(const oop obj) const;
 
+  inline bool is_obj_dead_full(const oop obj, const HeapRegion* hr) const;
+  inline bool is_obj_dead_full(const oop obj) const;
+
   G1ConcurrentMark* concurrent_mark() const { return _cm; }
 
   // Refinement
@@ -1435,9 +1442,9 @@
 
   // Perform verification.
 
-  // vo == UsePrevMarking  -> use "prev" marking information,
+  // vo == UsePrevMarking -> use "prev" marking information,
   // vo == UseNextMarking -> use "next" marking information
-  // vo == UseMarkWord    -> use the mark word in the object header
+  // vo == UseFullMarking -> use "next" marking bitmap but no TAMS
   //
   // NOTE: Only the "prev" marking information is guaranteed to be
   // consistent most of the time, so most calls to this should use
@@ -1446,7 +1453,7 @@
   // vo == UseNextMarking, which is to verify the "next" marking
   // information at the end of remark.
   // Currently there is only one place where this is called with
-  // vo == UseMarkWord, which is to verify the marking during a
+  // vo == UseFullMarking, which is to verify the marking during a
   // full GC.
   void verify(VerifyOption vo);
 
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -264,6 +264,14 @@
   return is_obj_ill(obj, heap_region_containing(obj));
 }
 
+inline bool G1CollectedHeap::is_obj_dead_full(const oop obj, const HeapRegion* hr) const {
+   return !isMarkedNext(obj) && !hr->is_archive();
+}
+
+inline bool G1CollectedHeap::is_obj_dead_full(const oop obj) const {
+    return is_obj_dead_full(obj, heap_region_containing(obj));
+}
+
 inline void G1CollectedHeap::set_humongous_reclaim_candidate(uint region, bool value) {
   assert(_hrm.at(region)->is_starts_humongous(), "Must start a humongous object");
   _humongous_reclaim_candidates.set_candidate(region, value);
--- a/src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,11 +37,6 @@
   return false;
 }
 
-HeapRegion* G1CollectedHeap::new_heap_region(uint hrs_index,
-                                             MemRegion mr) {
-  return new HeapRegion(hrs_index, bot(), mr);
-}
-
 G1Policy* G1CollectedHeap::create_g1_policy(STWGCTimer* gc_timer) {
   return new G1DefaultPolicy(gc_timer);
 }
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -634,7 +634,7 @@
 
   void work(uint worker_id) {
     SuspendibleThreadSetJoiner sts_join(_suspendible);
-    G1CollectedHeap::heap()->heap_region_par_iterate(&_cl, worker_id, &_hr_claimer);
+    G1CollectedHeap::heap()->heap_region_par_iterate_from_worker_offset(&_cl, &_hr_claimer, worker_id);
   }
 
   bool is_complete() {
@@ -1140,7 +1140,7 @@
     HRRSCleanupTask hrrs_cleanup_task;
     G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list,
                                            &hrrs_cleanup_task);
-    _g1h->heap_region_par_iterate(&g1_note_end, worker_id, &_hrclaimer);
+    _g1h->heap_region_par_iterate_from_worker_offset(&g1_note_end, &_hrclaimer, worker_id);
     assert(g1_note_end.complete(), "Shouldn't have yielded!");
 
     // Now update the lists
--- a/src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
+#include "gc/g1/heapRegion.hpp"
 #include "memory/virtualspace.hpp"
 
 void G1CMBitMap::print_on_error(outputStream* st, const char* prefix) const {
@@ -65,3 +66,10 @@
   _bm.at_put_range(addr_to_offset(intersection.start()),
                    addr_to_offset(intersection.end()), false);
 }
+
+void G1CMBitMap::clear_region(HeapRegion* region) {
+ if (!region->is_empty()) {
+   MemRegion mr(region->bottom(), region->top());
+   clear_range(mr);
+ }
+}
--- a/src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -28,6 +28,7 @@
 #include "gc/g1/g1RegionToSpaceMapper.hpp"
 #include "memory/allocation.hpp"
 #include "memory/memRegion.hpp"
+#include "oops/oopsHierarchy.hpp"
 #include "utilities/bitMap.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
@@ -35,6 +36,7 @@
 class G1CMBitMap;
 class G1CMTask;
 class G1ConcurrentMark;
+class HeapRegion;
 
 // Closure for iteration over bitmaps
 class G1CMBitMapClosure VALUE_OBJ_CLASS_SPEC {
@@ -96,6 +98,7 @@
   void initialize(MemRegion heap, G1RegionToSpaceMapper* storage);
 
   // Read marks
+  bool is_marked(oop obj) const;
   bool is_marked(HeapWord* addr) const {
     assert(_covered.contains(addr),
            "Address " PTR_FORMAT " is outside underlying space from " PTR_FORMAT " to " PTR_FORMAT,
@@ -120,9 +123,12 @@
   // Write marks.
   inline void mark(HeapWord* addr);
   inline void clear(HeapWord* addr);
+  inline void clear(oop obj);
   inline bool par_mark(HeapWord* addr);
+  inline bool par_mark(oop obj);
 
   void clear_range(MemRegion mr);
+  void clear_region(HeapRegion* hr);
 };
 
 #endif // SHARE_VM_GC_G1_G1CONCURRENTMARKBITMAP_HPP
--- a/src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.inline.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.inline.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -83,4 +83,16 @@
   return _bm.par_set_bit(addr_to_offset(addr));
 }
 
+inline bool G1CMBitMap::par_mark(oop obj) {
+  return par_mark((HeapWord*) obj);
+}
+
+inline bool G1CMBitMap::is_marked(oop obj) const{
+  return is_marked((HeapWord*) obj);
+}
+
+inline void G1CMBitMap::clear(oop obj) {
+  clear((HeapWord*) obj);
+}
+
 #endif // SHARE_VM_GC_G1_G1CONCURRENTMARKBITMAP_INLINE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "code/codeCache.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1CollectorPolicy.hpp"
+#include "gc/g1/g1FullCollector.hpp"
+#include "gc/g1/g1FullGCAdjustTask.hpp"
+#include "gc/g1/g1FullGCCompactTask.hpp"
+#include "gc/g1/g1FullGCMarker.inline.hpp"
+#include "gc/g1/g1FullGCMarkTask.hpp"
+#include "gc/g1/g1FullGCPrepareTask.hpp"
+#include "gc/g1/g1FullGCReferenceProcessorExecutor.hpp"
+#include "gc/g1/g1FullGCScope.hpp"
+#include "gc/g1/g1OopClosures.hpp"
+#include "gc/g1/g1StringDedup.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
+#include "gc/shared/preservedMarks.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "gc/shared/weakProcessor.hpp"
+#include "logging/log.hpp"
+#include "runtime/biasedLocking.hpp"
+#include "utilities/debug.hpp"
+
+static void clear_and_activate_derived_pointers() {
+#if COMPILER2_OR_JVMCI
+  DerivedPointerTable::clear();
+#endif
+}
+
+static void deactivate_derived_pointers() {
+#if COMPILER2_OR_JVMCI
+  DerivedPointerTable::set_active(false);
+#endif
+}
+
+static void update_derived_pointers() {
+#if COMPILER2_OR_JVMCI
+  DerivedPointerTable::update_pointers();
+#endif
+}
+
+G1FullCollector::G1FullCollector(G1FullGCScope* scope,
+                                 ReferenceProcessor* reference_processor,
+                                 G1CMBitMap* bitmap,
+                                 uint workers) :
+    _scope(scope),
+    _num_workers(workers),
+    _mark_bitmap(bitmap),
+    _oop_queue_set(_num_workers),
+    _array_queue_set(_num_workers),
+    _preserved_marks_set(true),
+    _reference_processor(reference_processor),
+    _serial_compaction_point(),
+    _is_alive(_mark_bitmap),
+    _is_alive_mutator(_reference_processor, &_is_alive) {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
+
+  _preserved_marks_set.init(_num_workers);
+  _markers = NEW_C_HEAP_ARRAY(G1FullGCMarker*, _num_workers, mtGC);
+  _compaction_points = NEW_C_HEAP_ARRAY(G1FullGCCompactionPoint*, _num_workers, mtGC);
+  for (uint i = 0; i < _num_workers; i++) {
+    _markers[i] = new G1FullGCMarker(i, _preserved_marks_set.get(i), mark_bitmap());
+    _compaction_points[i] = new G1FullGCCompactionPoint();
+    _oop_queue_set.register_queue(i, marker(i)->oop_stack());
+    _array_queue_set.register_queue(i, marker(i)->objarray_stack());
+  }
+}
+
+G1FullCollector::~G1FullCollector() {
+  for (uint i = 0; i < _num_workers; i++) {
+    delete _markers[i];
+    delete _compaction_points[i];
+  }
+  FREE_C_HEAP_ARRAY(G1FullGCMarker*, _markers);
+  FREE_C_HEAP_ARRAY(G1FullGCCompactionPoint*, _compaction_points);
+}
+
+void G1FullCollector::prepare_collection() {
+  _reference_processor->enable_discovery();
+  _reference_processor->setup_policy(scope()->should_clear_soft_refs());
+
+  // When collecting the permanent generation Method*s may be moving,
+  // so we either have to flush all bcp data or convert it into bci.
+  CodeCache::gc_prologue();
+
+  // We should save the marks of the currently locked biased monitors.
+  // The marking doesn't preserve the marks of biased objects.
+  BiasedLocking::preserve_marks();
+
+  // Clear and activate derived pointer collection.
+  clear_and_activate_derived_pointers();
+}
+
+void G1FullCollector::collect() {
+  phase1_mark_live_objects();
+  verify_after_marking();
+
+  // Don't add any more derived pointers during later phases
+  deactivate_derived_pointers();
+
+  phase2_prepare_compaction();
+
+  phase3_adjust_pointers();
+
+  phase4_do_compaction();
+}
+
+void G1FullCollector::complete_collection() {
+  // Restore all marks.
+  restore_marks();
+
+  // When the pointers have been adjusted and moved, we can
+  // update the derived pointer table.
+  update_derived_pointers();
+
+  BiasedLocking::restore_marks();
+  CodeCache::gc_epilogue();
+  JvmtiExport::gc_epilogue();
+}
+
+void G1FullCollector::phase1_mark_live_objects() {
+  // Recursively traverse all live objects and mark them.
+  GCTraceTime(Info, gc, phases) info("Phase 1: Mark live objects", scope()->timer());
+
+  // Do the actual marking.
+  G1FullGCMarkTask marking_task(this);
+  run_task(&marking_task);
+
+  // Process references discovered during marking.
+  G1FullGCReferenceProcessingExecutor reference_processing(this);
+  reference_processing.execute(scope()->timer(), scope()->tracer());
+
+  // Weak oops cleanup.
+  {
+    GCTraceTime(Debug, gc, phases) trace("Phase 1: Weak Processing", scope()->timer());
+    WeakProcessor::weak_oops_do(&_is_alive, &do_nothing_cl);
+  }
+
+  // Class unloading and cleanup.
+  if (ClassUnloading) {
+    GCTraceTime(Debug, gc, phases) debug("Phase 1: Class Unloading and Cleanup", scope()->timer());
+    // Unload classes and purge the SystemDictionary.
+    bool purged_class = SystemDictionary::do_unloading(&_is_alive, scope()->timer());
+    G1CollectedHeap::heap()->complete_cleaning(&_is_alive, purged_class);
+  } else {
+    GCTraceTime(Debug, gc, phases) debug("Phase 1: String and Symbol Tables Cleanup", scope()->timer());
+    // If no class unloading just clean out strings and symbols.
+    G1CollectedHeap::heap()->partial_cleaning(&_is_alive, true, true, G1StringDedup::is_enabled());
+  }
+
+  scope()->tracer()->report_object_count_after_gc(&_is_alive);
+}
+
+void G1FullCollector::prepare_compaction_common() {
+  G1FullGCPrepareTask task(this);
+  run_task(&task);
+
+  // To avoid OOM when there is memory left.
+  if (!task.has_freed_regions()) {
+    task.prepare_serial_compaction();
+  }
+}
+
+void G1FullCollector::phase2_prepare_compaction() {
+  GCTraceTime(Info, gc, phases) info("Phase 2: Prepare for compaction", scope()->timer());
+  prepare_compaction_ext(); // Will call prepare_compaction_common() above.
+}
+
+void G1FullCollector::phase3_adjust_pointers() {
+  // Adjust the pointers to reflect the new locations
+  GCTraceTime(Info, gc, phases) info("Phase 3: Adjust pointers and remembered sets", scope()->timer());
+
+  G1FullGCAdjustTask task(this);
+  run_task(&task);
+}
+
+void G1FullCollector::phase4_do_compaction() {
+  // Compact the heap using the compaction queues created in phase 2.
+  GCTraceTime(Info, gc, phases) info("Phase 4: Compact heap", scope()->timer());
+  G1FullGCCompactTask task(this);
+  run_task(&task);
+
+  // Serial compact to avoid OOM when very few free regions.
+  if (serial_compaction_point()->has_regions()) {
+    task.serial_compaction();
+  }
+}
+
+void G1FullCollector::restore_marks() {
+  SharedRestorePreservedMarksTaskExecutor task_executor(G1CollectedHeap::heap()->workers());
+  _preserved_marks_set.restore(&task_executor);
+  _preserved_marks_set.reclaim();
+}
+
+void G1FullCollector::run_task(AbstractGangTask* task) {
+  G1CollectedHeap::heap()->workers()->run_task(task, _num_workers);
+}
+
+void G1FullCollector::verify_after_marking() {
+  if (!VerifyDuringGC) {
+    //Only do verification if VerifyDuringGC is set.
+    return;
+  }
+
+  HandleMark hm;  // handle scope
+#if COMPILER2_OR_JVMCI
+  DerivedPointerTableDeactivate dpt_deact;
+#endif
+  G1CollectedHeap::heap()->prepare_for_verify();
+  // Note: we can verify only the heap here. When an object is
+  // marked, the previous value of the mark word (including
+  // identity hash values, ages, etc) is preserved, and the mark
+  // word is set to markOop::marked_value - effectively removing
+  // any hash values from the mark word. These hash values are
+  // used when verifying the dictionaries and so removing them
+  // from the mark word can make verification of the dictionaries
+  // fail. At the end of the GC, the original mark word values
+  // (including hash values) are restored to the appropriate
+  // objects.
+  GCTraceTime(Info, gc, verify)("During GC (full)");
+  G1CollectedHeap::heap()->verify(VerifyOption_G1UseFullMarking);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1FULLCOLLECTOR_HPP
+#define SHARE_GC_G1_G1FULLCOLLECTOR_HPP
+
+#include "gc/g1/g1FullGCCompactionPoint.hpp"
+#include "gc/g1/g1FullGCMarker.hpp"
+#include "gc/g1/g1FullGCOopClosures.hpp"
+#include "gc/shared/preservedMarks.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "gc/shared/taskqueue.hpp"
+#include "memory/allocation.hpp"
+
+class AbstractGangTask;
+class G1CMBitMap;
+class G1FullGCMarker;
+class G1FullGCScope;
+class G1FullGCCompactionPoint;
+class ReferenceProcessor;
+
+// The G1FullCollector holds data associated with the current Full GC.
+class G1FullCollector : StackObj {
+  G1FullGCScope*            _scope;
+  uint                      _num_workers;
+  G1FullGCMarker**          _markers;
+  G1FullGCCompactionPoint** _compaction_points;
+  G1CMBitMap*               _mark_bitmap;
+  OopQueueSet               _oop_queue_set;
+  ObjArrayTaskQueueSet      _array_queue_set;
+  PreservedMarksSet         _preserved_marks_set;
+  ReferenceProcessor*       _reference_processor;
+  G1FullGCCompactionPoint   _serial_compaction_point;
+
+  G1IsAliveClosure          _is_alive;
+  ReferenceProcessorIsAliveMutator _is_alive_mutator;
+
+public:
+  G1FullCollector(G1FullGCScope* scope,
+                  ReferenceProcessor* reference_processor,
+                  G1CMBitMap* mark_bitmap,
+                  uint workers);
+  ~G1FullCollector();
+
+  void prepare_collection();
+  void collect();
+  void complete_collection();
+
+  G1FullGCScope*           scope() { return _scope; }
+  uint                     workers() { return _num_workers; }
+  G1FullGCMarker*          marker(uint id) { return _markers[id]; }
+  G1FullGCCompactionPoint* compaction_point(uint id) { return _compaction_points[id]; }
+  G1CMBitMap*              mark_bitmap() { return _mark_bitmap; }
+  OopQueueSet*             oop_queue_set() { return &_oop_queue_set; }
+  ObjArrayTaskQueueSet*    array_queue_set() { return &_array_queue_set; }
+  PreservedMarksSet*       preserved_mark_set() { return &_preserved_marks_set; }
+  ReferenceProcessor*      reference_processor() { return _reference_processor; }
+  G1FullGCCompactionPoint* serial_compaction_point() { return &_serial_compaction_point; }
+
+private:
+  void phase1_mark_live_objects();
+  void phase2_prepare_compaction();
+  void phase3_adjust_pointers();
+  void phase4_do_compaction();
+
+  void restore_marks();
+  void verify_after_marking();
+
+  void run_task(AbstractGangTask* task);
+
+  // Prepare compaction extension support.
+  void prepare_compaction_ext();
+  void prepare_compaction_common();
+};
+
+
+#endif // SHARE_GC_G1_G1FULLCOLLECTOR_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullCollector_ext.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1FullCollector.hpp"
+
+void G1FullCollector::prepare_compaction_ext() {
+  prepare_compaction_common();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
+#include "gc/g1/g1FullCollector.hpp"
+#include "gc/g1/g1FullGCAdjustTask.hpp"
+#include "gc/g1/g1FullGCCompactionPoint.hpp"
+#include "gc/g1/g1FullGCMarker.hpp"
+#include "gc/g1/g1FullGCOopClosures.inline.hpp"
+#include "gc/g1/heapRegion.inline.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "logging/log.hpp"
+#include "utilities/ticks.inline.hpp"
+
+class G1AdjustLiveClosure : public StackObj {
+  G1AdjustAndRebuildClosure* _adjust_closure;
+public:
+  G1AdjustLiveClosure(G1AdjustAndRebuildClosure* cl) :
+    _adjust_closure(cl) { }
+
+  size_t apply(oop object) {
+    _adjust_closure->update_compaction_delta(object);
+    return object->oop_iterate_size(_adjust_closure);
+  }
+};
+
+class G1AdjustRegionClosure : public HeapRegionClosure {
+  G1CMBitMap* _bitmap;
+  uint _worker_id;
+ public:
+  G1AdjustRegionClosure(G1CMBitMap* bitmap, uint worker_id) :
+    _bitmap(bitmap),
+    _worker_id(worker_id) { }
+
+  bool doHeapRegion(HeapRegion* r) {
+    G1AdjustAndRebuildClosure cl(_worker_id);
+    if (r->is_humongous()) {
+      oop obj = oop(r->humongous_start_region()->bottom());
+      cl.update_compaction_delta(obj);
+      obj->oop_iterate(&cl, MemRegion(r->bottom(), r->top()));
+    } else if (r->is_open_archive()) {
+      // Only adjust the open archive regions, the closed ones
+      // never change.
+      G1AdjustLiveClosure adjust(&cl);
+      r->apply_to_marked_objects(_bitmap, &adjust);
+      // Open archive regions will not be compacted and the marking information is
+      // no longer needed. Clear it here to avoid having to do it later.
+      _bitmap->clear_region(r);
+    } else {
+      G1AdjustLiveClosure adjust(&cl);
+      r->apply_to_marked_objects(_bitmap, &adjust);
+    }
+    return false;
+  }
+};
+
+G1FullGCAdjustTask::G1FullGCAdjustTask(G1FullCollector* collector) :
+    G1FullGCTask("G1 Adjust and Rebuild", collector),
+    _root_processor(G1CollectedHeap::heap(), collector->workers()),
+    _hrclaimer(collector->workers()),
+    _adjust(),
+    _adjust_string_dedup(NULL, &_adjust, G1StringDedup::is_enabled()) {
+  // Need cleared claim bits for the roots processing
+  ClassLoaderDataGraph::clear_claimed_marks();
+}
+
+void G1FullGCAdjustTask::work(uint worker_id) {
+  Ticks start = Ticks::now();
+  ResourceMark rm;
+
+  // Adjust preserved marks first since they are not balanced.
+  G1FullGCMarker* marker = collector()->marker(worker_id);
+  marker->preserved_stack()->adjust_during_full_gc();
+
+  // Adjust the weak_roots.
+  CLDToOopClosure adjust_cld(&_adjust);
+  CodeBlobToOopClosure adjust_code(&_adjust, CodeBlobToOopClosure::FixRelocations);
+  _root_processor.process_full_gc_weak_roots(&_adjust);
+
+  // Needs to be last, process_all_roots calls all_tasks_completed(...).
+  _root_processor.process_all_roots(
+      &_adjust,
+      &adjust_cld,
+      &adjust_code);
+
+  // Adjust string dedup if enabled.
+  if (G1StringDedup::is_enabled()) {
+    G1StringDedup::parallel_unlink(&_adjust_string_dedup, worker_id);
+  }
+
+  // Now adjust pointers region by region
+  G1AdjustRegionClosure blk(collector()->mark_bitmap(), worker_id);
+  G1CollectedHeap::heap()->heap_region_par_iterate_from_worker_offset(&blk, &_hrclaimer, worker_id);
+  log_task("Adjust and Rebuild task", worker_id, start);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1FULLGCADJUSTTASK_HPP
+#define SHARE_GC_G1_G1FULLGCADJUSTTASK_HPP
+
+#include "gc/g1/g1FullGCOopClosures.hpp"
+#include "gc/g1/g1FullGCTask.hpp"
+#include "gc/g1/g1RootProcessor.hpp"
+#include "gc/g1/g1StringDedup.hpp"
+#include "gc/g1/heapRegionManager.hpp"
+#include "utilities/ticks.hpp"
+
+class G1CollectedHeap;
+
+class G1FullGCAdjustTask : public G1FullGCTask {
+  G1RootProcessor          _root_processor;
+  HeapRegionClaimer        _hrclaimer;
+  G1AdjustClosure          _adjust;
+  G1StringDedupUnlinkOrOopsDoClosure _adjust_string_dedup;
+
+public:
+  G1FullGCAdjustTask(G1FullCollector* collector);
+  void work(uint worker_id);
+};
+
+#endif // SHARE_GC_G1_G1FULLGCADJUSTTASK_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
+#include "gc/g1/g1FullCollector.hpp"
+#include "gc/g1/g1FullGCCompactionPoint.hpp"
+#include "gc/g1/g1FullGCCompactTask.hpp"
+#include "gc/g1/heapRegion.inline.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
+#include "logging/log.hpp"
+#include "utilities/ticks.inline.hpp"
+
+class G1ResetHumongousClosure : public HeapRegionClosure {
+  G1CMBitMap* _bitmap;
+
+public:
+  G1ResetHumongousClosure(G1CMBitMap* bitmap) :
+      _bitmap(bitmap) { }
+
+  bool doHeapRegion(HeapRegion* current) {
+    if (current->is_humongous()) {
+      if (current->is_starts_humongous()) {
+        oop obj = oop(current->bottom());
+        if (_bitmap->is_marked(obj)) {
+          // Clear bitmap and fix mark word.
+          _bitmap->clear(obj);
+          obj->init_mark();
+        } else {
+          assert(current->is_empty(), "Should have been cleared in phase 2.");
+        }
+      }
+      current->reset_during_compaction();
+    }
+    return false;
+  }
+};
+
+size_t G1FullGCCompactTask::G1CompactRegionClosure::apply(oop obj) {
+  size_t size = obj->size();
+  HeapWord* destination = (HeapWord*)obj->forwardee();
+  if (destination == NULL) {
+    // Object not moving
+    return size;
+  }
+
+  // copy object and reinit its mark
+  HeapWord* obj_addr = (HeapWord*) obj;
+  assert(obj_addr != destination, "everything in this pass should be moving");
+  Copy::aligned_conjoint_words(obj_addr, destination, size);
+  oop(destination)->init_mark();
+  assert(oop(destination)->klass() != NULL, "should have a class");
+
+  return size;
+}
+
+void G1FullGCCompactTask::compact_region(HeapRegion* hr) {
+  assert(!hr->is_humongous(), "Should be no humongous regions in compaction queue");
+  G1CompactRegionClosure compact(collector()->mark_bitmap());
+  hr->apply_to_marked_objects(collector()->mark_bitmap(), &compact);
+  // Once all objects have been moved the liveness information
+  // needs be cleared.
+  collector()->mark_bitmap()->clear_region(hr);
+  hr->complete_compaction();
+}
+
+void G1FullGCCompactTask::work(uint worker_id) {
+  Ticks start = Ticks::now();
+  GrowableArray<HeapRegion*>* compaction_queue = collector()->compaction_point(worker_id)->regions();
+  for (GrowableArrayIterator<HeapRegion*> it = compaction_queue->begin();
+       it != compaction_queue->end();
+       ++it) {
+    compact_region(*it);
+  }
+
+  G1ResetHumongousClosure hc(collector()->mark_bitmap());
+  G1CollectedHeap::heap()->heap_region_par_iterate_from_worker_offset(&hc, &_claimer, worker_id);
+  log_task("Compaction task", worker_id, start);
+}
+
+void G1FullGCCompactTask::serial_compaction() {
+  GCTraceTime(Debug, gc, phases) tm("Phase 4: Serial Compaction", collector()->scope()->timer());
+  GrowableArray<HeapRegion*>* compaction_queue = collector()->serial_compaction_point()->regions();
+  for (GrowableArrayIterator<HeapRegion*> it = compaction_queue->begin();
+       it != compaction_queue->end();
+       ++it) {
+    compact_region(*it);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactTask.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1FULLGCCOMPACTTASK_HPP
+#define SHARE_GC_G1_G1FULLGCCOMPACTTASK_HPP
+
+#include "gc/g1/g1FullGCCompactionPoint.hpp"
+#include "gc/g1/g1FullGCScope.hpp"
+#include "gc/g1/g1FullGCTask.hpp"
+#include "gc/g1/g1StringDedup.hpp"
+#include "gc/g1/heapRegionManager.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "utilities/ticks.hpp"
+
+class G1CollectedHeap;
+class G1CMBitMap;
+
+class G1FullGCCompactTask : public G1FullGCTask {
+protected:
+  HeapRegionClaimer _claimer;
+
+private:
+  void compact_region(HeapRegion* hr);
+
+public:
+  G1FullGCCompactTask(G1FullCollector* collector) :
+    G1FullGCTask("G1 Compact Task", collector),
+    _claimer(collector->workers()) { }
+  void work(uint worker_id);
+  void serial_compaction();
+
+  class G1CompactRegionClosure : public StackObj {
+    G1CMBitMap* _bitmap;
+
+  public:
+    G1CompactRegionClosure(G1CMBitMap* bitmap) : _bitmap(bitmap) { }
+    size_t apply(oop object);
+  };
+};
+
+#endif // SHARE_GC_G1_G1FULLGCCOMPACTTASK_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1FullGCCompactionPoint.hpp"
+#include "gc/g1/heapRegion.hpp"
+#include "oops/oop.inline.hpp"
+#include "utilities/debug.hpp"
+
+G1FullGCCompactionPoint::G1FullGCCompactionPoint() :
+    _current_region(NULL),
+    _threshold(NULL),
+    _compaction_top(NULL) {
+  _compaction_regions = new (ResourceObj::C_HEAP, mtGC) GrowableArray<HeapRegion*>(32, true, mtGC);
+  _compaction_region_iterator = _compaction_regions->begin();
+}
+
+G1FullGCCompactionPoint::~G1FullGCCompactionPoint() {
+  delete _compaction_regions;
+}
+
+void G1FullGCCompactionPoint::update() {
+  if (is_initialized()) {
+    _current_region->set_compaction_top(_compaction_top);
+  }
+}
+
+void G1FullGCCompactionPoint::initialize_values(bool init_threshold) {
+  _compaction_top = _current_region->compaction_top();
+  if (init_threshold) {
+    _threshold = _current_region->initialize_threshold();
+  }
+}
+
+bool G1FullGCCompactionPoint::has_regions() {
+  return !_compaction_regions->is_empty();
+}
+
+bool G1FullGCCompactionPoint::is_initialized() {
+  return _current_region != NULL;
+}
+
+void G1FullGCCompactionPoint::initialize(HeapRegion* hr, bool init_threshold) {
+  _current_region = hr;
+  initialize_values(init_threshold);
+}
+
+HeapRegion* G1FullGCCompactionPoint::current_region() {
+  return *_compaction_region_iterator;
+}
+
+HeapRegion* G1FullGCCompactionPoint::next_region() {
+  HeapRegion* next = *(++_compaction_region_iterator);
+  assert(next != NULL, "Must return valid region");
+  return next;
+}
+
+GrowableArray<HeapRegion*>* G1FullGCCompactionPoint::regions() {
+  return _compaction_regions;
+}
+
+bool G1FullGCCompactionPoint::object_will_fit(size_t size) {
+  size_t space_left = pointer_delta(_current_region->end(), _compaction_top);
+  return size <= space_left;
+}
+
+void G1FullGCCompactionPoint::switch_region() {
+  // Save compaction top in the region.
+  _current_region->set_compaction_top(_compaction_top);
+  // Get the next region and re-initialize the values.
+  _current_region = next_region();
+  initialize_values(true);
+}
+
+void G1FullGCCompactionPoint::forward(oop object, size_t size) {
+  assert(_current_region != NULL, "Must have been initialized");
+
+  // Ensure the object fit in the current region.
+  while (!object_will_fit(size)) {
+    switch_region();
+  }
+
+  // Store a forwarding pointer if the object should be moved.
+  if ((HeapWord*)object != _compaction_top) {
+    object->forward_to(oop(_compaction_top));
+  } else {
+    if (object->forwardee() != NULL) {
+      // Object should not move but mark-word is used so it looks like the
+      // object is forwarded. Need to clear the mark and it's no problem
+      // since it will be restored by preserved marks. There is an exception
+      // with BiasedLocking, in this case forwardee() will return NULL
+      // even if the mark-word is used. This is no problem since
+      // forwardee() will return NULL in the compaction phase as well.
+      object->init_mark();
+    } else {
+      // Make sure object has the correct mark-word set or that it will be
+      // fixed when restoring the preserved marks.
+      assert(object->mark() == markOopDesc::prototype_for_object(object) || // Correct mark
+             object->mark()->must_be_preserved(object) || // Will be restored by PreservedMarksSet
+             (UseBiasedLocking && object->has_bias_pattern()), // Will be restored by BiasedLocking
+             "should have correct prototype obj: " PTR_FORMAT " mark: " PTR_FORMAT " prototype: " PTR_FORMAT,
+             p2i(object), p2i(object->mark()), p2i(markOopDesc::prototype_for_object(object)));
+    }
+    assert(object->forwardee() == NULL, "should be forwarded to NULL");
+  }
+
+  // Update compaction values.
+  _compaction_top += size;
+  if (_compaction_top > _threshold) {
+    _threshold = _current_region->cross_threshold(_compaction_top - size, _compaction_top);
+  }
+}
+
+void G1FullGCCompactionPoint::add(HeapRegion* hr) {
+  _compaction_regions->append(hr);
+}
+
+void G1FullGCCompactionPoint::merge(G1FullGCCompactionPoint* other) {
+   _compaction_regions->appendAll(other->regions());
+}
+
+HeapRegion* G1FullGCCompactionPoint::remove_last() {
+  return _compaction_regions->pop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1FULLGCCOMPACTIONPOINT_HPP
+#define SHARE_GC_G1_G1FULLGCCOMPACTIONPOINT_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/growableArray.hpp"
+
+class HeapRegion;
+
+class G1FullGCCompactionPoint : public CHeapObj<mtGC> {
+  HeapRegion* _current_region;
+  HeapWord*   _threshold;
+  HeapWord*   _compaction_top;
+  GrowableArray<HeapRegion*>* _compaction_regions;
+  GrowableArrayIterator<HeapRegion*> _compaction_region_iterator;
+
+  bool object_will_fit(size_t size);
+  void initialize_values(bool init_threshold);
+  void switch_region();
+  HeapRegion* next_region();
+
+public:
+  G1FullGCCompactionPoint();
+  ~G1FullGCCompactionPoint();
+
+  bool has_regions();
+  bool is_initialized();
+  void initialize(HeapRegion* hr, bool init_threshold);
+  void update();
+  void forward(oop object, size_t size);
+  void add(HeapRegion* hr);
+  void merge(G1FullGCCompactionPoint* other);
+
+  HeapRegion* remove_last();
+  HeapRegion* current_region();
+
+  GrowableArray<HeapRegion*>* regions();
+};
+
+#endif // SHARE_GC_G1_G1FULLGCCOMPACTIONPOINT_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1FullCollector.hpp"
+#include "gc/g1/g1FullGCMarker.hpp"
+#include "gc/g1/g1FullGCMarkTask.hpp"
+#include "gc/g1/g1FullGCOopClosures.inline.hpp"
+#include "gc/g1/g1FullGCReferenceProcessorExecutor.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+
+G1FullGCMarkTask::G1FullGCMarkTask(G1FullCollector* collector) :
+    G1FullGCTask("G1 Parallel Marking Task", collector),
+    _root_processor(G1CollectedHeap::heap(), collector->workers()),
+    _terminator(collector->workers(), collector->array_queue_set()) {
+  // Need cleared claim bits for the roots processing
+  ClassLoaderDataGraph::clear_claimed_marks();
+}
+
+void G1FullGCMarkTask::work(uint worker_id) {
+  Ticks start = Ticks::now();
+  ResourceMark rm;
+  G1FullGCMarker* marker = collector()->marker(worker_id);
+  MarkingCodeBlobClosure code_closure(marker->mark_closure(), !CodeBlobToOopClosure::FixRelocations);
+
+  if (ClassUnloading) {
+    _root_processor.process_strong_roots(
+        marker->mark_closure(),
+        marker->cld_closure(),
+        &code_closure);
+  } else {
+    _root_processor.process_all_roots_no_string_table(
+        marker->mark_closure(),
+        marker->cld_closure(),
+        &code_closure);
+  }
+
+  // Mark stack is populated, now process and drain it.
+  marker->complete_marking(collector()->oop_queue_set(), collector()->array_queue_set(), &_terminator);
+
+  // This is the point where the entire marking should have completed.
+  assert(marker->oop_stack()->is_empty(), "Marking should have completed");
+  assert(marker->objarray_stack()->is_empty(), "Array marking should have completed");
+  log_task("Marking task", worker_id, start);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCMarkTask.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1FULLGCMARKTASK_HPP
+#define SHARE_GC_G1_G1FULLGCMARKTASK_HPP
+
+#include "gc/g1/g1FullGCCompactionPoint.hpp"
+#include "gc/g1/g1FullGCScope.hpp"
+#include "gc/g1/g1FullGCTask.hpp"
+#include "gc/g1/g1RootProcessor.hpp"
+#include "gc/g1/g1StringDedup.hpp"
+#include "gc/g1/heapRegionManager.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "utilities/ticks.hpp"
+
+class G1FullGCMarkTask : public G1FullGCTask {
+  G1RootProcessor          _root_processor;
+  ParallelTaskTerminator   _terminator;
+
+public:
+  G1FullGCMarkTask(G1FullCollector* collector);
+  void work(uint worker_id);
+};
+
+#endif // SHARE_GC_G1_G1FULLGCMARKTASK_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCMarker.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1FullGCMarker.inline.hpp"
+
+G1FullGCMarker::G1FullGCMarker(uint worker_id, PreservedMarks* preserved_stack, G1CMBitMap* bitmap) :
+    _worker_id(worker_id),
+    _mark_closure(worker_id, this, G1CollectedHeap::heap()->ref_processor_stw()),
+    _verify_closure(VerifyOption_G1UseFullMarking),
+    _cld_closure(mark_closure()),
+    _stack_closure(this),
+    _preserved_stack(preserved_stack),
+    _bitmap(bitmap) {
+  _oop_stack.initialize();
+  _objarray_stack.initialize();
+}
+
+G1FullGCMarker::~G1FullGCMarker() {
+  assert(is_empty(), "Must be empty at this point");
+}
+
+void G1FullGCMarker::complete_marking(OopQueueSet* oop_stacks,
+                                      ObjArrayTaskQueueSet* array_stacks,
+                                      ParallelTaskTerminator* terminator) {
+  int hash_seed = 17;
+  do {
+    drain_stack();
+    ObjArrayTask steal_array;
+    if (array_stacks->steal(_worker_id, &hash_seed, steal_array)) {
+      follow_array_chunk(objArrayOop(steal_array.obj()), steal_array.index());
+    } else {
+      oop steal_oop;
+      if (oop_stacks->steal(_worker_id, &hash_seed, steal_oop)) {
+        follow_object(steal_oop);
+      }
+    }
+  } while (!is_empty() || !terminator->offer_termination());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCMarker.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1FULLGCMARKER_HPP
+#define SHARE_GC_G1_G1FULLGCMARKER_HPP
+
+#include "gc/g1/g1FullGCOopClosures.hpp"
+#include "gc/shared/preservedMarks.hpp"
+#include "gc/shared/taskqueue.hpp"
+#include "memory/iterator.hpp"
+#include "oops/markOop.hpp"
+#include "oops/oop.hpp"
+#include "runtime/timer.hpp"
+#include "utilities/chunkedList.hpp"
+#include "utilities/growableArray.hpp"
+#include "utilities/stack.hpp"
+
+typedef OverflowTaskQueue<oop, mtGC>                 OopQueue;
+typedef OverflowTaskQueue<ObjArrayTask, mtGC>        ObjArrayTaskQueue;
+
+typedef GenericTaskQueueSet<OopQueue, mtGC>          OopQueueSet;
+typedef GenericTaskQueueSet<ObjArrayTaskQueue, mtGC> ObjArrayTaskQueueSet;
+
+class G1CMBitMap;
+
+class G1FullGCMarker : public CHeapObj<mtGC> {
+private:
+  uint               _worker_id;
+  // Backing mark bitmap
+  G1CMBitMap*        _bitmap;
+
+  // Mark stack
+  OopQueue           _oop_stack;
+  ObjArrayTaskQueue  _objarray_stack;
+  PreservedMarks*    _preserved_stack;
+
+  // Marking closures
+  G1MarkAndPushClosure _mark_closure;
+  G1VerifyOopClosure   _verify_closure;
+  G1FollowStackClosure _stack_closure;
+  CLDToOopClosure      _cld_closure;
+
+  inline bool is_empty();
+  inline bool pop_object(oop& obj);
+  inline bool pop_objarray(ObjArrayTask& array);
+  inline void push_objarray(oop obj, size_t index);
+  inline bool mark_object(oop obj);
+
+  // Marking helpers
+  inline void follow_object(oop obj);
+  inline void follow_array(objArrayOop array);
+  inline void follow_array_chunk(objArrayOop array, int index);
+public:
+  G1FullGCMarker(uint worker_id, PreservedMarks* preserved_stack, G1CMBitMap* bitmap);
+  ~G1FullGCMarker();
+
+  // Stack getters
+  OopQueue*          oop_stack()       { return &_oop_stack; }
+  ObjArrayTaskQueue* objarray_stack()  { return &_objarray_stack; }
+  PreservedMarks*    preserved_stack() { return _preserved_stack; }
+
+  // Marking entry points
+  template <class T> inline void mark_and_push(T* p);
+  inline void follow_klass(Klass* k);
+  inline void follow_cld(ClassLoaderData* cld);
+
+  inline void drain_stack();
+  void complete_marking(OopQueueSet* oop_stacks,
+                        ObjArrayTaskQueueSet* array_stacks,
+                        ParallelTaskTerminator* terminator);
+
+  // Closure getters
+  CLDToOopClosure*      cld_closure()   { return &_cld_closure; }
+  G1MarkAndPushClosure* mark_closure()  { return &_mark_closure; }
+  G1FollowStackClosure* stack_closure() { return &_stack_closure; }
+};
+
+#endif // SHARE_GC_G1_G1FULLGCMARKER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1MARKSTACK_INLINE_HPP
+#define SHARE_VM_GC_G1_G1MARKSTACK_INLINE_HPP
+
+#include "gc/g1/g1Allocator.inline.hpp"
+#include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
+#include "gc/g1/g1FullGCMarker.hpp"
+#include "gc/g1/g1StringDedup.hpp"
+#include "gc/g1/g1StringDedupQueue.hpp"
+#include "gc/shared/preservedMarks.inline.hpp"
+#include "utilities/debug.hpp"
+
+inline bool G1FullGCMarker::mark_object(oop obj) {
+  // Not marking closed archive objects.
+  if (G1ArchiveAllocator::is_closed_archive_object(obj)) {
+    return false;
+  }
+
+  // Try to mark.
+  if (!_bitmap->par_mark(obj)) {
+    // Lost mark race.
+    return false;
+  }
+
+  // Marked by us, preserve if needed.
+  markOop mark = obj->mark();
+  if (mark->must_be_preserved(obj) &&
+      !G1ArchiveAllocator::is_open_archive_object(obj)) {
+    preserved_stack()->push(obj, mark);
+  }
+
+  // Check if deduplicatable string.
+  if (G1StringDedup::is_enabled()) {
+    G1StringDedup::enqueue_from_mark(obj, _worker_id);
+  }
+  return true;
+}
+
+template <class T> inline void G1FullGCMarker::mark_and_push(T* p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+    if (mark_object(obj)) {
+      _oop_stack.push(obj);
+      assert(_bitmap->is_marked(obj), "Must be marked now - map self");
+    } else {
+      assert(_bitmap->is_marked(obj) || G1ArchiveAllocator::is_closed_archive_object(obj),
+             "Must be marked by other or closed archive object");
+    }
+  }
+}
+
+inline bool G1FullGCMarker::is_empty() {
+  return _oop_stack.is_empty() && _objarray_stack.is_empty();
+}
+
+inline bool G1FullGCMarker::pop_object(oop& oop) {
+  return _oop_stack.pop_overflow(oop) || _oop_stack.pop_local(oop);
+}
+
+inline void G1FullGCMarker::push_objarray(oop obj, size_t index) {
+  ObjArrayTask task(obj, index);
+  assert(task.is_valid(), "bad ObjArrayTask");
+  _objarray_stack.push(task);
+}
+
+inline bool G1FullGCMarker::pop_objarray(ObjArrayTask& arr) {
+  return _objarray_stack.pop_overflow(arr) || _objarray_stack.pop_local(arr);
+}
+
+inline void G1FullGCMarker::follow_array(objArrayOop array) {
+  follow_klass(array->klass());
+  // Don't push empty arrays to avoid unnecessary work.
+  if (array->length() > 0) {
+    push_objarray(array, 0);
+  }
+}
+
+void G1FullGCMarker::follow_array_chunk(objArrayOop array, int index) {
+  const int len = array->length();
+  const int beg_index = index;
+  assert(beg_index < len || len == 0, "index too large");
+
+  const int stride = MIN2(len - beg_index, (int) ObjArrayMarkingStride);
+  const int end_index = beg_index + stride;
+
+  array->oop_iterate_range(mark_closure(), beg_index, end_index);
+
+  if (VerifyDuringGC) {
+    _verify_closure.set_containing_obj(array);
+    NoHeaderExtendedOopClosure no(&_verify_closure);
+    array->oop_iterate_range(&no, beg_index, end_index);
+    if (_verify_closure.failures()) {
+      assert(false, "Failed");
+    }
+  }
+
+  if (end_index < len) {
+    push_objarray(array, end_index); // Push the continuation.
+  }
+}
+
+inline void G1FullGCMarker::follow_object(oop obj) {
+  assert(_bitmap->is_marked(obj), "should be marked");
+  if (obj->is_objArray()) {
+    // Handle object arrays explicitly to allow them to
+    // be split into chunks if needed.
+    follow_array((objArrayOop)obj);
+  } else {
+    obj->oop_iterate(mark_closure());
+    if (VerifyDuringGC) {
+      if (obj->is_instance() && InstanceKlass::cast(obj->klass())->is_reference_instance_klass()) {
+        return;
+      }
+      _verify_closure.set_containing_obj(obj);
+      obj->oop_iterate_no_header(&_verify_closure);
+      if (_verify_closure.failures()) {
+        log_warning(gc, verify)("Failed after %d", _verify_closure._cc);
+        assert(false, "Failed");
+      }
+    }
+  }
+}
+
+void G1FullGCMarker::drain_stack() {
+  do {
+    oop obj;
+    while (pop_object(obj)) {
+      assert(_bitmap->is_marked(obj), "must be marked");
+      follow_object(obj);
+    }
+    // Process ObjArrays one at a time to avoid marking stack bloat.
+    ObjArrayTask task;
+    if (pop_objarray(task)) {
+      follow_array_chunk(objArrayOop(task.obj()), task.index());
+    }
+  } while (!is_empty());
+}
+
+inline void G1FullGCMarker::follow_klass(Klass* k) {
+  oop op = k->klass_holder();
+  mark_and_push(&op);
+}
+
+inline void G1FullGCMarker::follow_cld(ClassLoaderData* cld) {
+  _cld_closure.do_cld(cld);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCOopClosures.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1FullGCMarker.inline.hpp"
+#include "gc/g1/g1FullGCOopClosures.inline.hpp"
+#include "gc/g1/g1_specialized_oop_closures.hpp"
+#include "logging/logStream.hpp"
+
+void G1MarkAndPushClosure::do_oop(oop* p) {
+  do_oop_nv(p);
+}
+
+void G1MarkAndPushClosure::do_oop(narrowOop* p) {
+  do_oop_nv(p);
+}
+
+bool G1MarkAndPushClosure::do_metadata() {
+  return do_metadata_nv();
+}
+
+void G1MarkAndPushClosure::do_klass(Klass* k) {
+  do_klass_nv(k);
+}
+
+void G1MarkAndPushClosure::do_cld(ClassLoaderData* cld) {
+  do_cld_nv(cld);
+}
+
+G1AdjustAndRebuildClosure::G1AdjustAndRebuildClosure(uint worker_id) :
+  _worker_id(worker_id),
+  _compaction_delta(0),
+  _g1h(G1CollectedHeap::heap()) { }
+
+void G1AdjustAndRebuildClosure::update_compaction_delta(oop obj) {
+  if (G1ArchiveAllocator::is_open_archive_object(obj)) {
+    _compaction_delta = 0;
+    return;
+  }
+  oop forwardee = obj->forwardee();
+  if (forwardee == NULL) {
+    // Object not moved.
+    _compaction_delta = 0;
+  } else {
+    // Object moved to forwardee, calculate delta.
+    _compaction_delta = calculate_compaction_delta(obj, forwardee);
+  }
+}
+
+void G1AdjustClosure::do_oop(oop* p)       { adjust_pointer(p); }
+void G1AdjustClosure::do_oop(narrowOop* p) { adjust_pointer(p); }
+
+void G1AdjustAndRebuildClosure::do_oop(oop* p)       { do_oop_nv(p); }
+void G1AdjustAndRebuildClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
+
+void G1FollowStackClosure::do_void() { _marker->drain_stack(); }
+
+void G1FullKeepAliveClosure::do_oop(oop* p) { do_oop_work(p); }
+void G1FullKeepAliveClosure::do_oop(narrowOop* p) { do_oop_work(p); }
+
+G1VerifyOopClosure::G1VerifyOopClosure(VerifyOption option) :
+   _g1h(G1CollectedHeap::heap()),
+   _containing_obj(NULL),
+   _verify_option(option),
+   _cc(0),
+   _failures(false) {
+}
+
+void G1VerifyOopClosure::print_object(outputStream* out, oop obj) {
+#ifdef PRODUCT
+  Klass* k = obj->klass();
+  const char* class_name = InstanceKlass::cast(k)->external_name();
+  out->print_cr("class name %s", class_name);
+#else // PRODUCT
+  obj->print_on(out);
+#endif // PRODUCT
+}
+
+template <class T> void G1VerifyOopClosure::do_oop_nv(T* p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    _cc++;
+    oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+    bool failed = false;
+    if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _verify_option)) {
+      MutexLockerEx x(ParGCRareEvent_lock,
+          Mutex::_no_safepoint_check_flag);
+      LogStreamHandle(Error, gc, verify) yy;
+      if (!_failures) {
+        yy.cr();
+        yy.print_cr("----------");
+      }
+      if (!_g1h->is_in_closed_subset(obj)) {
+        HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+        yy.print_cr("Field " PTR_FORMAT
+            " of live obj " PTR_FORMAT " in region "
+            "[" PTR_FORMAT ", " PTR_FORMAT ")",
+            p2i(p), p2i(_containing_obj),
+            p2i(from->bottom()), p2i(from->end()));
+        print_object(&yy, _containing_obj);
+        yy.print_cr("points to obj " PTR_FORMAT " not in the heap",
+            p2i(obj));
+      } else {
+        HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+        HeapRegion* to   = _g1h->heap_region_containing((HeapWord*)obj);
+        yy.print_cr("Field " PTR_FORMAT
+            " of live obj " PTR_FORMAT " in region "
+            "[" PTR_FORMAT ", " PTR_FORMAT ")",
+            p2i(p), p2i(_containing_obj),
+            p2i(from->bottom()), p2i(from->end()));
+        print_object(&yy, _containing_obj);
+        yy.print_cr("points to dead obj " PTR_FORMAT " in region "
+            "[" PTR_FORMAT ", " PTR_FORMAT ")",
+            p2i(obj), p2i(to->bottom()), p2i(to->end()));
+        print_object(&yy, obj);
+      }
+      yy.print_cr("----------");
+      yy.flush();
+      _failures = true;
+      failed = true;
+    }
+  }
+}
+
+// Generate G1 full GC specialized oop_oop_iterate functions.
+SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1FULL(ALL_KLASS_OOP_OOP_ITERATE_DEFN)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCOopClosures.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1FULLGCOOPCLOSURES_HPP
+#define SHARE_GC_G1_G1FULLGCOOPCLOSURES_HPP
+
+#include "memory/iterator.hpp"
+#include "memory/universe.hpp"
+
+class G1CollectedHeap;
+class G1FullCollector;
+class G1CMBitMap;
+class G1FullGCMarker;
+
+// Below are closures used by the G1 Full GC.
+class G1IsAliveClosure : public BoolObjectClosure {
+  G1CMBitMap* _bitmap;
+
+public:
+  G1IsAliveClosure(G1CMBitMap* bitmap) : _bitmap(bitmap) { }
+
+  virtual bool do_object_b(oop p);
+};
+
+class G1FullKeepAliveClosure: public OopClosure {
+  G1FullGCMarker* _marker;
+  template <class T>
+  inline void do_oop_work(T* p);
+
+public:
+  G1FullKeepAliveClosure(G1FullGCMarker* pm) : _marker(pm) { }
+
+  virtual void do_oop(oop* p);
+  virtual void do_oop(narrowOop* p);
+};
+
+class G1MarkAndPushClosure : public ExtendedOopClosure {
+  G1FullGCMarker* _marker;
+  uint _worker_id;
+
+public:
+  G1MarkAndPushClosure(uint worker, G1FullGCMarker* marker, ReferenceProcessor* ref) :
+    _marker(marker),
+    _worker_id(worker),
+    ExtendedOopClosure(ref) { }
+
+  template <class T> inline void do_oop_nv(T* p);
+  virtual void do_oop(oop* p);
+  virtual void do_oop(narrowOop* p);
+
+  virtual bool do_metadata();
+  bool do_metadata_nv();
+
+  virtual void do_klass(Klass* k);
+  void do_klass_nv(Klass* k);
+
+  virtual void do_cld(ClassLoaderData* cld);
+  void do_cld_nv(ClassLoaderData* cld);
+};
+
+class G1AdjustClosure : public OopClosure {
+public:
+  template <class T> static inline oop adjust_pointer(T* p);
+  virtual void do_oop(oop* p);
+  virtual void do_oop(narrowOop* p);
+};
+
+class G1AdjustAndRebuildClosure : public ExtendedOopClosure {
+  uint _worker_id;
+  size_t _compaction_delta;
+  G1CollectedHeap* _g1h;
+
+  inline size_t calculate_compaction_delta(oop current, oop forwardee);
+  template <class T> inline T* add_compaction_delta(T* p);
+
+public:
+  G1AdjustAndRebuildClosure(uint worker_id);
+
+  void update_compaction_delta(oop obj);
+
+  template <class T> inline void add_reference(T* from_field, oop reference, uint worker_id);
+  template <class T> void do_oop_nv(T* p);
+  virtual void do_oop(oop* p);
+  virtual void do_oop(narrowOop* p);
+
+  virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
+};
+
+class G1AdjustObjectClosure {
+  G1AdjustAndRebuildClosure* _closure;
+
+public:
+  G1AdjustObjectClosure(G1AdjustAndRebuildClosure* cl) : _closure(cl) { }
+
+  inline int adjust_object(oop obj);
+};
+
+class G1VerifyOopClosure: public OopClosure {
+private:
+  G1CollectedHeap* _g1h;
+  bool             _failures;
+  oop              _containing_obj;
+  VerifyOption     _verify_option;
+
+public:
+  int _cc;
+  G1VerifyOopClosure(VerifyOption option);
+
+  void set_containing_obj(oop obj) {
+    _containing_obj = obj;
+  }
+
+  bool failures() { return _failures; }
+  void print_object(outputStream* out, oop obj);
+
+  template <class T> void do_oop_nv(T* p);
+
+  void do_oop(oop* p)       { do_oop_nv(p); }
+  void do_oop(narrowOop* p) { do_oop_nv(p); }
+};
+
+class G1FollowStackClosure: public VoidClosure {
+  G1FullGCMarker* _marker;
+
+public:
+  G1FollowStackClosure(G1FullGCMarker* marker) : _marker(marker) {}
+  virtual void do_void();
+};
+
+#endif // SHARE_GC_G1_G1FULLGCOOPCLOSURES_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCOopClosures.inline.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1FULLGCOOPCLOSURES_INLINE_HPP
+#define SHARE_VM_GC_G1_G1FULLGCOOPCLOSURES_INLINE_HPP
+
+#include "gc/g1/g1Allocator.hpp"
+#include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
+#include "gc/g1/g1FullGCMarker.inline.hpp"
+#include "gc/g1/g1FullGCOopClosures.hpp"
+#include "gc/g1/heapRegionRemSet.hpp"
+#include "memory/iterator.inline.hpp"
+
+template <typename T>
+inline void G1MarkAndPushClosure::do_oop_nv(T* p) {
+  _marker->mark_and_push(p);
+}
+
+inline bool G1MarkAndPushClosure::do_metadata_nv() {
+  return true;
+}
+
+inline void G1MarkAndPushClosure::do_klass_nv(Klass* k) {
+  _marker->follow_klass(k);
+}
+
+inline void G1MarkAndPushClosure::do_cld_nv(ClassLoaderData* cld) {
+  _marker->follow_cld(cld);
+}
+
+template <class T> inline oop G1AdjustClosure::adjust_pointer(T* p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (oopDesc::is_null(heap_oop)) {
+    // NULL reference, return NULL.
+    return NULL;
+  }
+
+  oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+  assert(Universe::heap()->is_in(obj), "should be in heap");
+  if (G1ArchiveAllocator::is_archive_object(obj)) {
+    // Never forwarding archive objects, return current reference.
+    return obj;
+  }
+
+  oop forwardee = obj->forwardee();
+  if (forwardee == NULL) {
+    // Not forwarded, return current reference.
+    assert(obj->mark() == markOopDesc::prototype_for_object(obj) || // Correct mark
+           obj->mark()->must_be_preserved(obj) || // Will be restored by PreservedMarksSet
+           (UseBiasedLocking && obj->has_bias_pattern()), // Will be restored by BiasedLocking
+           "Must have correct prototype or be preserved, obj: " PTR_FORMAT ", mark: " PTR_FORMAT ", prototype: " PTR_FORMAT,
+           p2i(obj), p2i(obj->mark()), p2i(markOopDesc::prototype_for_object(obj)));
+    return obj;
+  }
+
+  // Forwarded, update and return new reference.
+  assert(Universe::heap()->is_in_reserved(forwardee), "should be in object space");
+  oopDesc::encode_store_heap_oop_not_null(p, forwardee);
+  return forwardee;
+}
+
+template <class T>
+inline void G1AdjustAndRebuildClosure::add_reference(T* from_field, oop reference, uint worker_id) {
+  if (HeapRegion::is_in_same_region(from_field, reference)) {
+    return;
+  }
+  _g1h->heap_region_containing(reference)->rem_set()->add_reference(from_field, worker_id);
+}
+
+inline size_t G1AdjustAndRebuildClosure::calculate_compaction_delta(oop current, oop forwardee) {
+  return pointer_delta((HeapWord*)forwardee, (HeapWord*)current);
+}
+
+template <class T>
+inline T* G1AdjustAndRebuildClosure::add_compaction_delta(T* p) {
+  return (T*)((HeapWord*)p + _compaction_delta);
+}
+
+template<typename T>
+void G1AdjustAndRebuildClosure::do_oop_nv(T* p) {
+  oop new_reference = G1AdjustClosure::adjust_pointer(p);
+  if (new_reference == NULL) {
+    return;
+  }
+
+  // Update p using the calculated compaction delta to
+  // get the new field address.
+  T* new_field = add_compaction_delta(p);
+  // Update the remembered set.
+  add_reference(new_field, new_reference, _worker_id);
+}
+
+inline int G1AdjustObjectClosure::adjust_object(oop obj) {
+  _closure->update_compaction_delta(obj);
+  return obj->oop_iterate_size(_closure);
+}
+
+inline bool G1IsAliveClosure::do_object_b(oop p) {
+  return _bitmap->is_marked(p) || G1ArchiveAllocator::is_closed_archive_object(p);
+}
+
+template<typename T>
+inline void G1FullKeepAliveClosure::do_oop_work(T* p) {
+  _marker->mark_and_push(p);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
+#include "gc/g1/g1FullCollector.hpp"
+#include "gc/g1/g1FullGCCompactionPoint.hpp"
+#include "gc/g1/g1FullGCMarker.hpp"
+#include "gc/g1/g1FullGCOopClosures.inline.hpp"
+#include "gc/g1/g1FullGCPrepareTask.hpp"
+#include "gc/g1/g1HotCardCache.hpp"
+#include "gc/g1/heapRegion.inline.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "logging/log.hpp"
+#include "utilities/ticks.inline.hpp"
+
+bool G1FullGCPrepareTask::G1CalculatePointersClosure::doHeapRegion(HeapRegion* hr) {
+  if (hr->is_humongous()) {
+    oop obj = oop(hr->humongous_start_region()->bottom());
+    if (_bitmap->is_marked(obj)) {
+      if (hr->is_starts_humongous()) {
+        obj->forward_to(obj);
+      }
+    } else {
+      free_humongous_region(hr);
+    }
+  } else if (!hr->is_pinned()) {
+    prepare_for_compaction(hr);
+  }
+
+  // Reset data structures not valid after Full GC.
+  reset_region_metadata(hr);
+
+  return false;
+}
+
+G1FullGCPrepareTask::G1FullGCPrepareTask(G1FullCollector* collector) :
+    G1FullGCTask("G1 Prepare Compact Task", collector),
+    _hrclaimer(collector->workers()),
+    _freed_regions(false) {
+}
+
+void G1FullGCPrepareTask::set_freed_regions() {
+  if (!_freed_regions) {
+    _freed_regions = true;
+  }
+}
+
+bool G1FullGCPrepareTask::has_freed_regions() {
+  return _freed_regions;
+}
+
+void G1FullGCPrepareTask::work(uint worker_id) {
+  Ticks start = Ticks::now();
+  G1FullGCCompactionPoint* compaction_point = collector()->compaction_point(worker_id);
+  G1CalculatePointersClosure closure(collector()->mark_bitmap(), compaction_point);
+  G1CollectedHeap::heap()->heap_region_par_iterate_from_start(&closure, &_hrclaimer);
+
+  // Update humongous region sets
+  closure.update_sets();
+  compaction_point->update();
+
+  // Check if any regions was freed by this worker and store in task.
+  if (closure.freed_regions()) {
+    set_freed_regions();
+  }
+  log_task("Prepare compaction task", worker_id, start);
+}
+
+G1FullGCPrepareTask::G1CalculatePointersClosure::G1CalculatePointersClosure(G1CMBitMap* bitmap,
+                                                                            G1FullGCCompactionPoint* cp) :
+    _g1h(G1CollectedHeap::heap()),
+    _bitmap(bitmap),
+    _cp(cp),
+    _humongous_regions_removed(0) { }
+
+void G1FullGCPrepareTask::G1CalculatePointersClosure::free_humongous_region(HeapRegion* hr) {
+  FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
+
+  hr->set_containing_set(NULL);
+  _humongous_regions_removed++;
+
+  _g1h->free_humongous_region(hr, &dummy_free_list, false /* skip_remset */);
+  prepare_for_compaction(hr);
+  dummy_free_list.remove_all();
+}
+
+void G1FullGCPrepareTask::G1CalculatePointersClosure::reset_region_metadata(HeapRegion* hr) {
+  hr->reset_gc_time_stamp();
+  hr->rem_set()->clear();
+
+  _g1h->g1_barrier_set()->clear(MemRegion(hr->bottom(), hr->end()));
+
+  if (_g1h->g1_hot_card_cache()->use_cache()) {
+    _g1h->g1_hot_card_cache()->reset_card_counts(hr);
+  }
+}
+
+G1FullGCPrepareTask::G1PrepareCompactLiveClosure::G1PrepareCompactLiveClosure(G1FullGCCompactionPoint* cp) :
+    _cp(cp) { }
+
+size_t G1FullGCPrepareTask::G1PrepareCompactLiveClosure::apply(oop object) {
+  size_t size = object->size();
+  _cp->forward(object, size);
+  return size;
+}
+
+size_t G1FullGCPrepareTask::G1RePrepareClosure::apply(oop obj) {
+  // We only re-prepare objects forwarded within the current region, so
+  // skip objects that are already forwarded to another region.
+  oop forwarded_to = obj->forwardee();
+  if (forwarded_to != NULL && !_current->is_in(forwarded_to)) {
+    return obj->size();
+  }
+
+  // Get size and forward.
+  size_t size = obj->size();
+  _cp->forward(obj, size);
+
+  return size;
+}
+
+void G1FullGCPrepareTask::G1CalculatePointersClosure::prepare_for_compaction_work(G1FullGCCompactionPoint* cp,
+                                                                                  HeapRegion* hr) {
+  G1PrepareCompactLiveClosure prepare_compact(cp);
+  hr->set_compaction_top(hr->bottom());
+  hr->apply_to_marked_objects(_bitmap, &prepare_compact);
+}
+
+void G1FullGCPrepareTask::G1CalculatePointersClosure::prepare_for_compaction(HeapRegion* hr) {
+  if (!_cp->is_initialized()) {
+    hr->set_compaction_top(hr->bottom());
+    _cp->initialize(hr, true);
+  }
+  // Add region to the compaction queue and prepare it.
+  _cp->add(hr);
+  prepare_for_compaction_work(_cp, hr);
+}
+
+void G1FullGCPrepareTask::prepare_serial_compaction() {
+  GCTraceTime(Debug, gc, phases) debug("Phase 2: Prepare Serial Compaction", collector()->scope()->timer());
+  // At this point we know that no regions were completely freed by
+  // the parallel compaction. That means that the last region of
+  // all compaction queues still have data in them. We try to compact
+  // these regions in serial to avoid a premature OOM.
+  for (uint i = 0; i < collector()->workers(); i++) {
+    G1FullGCCompactionPoint* cp = collector()->compaction_point(i);
+    if (cp->has_regions()) {
+      collector()->serial_compaction_point()->add(cp->remove_last());
+    }
+  }
+
+  // Update the forwarding information for the regions in the serial
+  // compaction point.
+  G1FullGCCompactionPoint* cp = collector()->serial_compaction_point();
+  for (GrowableArrayIterator<HeapRegion*> it = cp->regions()->begin(); it != cp->regions()->end(); ++it) {
+    HeapRegion* current = *it;
+    if (!cp->is_initialized()) {
+      // Initialize the compaction point. Nothing more is needed for the first heap region
+      // since it is already prepared for compaction.
+      cp->initialize(current, false);
+    } else {
+      assert(!current->is_humongous(), "Should be no humongous regions in compaction queue");
+      G1RePrepareClosure re_prepare(cp, current);
+      current->set_compaction_top(current->bottom());
+      current->apply_to_marked_objects(collector()->mark_bitmap(), &re_prepare);
+    }
+  }
+  cp->update();
+}
+
+void G1FullGCPrepareTask::G1CalculatePointersClosure::update_sets() {
+  // We'll recalculate total used bytes and recreate the free list
+  // at the end of the GC, so no point in updating those values here.
+  _g1h->remove_from_old_sets(0, _humongous_regions_removed);
+}
+
+bool G1FullGCPrepareTask::G1CalculatePointersClosure::freed_regions() {
+  if (_humongous_regions_removed > 0) {
+    // Free regions from dead humongous regions.
+    return true;
+  }
+
+  if (!_cp->has_regions()) {
+    // No regions in queue, so no free ones either.
+    return false;
+  }
+
+  if (_cp->current_region() != _cp->regions()->last()) {
+    // The current region used for compaction is not the last in the
+    // queue. That means there is at least one free region in the queue.
+    return true;
+  }
+
+  // No free regions in the queue.
+  return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1FULLGCPREPARETASK_HPP
+#define SHARE_GC_G1_G1FULLGCPREPARETASK_HPP
+
+#include "gc/g1/g1FullGCCompactionPoint.hpp"
+#include "gc/g1/g1FullGCScope.hpp"
+#include "gc/g1/g1FullGCTask.hpp"
+#include "gc/g1/g1RootProcessor.hpp"
+#include "gc/g1/g1StringDedup.hpp"
+#include "gc/g1/heapRegionManager.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "utilities/ticks.hpp"
+
+class G1CMBitMap;
+
+class G1FullGCPrepareTask : public G1FullGCTask {
+protected:
+  volatile bool     _freed_regions;
+  HeapRegionClaimer _hrclaimer;
+
+  void set_freed_regions();
+
+public:
+  G1FullGCPrepareTask(G1FullCollector* collector);
+  void work(uint worker_id);
+  void prepare_serial_compaction();
+  bool has_freed_regions();
+
+protected:
+  class G1CalculatePointersClosure : public HeapRegionClosure {
+  protected:
+    G1CollectedHeap* _g1h;
+    G1CMBitMap* _bitmap;
+    G1FullGCCompactionPoint* _cp;
+    uint _humongous_regions_removed;
+
+    virtual void prepare_for_compaction(HeapRegion* hr);
+    void prepare_for_compaction_work(G1FullGCCompactionPoint* cp, HeapRegion* hr);
+    void free_humongous_region(HeapRegion* hr);
+    void reset_region_metadata(HeapRegion* hr);
+
+  public:
+    G1CalculatePointersClosure(G1CMBitMap* bitmap,
+                               G1FullGCCompactionPoint* cp);
+
+    void update_sets();
+    bool doHeapRegion(HeapRegion* hr);
+    bool freed_regions();
+  };
+
+  class G1PrepareCompactLiveClosure : public StackObj {
+    G1FullGCCompactionPoint* _cp;
+
+  public:
+    G1PrepareCompactLiveClosure(G1FullGCCompactionPoint* cp);
+    size_t apply(oop object);
+  };
+
+  class G1RePrepareClosure : public StackObj {
+    G1FullGCCompactionPoint* _cp;
+    HeapRegion* _current;
+
+  public:
+    G1RePrepareClosure(G1FullGCCompactionPoint* hrcp,
+                       HeapRegion* hr) :
+        _cp(hrcp),
+        _current(hr) { }
+
+    size_t apply(oop object);
+  };
+};
+
+#endif // SHARE_GC_G1_G1FULLGCPREPARETASK_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1FullCollector.hpp"
+#include "gc/g1/g1FullGCMarker.hpp"
+#include "gc/g1/g1FullGCOopClosures.inline.hpp"
+#include "gc/g1/g1FullGCReferenceProcessorExecutor.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+
+G1FullGCReferenceProcessingExecutor::G1FullGCReferenceProcessingExecutor(G1FullCollector* collector) :
+    _collector(collector),
+    _reference_processor(collector->reference_processor()),
+    _old_mt_degree(_reference_processor->num_q()) {
+  if (_reference_processor->processing_is_mt()) {
+    _reference_processor->set_active_mt_degree(_collector->workers());
+  }
+}
+
+G1FullGCReferenceProcessingExecutor::~G1FullGCReferenceProcessingExecutor() {
+  if (_reference_processor->processing_is_mt()) {
+    _reference_processor->set_active_mt_degree(_old_mt_degree);
+  }
+}
+
+G1FullGCReferenceProcessingExecutor::G1RefProcTaskProxy::G1RefProcTaskProxy(ProcessTask& proc_task,
+                                                                      G1FullCollector* collector) :
+     AbstractGangTask("G1 reference processing task"),
+     _proc_task(proc_task),
+     _collector(collector),
+     _terminator(_collector->workers(), _collector->oop_queue_set()) { }
+
+void G1FullGCReferenceProcessingExecutor::G1RefProcTaskProxy::work(uint worker_id) {
+  G1FullGCMarker* marker = _collector->marker(worker_id);
+  G1IsAliveClosure is_alive(_collector->mark_bitmap());
+  G1FullKeepAliveClosure keep_alive(marker);
+  _proc_task.work(worker_id,
+                  is_alive,
+                  keep_alive,
+                  *marker->stack_closure());
+}
+
+G1FullGCReferenceProcessingExecutor::G1RefEnqueueTaskProxy::G1RefEnqueueTaskProxy(EnqueueTask& enq_task) :
+  AbstractGangTask("G1 reference enqueue task"),
+  _enq_task(enq_task) { }
+
+void G1FullGCReferenceProcessingExecutor::G1RefEnqueueTaskProxy::work(uint worker_id) {
+  _enq_task.work(worker_id);
+}
+
+void G1FullGCReferenceProcessingExecutor::run_task(AbstractGangTask* task) {
+  G1CollectedHeap::heap()->workers()->run_task(task, _collector->workers());
+}
+
+void G1FullGCReferenceProcessingExecutor::execute(ProcessTask& proc_task) {
+  G1RefProcTaskProxy proc_task_proxy(proc_task, _collector);
+  run_task(&proc_task_proxy);
+}
+
+// Driver routine for parallel reference processing.
+void G1FullGCReferenceProcessingExecutor::execute(EnqueueTask& enq_task) {
+  G1RefEnqueueTaskProxy enq_task_proxy(enq_task);
+  run_task(&enq_task_proxy);
+}
+
+void G1FullGCReferenceProcessingExecutor::execute(STWGCTimer* timer, G1FullGCTracer* tracer) {
+  GCTraceTime(Debug, gc, phases) debug("Phase 1: Reference Processing", timer);
+  // Process reference objects found during marking.
+  G1FullGCMarker* marker = _collector->marker(0);
+  G1IsAliveClosure is_alive(_collector->mark_bitmap());
+  G1FullKeepAliveClosure keep_alive(marker);
+  ReferenceProcessorPhaseTimes pt(timer, _reference_processor->num_q());
+  AbstractRefProcTaskExecutor* executor = _reference_processor->processing_is_mt() ? this : NULL;
+
+  // Process discovered references, use this executor if multi-threaded
+  // processing is enabled.
+  const ReferenceProcessorStats& stats =
+      _reference_processor->process_discovered_references(&is_alive,
+                                                          &keep_alive,
+                                                          marker->stack_closure(),
+                                                          executor,
+                                                          &pt);
+
+  tracer->report_gc_reference_stats(stats);
+  pt.print_all_references();
+
+  assert(marker->oop_stack()->is_empty(), "Should be no oops on the stack");
+
+  // Now enqueue the references.
+  _reference_processor->enqueue_discovered_references(executor, &pt);
+  pt.print_enqueue_phase();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1FULLGCREFERENCEPROCESSOREXECUTOR_HPP
+#define SHARE_GC_G1_G1FULLGCREFERENCEPROCESSOREXECUTOR_HPP
+
+#include "gc/g1/g1FullGCCompactionPoint.hpp"
+#include "gc/g1/g1FullGCScope.hpp"
+#include "gc/g1/g1FullGCTask.hpp"
+#include "gc/g1/g1RootProcessor.hpp"
+#include "gc/g1/g1StringDedup.hpp"
+#include "gc/g1/heapRegionManager.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "utilities/ticks.hpp"
+
+class G1FullGCTracer;
+class STWGCTimer;
+
+class G1FullGCReferenceProcessingExecutor: public AbstractRefProcTaskExecutor {
+  G1FullCollector*    _collector;
+  ReferenceProcessor* _reference_processor;
+  uint                _old_mt_degree;
+
+public:
+  G1FullGCReferenceProcessingExecutor(G1FullCollector* collector);
+  ~G1FullGCReferenceProcessingExecutor();
+
+  // Do reference processing.
+  void execute(STWGCTimer* timer, G1FullGCTracer* tracer);
+
+  // Executes the given task using concurrent marking worker threads.
+  virtual void execute(ProcessTask& task);
+  virtual void execute(EnqueueTask& task);
+
+private:
+  void run_task(AbstractGangTask* task);
+
+  class G1RefProcTaskProxy : public AbstractGangTask {
+    typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
+    ProcessTask&             _proc_task;
+    G1FullCollector*         _collector;
+    ParallelTaskTerminator   _terminator;
+
+  public:
+    G1RefProcTaskProxy(ProcessTask& proc_task,
+                       G1FullCollector* scope);
+
+    virtual void work(uint worker_id);
+  };
+
+  class G1RefEnqueueTaskProxy: public AbstractGangTask {
+    typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
+    EnqueueTask& _enq_task;
+
+  public:
+    G1RefEnqueueTaskProxy(EnqueueTask& enq_task);
+    virtual void work(uint worker_id);
+  };
+};
+
+#endif // SHARE_GC_G1_G1FULLGCREFERENCEPROCESSOREXECUTOR_HPP
--- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -25,13 +25,6 @@
 #include "precompiled.hpp"
 #include "gc/g1/g1FullGCScope.hpp"
 
-G1FullGCScope* G1FullGCScope::_instance = NULL;
-
-G1FullGCScope* G1FullGCScope::instance() {
-  assert(_instance != NULL, "Must be setup already");
-  return _instance;
-}
-
 G1FullGCScope::G1FullGCScope(bool explicit_gc, bool clear_soft) :
     _rm(),
     _explicit_gc(explicit_gc),
@@ -46,12 +39,10 @@
     _memory_stats(true, _g1h->gc_cause()),
     _collector_stats(_g1h->g1mm()->full_collection_counters()),
     _heap_transition(_g1h) {
-  assert(_instance == NULL, "Only one scope at a time");
   _timer.register_gc_start();
   _tracer.report_gc_start(_g1h->gc_cause(), _timer.gc_start());
   _g1h->pre_full_gc_dump(&_timer);
   _g1h->trace_heap_before_gc(&_tracer);
-  _instance = this;
 }
 
 G1FullGCScope::~G1FullGCScope() {
@@ -64,7 +55,6 @@
   _g1h->post_full_gc_dump(&_timer);
   _timer.register_gc_end();
   _tracer.report_gc_end(_timer.gc_end(), _timer.time_partitions());
-  _instance = NULL;
 }
 
 bool G1FullGCScope::is_explicit_gc() {
@@ -79,7 +69,7 @@
   return &_timer;
 }
 
-SerialOldTracer* G1FullGCScope::tracer() {
+G1FullGCTracer* G1FullGCScope::tracer() {
   return &_tracer;
 }
 
--- a/src/hotspot/share/gc/g1/g1FullGCScope.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCScope.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -45,7 +45,7 @@
   GCIdMark                _gc_id;
   SvcGCMarker             _svc_marker;
   STWGCTimer              _timer;
-  SerialOldTracer         _tracer;
+  G1FullGCTracer          _tracer;
   IsGCActiveMark          _active;
   GCTraceCPUTime          _cpu_time;
   ClearedAllSoftRefs      _soft_refs;
@@ -53,11 +53,7 @@
   TraceMemoryManagerStats _memory_stats;
   G1HeapTransition        _heap_transition;
 
-  // Singleton instance.
-  static G1FullGCScope* _instance;
 public:
-  static G1FullGCScope* instance();
-
   G1FullGCScope(bool explicit_gc, bool clear_soft);
   ~G1FullGCScope();
 
@@ -65,7 +61,7 @@
   bool should_clear_soft_refs();
 
   STWGCTimer* timer();
-  SerialOldTracer* tracer();
+  G1FullGCTracer* tracer();
   G1HeapTransition* heap_transition();
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCTask.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1FullGCTask.hpp"
+#include "logging/log.hpp"
+#include "utilities/ticks.inline.hpp"
+
+void G1FullGCTask::log_task(const char* name, uint worker_id, const Ticks& start, const Ticks& stop) {
+  Tickspan duration = stop - start;
+  double duration_ms = TimeHelper::counter_to_millis(duration.value());
+  log_trace(gc, phases)("%s (%u) %.3fms", name, worker_id, duration_ms);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1FullGCTask.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1FULLGCTASK_HPP
+#define SHARE_GC_G1_G1FULLGCTASK_HPP
+
+#include "gc/shared/workgroup.hpp"
+#include "utilities/ticks.hpp"
+
+class G1FullCollector;
+
+class G1FullGCTask : public AbstractGangTask {
+  G1FullCollector* _collector;
+
+protected:
+  G1FullGCTask(const char* name, G1FullCollector* collector) :
+    AbstractGangTask(name),
+    _collector(collector) { }
+
+  G1FullCollector* collector() { return _collector; }
+  void log_task(const char* name, uint worker_id, const Ticks& start, const Ticks& stop = Ticks::now());
+};
+
+#endif // SHARE_GC_G1_G1FULLGCTASK_HPP
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -48,7 +48,7 @@
 public:
   // _vo == UsePrevMarking -> use "prev" marking information,
   // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
+  // _vo == UseFullMarking -> use "next" marking bitmap but no TAMS
   VerifyRootsClosure(VerifyOption vo) :
     _g1h(G1CollectedHeap::heap()),
     _vo(vo),
@@ -63,9 +63,6 @@
       if (_g1h->is_obj_dead_cond(obj, _vo)) {
         Log(gc, verify) log;
         log.error("Root location " PTR_FORMAT " points to dead obj " PTR_FORMAT, p2i(p), p2i(obj));
-        if (_vo == VerifyOption_G1UseMarkWord) {
-          log.error("  Mark word: " PTR_FORMAT, p2i(obj->mark()));
-        }
         ResourceMark rm;
         LogStream ls(log.error());
         obj->print_on(&ls);
@@ -95,7 +92,7 @@
     }
 
     // Don't check the code roots during marking verification in a full GC
-    if (_vo == VerifyOption_G1UseMarkWord) {
+    if (_vo == VerifyOption_G1UseFullMarking) {
       return;
     }
 
@@ -203,7 +200,7 @@
 public:
   // _vo == UsePrevMarking -> use "prev" marking information,
   // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
+  // _vo == UseFullMarking -> use "next" marking bitmap but no TAMS.
   VerifyObjsInRegionClosure(HeapRegion *hr, VerifyOption vo)
     : _live_bytes(0), _hr(hr), _vo(vo) {
     _g1h = G1CollectedHeap::heap();
@@ -212,15 +209,15 @@
     VerifyLivenessOopClosure isLive(_g1h, _vo);
     assert(o != NULL, "Huh?");
     if (!_g1h->is_obj_dead_cond(o, _vo)) {
-      // If the object is alive according to the mark word,
+      // If the object is alive according to the full gc mark,
       // then verify that the marking information agrees.
       // Note we can't verify the contra-positive of the
       // above: if the object is dead (according to the mark
       // word), it may not be marked, or may have been marked
       // but has since became dead, or may have been allocated
       // since the last marking.
-      if (_vo == VerifyOption_G1UseMarkWord) {
-        guarantee(!_g1h->is_obj_dead(o), "mark word and concurrent mark mismatch");
+      if (_vo == VerifyOption_G1UseFullMarking) {
+        guarantee(!_g1h->is_obj_dead(o), "Full GC marking and concurrent mark mismatch");
       }
 
       o->oop_iterate_no_header(&isLive);
@@ -299,7 +296,7 @@
 public:
   // _vo == UsePrevMarking -> use "prev" marking information,
   // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
+  // _vo == UseFullMarking -> use "next" marking bitmap but no TAMS
   VerifyRegionClosure(bool par, VerifyOption vo)
     : _par(par),
       _vo(vo),
@@ -357,7 +354,7 @@
 public:
   // _vo == UsePrevMarking -> use "prev" marking information,
   // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
+  // _vo == UseFullMarking -> use "next" marking bitmap but no TAMS
   G1ParVerifyTask(G1CollectedHeap* g1h, VerifyOption vo) :
       AbstractGangTask("Parallel verify task"),
       _g1h(g1h),
@@ -372,7 +369,7 @@
   void work(uint worker_id) {
     HandleMark hm;
     VerifyRegionClosure blk(true, _vo);
-    _g1h->heap_region_par_iterate(&blk, worker_id, &_hrclaimer);
+    _g1h->heap_region_par_iterate_from_worker_offset(&blk, &_hrclaimer, worker_id);
     if (blk.failures()) {
       _failures = true;
     }
@@ -407,7 +404,7 @@
 
   bool failures = rootsCl.failures() || codeRootsCl.failures();
 
-  if (vo != VerifyOption_G1UseMarkWord) {
+  if (!_g1h->g1_policy()->collector_state()->full_collection()) {
     // If we're verifying during a full GC then the region sets
     // will have been torn down at the start of the GC. Therefore
     // verifying the region sets will fail. So we only verify
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -46,9 +46,9 @@
 
   // Perform verification.
 
-  // vo == UsePrevMarking  -> use "prev" marking information,
+  // vo == UsePrevMarking -> use "prev" marking information,
   // vo == UseNextMarking -> use "next" marking information
-  // vo == UseMarkWord    -> use the mark word in the object header
+  // vo == UseFullMarking -> use "next" marking bitmap but no TAMS
   //
   // NOTE: Only the "prev" marking information is guaranteed to be
   // consistent most of the time, so most calls to this should use
@@ -57,7 +57,7 @@
   // vo == UseNextMarking, which is to verify the "next" marking
   // information at the end of remark.
   // Currently there is only one place where this is called with
-  // vo == UseMarkWord, which is to verify the marking during a
+  // vo == UseFullMarking, which is to verify the marking during a
   // full GC.
   void verify(VerifyOption vo);
 
--- a/src/hotspot/share/gc/g1/g1HotCardCache.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1HotCardCache.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -110,7 +110,3 @@
 void G1HotCardCache::reset_card_counts(HeapRegion* hr) {
   _card_counts.clear_region(hr);
 }
-
-void G1HotCardCache::reset_card_counts() {
-  _card_counts.clear_all();
-}
--- a/src/hotspot/share/gc/g1/g1HotCardCache.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1HotCardCache.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -128,9 +128,6 @@
     }
   }
 
-  // Zeros the values in the card counts table for entire committed heap
-  void reset_card_counts();
-
   // Zeros the values in the card counts table for the given region
   void reset_card_counts(HeapRegion* hr);
 
--- a/src/hotspot/share/gc/g1/g1MarkSweep.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,387 +0,0 @@
-/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "classfile/javaClasses.hpp"
-#include "classfile/symbolTable.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "classfile/vmSymbols.hpp"
-#include "code/codeCache.hpp"
-#include "code/icBuffer.hpp"
-#include "gc/g1/g1FullGCScope.hpp"
-#include "gc/g1/g1MarkSweep.hpp"
-#include "gc/g1/g1RootProcessor.hpp"
-#include "gc/g1/g1StringDedup.hpp"
-#include "gc/serial/markSweep.inline.hpp"
-#include "gc/shared/gcHeapSummary.hpp"
-#include "gc/shared/gcLocker.hpp"
-#include "gc/shared/gcTimer.hpp"
-#include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.inline.hpp"
-#include "gc/shared/genCollectedHeap.hpp"
-#include "gc/shared/modRefBarrierSet.hpp"
-#include "gc/shared/referencePolicy.hpp"
-#include "gc/shared/space.hpp"
-#include "gc/shared/weakProcessor.hpp"
-#include "oops/instanceRefKlass.hpp"
-#include "oops/oop.inline.hpp"
-#include "prims/jvmtiExport.hpp"
-#include "runtime/atomic.hpp"
-#include "runtime/biasedLocking.hpp"
-#include "runtime/synchronizer.hpp"
-#include "runtime/thread.hpp"
-#include "runtime/vmThread.hpp"
-#include "utilities/copy.hpp"
-#include "utilities/events.hpp"
-
-class HeapRegion;
-
-void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp,
-                                      bool clear_all_softrefs) {
-  assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
-  HandleMark hm;  // Discard invalid handles created during gc
-
-#if COMPILER2_OR_JVMCI
-  DerivedPointerTable::clear();
-#endif
-#ifdef ASSERT
-  if (G1CollectedHeap::heap()->collector_policy()->should_clear_all_soft_refs()) {
-    assert(clear_all_softrefs, "Policy should have been checked earler");
-  }
-#endif
-  // hook up weak ref data so it can be used during Mark-Sweep
-  assert(GenMarkSweep::ref_processor() == NULL, "no stomping");
-  assert(rp != NULL, "should be non-NULL");
-  assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Precondition");
-
-  GenMarkSweep::set_ref_processor(rp);
-  rp->setup_policy(clear_all_softrefs);
-
-  // When collecting the permanent generation Method*s may be moving,
-  // so we either have to flush all bcp data or convert it into bci.
-  CodeCache::gc_prologue();
-
-  bool marked_for_unloading = false;
-
-  allocate_stacks();
-
-  // We should save the marks of the currently locked biased monitors.
-  // The marking doesn't preserve the marks of biased objects.
-  BiasedLocking::preserve_marks();
-
-  // Process roots and do the marking.
-  mark_sweep_phase1(marked_for_unloading, clear_all_softrefs);
-
-  // Prepare compaction.
-  mark_sweep_phase2();
-
-#if COMPILER2_OR_JVMCI
-  // Don't add any more derived pointers during phase3
-  DerivedPointerTable::set_active(false);
-#endif
-
-  // Adjust all pointers.
-  mark_sweep_phase3();
-
-  // Do the actual compaction.
-  mark_sweep_phase4();
-
-  GenMarkSweep::restore_marks();
-  BiasedLocking::restore_marks();
-  GenMarkSweep::deallocate_stacks();
-
-#if COMPILER2_OR_JVMCI
-  // Now update the derived pointers.
-  DerivedPointerTable::update_pointers();
-#endif
-
-  CodeCache::gc_epilogue();
-  JvmtiExport::gc_epilogue();
-
-  // refs processing: clean slate
-  GenMarkSweep::set_ref_processor(NULL);
-}
-
-STWGCTimer* G1MarkSweep::gc_timer() {
-  return G1FullGCScope::instance()->timer();
-}
-
-SerialOldTracer* G1MarkSweep::gc_tracer() {
-  return G1FullGCScope::instance()->tracer();
-}
-
-void G1MarkSweep::allocate_stacks() {
-  GenMarkSweep::_preserved_count_max = 0;
-  GenMarkSweep::_preserved_marks = NULL;
-  GenMarkSweep::_preserved_count = 0;
-}
-
-void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
-                                    bool clear_all_softrefs) {
-  // Recursively traverse all live objects and mark them
-  GCTraceTime(Info, gc, phases) tm("Phase 1: Mark live objects", gc_timer());
-
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-
-  // Need cleared claim bits for the roots processing
-  ClassLoaderDataGraph::clear_claimed_marks();
-
-  MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations);
-  {
-    G1RootProcessor root_processor(g1h, 1);
-    if (ClassUnloading) {
-      root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure,
-                                          &GenMarkSweep::follow_cld_closure,
-                                          &follow_code_closure);
-    } else {
-      root_processor.process_all_roots_no_string_table(
-                                          &GenMarkSweep::follow_root_closure,
-                                          &GenMarkSweep::follow_cld_closure,
-                                          &follow_code_closure);
-    }
-  }
-
-  {
-    GCTraceTime(Debug, gc, phases) trace("Reference Processing", gc_timer());
-
-    // Process reference objects found during marking
-    ReferenceProcessor* rp = GenMarkSweep::ref_processor();
-    assert(rp == g1h->ref_processor_stw(), "Sanity");
-
-    rp->setup_policy(clear_all_softrefs);
-    ReferenceProcessorPhaseTimes pt(gc_timer(), rp->num_q());
-
-    const ReferenceProcessorStats& stats =
-        rp->process_discovered_references(&GenMarkSweep::is_alive,
-                                          &GenMarkSweep::keep_alive,
-                                          &GenMarkSweep::follow_stack_closure,
-                                          NULL,
-                                          &pt);
-    gc_tracer()->report_gc_reference_stats(stats);
-    pt.print_all_references();
-  }
-
-  // This is the point where the entire marking should have completed.
-  assert(GenMarkSweep::_marking_stack.is_empty(), "Marking should have completed");
-
-  {
-    GCTraceTime(Debug, gc, phases) trace("Weak Processing", gc_timer());
-    WeakProcessor::weak_oops_do(&GenMarkSweep::is_alive, &do_nothing_cl);
-  }
-
-  if (ClassUnloading) {
-    GCTraceTime(Debug, gc, phases) trace("Class Unloading", gc_timer());
-
-    // Unload classes and purge the SystemDictionary.
-    bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive, gc_timer());
-
-    g1h->complete_cleaning(&GenMarkSweep::is_alive, purged_class);
-  } else {
-    GCTraceTime(Debug, gc, phases) trace("Cleanup", gc_timer());
-    g1h->partial_cleaning(&GenMarkSweep::is_alive, true, true, G1StringDedup::is_enabled());
-  }
-
-  if (VerifyDuringGC) {
-    HandleMark hm;  // handle scope
-#if COMPILER2_OR_JVMCI
-    DerivedPointerTableDeactivate dpt_deact;
-#endif
-    g1h->prepare_for_verify();
-    // Note: we can verify only the heap here. When an object is
-    // marked, the previous value of the mark word (including
-    // identity hash values, ages, etc) is preserved, and the mark
-    // word is set to markOop::marked_value - effectively removing
-    // any hash values from the mark word. These hash values are
-    // used when verifying the dictionaries and so removing them
-    // from the mark word can make verification of the dictionaries
-    // fail. At the end of the GC, the original mark word values
-    // (including hash values) are restored to the appropriate
-    // objects.
-    GCTraceTime(Info, gc, verify)("During GC (full)");
-    g1h->verify(VerifyOption_G1UseMarkWord);
-  }
-
-  gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive);
-}
-
-
-void G1MarkSweep::mark_sweep_phase2() {
-  // Now all live objects are marked, compute the new object addresses.
-
-  // It is not required that we traverse spaces in the same order in
-  // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
-  // tracking expects us to do so. See comment under phase4.
-
-  GCTraceTime(Info, gc, phases) tm("Phase 2: Compute new object addresses", gc_timer());
-
-  prepare_compaction();
-}
-
-class G1AdjustPointersClosure: public HeapRegionClosure {
- public:
-  bool doHeapRegion(HeapRegion* r) {
-    if (r->is_humongous()) {
-      if (r->is_starts_humongous()) {
-        // We must adjust the pointers on the single H object.
-        oop obj = oop(r->bottom());
-        // point all the oops to the new location
-        MarkSweep::adjust_pointers(obj);
-      }
-    } else if (!r->is_closed_archive()) {
-      // This really ought to be "as_CompactibleSpace"...
-      r->adjust_pointers();
-    }
-    return false;
-  }
-};
-
-void G1MarkSweep::mark_sweep_phase3() {
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-
-  // Adjust the pointers to reflect the new locations
-  GCTraceTime(Info, gc, phases) tm("Phase 3: Adjust pointers", gc_timer());
-
-  // Need cleared claim bits for the roots processing
-  ClassLoaderDataGraph::clear_claimed_marks();
-
-  CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations);
-  {
-    G1RootProcessor root_processor(g1h, 1);
-    root_processor.process_all_roots(&GenMarkSweep::adjust_pointer_closure,
-                                     &GenMarkSweep::adjust_cld_closure,
-                                     &adjust_code_closure);
-  }
-
-  assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity");
-  g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_pointer_closure);
-
-  // Now adjust pointers in remaining weak roots.  (All of which should
-  // have been cleared if they pointed to non-surviving objects.)
-  WeakProcessor::oops_do(&GenMarkSweep::adjust_pointer_closure);
-
-  if (G1StringDedup::is_enabled()) {
-    G1StringDedup::oops_do(&GenMarkSweep::adjust_pointer_closure);
-  }
-
-  GenMarkSweep::adjust_marks();
-
-  G1AdjustPointersClosure blk;
-  g1h->heap_region_iterate(&blk);
-}
-
-class G1SpaceCompactClosure: public HeapRegionClosure {
-public:
-  G1SpaceCompactClosure() {}
-
-  bool doHeapRegion(HeapRegion* hr) {
-    if (hr->is_humongous()) {
-      if (hr->is_starts_humongous()) {
-        oop obj = oop(hr->bottom());
-        if (obj->is_gc_marked()) {
-          obj->init_mark();
-        } else {
-          assert(hr->is_empty(), "Should have been cleared in phase 2.");
-        }
-      }
-      hr->reset_during_compaction();
-    } else if (!hr->is_pinned()) {
-      hr->compact();
-    }
-    return false;
-  }
-};
-
-void G1MarkSweep::mark_sweep_phase4() {
-  // All pointers are now adjusted, move objects accordingly
-
-  // The ValidateMarkSweep live oops tracking expects us to traverse spaces
-  // in the same order in phase2, phase3 and phase4. We don't quite do that
-  // here (code and comment not fixed for perm removal), so we tell the validate code
-  // to use a higher index (saved from phase2) when verifying perm_gen.
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-
-  GCTraceTime(Info, gc, phases) tm("Phase 4: Move objects", gc_timer());
-
-  G1SpaceCompactClosure blk;
-  g1h->heap_region_iterate(&blk);
-
-}
-
-void G1MarkSweep::prepare_compaction_work(G1PrepareCompactClosure* blk) {
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  g1h->heap_region_iterate(blk);
-  blk->update_sets();
-}
-
-void G1PrepareCompactClosure::free_humongous_region(HeapRegion* hr) {
-  HeapWord* end = hr->end();
-  FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
-
-  hr->set_containing_set(NULL);
-  _humongous_regions_removed++;
-
-  _g1h->free_humongous_region(hr, &dummy_free_list, false /* skip_remset */);
-  prepare_for_compaction(hr, end);
-  dummy_free_list.remove_all();
-}
-
-void G1PrepareCompactClosure::prepare_for_compaction(HeapRegion* hr, HeapWord* end) {
-  // If this is the first live region that we came across which we can compact,
-  // initialize the CompactPoint.
-  if (!is_cp_initialized()) {
-    _cp.space = hr;
-    _cp.threshold = hr->initialize_threshold();
-  }
-  prepare_for_compaction_work(&_cp, hr, end);
-}
-
-void G1PrepareCompactClosure::prepare_for_compaction_work(CompactPoint* cp,
-                                                          HeapRegion* hr,
-                                                          HeapWord* end) {
-  hr->prepare_for_compaction(cp);
-  // Also clear the part of the card table that will be unused after
-  // compaction.
-  _mrbs->clear(MemRegion(hr->compaction_top(), end));
-}
-
-void G1PrepareCompactClosure::update_sets() {
-  // We'll recalculate total used bytes and recreate the free list
-  // at the end of the GC, so no point in updating those values here.
-  _g1h->remove_from_old_sets(0, _humongous_regions_removed);
-}
-
-bool G1PrepareCompactClosure::doHeapRegion(HeapRegion* hr) {
-  if (hr->is_humongous()) {
-    oop obj = oop(hr->humongous_start_region()->bottom());
-    if (hr->is_starts_humongous() && obj->is_gc_marked()) {
-      obj->forward_to(obj);
-    }
-    if (!obj->is_gc_marked()) {
-      free_humongous_region(hr);
-    }
-  } else if (!hr->is_pinned()) {
-    prepare_for_compaction(hr, hr->end());
-  }
-  return false;
-}
--- a/src/hotspot/share/gc/g1/g1MarkSweep.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_G1_G1MARKSWEEP_HPP
-#define SHARE_VM_GC_G1_G1MARKSWEEP_HPP
-
-#include "gc/g1/g1CollectedHeap.hpp"
-#include "gc/g1/heapRegion.hpp"
-#include "gc/serial/genMarkSweep.hpp"
-#include "gc/shared/generation.hpp"
-#include "memory/universe.hpp"
-#include "oops/markOop.hpp"
-#include "oops/oop.hpp"
-#include "runtime/timer.hpp"
-#include "utilities/growableArray.hpp"
-
-class ReferenceProcessor;
-
-// G1MarkSweep takes care of global mark-compact garbage collection for a
-// G1CollectedHeap using a four-phase pointer forwarding algorithm.  All
-// generations are assumed to support marking; those that can also support
-// compaction.
-//
-// Class unloading will only occur when a full gc is invoked.
-class G1PrepareCompactClosure;
-class G1ArchiveRegionMap;
-
-class G1MarkSweep : AllStatic {
- public:
-
-  static void invoke_at_safepoint(ReferenceProcessor* rp,
-                                  bool clear_all_softrefs);
-
-  static STWGCTimer* gc_timer();
-  static SerialOldTracer* gc_tracer();
-
-private:
-  // Mark live objects
-  static void mark_sweep_phase1(bool& marked_for_deopt,
-                                bool clear_all_softrefs);
-  // Calculate new addresses
-  static void mark_sweep_phase2();
-  // Update pointers
-  static void mark_sweep_phase3();
-  // Move objects to new positions
-  static void mark_sweep_phase4();
-
-  static void allocate_stacks();
-  static void prepare_compaction();
-  static void prepare_compaction_work(G1PrepareCompactClosure* blk);
-};
-
-class G1PrepareCompactClosure : public HeapRegionClosure {
- protected:
-  G1CollectedHeap* _g1h;
-  ModRefBarrierSet* _mrbs;
-  CompactPoint _cp;
-  uint _humongous_regions_removed;
-
-  virtual void prepare_for_compaction(HeapRegion* hr, HeapWord* end);
-  void prepare_for_compaction_work(CompactPoint* cp, HeapRegion* hr, HeapWord* end);
-  void free_humongous_region(HeapRegion* hr);
-  bool is_cp_initialized() const { return _cp.space != NULL; }
-
- public:
-  G1PrepareCompactClosure() :
-    _g1h(G1CollectedHeap::heap()),
-    _mrbs(_g1h->g1_barrier_set()),
-    _humongous_regions_removed(0) { }
-
-  void update_sets();
-  bool doHeapRegion(HeapRegion* hr);
-};
-
-#endif // SHARE_VM_GC_G1_G1MARKSWEEP_HPP
--- a/src/hotspot/share/gc/g1/g1MarkSweep_ext.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/g1/g1MarkSweep.hpp"
-
-void G1MarkSweep::prepare_compaction() {
-  G1PrepareCompactClosure blk;
-  G1MarkSweep::prepare_compaction_work(&blk);
-}
--- a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -30,7 +30,6 @@
 #include "gc/g1/g1OopClosures.hpp"
 #include "gc/g1/g1ParScanThreadState.inline.hpp"
 #include "gc/g1/g1RemSet.hpp"
-#include "gc/g1/g1RemSet.inline.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "memory/iterator.inline.hpp"
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -26,7 +26,7 @@
 #define SHARE_VM_GC_G1_G1PARSCANTHREADSTATE_INLINE_HPP
 
 #include "gc/g1/g1ParScanThreadState.hpp"
-#include "gc/g1/g1RemSet.inline.hpp"
+#include "gc/g1/g1RemSet.hpp"
 #include "oops/oop.inline.hpp"
 
 template <class T> void G1ParScanThreadState::do_oop_evac(T* p, HeapRegion* from) {
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -31,7 +31,7 @@
 #include "gc/g1/g1GCPhaseTimes.hpp"
 #include "gc/g1/g1HotCardCache.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
-#include "gc/g1/g1RemSet.inline.hpp"
+#include "gc/g1/g1RemSet.hpp"
 #include "gc/g1/g1SATBCardTableModRefBS.inline.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
@@ -532,7 +532,7 @@
 
 void G1RemSet::scrub(uint worker_num, HeapRegionClaimer *hrclaimer) {
   G1ScrubRSClosure scrub_cl(&_card_live_data);
-  _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
+  _g1->heap_region_par_iterate_from_worker_offset(&scrub_cl, hrclaimer, worker_num);
 }
 
 inline void check_card_ptr(jbyte* card_ptr, CardTableModRefBS* ct_bs) {
--- a/src/hotspot/share/gc/g1/g1RemSet.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1RemSet.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -114,10 +114,6 @@
 
   G1RemSetScanState* scan_state() const { return _scan_state; }
 
-  // Record, if necessary, the fact that *p (where "p" is in region "from",
-  // which is required to be non-NULL) has changed to a new non-NULL value.
-  template <class T> void par_write_ref(HeapRegion* from, T* p, uint tid);
-
   // Eliminates any remembered set entries that correspond to dead heap ranges.
   void scrub(uint worker_num, HeapRegionClaimer* hrclaimer);
 
@@ -191,25 +187,4 @@
   size_t cards_skipped() const { return _cards_skipped; }
 };
 
-class RebuildRSOopClosure: public ExtendedOopClosure {
-  HeapRegion* _from;
-  G1RemSet* _rs;
-  uint _worker_i;
-
-  template <class T> void do_oop_work(T* p);
-
-public:
-  RebuildRSOopClosure(G1RemSet* rs, uint worker_i = 0) :
-    _from(NULL), _rs(rs), _worker_i(worker_i)
-  {}
-
-  void set_from(HeapRegion* from) {
-    assert(from != NULL, "from region must be non-NULL");
-    _from = from;
-  }
-
-  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
-  virtual void do_oop(oop* p)       { do_oop_work(p); }
-};
-
 #endif // SHARE_VM_GC_G1_G1REMSET_HPP
--- a/src/hotspot/share/gc/g1/g1RemSet.inline.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_G1_G1REMSET_INLINE_HPP
-#define SHARE_VM_GC_G1_G1REMSET_INLINE_HPP
-
-#include "gc/g1/g1RemSet.hpp"
-#include "gc/g1/heapRegion.hpp"
-#include "gc/g1/heapRegionRemSet.hpp"
-#include "oops/oop.inline.hpp"
-
-template <class T>
-inline void G1RemSet::par_write_ref(HeapRegion* from, T* p, uint tid) {
-  oop obj = oopDesc::load_decode_heap_oop(p);
-  if (obj == NULL) {
-    return;
-  }
-
-#ifdef ASSERT
-  // can't do because of races
-  // assert(oopDesc::is_oop_or_null(obj), "expected an oop");
-  assert(check_obj_alignment(obj), "not oop aligned");
-  assert(_g1->is_in_reserved(obj), "must be in heap");
-#endif // ASSERT
-
-  assert(from->is_in_reserved(p) || from->is_starts_humongous(), "p is not in from");
-
-  HeapRegion* to = _g1->heap_region_containing(obj);
-  if (from != to) {
-    assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
-    to->rem_set()->add_reference(p, tid);
-  }
-}
-
-template <class T>
-inline void RebuildRSOopClosure::do_oop_work(T* p) {
-  assert(_from != NULL, "from region must be non-NULL");
-  _rs->par_write_ref(_from, p, _worker_i);
-}
-
-#endif // SHARE_VM_GC_G1_G1REMSET_INLINE_HPP
--- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -26,7 +26,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/g1ConcurrentRefineThread.hpp"
-#include "gc/g1/g1RemSet.inline.hpp"
+#include "gc/g1/g1RemSet.hpp"
 #include "gc/g1/g1RemSetSummary.hpp"
 #include "gc/g1/g1YoungRemSetSamplingThread.hpp"
 #include "gc/g1/heapRegion.hpp"
--- a/src/hotspot/share/gc/g1/g1RootProcessor.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -37,6 +37,7 @@
 #include "gc/g1/g1RootClosures.hpp"
 #include "gc/g1/g1RootProcessor.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
+#include "gc/shared/weakProcessor.hpp"
 #include "memory/allocation.inline.hpp"
 #include "runtime/mutex.hpp"
 #include "services/management.hpp"
@@ -319,6 +320,16 @@
   }
 }
 
+void G1RootProcessor::process_full_gc_weak_roots(OopClosure* oops) {
+  if (!_process_strong_tasks.is_task_claimed(G1RP_PS_refProcessor_oops_do)) {
+    _g1h->ref_processor_stw()->weak_oops_do(oops);
+  }
+
+  if (!_process_strong_tasks.is_task_claimed(G1RP_PS_weakProcessor_oops_do)) {
+    WeakProcessor::oops_do(oops);
+  }
+}
+
 uint G1RootProcessor::n_workers() const {
   return _srs.n_threads();
 }
--- a/src/hotspot/share/gc/g1/g1RootProcessor.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -65,6 +65,7 @@
     G1RP_PS_aot_oops_do,
     G1RP_PS_filter_satb_buffers,
     G1RP_PS_refProcessor_oops_do,
+    G1RP_PS_weakProcessor_oops_do,
     // Leave this one last.
     G1RP_PS_NumElements
   };
@@ -118,6 +119,10 @@
                                          CLDClosure* clds,
                                          CodeBlobClosure* blobs);
 
+  // Apply closure to weak roots in the system. Used during the adjust phase
+  // for the Full GC.
+  void process_full_gc_weak_roots(OopClosure* oops);
+
   // Number of worker threads used by the root processor.
   uint n_workers() const;
 };
--- a/src/hotspot/share/gc/g1/g1SerialFullCollector.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/g1/g1CollectedHeap.inline.hpp"
-#include "gc/g1/g1FullGCScope.hpp"
-#include "gc/g1/g1MarkSweep.hpp"
-#include "gc/g1/g1RemSet.inline.hpp"
-#include "gc/g1/g1SerialFullCollector.hpp"
-#include "gc/g1/heapRegionRemSet.hpp"
-#include "gc/shared/referenceProcessor.hpp"
-
-G1SerialFullCollector::G1SerialFullCollector(G1FullGCScope* scope,
-                                             ReferenceProcessor* reference_processor) :
-    _scope(scope),
-    _reference_processor(reference_processor),
-    _is_alive_mutator(_reference_processor, NULL),
-    _mt_discovery_mutator(_reference_processor, false) {
-  // Temporarily make discovery by the STW ref processor single threaded (non-MT)
-  // and clear the STW ref processor's _is_alive_non_header field.
-}
-
-void G1SerialFullCollector::prepare_collection() {
-  _reference_processor->enable_discovery();
-  _reference_processor->setup_policy(_scope->should_clear_soft_refs());
-}
-
-void G1SerialFullCollector::complete_collection() {
-  // Enqueue any discovered reference objects that have
-  // not been removed from the discovered lists.
-  ReferenceProcessorPhaseTimes pt(NULL, _reference_processor->num_q());
-  _reference_processor->enqueue_discovered_references(NULL, &pt);
-  pt.print_enqueue_phase();
-
-  // Iterate the heap and rebuild the remembered sets.
-  rebuild_remembered_sets();
-}
-
-void G1SerialFullCollector::collect() {
-  // Do the actual collection work.
-  G1MarkSweep::invoke_at_safepoint(_reference_processor, _scope->should_clear_soft_refs());
-}
-
-class PostMCRemSetClearClosure: public HeapRegionClosure {
-  G1CollectedHeap* _g1h;
-  ModRefBarrierSet* _mr_bs;
-public:
-  PostMCRemSetClearClosure(G1CollectedHeap* g1h, ModRefBarrierSet* mr_bs) :
-    _g1h(g1h), _mr_bs(mr_bs) {}
-
-  bool doHeapRegion(HeapRegion* r) {
-    HeapRegionRemSet* hrrs = r->rem_set();
-
-    _g1h->reset_gc_time_stamps(r);
-
-    if (r->is_continues_humongous()) {
-      // We'll assert that the strong code root list and RSet is empty
-      assert(hrrs->strong_code_roots_list_length() == 0, "sanity");
-      assert(hrrs->occupied() == 0, "RSet should be empty");
-    } else {
-      hrrs->clear();
-    }
-    // You might think here that we could clear just the cards
-    // corresponding to the used region.  But no: if we leave a dirty card
-    // in a region we might allocate into, then it would prevent that card
-    // from being enqueued, and cause it to be missed.
-    // Re: the performance cost: we shouldn't be doing full GC anyway!
-    _mr_bs->clear(MemRegion(r->bottom(), r->end()));
-
-    return false;
-  }
-};
-
-
-class RebuildRSOutOfRegionClosure: public HeapRegionClosure {
-  G1CollectedHeap*   _g1h;
-  RebuildRSOopClosure _cl;
-public:
-  RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, uint worker_i = 0) :
-    _cl(g1->g1_rem_set(), worker_i),
-    _g1h(g1)
-  { }
-
-  bool doHeapRegion(HeapRegion* r) {
-    if (!r->is_continues_humongous()) {
-      _cl.set_from(r);
-      r->oop_iterate(&_cl);
-    }
-    return false;
-  }
-};
-
-class ParRebuildRSTask: public AbstractGangTask {
-  G1CollectedHeap* _g1;
-  HeapRegionClaimer _hrclaimer;
-
-public:
-  ParRebuildRSTask(G1CollectedHeap* g1) :
-      AbstractGangTask("ParRebuildRSTask"), _g1(g1), _hrclaimer(g1->workers()->active_workers()) {}
-
-  void work(uint worker_id) {
-    RebuildRSOutOfRegionClosure rebuild_rs(_g1, worker_id);
-    _g1->heap_region_par_iterate(&rebuild_rs, worker_id, &_hrclaimer);
-  }
-};
-
-void G1SerialFullCollector::rebuild_remembered_sets() {
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  // First clear the stale remembered sets.
-  PostMCRemSetClearClosure rs_clear(g1h, g1h->g1_barrier_set());
-  g1h->heap_region_iterate(&rs_clear);
-
-  // Rebuild remembered sets of all regions.
-  uint n_workers = AdaptiveSizePolicy::calc_active_workers(g1h->workers()->total_workers(),
-                                                           g1h->workers()->active_workers(),
-                                                           Threads::number_of_non_daemon_threads());
-  g1h->workers()->update_active_workers(n_workers);
-  log_info(gc,task)("Using %u workers of %u to rebuild remembered set", n_workers, g1h->workers()->total_workers());
-
-  ParRebuildRSTask rebuild_rs_task(g1h);
-  g1h->workers()->run_task(&rebuild_rs_task);
-}
--- a/src/hotspot/share/gc/g1/g1SerialFullCollector.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_G1_G1SERIALCOLLECTOR_HPP
-#define SHARE_VM_GC_G1_G1SERIALCOLLECTOR_HPP
-
-#include "memory/allocation.hpp"
-
-class G1FullGCScope;
-class ReferenceProcessor;
-
-class G1SerialFullCollector : StackObj {
-  G1FullGCScope*                       _scope;
-  ReferenceProcessor*                  _reference_processor;
-  ReferenceProcessorIsAliveMutator     _is_alive_mutator;
-  ReferenceProcessorMTDiscoveryMutator _mt_discovery_mutator;
-
-  void rebuild_remembered_sets();
-
-public:
-  G1SerialFullCollector(G1FullGCScope* scope, ReferenceProcessor* reference_processor);
-
-  void prepare_collection();
-  void collect();
-  void complete_collection();
-};
-
-#endif // SHARE_VM_GC_G1_G1SERIALCOLLECTOR_HPP
--- a/src/hotspot/share/gc/g1/g1StringDedup.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1StringDedup.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -65,10 +65,10 @@
   return false;
 }
 
-void G1StringDedup::enqueue_from_mark(oop java_string) {
+void G1StringDedup::enqueue_from_mark(oop java_string, uint worker_id) {
   assert(is_enabled(), "String deduplication not enabled");
   if (is_candidate_from_mark(java_string)) {
-    G1StringDedupQueue::push(0 /* worker_id */, java_string);
+    G1StringDedupQueue::push(worker_id, java_string);
   }
 }
 
--- a/src/hotspot/share/gc/g1/g1StringDedup.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1StringDedup.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -125,7 +125,7 @@
   // Enqueues a deduplication candidate for later processing by the deduplication
   // thread. Before enqueuing, these functions apply the appropriate candidate
   // selection policy to filters out non-candidates.
-  static void enqueue_from_mark(oop java_string);
+  static void enqueue_from_mark(oop java_string, uint worker_id);
   static void enqueue_from_evacuation(bool from_young, bool to_young,
                                       unsigned int queue, oop java_string);
 
--- a/src/hotspot/share/gc/g1/g1_specialized_oop_closures.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/g1_specialized_oop_closures.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -41,6 +41,9 @@
 class G1CMOopClosure;
 class G1RootRegionScanClosure;
 
+class G1MarkAndPushClosure;
+class G1AdjustAndRebuildClosure;
+
 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1(f) \
       f(G1ScanEvacuatedObjClosure,_nv)             \
       f(G1ScanObjsDuringUpdateRSClosure,_nv)       \
@@ -49,4 +52,8 @@
       f(G1CMOopClosure,_nv)                        \
       f(G1RootRegionScanClosure,_nv)
 
+#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1FULL(f) \
+      f(G1MarkAndPushClosure,_nv)                      \
+      f(G1AdjustAndRebuildClosure,_nv)
+
 #endif // SHARE_VM_GC_G1_G1_SPECIALIZED_OOP_CLOSURES_HPP
--- a/src/hotspot/share/gc/g1/heapRegion.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/heapRegion.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -42,6 +42,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/orderAccess.inline.hpp"
+#include "utilities/growableArray.hpp"
 
 int    HeapRegion::LogOfHRGrainBytes = 0;
 int    HeapRegion::LogOfHRGrainWords = 0;
@@ -106,14 +107,6 @@
   }
 }
 
-void HeapRegion::reset_after_compaction() {
-  G1ContiguousSpace::reset_after_compaction();
-  // After a compaction the mark bitmap is invalid, so we must
-  // treat all objects as being inside the unmarked area.
-  zero_marked_bytes();
-  init_top_at_mark_start();
-}
-
 void HeapRegion::hr_clear(bool keep_remset, bool clear_space, bool locked) {
   assert(_humongous_start_region == NULL,
          "we should have already filtered out humongous regions");
@@ -278,10 +271,6 @@
                                             (uint)allocation_context());
 }
 
-CompactibleSpace* HeapRegion::next_compaction_space() const {
-  return G1CollectedHeap::heap()->next_compaction_region(this);
-}
-
 void HeapRegion::note_self_forwarding_removal_start(bool during_initial_mark,
                                                     bool during_conc_mark) {
   // We always recreate the prev marking info and we'll explicitly
@@ -411,7 +400,7 @@
     // We're not verifying code roots.
     return;
   }
-  if (vo == VerifyOption_G1UseMarkWord) {
+  if (vo == VerifyOption_G1UseFullMarking) {
     // Marking verification during a full GC is performed after class
     // unloading, code cache unloading, etc so the strong code roots
     // attached to each heap region are in an inconsistent state. They won't
@@ -482,7 +471,7 @@
 public:
   // _vo == UsePrevMarking -> use "prev" marking information,
   // _vo == UseNextMarking -> use "next" marking information,
-  // _vo == UseMarkWord    -> use mark word from object header.
+  // _vo == UseFullMarking -> use "next" marking bitmap but no TAMS.
   G1VerificationClosure(G1CollectedHeap* g1h, VerifyOption vo) :
     _g1h(g1h), _bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())),
     _containing_obj(NULL), _failures(false), _n_failures(0), _vo(vo) {
@@ -833,7 +822,8 @@
 }
 
 void HeapRegion::prepare_for_compaction(CompactPoint* cp) {
-  scan_and_forward(this, cp);
+  // Not used for G1 anymore, but pure virtual in Space.
+  ShouldNotReachHere();
 }
 
 // G1OffsetTableContigSpace code; copied from space.cpp.  Hope this can go
--- a/src/hotspot/share/gc/g1/heapRegion.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/heapRegion.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -57,6 +57,7 @@
 
 class G1CollectedHeap;
 class G1CMBitMap;
+class G1IsAliveAndApplyClosure;
 class HeapRegionRemSet;
 class HeapRegionRemSetIterator;
 class HeapRegion;
@@ -355,8 +356,14 @@
   // and the amount of unallocated words if called on top()
   size_t block_size(const HeapWord* p) const;
 
+  // Scans through the region using the bitmap to determine what
+  // objects to call size_t ApplyToMarkedClosure::apply(oop) for.
+  template<typename ApplyToMarkedClosure>
+  inline void apply_to_marked_objects(G1CMBitMap* bitmap, ApplyToMarkedClosure* closure);
   // Override for scan_and_forward support.
   void prepare_for_compaction(CompactPoint* cp);
+  // Update heap region to be consistent after compaction.
+  void complete_compaction();
 
   inline HeapWord* par_allocate_no_bot_updates(size_t min_word_size, size_t desired_word_size, size_t* word_size);
   inline HeapWord* allocate_no_bot_updates(size_t word_size);
@@ -672,10 +679,6 @@
     _predicted_elapsed_time_ms = ms;
   }
 
-  virtual CompactibleSpace* next_compaction_space() const;
-
-  virtual void reset_after_compaction();
-
   // Routines for managing a list of code roots (attached to the
   // this region's RSet) that point into this heap region.
   void add_strong_code_root(nmethod* nm);
@@ -693,9 +696,9 @@
   void print() const;
   void print_on(outputStream* st) const;
 
-  // vo == UsePrevMarking  -> use "prev" marking information,
+  // vo == UsePrevMarking -> use "prev" marking information,
   // vo == UseNextMarking -> use "next" marking information
-  // vo == UseMarkWord    -> use the mark word in the object header
+  // vo == UseFullMarking -> use "next" marking bitmap but no TAMS
   //
   // NOTE: Only the "prev" marking information is guaranteed to be
   // consistent most of the time, so most calls to this should use
@@ -704,7 +707,7 @@
   // vo == UseNextMarking, which is to verify the "next" marking
   // information at the end of remark.
   // Currently there is only one place where this is called with
-  // vo == UseMarkWord, which is to verify the marking during a
+  // vo == UseFullMarking, which is to verify the marking during a
   // full GC.
   void verify(VerifyOption vo, bool *failures) const;
 
--- a/src/hotspot/share/gc/g1/heapRegion.inline.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/heapRegion.inline.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -27,10 +27,12 @@
 
 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "gc/shared/space.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/prefetch.inline.hpp"
 #include "utilities/align.hpp"
 
 inline HeapWord* G1ContiguousSpace::allocate_impl(size_t min_word_size,
@@ -180,6 +182,45 @@
   return block_size_using_bitmap(addr, G1CollectedHeap::heap()->concurrent_mark()->prev_mark_bitmap());
 }
 
+inline void HeapRegion::complete_compaction() {
+  // Reset space and bot after compaction is complete if needed.
+  reset_after_compaction();
+  if (used_region().is_empty()) {
+    reset_bot();
+  }
+
+  // After a compaction the mark bitmap is invalid, so we must
+  // treat all objects as being inside the unmarked area.
+  zero_marked_bytes();
+  init_top_at_mark_start();
+
+  // Clear unused heap memory in debug builds.
+  if (ZapUnusedHeapArea) {
+    mangle_unused_area();
+  }
+}
+
+template<typename ApplyToMarkedClosure>
+inline void HeapRegion::apply_to_marked_objects(G1CMBitMap* bitmap, ApplyToMarkedClosure* closure) {
+  HeapWord* limit = scan_limit();
+  HeapWord* next_addr = bottom();
+
+  while (next_addr < limit) {
+    Prefetch::write(next_addr, PrefetchScanIntervalInBytes);
+    // This explicit is_marked check is a way to avoid
+    // some extra work done by get_next_marked_addr for
+    // the case where next_addr is marked.
+    if (bitmap->is_marked(next_addr)) {
+      oop current = oop(next_addr);
+      next_addr += closure->apply(current);
+    } else {
+      next_addr = bitmap->get_next_marked_addr(next_addr, limit);
+    }
+  }
+
+  assert(next_addr == limit, "Should stop the scan at the limit.");
+}
+
 inline HeapWord* HeapRegion::par_allocate_no_bot_updates(size_t min_word_size,
                                                          size_t desired_word_size,
                                                          size_t* actual_word_size) {
--- a/src/hotspot/share/gc/g1/heapRegionManager.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -327,9 +327,7 @@
   return true;
 }
 
-void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const {
-  const uint start_index = hrclaimer->start_region_for_worker(worker_id);
-
+void HeapRegionManager::par_iterate(HeapRegionClosure* blk, HeapRegionClaimer* hrclaimer, const uint start_index) const {
   // Every worker will actually look at all regions, skipping over regions that
   // are currently not committed.
   // This also (potentially) iterates over regions newly allocated during GC. This
@@ -493,7 +491,7 @@
   }
 }
 
-uint HeapRegionClaimer::start_region_for_worker(uint worker_id) const {
+uint HeapRegionClaimer::offset_for_worker(uint worker_id) const {
   assert(worker_id < _n_workers, "Invalid worker_id.");
   return _n_regions * worker_id / _n_workers;
 }
--- a/src/hotspot/share/gc/g1/heapRegionManager.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/g1/heapRegionManager.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -189,7 +189,7 @@
     return _free_list.length();
   }
 
-  size_t total_capacity_bytes() const {
+  size_t total_free_bytes() const {
     return num_free_regions() * HeapRegion::GrainBytes;
   }
 
@@ -240,7 +240,7 @@
   // terminating the iteration early if doHeapRegion() returns true.
   void iterate(HeapRegionClosure* blk) const;
 
-  void par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const;
+  void par_iterate(HeapRegionClosure* blk, HeapRegionClaimer* hrclaimer, const uint start_index) const;
 
   // Uncommit up to num_regions_to_remove regions that are completely free.
   // Return the actual number of uncommitted regions.
@@ -274,9 +274,8 @@
     return _n_regions;
   }
 
-  // Calculate the starting region for given worker so
-  // that they do not all start from the same region.
-  uint start_region_for_worker(uint worker_id) const;
+  // Return a start offset given a worker id.
+  uint offset_for_worker(uint worker_id) const;
 
   // Check if region has been claimed with this HRClaimer.
   bool is_region_claimed(uint region_index) const;
--- a/src/hotspot/share/gc/serial/markSweep.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/serial/markSweep.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -65,13 +65,6 @@
 CLDToOopClosure               MarkSweep::adjust_cld_closure(&adjust_pointer_closure);
 
 inline void MarkSweep::mark_object(oop obj) {
-#if INCLUDE_ALL_GCS
-  if (G1StringDedup::is_enabled()) {
-    // We must enqueue the object before it is marked
-    // as we otherwise can't read the object's age.
-    G1StringDedup::enqueue_from_mark(obj);
-  }
-#endif
   // 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 markSweep.
   markOop mark = obj->mark();
--- a/src/hotspot/share/gc/shared/gcName.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/shared/gcName.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
   G1New,
   ConcurrentMarkSweep,
   G1Old,
+  G1Full,
   GCNameEndSentinel
 };
 
@@ -53,6 +54,7 @@
       case G1New: return "G1New";
       case ConcurrentMarkSweep: return "ConcurrentMarkSweep";
       case G1Old: return "G1Old";
+      case G1Full: return "G1Full";
       default: ShouldNotReachHere(); return NULL;
     }
   }
--- a/src/hotspot/share/gc/shared/gcTrace.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/shared/gcTrace.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -289,6 +289,12 @@
                                      double predicted_marking_length,
                                      bool prediction_active);
 };
+
+class G1FullGCTracer : public OldGCTracer {
+ public:
+  G1FullGCTracer() : OldGCTracer(G1Full) {}
+};
+
 #endif
 
 class CMSTracer : public OldGCTracer {
--- a/src/hotspot/share/gc/shared/preservedMarks.cpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/shared/preservedMarks.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,18 @@
   assert_empty();
 }
 
+void PreservedMarks::adjust_during_full_gc() {
+  StackIterator<OopAndMarkOop, mtGC> iter(_stack);
+  while (!iter.is_empty()) {
+    OopAndMarkOop* elem = iter.next_addr();
+
+    oop obj = elem->get_oop();
+    if (obj->is_forwarded()) {
+      elem->set_oop(obj->forwardee());
+    }
+  }
+}
+
 void PreservedMarks::restore_and_increment(volatile size_t* const total_size_addr) {
   const size_t stack_size = size();
   restore();
@@ -104,7 +116,6 @@
   }
 };
 
-
 void PreservedMarksSet::reclaim() {
   assert_empty();
 
--- a/src/hotspot/share/gc/shared/preservedMarks.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/shared/preservedMarks.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,7 @@
 
 class PreservedMarks VALUE_OBJ_CLASS_SPEC {
 private:
-  class OopAndMarkOop {
+  class OopAndMarkOop VALUE_OBJ_CLASS_SPEC {
   private:
     oop _o;
     markOop _m;
@@ -43,23 +43,26 @@
   public:
     OopAndMarkOop(oop obj, markOop m) : _o(obj), _m(m) { }
 
-    void set_mark() const {
-      _o->set_mark(_m);
-    }
+    oop get_oop() { return _o; }
+    void set_mark() const { _o->set_mark(_m); }
+    void set_oop(oop obj) { _o = obj; }
   };
   typedef Stack<OopAndMarkOop, mtGC> OopAndMarkOopStack;
 
   OopAndMarkOopStack _stack;
 
   inline bool should_preserve_mark(oop obj, markOop m) const;
-  inline void push(oop obj, markOop m);
 
 public:
   size_t size() const { return _stack.size(); }
+  inline void push(oop obj, markOop m);
   inline void push_if_necessary(oop obj, markOop m);
   // Iterate over the stack, restore all preserved marks, and
   // reclaim the memory taken up by the stack segments.
   void restore();
+  // Iterate over the stack, adjust all preserved marks according
+  // to their forwarding location stored in the mark.
+  void adjust_during_full_gc();
 
   void restore_and_increment(volatile size_t* const _total_size_addr);
   inline static void init_forwarded_mark(oop obj);
--- a/src/hotspot/share/gc/shared/specialized_oop_closures.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/shared/specialized_oop_closures.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -110,7 +110,8 @@
 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f)       \
   SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_MS(f)            \
   SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_CMS(f)           \
-  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1(f)
+  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1(f)            \
+  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1FULL(f)
 #else  // INCLUDE_ALL_GCS
 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f)       \
   SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_MS(f)
--- a/src/hotspot/share/gc/shared/taskqueue.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/shared/taskqueue.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -369,6 +369,7 @@
   typedef typename T::element_type E;
 
   GenericTaskQueueSet(int n);
+  ~GenericTaskQueueSet();
 
   bool steal_best_of_2(uint queue_num, int* seed, E& t);
 
--- a/src/hotspot/share/gc/shared/taskqueue.inline.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/gc/shared/taskqueue.inline.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -42,6 +42,11 @@
   }
 }
 
+template <class T, MEMFLAGS F>
+inline GenericTaskQueueSet<T, F>::~GenericTaskQueueSet() {
+  FREE_C_HEAP_ARRAY(T*, _queues);
+}
+
 template<class E, MEMFLAGS F, unsigned int N>
 inline void GenericTaskQueue<E, F, N>::initialize() {
   _elems = ArrayAllocator<E>::allocate(N, F);
@@ -49,7 +54,6 @@
 
 template<class E, MEMFLAGS F, unsigned int N>
 inline GenericTaskQueue<E, F, N>::~GenericTaskQueue() {
-  assert(false, "This code is currently never called");
   ArrayAllocator<E>::free(const_cast<E*>(_elems), N);
 }
 
--- a/src/hotspot/share/memory/universe.hpp	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/hotspot/share/memory/universe.hpp	Tue Nov 14 11:33:23 2017 +0100
@@ -90,7 +90,7 @@
       // G1
       VerifyOption_G1UsePrevMarking = VerifyOption_Default,
       VerifyOption_G1UseNextMarking = VerifyOption_G1UsePrevMarking + 1,
-      VerifyOption_G1UseMarkWord    = VerifyOption_G1UseNextMarking + 1
+      VerifyOption_G1UseFullMarking = VerifyOption_G1UseNextMarking + 1
 };
 
 class Universe: AllStatic {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCName.java	Mon Oct 30 08:34:54 2017 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCName.java	Tue Nov 14 11:33:23 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
   G1New ("G1New"),
   ConcurrentMarkSweep ("ConcurrentMarkSweep"),
   G1Old ("G1Old"),
+  G1Full ("G1Full"),
   GCNameEndSentinel ("GCNameEndSentinel");
 
   private final String value;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/g1/test_heapRegion.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1BlockOffsetTable.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
+#include "gc/g1/heapRegion.inline.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "unittest.hpp"
+
+class VerifyAndCountMarkClosure : public StackObj {
+  int _count;
+  G1CMBitMap* _bm;
+
+  void ensure_marked(HeapWord* addr) {
+    ASSERT_TRUE(_bm->is_marked(addr));
+  }
+
+public:
+  VerifyAndCountMarkClosure(G1CMBitMap* bm) : _count(0), _bm(bm) { }
+
+  virtual size_t apply(oop object) {
+    _count++;
+    ensure_marked((HeapWord*) object);
+    // Must return positive size to advance the iteration.
+    return MinObjAlignment;
+  }
+
+  void reset() {
+    _count = 0;
+  }
+
+  int count() {
+    return _count;
+  }
+};
+
+#define MARK_OFFSET_1 ( 17 * MinObjAlignment)
+#define MARK_OFFSET_2 ( 99 * MinObjAlignment)
+#define MARK_OFFSET_3 (337 * MinObjAlignment)
+
+TEST_OTHER_VM(HeapRegion, apply_to_marked_objects) {
+  if (!UseG1GC) {
+    return;
+  }
+
+  G1CollectedHeap* heap = G1CollectedHeap::heap();
+
+  // Using region 0 for testing.
+  HeapRegion* region = heap->heap_region_containing(heap->bottom_addr_for_region(0));
+
+  // Mark some "oops" in the bitmap.
+  G1CMBitMap* bitmap = heap->concurrent_mark()->next_mark_bitmap();
+  bitmap->mark(region->bottom());
+  bitmap->mark(region->bottom() + MARK_OFFSET_1);
+  bitmap->mark(region->bottom() + MARK_OFFSET_2);
+  bitmap->mark(region->bottom() + MARK_OFFSET_3);
+  bitmap->mark(region->end());
+
+  VerifyAndCountMarkClosure cl(bitmap);
+
+  // When top is equal to bottom the closure should not be
+  // applied to any object because apply_to_marked_objects
+  // will stop at HeapRegion::scan_limit which is equal to top.
+  region->set_top(region->bottom());
+  region->apply_to_marked_objects(bitmap, &cl);
+  EXPECT_EQ(0, cl.count());
+  cl.reset();
+
+  // Set top to offset_1 and expect only to find 1 entry (bottom)
+  region->set_top(region->bottom() + MARK_OFFSET_1);
+  region->apply_to_marked_objects(bitmap, &cl);
+  EXPECT_EQ(1, cl.count());
+  cl.reset();
+
+  // Set top to (offset_2 + 1) and expect only to find 3
+  // entries (bottom, offset_1 and offset_2)
+  region->set_top(region->bottom() + MARK_OFFSET_2 + MinObjAlignment);
+  region->apply_to_marked_objects(bitmap, &cl);
+  EXPECT_EQ(3, cl.count());
+  cl.reset();
+
+  // Still expect same 3 entries when top is (offset_3 - 1)
+  region->set_top(region->bottom() + MARK_OFFSET_3 - MinObjAlignment);
+  region->apply_to_marked_objects(bitmap, &cl);
+  EXPECT_EQ(3, cl.count());
+  cl.reset();
+
+  // Setting top to end should render 4 entries.
+  region->set_top(region->end());
+  region->apply_to_marked_objects(bitmap, &cl);
+  EXPECT_EQ(4, cl.count());
+  cl.reset();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/shared/test_preservedMarks.cpp	Tue Nov 14 11:33:23 2017 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/preservedMarks.inline.hpp"
+#include "unittest.hpp"
+
+class ScopedDisabledBiasedLocking {
+  bool _orig;
+public:
+  ScopedDisabledBiasedLocking() : _orig(UseBiasedLocking) { UseBiasedLocking = false; }
+  ~ScopedDisabledBiasedLocking() { UseBiasedLocking = _orig; }
+};
+
+// Class to create a "fake" oop with a mark that will
+// return true for calls to must_be_preserved().
+class FakeOop {
+  oopDesc _oop;
+
+public:
+  FakeOop() : _oop() { _oop.set_mark(originalMark()); }
+
+  oop get_oop() { return &_oop; }
+  markOop mark() { return _oop.mark(); }
+  void set_mark(markOop m) { _oop.set_mark(m); }
+  void forward_to(oop obj) {
+    markOop m = markOopDesc::encode_pointer_as_mark(obj);
+    _oop.set_mark(m);
+  }
+
+  static markOop originalMark() { return markOop(markOopDesc::lock_mask_in_place); }
+  static markOop changedMark()  { return markOop(0x4711); }
+};
+
+TEST_VM(PreservedMarks, iterate_and_restore) {
+  // Need to disable biased locking to easily
+  // create oops that "must_be_preseved"
+  ScopedDisabledBiasedLocking dbl;
+
+  PreservedMarks pm;
+  FakeOop o1;
+  FakeOop o2;
+  FakeOop o3;
+  FakeOop o4;
+
+  // Make sure initial marks are correct.
+  ASSERT_EQ(o1.mark(), FakeOop::originalMark());
+  ASSERT_EQ(o2.mark(), FakeOop::originalMark());
+  ASSERT_EQ(o3.mark(), FakeOop::originalMark());
+  ASSERT_EQ(o4.mark(), FakeOop::originalMark());
+
+  // Change the marks and verify change.
+  o1.set_mark(FakeOop::changedMark());
+  o2.set_mark(FakeOop::changedMark());
+  ASSERT_EQ(o1.mark(), FakeOop::changedMark());
+  ASSERT_EQ(o2.mark(), FakeOop::changedMark());
+
+  // Push o1 and o2 to have their marks preserved.
+  pm.push(o1.get_oop(), o1.mark());
+  pm.push(o2.get_oop(), o2.mark());
+
+  // Fake a move from o1->o3 and o2->o4.
+  o1.forward_to(o3.get_oop());
+  o2.forward_to(o4.get_oop());
+  ASSERT_EQ(o1.get_oop()->forwardee(), o3.get_oop());
+  ASSERT_EQ(o2.get_oop()->forwardee(), o4.get_oop());
+  // Adjust will update the PreservedMarks stack to
+  // make sure the mark is updated at the new location.
+  pm.adjust_during_full_gc();
+
+  // Restore all preserved and verify that the changed
+  // mark is now present at o3 and o4.
+  pm.restore();
+  ASSERT_EQ(o3.mark(), FakeOop::changedMark());
+  ASSERT_EQ(o4.mark(), FakeOop::changedMark());
+}
--- a/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java	Mon Oct 30 08:34:54 2017 +0100
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java	Tue Nov 14 11:33:23 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -156,8 +156,9 @@
             if (args.length != 3) {
                 throw new IllegalArgumentException("Expected 3 args: <minRatio> <maxRatio> <shrinkHeapInSteps>");
             }
-            if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.PSOld) {
-                System.out.println("Test is not applicable to parallel GC");
+            if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.PSOld ||
+                GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.G1) {
+                System.out.println("Test is not applicable to parallel full GCs");
                 return;
             }