88 // apply to TLAB allocation, which is not part of this interface: it |
88 // apply to TLAB allocation, which is not part of this interface: it |
89 // is done by clients of this interface.) |
89 // is done by clients of this interface.) |
90 |
90 |
91 // Notes on implementation of parallelism in different tasks. |
91 // Notes on implementation of parallelism in different tasks. |
92 // |
92 // |
93 // G1ParVerifyTask uses heap_region_par_iterate_chunked() for parallelism. |
93 // G1ParVerifyTask uses heap_region_par_iterate() for parallelism. |
94 // The number of GC workers is passed to heap_region_par_iterate_chunked(). |
94 // The number of GC workers is passed to heap_region_par_iterate(). |
95 // It does use run_task() which sets _n_workers in the task. |
95 // It does use run_task() which sets _n_workers in the task. |
96 // G1ParTask executes g1_process_roots() -> |
96 // G1ParTask executes g1_process_roots() -> |
97 // SharedHeap::process_roots() which calls eventually to |
97 // SharedHeap::process_roots() which calls eventually to |
98 // CardTableModRefBS::par_non_clean_card_iterate_work() which uses |
98 // CardTableModRefBS::par_non_clean_card_iterate_work() which uses |
99 // SequentialSubTasksDone. SharedHeap::process_roots() also |
99 // SequentialSubTasksDone. SharedHeap::process_roots() also |
1213 } |
1213 } |
1214 }; |
1214 }; |
1215 |
1215 |
1216 class ParRebuildRSTask: public AbstractGangTask { |
1216 class ParRebuildRSTask: public AbstractGangTask { |
1217 G1CollectedHeap* _g1; |
1217 G1CollectedHeap* _g1; |
|
1218 HeapRegionClaimer _hrclaimer; |
|
1219 |
1218 public: |
1220 public: |
1219 ParRebuildRSTask(G1CollectedHeap* g1) |
1221 ParRebuildRSTask(G1CollectedHeap* g1) : |
1220 : AbstractGangTask("ParRebuildRSTask"), |
1222 AbstractGangTask("ParRebuildRSTask"), _g1(g1), _hrclaimer(g1->workers()->active_workers()) {} |
1221 _g1(g1) |
|
1222 { } |
|
1223 |
1223 |
1224 void work(uint worker_id) { |
1224 void work(uint worker_id) { |
1225 RebuildRSOutOfRegionClosure rebuild_rs(_g1, worker_id); |
1225 RebuildRSOutOfRegionClosure rebuild_rs(_g1, worker_id); |
1226 _g1->heap_region_par_iterate_chunked(&rebuild_rs, worker_id, |
1226 _g1->heap_region_par_iterate(&rebuild_rs, worker_id, &_hrclaimer); |
1227 _g1->workers()->active_workers(), |
|
1228 HeapRegion::RebuildRSClaimValue); |
|
1229 } |
1227 } |
1230 }; |
1228 }; |
1231 |
1229 |
1232 class PostCompactionPrinterClosure: public HeapRegionClosure { |
1230 class PostCompactionPrinterClosure: public HeapRegionClosure { |
1233 private: |
1231 private: |
1453 // no get carried forward to a serial phase where there |
1451 // no get carried forward to a serial phase where there |
1454 // may be code that is "possibly_parallel". |
1452 // may be code that is "possibly_parallel". |
1455 set_par_threads(n_workers); |
1453 set_par_threads(n_workers); |
1456 |
1454 |
1457 ParRebuildRSTask rebuild_rs_task(this); |
1455 ParRebuildRSTask rebuild_rs_task(this); |
1458 assert(check_heap_region_claim_values( |
|
1459 HeapRegion::InitialClaimValue), "sanity check"); |
|
1460 assert(UseDynamicNumberOfGCThreads || |
1456 assert(UseDynamicNumberOfGCThreads || |
1461 workers()->active_workers() == workers()->total_workers(), |
1457 workers()->active_workers() == workers()->total_workers(), |
1462 "Unless dynamic should use total workers"); |
1458 "Unless dynamic should use total workers"); |
1463 // Use the most recent number of active workers |
1459 // Use the most recent number of active workers |
1464 assert(workers()->active_workers() > 0, |
1460 assert(workers()->active_workers() > 0, |
1465 "Active workers not properly set"); |
1461 "Active workers not properly set"); |
1466 set_par_threads(workers()->active_workers()); |
1462 set_par_threads(workers()->active_workers()); |
1467 workers()->run_task(&rebuild_rs_task); |
1463 workers()->run_task(&rebuild_rs_task); |
1468 set_par_threads(0); |
1464 set_par_threads(0); |
1469 assert(check_heap_region_claim_values( |
|
1470 HeapRegion::RebuildRSClaimValue), "sanity check"); |
|
1471 reset_heap_region_claim_values(); |
|
1472 } else { |
1465 } else { |
1473 RebuildRSOutOfRegionClosure rebuild_rs(this); |
1466 RebuildRSOutOfRegionClosure rebuild_rs(this); |
1474 heap_region_iterate(&rebuild_rs); |
1467 heap_region_iterate(&rebuild_rs); |
1475 } |
1468 } |
1476 |
1469 |
2632 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { |
2625 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { |
2633 _hrm.iterate(cl); |
2626 _hrm.iterate(cl); |
2634 } |
2627 } |
2635 |
2628 |
2636 void |
2629 void |
2637 G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl, |
2630 G1CollectedHeap::heap_region_par_iterate(HeapRegionClosure* cl, |
2638 uint worker_id, |
2631 uint worker_id, |
2639 uint num_workers, |
2632 HeapRegionClaimer *hrclaimer) const { |
2640 jint claim_value) const { |
2633 _hrm.par_iterate(cl, worker_id, hrclaimer); |
2641 _hrm.par_iterate(cl, worker_id, num_workers, claim_value); |
2634 } |
2642 } |
|
2643 |
|
2644 class ResetClaimValuesClosure: public HeapRegionClosure { |
|
2645 public: |
|
2646 bool doHeapRegion(HeapRegion* r) { |
|
2647 r->set_claim_value(HeapRegion::InitialClaimValue); |
|
2648 return false; |
|
2649 } |
|
2650 }; |
|
2651 |
|
2652 void G1CollectedHeap::reset_heap_region_claim_values() { |
|
2653 ResetClaimValuesClosure blk; |
|
2654 heap_region_iterate(&blk); |
|
2655 } |
|
2656 |
|
2657 void G1CollectedHeap::reset_cset_heap_region_claim_values() { |
|
2658 ResetClaimValuesClosure blk; |
|
2659 collection_set_iterate(&blk); |
|
2660 } |
|
2661 |
|
2662 #ifdef ASSERT |
|
2663 // This checks whether all regions in the heap have the correct claim |
|
2664 // value. I also piggy-backed on this a check to ensure that the |
|
2665 // humongous_start_region() information on "continues humongous" |
|
2666 // regions is correct. |
|
2667 |
|
2668 class CheckClaimValuesClosure : public HeapRegionClosure { |
|
2669 private: |
|
2670 jint _claim_value; |
|
2671 uint _failures; |
|
2672 HeapRegion* _sh_region; |
|
2673 |
|
2674 public: |
|
2675 CheckClaimValuesClosure(jint claim_value) : |
|
2676 _claim_value(claim_value), _failures(0), _sh_region(NULL) { } |
|
2677 bool doHeapRegion(HeapRegion* r) { |
|
2678 if (r->claim_value() != _claim_value) { |
|
2679 gclog_or_tty->print_cr("Region " HR_FORMAT ", " |
|
2680 "claim value = %d, should be %d", |
|
2681 HR_FORMAT_PARAMS(r), |
|
2682 r->claim_value(), _claim_value); |
|
2683 ++_failures; |
|
2684 } |
|
2685 if (!r->is_humongous()) { |
|
2686 _sh_region = NULL; |
|
2687 } else if (r->is_starts_humongous()) { |
|
2688 _sh_region = r; |
|
2689 } else if (r->is_continues_humongous()) { |
|
2690 if (r->humongous_start_region() != _sh_region) { |
|
2691 gclog_or_tty->print_cr("Region " HR_FORMAT ", " |
|
2692 "HS = "PTR_FORMAT", should be "PTR_FORMAT, |
|
2693 HR_FORMAT_PARAMS(r), |
|
2694 r->humongous_start_region(), |
|
2695 _sh_region); |
|
2696 ++_failures; |
|
2697 } |
|
2698 } |
|
2699 return false; |
|
2700 } |
|
2701 uint failures() { return _failures; } |
|
2702 }; |
|
2703 |
|
2704 bool G1CollectedHeap::check_heap_region_claim_values(jint claim_value) { |
|
2705 CheckClaimValuesClosure cl(claim_value); |
|
2706 heap_region_iterate(&cl); |
|
2707 return cl.failures() == 0; |
|
2708 } |
|
2709 |
|
2710 class CheckClaimValuesInCSetHRClosure: public HeapRegionClosure { |
|
2711 private: |
|
2712 jint _claim_value; |
|
2713 uint _failures; |
|
2714 |
|
2715 public: |
|
2716 CheckClaimValuesInCSetHRClosure(jint claim_value) : |
|
2717 _claim_value(claim_value), _failures(0) { } |
|
2718 |
|
2719 uint failures() { return _failures; } |
|
2720 |
|
2721 bool doHeapRegion(HeapRegion* hr) { |
|
2722 assert(hr->in_collection_set(), "how?"); |
|
2723 assert(!hr->is_humongous(), "H-region in CSet"); |
|
2724 if (hr->claim_value() != _claim_value) { |
|
2725 gclog_or_tty->print_cr("CSet Region " HR_FORMAT ", " |
|
2726 "claim value = %d, should be %d", |
|
2727 HR_FORMAT_PARAMS(hr), |
|
2728 hr->claim_value(), _claim_value); |
|
2729 _failures += 1; |
|
2730 } |
|
2731 return false; |
|
2732 } |
|
2733 }; |
|
2734 |
|
2735 bool G1CollectedHeap::check_cset_heap_region_claim_values(jint claim_value) { |
|
2736 CheckClaimValuesInCSetHRClosure cl(claim_value); |
|
2737 collection_set_iterate(&cl); |
|
2738 return cl.failures() == 0; |
|
2739 } |
|
2740 #endif // ASSERT |
|
2741 |
2635 |
2742 // Clear the cached CSet starting regions and (more importantly) |
2636 // Clear the cached CSet starting regions and (more importantly) |
2743 // the time stamps. Called when we reset the GC time stamp. |
2637 // the time stamps. Called when we reset the GC time stamp. |
2744 void G1CollectedHeap::clear_cset_start_regions() { |
2638 void G1CollectedHeap::clear_cset_start_regions() { |
2745 assert(_worker_cset_start_region != NULL, "sanity"); |
2639 assert(_worker_cset_start_region != NULL, "sanity"); |
3250 |
3144 |
3251 // This is the task used for parallel verification of the heap regions |
3145 // This is the task used for parallel verification of the heap regions |
3252 |
3146 |
3253 class G1ParVerifyTask: public AbstractGangTask { |
3147 class G1ParVerifyTask: public AbstractGangTask { |
3254 private: |
3148 private: |
3255 G1CollectedHeap* _g1h; |
3149 G1CollectedHeap* _g1h; |
3256 VerifyOption _vo; |
3150 VerifyOption _vo; |
3257 bool _failures; |
3151 bool _failures; |
|
3152 HeapRegionClaimer _hrclaimer; |
3258 |
3153 |
3259 public: |
3154 public: |
3260 // _vo == UsePrevMarking -> use "prev" marking information, |
3155 // _vo == UsePrevMarking -> use "prev" marking information, |
3261 // _vo == UseNextMarking -> use "next" marking information, |
3156 // _vo == UseNextMarking -> use "next" marking information, |
3262 // _vo == UseMarkWord -> use mark word from object header. |
3157 // _vo == UseMarkWord -> use mark word from object header. |
3263 G1ParVerifyTask(G1CollectedHeap* g1h, VerifyOption vo) : |
3158 G1ParVerifyTask(G1CollectedHeap* g1h, VerifyOption vo) : |
3264 AbstractGangTask("Parallel verify task"), |
3159 AbstractGangTask("Parallel verify task"), |
3265 _g1h(g1h), |
3160 _g1h(g1h), |
3266 _vo(vo), |
3161 _vo(vo), |
3267 _failures(false) { } |
3162 _failures(false), |
|
3163 _hrclaimer(g1h->workers()->active_workers()) {} |
3268 |
3164 |
3269 bool failures() { |
3165 bool failures() { |
3270 return _failures; |
3166 return _failures; |
3271 } |
3167 } |
3272 |
3168 |
3273 void work(uint worker_id) { |
3169 void work(uint worker_id) { |
3274 HandleMark hm; |
3170 HandleMark hm; |
3275 VerifyRegionClosure blk(true, _vo); |
3171 VerifyRegionClosure blk(true, _vo); |
3276 _g1h->heap_region_par_iterate_chunked(&blk, worker_id, |
3172 _g1h->heap_region_par_iterate(&blk, worker_id, &_hrclaimer); |
3277 _g1h->workers()->active_workers(), |
|
3278 HeapRegion::ParVerifyClaimValue); |
|
3279 if (blk.failures()) { |
3173 if (blk.failures()) { |
3280 _failures = true; |
3174 _failures = true; |
3281 } |
3175 } |
3282 } |
3176 } |
3283 }; |
3177 }; |
3315 verify_region_sets(); |
3209 verify_region_sets(); |
3316 } |
3210 } |
3317 |
3211 |
3318 if (!silent) { gclog_or_tty->print("HeapRegions "); } |
3212 if (!silent) { gclog_or_tty->print("HeapRegions "); } |
3319 if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { |
3213 if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { |
3320 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), |
|
3321 "sanity check"); |
|
3322 |
3214 |
3323 G1ParVerifyTask task(this, vo); |
3215 G1ParVerifyTask task(this, vo); |
3324 assert(UseDynamicNumberOfGCThreads || |
3216 assert(UseDynamicNumberOfGCThreads || |
3325 workers()->active_workers() == workers()->total_workers(), |
3217 workers()->active_workers() == workers()->total_workers(), |
3326 "If not dynamic should be using all the workers"); |
3218 "If not dynamic should be using all the workers"); |
4287 delete _evac_failure_scan_stack; |
4168 delete _evac_failure_scan_stack; |
4288 _evac_failure_scan_stack = NULL; |
4169 _evac_failure_scan_stack = NULL; |
4289 } |
4170 } |
4290 |
4171 |
4291 void G1CollectedHeap::remove_self_forwarding_pointers() { |
4172 void G1CollectedHeap::remove_self_forwarding_pointers() { |
4292 assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity"); |
|
4293 |
|
4294 double remove_self_forwards_start = os::elapsedTime(); |
4173 double remove_self_forwards_start = os::elapsedTime(); |
4295 |
4174 |
|
4175 set_par_threads(); |
4296 G1ParRemoveSelfForwardPtrsTask rsfp_task(this); |
4176 G1ParRemoveSelfForwardPtrsTask rsfp_task(this); |
4297 |
4177 workers()->run_task(&rsfp_task); |
4298 if (G1CollectedHeap::use_parallel_gc_threads()) { |
4178 set_par_threads(0); |
4299 set_par_threads(); |
|
4300 workers()->run_task(&rsfp_task); |
|
4301 set_par_threads(0); |
|
4302 } else { |
|
4303 rsfp_task.work(0); |
|
4304 } |
|
4305 |
|
4306 assert(check_cset_heap_region_claim_values(HeapRegion::ParEvacFailureClaimValue), "sanity"); |
|
4307 |
|
4308 // Reset the claim values in the regions in the collection set. |
|
4309 reset_cset_heap_region_claim_values(); |
|
4310 |
|
4311 assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity"); |
|
4312 |
4179 |
4313 // Now restore saved marks, if any. |
4180 // Now restore saved marks, if any. |
4314 assert(_objs_with_preserved_marks.size() == |
4181 assert(_objs_with_preserved_marks.size() == |
4315 _preserved_marks_of_objs.size(), "Both or none."); |
4182 _preserved_marks_of_objs.size(), "Both or none."); |
4316 while (!_objs_with_preserved_marks.is_empty()) { |
4183 while (!_objs_with_preserved_marks.is_empty()) { |
5946 // collection set are reset when the collection set is freed. |
5813 // collection set are reset when the collection set is freed. |
5947 hot_card_cache->reset_hot_cache(); |
5814 hot_card_cache->reset_hot_cache(); |
5948 hot_card_cache->set_use_cache(true); |
5815 hot_card_cache->set_use_cache(true); |
5949 |
5816 |
5950 purge_code_root_memory(); |
5817 purge_code_root_memory(); |
5951 |
|
5952 if (g1_policy()->during_initial_mark_pause()) { |
|
5953 // Reset the claim values set during marking the strong code roots |
|
5954 reset_heap_region_claim_values(); |
|
5955 } |
|
5956 |
5818 |
5957 finalize_for_evac_failure(); |
5819 finalize_for_evac_failure(); |
5958 |
5820 |
5959 if (evacuation_failed()) { |
5821 if (evacuation_failed()) { |
5960 remove_self_forwarding_pointers(); |
5822 remove_self_forwarding_pointers(); |