1203 report_object_count(mark_finished);
1204 }
1205
1206 // Statistics
1207 double now = os::elapsedTime();
1208 _remark_mark_times.add((mark_work_end - start) * 1000.0);
1209 _remark_weak_ref_times.add((now - mark_work_end) * 1000.0);
1210 _remark_times.add((now - start) * 1000.0);
1211
1212 g1p->record_concurrent_mark_remark_end();
1213 }
1214
1215 class G1ReclaimEmptyRegionsTask : public AbstractGangTask {
1216 // Per-region work during the Cleanup pause.
1217 class G1ReclaimEmptyRegionsClosure : public HeapRegionClosure {
1218 G1CollectedHeap* _g1h;
1219 size_t _freed_bytes;
1220 FreeRegionList* _local_cleanup_list;
1221 uint _old_regions_removed;
1222 uint _humongous_regions_removed;
1223 HRRSCleanupTask* _hrrs_cleanup_task;
1224
1225 public:
1226 G1ReclaimEmptyRegionsClosure(G1CollectedHeap* g1h,
1227 FreeRegionList* local_cleanup_list,
1228 HRRSCleanupTask* hrrs_cleanup_task) :
1229 _g1h(g1h),
1230 _freed_bytes(0),
1231 _local_cleanup_list(local_cleanup_list),
1232 _old_regions_removed(0),
1233 _humongous_regions_removed(0),
1234 _hrrs_cleanup_task(hrrs_cleanup_task) { }
1235
1236 size_t freed_bytes() { return _freed_bytes; }
1237 const uint old_regions_removed() { return _old_regions_removed; }
1238 const uint humongous_regions_removed() { return _humongous_regions_removed; }
1239
1240 bool do_heap_region(HeapRegion *hr) {
1241 if (hr->used() > 0 && hr->max_live_bytes() == 0 && !hr->is_young() && !hr->is_archive()) {
1242 _freed_bytes += hr->used();
1243 hr->set_containing_set(NULL);
1244 if (hr->is_humongous()) {
1245 _humongous_regions_removed++;
1246 _g1h->free_humongous_region(hr, _local_cleanup_list);
1247 } else {
1248 _old_regions_removed++;
1249 _g1h->free_region(hr, _local_cleanup_list, false /* skip_remset */, false /* skip_hcc */, true /* locked */);
1250 }
1251 hr->clear_cardtable();
1252 _g1h->concurrent_mark()->clear_statistics_in_region(hr->hrm_index());
1253 log_trace(gc)("Reclaimed empty region %u (%s) bot " PTR_FORMAT, hr->hrm_index(), hr->get_short_type_str(), p2i(hr->bottom()));
1254 } else {
1255 hr->rem_set()->do_cleanup_work(_hrrs_cleanup_task);
1256 }
1257
1258 return false;
1259 }
1260 };
1261
1262 G1CollectedHeap* _g1h;
1263 FreeRegionList* _cleanup_list;
1264 HeapRegionClaimer _hrclaimer;
1265
1266 public:
1267 G1ReclaimEmptyRegionsTask(G1CollectedHeap* g1h, FreeRegionList* cleanup_list, uint n_workers) :
1268 AbstractGangTask("G1 Cleanup"),
1269 _g1h(g1h),
1270 _cleanup_list(cleanup_list),
1271 _hrclaimer(n_workers) {
1272
1273 HeapRegionRemSet::reset_for_cleanup_tasks();
1274 }
1275
1276 void work(uint worker_id) {
1277 FreeRegionList local_cleanup_list("Local Cleanup List");
1278 HRRSCleanupTask hrrs_cleanup_task;
1279 G1ReclaimEmptyRegionsClosure cl(_g1h,
1280 &local_cleanup_list,
1281 &hrrs_cleanup_task);
1282 _g1h->heap_region_par_iterate_from_worker_offset(&cl, &_hrclaimer, worker_id);
1283 assert(cl.is_complete(), "Shouldn't have aborted!");
1284
1285 // Now update the old/humongous region sets
1286 _g1h->remove_from_old_sets(cl.old_regions_removed(), cl.humongous_regions_removed());
1287 {
1288 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
1289 _g1h->decrement_summary_bytes(cl.freed_bytes());
1290
1291 _cleanup_list->add_ordered(&local_cleanup_list);
1292 assert(local_cleanup_list.is_empty(), "post-condition");
1293
1294 HeapRegionRemSet::finish_cleanup_task(&hrrs_cleanup_task);
1295 }
1296 }
1297 };
1298
1299 void G1ConcurrentMark::reclaim_empty_regions() {
1300 WorkGang* workers = _g1h->workers();
1301 FreeRegionList empty_regions_list("Empty Regions After Mark List");
1302
1303 G1ReclaimEmptyRegionsTask cl(_g1h, &empty_regions_list, workers->active_workers());
1304 workers->run_task(&cl);
1305
1306 if (!empty_regions_list.is_empty()) {
1307 log_debug(gc)("Reclaimed %u empty regions", empty_regions_list.length());
1308 // Now print the empty regions list.
1309 G1HRPrinter* hrp = _g1h->hr_printer();
1310 if (hrp->is_active()) {
1311 FreeRegionListIterator iter(&empty_regions_list);
1312 while (iter.more_available()) {
1313 HeapRegion* hr = iter.get_next();
1314 hrp->cleanup(hr);
|
1203 report_object_count(mark_finished);
1204 }
1205
1206 // Statistics
1207 double now = os::elapsedTime();
1208 _remark_mark_times.add((mark_work_end - start) * 1000.0);
1209 _remark_weak_ref_times.add((now - mark_work_end) * 1000.0);
1210 _remark_times.add((now - start) * 1000.0);
1211
1212 g1p->record_concurrent_mark_remark_end();
1213 }
1214
1215 class G1ReclaimEmptyRegionsTask : public AbstractGangTask {
1216 // Per-region work during the Cleanup pause.
1217 class G1ReclaimEmptyRegionsClosure : public HeapRegionClosure {
1218 G1CollectedHeap* _g1h;
1219 size_t _freed_bytes;
1220 FreeRegionList* _local_cleanup_list;
1221 uint _old_regions_removed;
1222 uint _humongous_regions_removed;
1223
1224 public:
1225 G1ReclaimEmptyRegionsClosure(G1CollectedHeap* g1h,
1226 FreeRegionList* local_cleanup_list) :
1227 _g1h(g1h),
1228 _freed_bytes(0),
1229 _local_cleanup_list(local_cleanup_list),
1230 _old_regions_removed(0),
1231 _humongous_regions_removed(0) { }
1232
1233 size_t freed_bytes() { return _freed_bytes; }
1234 const uint old_regions_removed() { return _old_regions_removed; }
1235 const uint humongous_regions_removed() { return _humongous_regions_removed; }
1236
1237 bool do_heap_region(HeapRegion *hr) {
1238 if (hr->used() > 0 && hr->max_live_bytes() == 0 && !hr->is_young() && !hr->is_archive()) {
1239 _freed_bytes += hr->used();
1240 hr->set_containing_set(NULL);
1241 if (hr->is_humongous()) {
1242 _humongous_regions_removed++;
1243 _g1h->free_humongous_region(hr, _local_cleanup_list);
1244 } else {
1245 _old_regions_removed++;
1246 _g1h->free_region(hr, _local_cleanup_list, false /* skip_remset */, false /* skip_hcc */, true /* locked */);
1247 }
1248 hr->clear_cardtable();
1249 _g1h->concurrent_mark()->clear_statistics_in_region(hr->hrm_index());
1250 log_trace(gc)("Reclaimed empty region %u (%s) bot " PTR_FORMAT, hr->hrm_index(), hr->get_short_type_str(), p2i(hr->bottom()));
1251 }
1252
1253 return false;
1254 }
1255 };
1256
1257 G1CollectedHeap* _g1h;
1258 FreeRegionList* _cleanup_list;
1259 HeapRegionClaimer _hrclaimer;
1260
1261 public:
1262 G1ReclaimEmptyRegionsTask(G1CollectedHeap* g1h, FreeRegionList* cleanup_list, uint n_workers) :
1263 AbstractGangTask("G1 Cleanup"),
1264 _g1h(g1h),
1265 _cleanup_list(cleanup_list),
1266 _hrclaimer(n_workers) {
1267 }
1268
1269 void work(uint worker_id) {
1270 FreeRegionList local_cleanup_list("Local Cleanup List");
1271 G1ReclaimEmptyRegionsClosure cl(_g1h, &local_cleanup_list);
1272 _g1h->heap_region_par_iterate_from_worker_offset(&cl, &_hrclaimer, worker_id);
1273 assert(cl.is_complete(), "Shouldn't have aborted!");
1274
1275 // Now update the old/humongous region sets
1276 _g1h->remove_from_old_sets(cl.old_regions_removed(), cl.humongous_regions_removed());
1277 {
1278 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
1279 _g1h->decrement_summary_bytes(cl.freed_bytes());
1280
1281 _cleanup_list->add_ordered(&local_cleanup_list);
1282 assert(local_cleanup_list.is_empty(), "post-condition");
1283 }
1284 }
1285 };
1286
1287 void G1ConcurrentMark::reclaim_empty_regions() {
1288 WorkGang* workers = _g1h->workers();
1289 FreeRegionList empty_regions_list("Empty Regions After Mark List");
1290
1291 G1ReclaimEmptyRegionsTask cl(_g1h, &empty_regions_list, workers->active_workers());
1292 workers->run_task(&cl);
1293
1294 if (!empty_regions_list.is_empty()) {
1295 log_debug(gc)("Reclaimed %u empty regions", empty_regions_list.length());
1296 // Now print the empty regions list.
1297 G1HRPrinter* hrp = _g1h->hr_printer();
1298 if (hrp->is_active()) {
1299 FreeRegionListIterator iter(&empty_regions_list);
1300 while (iter.more_available()) {
1301 HeapRegion* hr = iter.get_next();
1302 hrp->cleanup(hr);
|