hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp
changeset 38162 4e2c3433a3ae
parent 38155 a4501a2965dc
child 38177 b0c9cb06506b
child 38183 cb68e4923223
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Mon May 02 12:44:25 2016 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Wed Apr 27 16:11:45 2016 +0200
@@ -57,6 +57,7 @@
 #include "runtime/java.hpp"
 #include "runtime/prefetch.inline.hpp"
 #include "services/memTracker.hpp"
+#include "utilities/growableArray.hpp"
 
 // Concurrent marking bit map wrapper
 
@@ -261,7 +262,7 @@
 
 G1CMRootRegions::G1CMRootRegions() :
   _young_list(NULL), _cm(NULL), _scan_in_progress(false),
-  _should_abort(false),  _next_survivor(NULL) { }
+  _should_abort(false), _claimed_survivor_index(0) { }
 
 void G1CMRootRegions::init(G1CollectedHeap* g1h, G1ConcurrentMark* cm) {
   _young_list = g1h->young_list();
@@ -272,9 +273,8 @@
   assert(!scan_in_progress(), "pre-condition");
 
   // Currently, only survivors can be root regions.
-  assert(_next_survivor == NULL, "pre-condition");
-  _next_survivor = _young_list->first_survivor_region();
-  _scan_in_progress = (_next_survivor != NULL);
+  _claimed_survivor_index = 0;
+  _scan_in_progress = true;
   _should_abort = false;
 }
 
@@ -286,27 +286,13 @@
   }
 
   // Currently, only survivors can be root regions.
-  HeapRegion* res = _next_survivor;
-  if (res != NULL) {
-    MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag);
-    // Read it again in case it changed while we were waiting for the lock.
-    res = _next_survivor;
-    if (res != NULL) {
-      if (res == _young_list->last_survivor_region()) {
-        // We just claimed the last survivor so store NULL to indicate
-        // that we're done.
-        _next_survivor = NULL;
-      } else {
-        _next_survivor = res->get_next_young_region();
-      }
-    } else {
-      // Someone else claimed the last survivor while we were trying
-      // to take the lock so nothing else to do.
-    }
+  const GrowableArray<HeapRegion*>* survivor_regions = _young_list->survivor_regions();
+
+  int claimed_index = Atomic::add(1, &_claimed_survivor_index) - 1;
+  if (claimed_index < survivor_regions->length()) {
+    return survivor_regions->at(claimed_index);
   }
-  assert(res == NULL || res->is_survivor(), "post-condition");
-
-  return res;
+  return NULL;
 }
 
 void G1CMRootRegions::notify_scan_done() {
@@ -324,9 +310,10 @@
 
   // Currently, only survivors can be root regions.
   if (!_should_abort) {
-    assert(_next_survivor == NULL, "we should have claimed all survivors");
+    assert(_claimed_survivor_index >= _young_list->survivor_regions()->length(),
+           "we should have claimed all survivors, claimed index = %d, length = %d",
+           _claimed_survivor_index, _young_list->survivor_regions()->length());
   }
-  _next_survivor = NULL;
 
   notify_scan_done();
 }