1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Sep 18 09:57:47 2009 -0700 1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Sep 23 23:56:15 2009 -0700 1.3 @@ -25,6 +25,8 @@ 1.4 #include "incls/_precompiled.incl" 1.5 #include "incls/_g1CollectedHeap.cpp.incl" 1.6 1.7 +size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0; 1.8 + 1.9 // turn it on so that the contents of the young list (scan-only / 1.10 // to-be-collected) are printed at "strategic" points before / during 1.11 // / after the collection --- this is useful for debugging 1.12 @@ -927,7 +929,6 @@ 1.13 TraceTime t(full ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty); 1.14 1.15 double start = os::elapsedTime(); 1.16 - GCOverheadReporter::recordSTWStart(start); 1.17 g1_policy()->record_full_collection_start(); 1.18 1.19 gc_prologue(true); 1.20 @@ -1049,7 +1050,6 @@ 1.21 } 1.22 1.23 double end = os::elapsedTime(); 1.24 - GCOverheadReporter::recordSTWEnd(end); 1.25 g1_policy()->record_full_collection_end(); 1.26 1.27 #ifdef TRACESPINNING 1.28 @@ -1396,6 +1396,9 @@ 1.29 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { 1.30 vm_exit_during_initialization("Failed necessary allocation."); 1.31 } 1.32 + 1.33 + _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2; 1.34 + 1.35 int n_queues = MAX2((int)ParallelGCThreads, 1); 1.36 _task_queues = new RefToScanQueueSet(n_queues); 1.37 1.38 @@ -1548,9 +1551,10 @@ 1.39 const size_t max_region_idx = ((size_t)1 << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1; 1.40 guarantee((max_regions() - 1) <= max_region_idx, "too many regions"); 1.41 1.42 - const size_t cards_per_region = HeapRegion::GrainBytes >> CardTableModRefBS::card_shift; 1.43 size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1; 1.44 - guarantee(cards_per_region < max_cards_per_region, "too many cards per region"); 1.45 + guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized"); 1.46 + guarantee((size_t) HeapRegion::CardsPerRegion < max_cards_per_region, 1.47 + "too many cards per region"); 1.48 1.49 _bot_shared = new G1BlockOffsetSharedArray(_reserved, 1.50 heap_word_size(init_byte_size)); 1.51 @@ -1610,9 +1614,6 @@ 1.52 // Do later initialization work for concurrent refinement. 1.53 _cg1r->init(); 1.54 1.55 - const char* group_names[] = { "CR", "ZF", "CM", "CL" }; 1.56 - GCOverheadReporter::initGCOverheadReporter(4, group_names); 1.57 - 1.58 return JNI_OK; 1.59 } 1.60 1.61 @@ -2434,8 +2435,6 @@ 1.62 } 1.63 g1_policy()->print_yg_surv_rate_info(); 1.64 1.65 - GCOverheadReporter::printGCOverhead(); 1.66 - 1.67 SpecializationStats::print(); 1.68 } 1.69 1.70 @@ -2672,7 +2671,6 @@ 1.71 // The elapsed time induced by the start time below deliberately elides 1.72 // the possible verification above. 1.73 double start_time_sec = os::elapsedTime(); 1.74 - GCOverheadReporter::recordSTWStart(start_time_sec); 1.75 size_t start_used_bytes = used(); 1.76 1.77 g1_policy()->record_collection_pause_start(start_time_sec, 1.78 @@ -2750,8 +2748,6 @@ 1.79 _in_cset_fast_test = NULL; 1.80 _in_cset_fast_test_base = NULL; 1.81 1.82 - release_gc_alloc_regions(false /* totally */); 1.83 - 1.84 cleanup_surviving_young_words(); 1.85 1.86 if (g1_policy()->in_young_gc_mode()) { 1.87 @@ -2801,7 +2797,6 @@ 1.88 double end_time_sec = os::elapsedTime(); 1.89 double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS; 1.90 g1_policy()->record_pause_time_ms(pause_time_ms); 1.91 - GCOverheadReporter::recordSTWEnd(end_time_sec); 1.92 g1_policy()->record_collection_pause_end(abandoned); 1.93 1.94 assert(regions_accounted_for(), "Region leakage."); 1.95 @@ -4152,6 +4147,7 @@ 1.96 G1KeepAliveClosure keep_alive(this); 1.97 JNIHandles::weak_oops_do(&is_alive, &keep_alive); 1.98 } 1.99 + release_gc_alloc_regions(false /* totally */); 1.100 g1_rem_set()->cleanup_after_oops_into_collection_set_do(); 1.101 1.102 concurrent_g1_refine()->clear_hot_cache(); 1.103 @@ -4285,12 +4281,18 @@ 1.104 class G1ParCleanupCTTask : public AbstractGangTask { 1.105 CardTableModRefBS* _ct_bs; 1.106 G1CollectedHeap* _g1h; 1.107 + HeapRegion* volatile _so_head; 1.108 + HeapRegion* volatile _su_head; 1.109 public: 1.110 G1ParCleanupCTTask(CardTableModRefBS* ct_bs, 1.111 - G1CollectedHeap* g1h) : 1.112 + G1CollectedHeap* g1h, 1.113 + HeapRegion* scan_only_list, 1.114 + HeapRegion* survivor_list) : 1.115 AbstractGangTask("G1 Par Cleanup CT Task"), 1.116 _ct_bs(ct_bs), 1.117 - _g1h(g1h) 1.118 + _g1h(g1h), 1.119 + _so_head(scan_only_list), 1.120 + _su_head(survivor_list) 1.121 { } 1.122 1.123 void work(int i) { 1.124 @@ -4298,22 +4300,64 @@ 1.125 while (r = _g1h->pop_dirty_cards_region()) { 1.126 clear_cards(r); 1.127 } 1.128 - } 1.129 + // Redirty the cards of the scan-only and survivor regions. 1.130 + dirty_list(&this->_so_head); 1.131 + dirty_list(&this->_su_head); 1.132 + } 1.133 + 1.134 void clear_cards(HeapRegion* r) { 1.135 // Cards for Survivor and Scan-Only regions will be dirtied later. 1.136 if (!r->is_scan_only() && !r->is_survivor()) { 1.137 _ct_bs->clear(MemRegion(r->bottom(), r->end())); 1.138 } 1.139 } 1.140 + 1.141 + void dirty_list(HeapRegion* volatile * head_ptr) { 1.142 + HeapRegion* head; 1.143 + do { 1.144 + // Pop region off the list. 1.145 + head = *head_ptr; 1.146 + if (head != NULL) { 1.147 + HeapRegion* r = (HeapRegion*) 1.148 + Atomic::cmpxchg_ptr(head->get_next_young_region(), head_ptr, head); 1.149 + if (r == head) { 1.150 + assert(!r->isHumongous(), "Humongous regions shouldn't be on survivor list"); 1.151 + _ct_bs->dirty(MemRegion(r->bottom(), r->end())); 1.152 + } 1.153 + } 1.154 + } while (*head_ptr != NULL); 1.155 + } 1.156 }; 1.157 1.158 1.159 +#ifndef PRODUCT 1.160 +class G1VerifyCardTableCleanup: public HeapRegionClosure { 1.161 + CardTableModRefBS* _ct_bs; 1.162 +public: 1.163 + G1VerifyCardTableCleanup(CardTableModRefBS* ct_bs) 1.164 + : _ct_bs(ct_bs) 1.165 + { } 1.166 + virtual bool doHeapRegion(HeapRegion* r) 1.167 + { 1.168 + MemRegion mr(r->bottom(), r->end()); 1.169 + if (r->is_scan_only() || r->is_survivor()) { 1.170 + _ct_bs->verify_dirty_region(mr); 1.171 + } else { 1.172 + _ct_bs->verify_clean_region(mr); 1.173 + } 1.174 + return false; 1.175 + } 1.176 +}; 1.177 +#endif 1.178 + 1.179 void G1CollectedHeap::cleanUpCardTable() { 1.180 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); 1.181 double start = os::elapsedTime(); 1.182 1.183 // Iterate over the dirty cards region list. 1.184 - G1ParCleanupCTTask cleanup_task(ct_bs, this); 1.185 + G1ParCleanupCTTask cleanup_task(ct_bs, this, 1.186 + _young_list->first_scan_only_region(), 1.187 + _young_list->first_survivor_region()); 1.188 if (ParallelGCThreads > 0) { 1.189 set_par_threads(workers()->total_workers()); 1.190 workers()->run_task(&cleanup_task); 1.191 @@ -4329,18 +4373,22 @@ 1.192 } 1.193 r->set_next_dirty_cards_region(NULL); 1.194 } 1.195 - } 1.196 - // now, redirty the cards of the scan-only and survivor regions 1.197 - // (it seemed faster to do it this way, instead of iterating over 1.198 - // all regions and then clearing / dirtying as appropriate) 1.199 - dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region()); 1.200 - dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region()); 1.201 - 1.202 + // now, redirty the cards of the scan-only and survivor regions 1.203 + // (it seemed faster to do it this way, instead of iterating over 1.204 + // all regions and then clearing / dirtying as appropriate) 1.205 + dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region()); 1.206 + dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region()); 1.207 + } 1.208 double elapsed = os::elapsedTime() - start; 1.209 g1_policy()->record_clear_ct_time( elapsed * 1000.0); 1.210 +#ifndef PRODUCT 1.211 + if (G1VerifyCTCleanup || VerifyAfterGC) { 1.212 + G1VerifyCardTableCleanup cleanup_verifier(ct_bs); 1.213 + heap_region_iterate(&cleanup_verifier); 1.214 + } 1.215 +#endif 1.216 } 1.217 1.218 - 1.219 void G1CollectedHeap::do_collection_pause_if_appropriate(size_t word_size) { 1.220 if (g1_policy()->should_do_collection_pause(word_size)) { 1.221 do_collection_pause(); 1.222 @@ -5033,7 +5081,7 @@ 1.223 return hr->is_in(p); 1.224 } 1.225 } 1.226 -#endif // PRODUCT 1.227 +#endif // !PRODUCT 1.228 1.229 void G1CollectedHeap::g1_unimplemented() { 1.230 // Unimplemented();