1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Aug 13 16:22:45 2009 -0700 1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Aug 31 05:27:29 2009 -0700 1.3 @@ -2739,8 +2739,6 @@ 1.4 _in_cset_fast_test = NULL; 1.5 _in_cset_fast_test_base = NULL; 1.6 1.7 - release_gc_alloc_regions(false /* totally */); 1.8 - 1.9 cleanup_surviving_young_words(); 1.10 1.11 if (g1_policy()->in_young_gc_mode()) { 1.12 @@ -4132,6 +4130,7 @@ 1.13 G1KeepAliveClosure keep_alive(this); 1.14 JNIHandles::weak_oops_do(&is_alive, &keep_alive); 1.15 } 1.16 + release_gc_alloc_regions(false /* totally */); 1.17 g1_rem_set()->cleanup_after_oops_into_collection_set_do(); 1.18 1.19 concurrent_g1_refine()->clear_hot_cache(); 1.20 @@ -4265,12 +4264,18 @@ 1.21 class G1ParCleanupCTTask : public AbstractGangTask { 1.22 CardTableModRefBS* _ct_bs; 1.23 G1CollectedHeap* _g1h; 1.24 + HeapRegion* volatile _so_head; 1.25 + HeapRegion* volatile _su_head; 1.26 public: 1.27 G1ParCleanupCTTask(CardTableModRefBS* ct_bs, 1.28 - G1CollectedHeap* g1h) : 1.29 + G1CollectedHeap* g1h, 1.30 + HeapRegion* scan_only_list, 1.31 + HeapRegion* survivor_list) : 1.32 AbstractGangTask("G1 Par Cleanup CT Task"), 1.33 _ct_bs(ct_bs), 1.34 - _g1h(g1h) 1.35 + _g1h(g1h), 1.36 + _so_head(scan_only_list), 1.37 + _su_head(survivor_list) 1.38 { } 1.39 1.40 void work(int i) { 1.41 @@ -4278,22 +4283,64 @@ 1.42 while (r = _g1h->pop_dirty_cards_region()) { 1.43 clear_cards(r); 1.44 } 1.45 - } 1.46 + // Redirty the cards of the scan-only and survivor regions. 1.47 + dirty_list(&this->_so_head); 1.48 + dirty_list(&this->_su_head); 1.49 + } 1.50 + 1.51 void clear_cards(HeapRegion* r) { 1.52 // Cards for Survivor and Scan-Only regions will be dirtied later. 1.53 if (!r->is_scan_only() && !r->is_survivor()) { 1.54 _ct_bs->clear(MemRegion(r->bottom(), r->end())); 1.55 } 1.56 } 1.57 + 1.58 + void dirty_list(HeapRegion* volatile * head_ptr) { 1.59 + HeapRegion* head; 1.60 + do { 1.61 + // Pop region off the list. 1.62 + head = *head_ptr; 1.63 + if (head != NULL) { 1.64 + HeapRegion* r = (HeapRegion*) 1.65 + Atomic::cmpxchg_ptr(head->get_next_young_region(), head_ptr, head); 1.66 + if (r == head) { 1.67 + assert(!r->isHumongous(), "Humongous regions shouldn't be on survivor list"); 1.68 + _ct_bs->dirty(MemRegion(r->bottom(), r->end())); 1.69 + } 1.70 + } 1.71 + } while (*head_ptr != NULL); 1.72 + } 1.73 }; 1.74 1.75 1.76 +#ifndef PRODUCT 1.77 +class G1VerifyCardTableCleanup: public HeapRegionClosure { 1.78 + CardTableModRefBS* _ct_bs; 1.79 +public: 1.80 + G1VerifyCardTableCleanup(CardTableModRefBS* ct_bs) 1.81 + : _ct_bs(ct_bs) 1.82 + { } 1.83 + virtual bool doHeapRegion(HeapRegion* r) 1.84 + { 1.85 + MemRegion mr(r->bottom(), r->end()); 1.86 + if (r->is_scan_only() || r->is_survivor()) { 1.87 + _ct_bs->verify_dirty_region(mr); 1.88 + } else { 1.89 + _ct_bs->verify_clean_region(mr); 1.90 + } 1.91 + return false; 1.92 + } 1.93 +}; 1.94 +#endif 1.95 + 1.96 void G1CollectedHeap::cleanUpCardTable() { 1.97 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); 1.98 double start = os::elapsedTime(); 1.99 1.100 // Iterate over the dirty cards region list. 1.101 - G1ParCleanupCTTask cleanup_task(ct_bs, this); 1.102 + G1ParCleanupCTTask cleanup_task(ct_bs, this, 1.103 + _young_list->first_scan_only_region(), 1.104 + _young_list->first_survivor_region()); 1.105 if (ParallelGCThreads > 0) { 1.106 set_par_threads(workers()->total_workers()); 1.107 workers()->run_task(&cleanup_task); 1.108 @@ -4309,18 +4356,22 @@ 1.109 } 1.110 r->set_next_dirty_cards_region(NULL); 1.111 } 1.112 - } 1.113 - // now, redirty the cards of the scan-only and survivor regions 1.114 - // (it seemed faster to do it this way, instead of iterating over 1.115 - // all regions and then clearing / dirtying as appropriate) 1.116 - dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region()); 1.117 - dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region()); 1.118 - 1.119 + // now, redirty the cards of the scan-only and survivor regions 1.120 + // (it seemed faster to do it this way, instead of iterating over 1.121 + // all regions and then clearing / dirtying as appropriate) 1.122 + dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region()); 1.123 + dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region()); 1.124 + } 1.125 double elapsed = os::elapsedTime() - start; 1.126 g1_policy()->record_clear_ct_time( elapsed * 1000.0); 1.127 +#ifndef PRODUCT 1.128 + if (G1VerifyCTCleanup || VerifyAfterGC) { 1.129 + G1VerifyCardTableCleanup cleanup_verifier(ct_bs); 1.130 + heap_region_iterate(&cleanup_verifier); 1.131 + } 1.132 +#endif 1.133 } 1.134 1.135 - 1.136 void G1CollectedHeap::do_collection_pause_if_appropriate(size_t word_size) { 1.137 if (g1_policy()->should_do_collection_pause(word_size)) { 1.138 do_collection_pause();