hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp
changeset 27009 e7e723732b6b
parent 26846 7d4376f8560e
child 27880 afb974a04396
child 27885 7786b3940066
equal deleted inserted replaced
27008:10d6c1e39d87 27009:e7e723732b6b
   258          err_msg("The region at the current position %u must be available or at the end of the heap.", cur));
   258          err_msg("The region at the current position %u must be available or at the end of the heap.", cur));
   259 #endif
   259 #endif
   260   return num_regions;
   260   return num_regions;
   261 }
   261 }
   262 
   262 
   263 uint HeapRegionManager::start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const {
   263 void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const {
   264   return num_regions * worker_i / num_workers;
   264   const uint start_index = hrclaimer->start_region_for_worker(worker_id);
   265 }
       
   266 
       
   267 void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num_workers, jint claim_value) const {
       
   268   const uint start_index = start_region_for_worker(worker_id, num_workers, _allocated_heapregions_length);
       
   269 
   265 
   270   // Every worker will actually look at all regions, skipping over regions that
   266   // Every worker will actually look at all regions, skipping over regions that
   271   // are currently not committed.
   267   // are currently not committed.
   272   // This also (potentially) iterates over regions newly allocated during GC. This
   268   // This also (potentially) iterates over regions newly allocated during GC. This
   273   // is no problem except for some extra work.
   269   // is no problem except for some extra work.
   274   for (uint count = 0; count < _allocated_heapregions_length; count++) {
   270   const uint n_regions = hrclaimer->n_regions();
   275     const uint index = (start_index + count) % _allocated_heapregions_length;
   271   for (uint count = 0; count < n_regions; count++) {
   276     assert(0 <= index && index < _allocated_heapregions_length, "sanity");
   272     const uint index = (start_index + count) % n_regions;
       
   273     assert(0 <= index && index < n_regions, "sanity");
   277     // Skip over unavailable regions
   274     // Skip over unavailable regions
   278     if (!is_available(index)) {
   275     if (!is_available(index)) {
   279       continue;
   276       continue;
   280     }
   277     }
   281     HeapRegion* r = _regions.get_by_index(index);
   278     HeapRegion* r = _regions.get_by_index(index);
   282     // We'll ignore "continues humongous" regions (we'll process them
   279     // We'll ignore "continues humongous" regions (we'll process them
   283     // when we come across their corresponding "start humongous"
   280     // when we come across their corresponding "start humongous"
   284     // region) and regions already claimed.
   281     // region) and regions already claimed.
   285     if (r->claim_value() == claim_value || r->is_continues_humongous()) {
   282     if (hrclaimer->is_region_claimed(index) || r->is_continues_humongous()) {
   286       continue;
   283       continue;
   287     }
   284     }
   288     // OK, try to claim it
   285     // OK, try to claim it
   289     if (!r->claimHeapRegion(claim_value)) {
   286     if (!hrclaimer->claim_region(index)) {
   290       continue;
   287       continue;
   291     }
   288     }
   292     // Success!
   289     // Success!
   293     if (r->is_starts_humongous()) {
   290     if (r->is_starts_humongous()) {
   294       // If the region is "starts humongous" we'll iterate over its
   291       // If the region is "starts humongous" we'll iterate over its
   304 
   301 
   305         assert(chr->is_continues_humongous(), "Must be humongous region");
   302         assert(chr->is_continues_humongous(), "Must be humongous region");
   306         assert(chr->humongous_start_region() == r,
   303         assert(chr->humongous_start_region() == r,
   307                err_msg("Must work on humongous continuation of the original start region "
   304                err_msg("Must work on humongous continuation of the original start region "
   308                        PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr)));
   305                        PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr)));
   309         assert(chr->claim_value() != claim_value,
   306         assert(!hrclaimer->is_region_claimed(ch_index),
   310                "Must not have been claimed yet because claiming of humongous continuation first claims the start region");
   307                "Must not have been claimed yet because claiming of humongous continuation first claims the start region");
   311 
   308 
   312         bool claim_result = chr->claimHeapRegion(claim_value);
   309         // There's no need to actually claim the continues humongous region, but we can do it in an assert as an extra precaution.
   313         // We should always be able to claim it; no one else should
   310         assert(hrclaimer->claim_region(ch_index), "We should always be able to claim the continuesHumongous part of the humongous object");
   314         // be trying to claim this region.
       
   315         guarantee(claim_result, "We should always be able to claim the is_continues_humongous part of the humongous object");
       
   316 
   311 
   317         bool res2 = blk->doHeapRegion(chr);
   312         bool res2 = blk->doHeapRegion(chr);
   318         if (res2) {
   313         if (res2) {
   319           return;
   314           return;
   320         }
   315         }
   443 void HeapRegionManager::verify_optional() {
   438 void HeapRegionManager::verify_optional() {
   444   verify();
   439   verify();
   445 }
   440 }
   446 #endif // PRODUCT
   441 #endif // PRODUCT
   447 
   442 
       
   443 HeapRegionClaimer::HeapRegionClaimer(uint n_workers) :
       
   444     _n_workers(n_workers), _n_regions(G1CollectedHeap::heap()->_hrm._allocated_heapregions_length), _claims(NULL) {
       
   445   assert(n_workers > 0, "Need at least one worker.");
       
   446   _claims = NEW_C_HEAP_ARRAY(uint, _n_regions, mtGC);
       
   447   memset(_claims, Unclaimed, sizeof(*_claims) * _n_regions);
       
   448 }
       
   449 
       
   450 HeapRegionClaimer::~HeapRegionClaimer() {
       
   451   if (_claims != NULL) {
       
   452     FREE_C_HEAP_ARRAY(uint, _claims, mtGC);
       
   453   }
       
   454 }
       
   455 
       
   456 uint HeapRegionClaimer::start_region_for_worker(uint worker_id) const {
       
   457   assert(worker_id < _n_workers, "Invalid worker_id.");
       
   458   return _n_regions * worker_id / _n_workers;
       
   459 }
       
   460 
       
   461 bool HeapRegionClaimer::is_region_claimed(uint region_index) const {
       
   462   assert(region_index < _n_regions, "Invalid index.");
       
   463   return _claims[region_index] == Claimed;
       
   464 }
       
   465 
       
   466 bool HeapRegionClaimer::claim_region(uint region_index) {
       
   467   assert(region_index < _n_regions, "Invalid index.");
       
   468   uint old_val = Atomic::cmpxchg(Claimed, &_claims[region_index], Unclaimed);
       
   469   return old_val == Unclaimed;
       
   470 }