diff -r 6a8ccac44f41 -r 54b3b351d6f9 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Sep 18 09:57:47 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Sep 23 23:56:15 2009 -0700 @@ -25,6 +25,8 @@ #include "incls/_precompiled.incl" #include "incls/_g1CollectedHeap.cpp.incl" +size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0; + // turn it on so that the contents of the young list (scan-only / // to-be-collected) are printed at "strategic" points before / during // / after the collection --- this is useful for debugging @@ -927,7 +929,6 @@ TraceTime t(full ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty); double start = os::elapsedTime(); - GCOverheadReporter::recordSTWStart(start); g1_policy()->record_full_collection_start(); gc_prologue(true); @@ -1049,7 +1050,6 @@ } double end = os::elapsedTime(); - GCOverheadReporter::recordSTWEnd(end); g1_policy()->record_full_collection_end(); #ifdef TRACESPINNING @@ -1396,6 +1396,9 @@ if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { vm_exit_during_initialization("Failed necessary allocation."); } + + _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2; + int n_queues = MAX2((int)ParallelGCThreads, 1); _task_queues = new RefToScanQueueSet(n_queues); @@ -1548,9 +1551,10 @@ const size_t max_region_idx = ((size_t)1 << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1; guarantee((max_regions() - 1) <= max_region_idx, "too many regions"); - const size_t cards_per_region = HeapRegion::GrainBytes >> CardTableModRefBS::card_shift; size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1; - guarantee(cards_per_region < max_cards_per_region, "too many cards per region"); + guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized"); + guarantee((size_t) HeapRegion::CardsPerRegion < max_cards_per_region, + "too many cards per region"); _bot_shared = new G1BlockOffsetSharedArray(_reserved, heap_word_size(init_byte_size)); @@ -1610,9 +1614,6 @@ // Do later initialization work for concurrent refinement. _cg1r->init(); - const char* group_names[] = { "CR", "ZF", "CM", "CL" }; - GCOverheadReporter::initGCOverheadReporter(4, group_names); - return JNI_OK; } @@ -2434,8 +2435,6 @@ } g1_policy()->print_yg_surv_rate_info(); - GCOverheadReporter::printGCOverhead(); - SpecializationStats::print(); } @@ -2672,7 +2671,6 @@ // The elapsed time induced by the start time below deliberately elides // the possible verification above. double start_time_sec = os::elapsedTime(); - GCOverheadReporter::recordSTWStart(start_time_sec); size_t start_used_bytes = used(); g1_policy()->record_collection_pause_start(start_time_sec, @@ -2750,8 +2748,6 @@ _in_cset_fast_test = NULL; _in_cset_fast_test_base = NULL; - release_gc_alloc_regions(false /* totally */); - cleanup_surviving_young_words(); if (g1_policy()->in_young_gc_mode()) { @@ -2801,7 +2797,6 @@ double end_time_sec = os::elapsedTime(); double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS; g1_policy()->record_pause_time_ms(pause_time_ms); - GCOverheadReporter::recordSTWEnd(end_time_sec); g1_policy()->record_collection_pause_end(abandoned); assert(regions_accounted_for(), "Region leakage."); @@ -4152,6 +4147,7 @@ G1KeepAliveClosure keep_alive(this); JNIHandles::weak_oops_do(&is_alive, &keep_alive); } + release_gc_alloc_regions(false /* totally */); g1_rem_set()->cleanup_after_oops_into_collection_set_do(); concurrent_g1_refine()->clear_hot_cache(); @@ -4285,12 +4281,18 @@ class G1ParCleanupCTTask : public AbstractGangTask { CardTableModRefBS* _ct_bs; G1CollectedHeap* _g1h; + HeapRegion* volatile _so_head; + HeapRegion* volatile _su_head; public: G1ParCleanupCTTask(CardTableModRefBS* ct_bs, - G1CollectedHeap* g1h) : + G1CollectedHeap* g1h, + HeapRegion* scan_only_list, + HeapRegion* survivor_list) : AbstractGangTask("G1 Par Cleanup CT Task"), _ct_bs(ct_bs), - _g1h(g1h) + _g1h(g1h), + _so_head(scan_only_list), + _su_head(survivor_list) { } void work(int i) { @@ -4298,22 +4300,64 @@ while (r = _g1h->pop_dirty_cards_region()) { clear_cards(r); } - } + // Redirty the cards of the scan-only and survivor regions. + dirty_list(&this->_so_head); + dirty_list(&this->_su_head); + } + void clear_cards(HeapRegion* r) { // Cards for Survivor and Scan-Only regions will be dirtied later. if (!r->is_scan_only() && !r->is_survivor()) { _ct_bs->clear(MemRegion(r->bottom(), r->end())); } } + + void dirty_list(HeapRegion* volatile * head_ptr) { + HeapRegion* head; + do { + // Pop region off the list. + head = *head_ptr; + if (head != NULL) { + HeapRegion* r = (HeapRegion*) + Atomic::cmpxchg_ptr(head->get_next_young_region(), head_ptr, head); + if (r == head) { + assert(!r->isHumongous(), "Humongous regions shouldn't be on survivor list"); + _ct_bs->dirty(MemRegion(r->bottom(), r->end())); + } + } + } while (*head_ptr != NULL); + } }; +#ifndef PRODUCT +class G1VerifyCardTableCleanup: public HeapRegionClosure { + CardTableModRefBS* _ct_bs; +public: + G1VerifyCardTableCleanup(CardTableModRefBS* ct_bs) + : _ct_bs(ct_bs) + { } + virtual bool doHeapRegion(HeapRegion* r) + { + MemRegion mr(r->bottom(), r->end()); + if (r->is_scan_only() || r->is_survivor()) { + _ct_bs->verify_dirty_region(mr); + } else { + _ct_bs->verify_clean_region(mr); + } + return false; + } +}; +#endif + void G1CollectedHeap::cleanUpCardTable() { CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); double start = os::elapsedTime(); // Iterate over the dirty cards region list. - G1ParCleanupCTTask cleanup_task(ct_bs, this); + G1ParCleanupCTTask cleanup_task(ct_bs, this, + _young_list->first_scan_only_region(), + _young_list->first_survivor_region()); if (ParallelGCThreads > 0) { set_par_threads(workers()->total_workers()); workers()->run_task(&cleanup_task); @@ -4329,18 +4373,22 @@ } r->set_next_dirty_cards_region(NULL); } - } - // now, redirty the cards of the scan-only and survivor regions - // (it seemed faster to do it this way, instead of iterating over - // all regions and then clearing / dirtying as appropriate) - dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region()); - dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region()); - + // now, redirty the cards of the scan-only and survivor regions + // (it seemed faster to do it this way, instead of iterating over + // all regions and then clearing / dirtying as appropriate) + dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region()); + dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region()); + } double elapsed = os::elapsedTime() - start; g1_policy()->record_clear_ct_time( elapsed * 1000.0); +#ifndef PRODUCT + if (G1VerifyCTCleanup || VerifyAfterGC) { + G1VerifyCardTableCleanup cleanup_verifier(ct_bs); + heap_region_iterate(&cleanup_verifier); + } +#endif } - void G1CollectedHeap::do_collection_pause_if_appropriate(size_t word_size) { if (g1_policy()->should_do_collection_pause(word_size)) { do_collection_pause(); @@ -5033,7 +5081,7 @@ return hr->is_in(p); } } -#endif // PRODUCT +#endif // !PRODUCT void G1CollectedHeap::g1_unimplemented() { // Unimplemented();