< prev index next >

src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp

Print this page

        

*** 40,49 **** --- 40,50 ---- #include "gc/shared/cardGeneration.inline.hpp" #include "gc/shared/cardTableRS.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/collectorCounters.hpp" #include "gc/shared/collectorPolicy.hpp" + #include "gc/shared/gcId.hpp" #include "gc/shared/gcLocker.inline.hpp" #include "gc/shared/gcPolicyCounters.hpp" #include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTraceTime.hpp"
*** 1591,1601 **** gc_timer->register_gc_start(); SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer(); gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start()); ! GCTraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, NULL, gc_tracer->gc_id()); // Temporarily widen the span of the weak reference processing to // the entire heap. MemRegion new_span(GenCollectedHeap::heap()->reserved_region()); ReferenceProcessorSpanMutator rp_mut_span(ref_processor(), new_span); --- 1592,1602 ---- gc_timer->register_gc_start(); SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer(); gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start()); ! GCTraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, NULL); // Temporarily widen the span of the weak reference processing to // the entire heap. MemRegion new_span(GenCollectedHeap::heap()->reserved_region()); ReferenceProcessorSpanMutator rp_mut_span(ref_processor(), new_span);
*** 2823,2842 **** // phases. class CMSPhaseAccounting: public StackObj { public: CMSPhaseAccounting(CMSCollector *collector, const char *phase, - const GCId gc_id, bool print_cr = true); ~CMSPhaseAccounting(); private: CMSCollector *_collector; const char *_phase; elapsedTimer _wallclock; bool _print_cr; - const GCId _gc_id; public: // Not MT-safe; so do not pass around these StackObj's // where they may be accessed by other threads. jlong wallclock_millis() { --- 2824,2841 ----
*** 2848,2866 **** } }; CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector, const char *phase, - const GCId gc_id, bool print_cr) : ! _collector(collector), _phase(phase), _print_cr(print_cr), _gc_id(gc_id) { if (PrintCMSStatistics != 0) { _collector->resetYields(); } if (PrintGCDetails) { ! gclog_or_tty->gclog_stamp(_gc_id); gclog_or_tty->print_cr("[%s-concurrent-%s-start]", _collector->cmsGen()->short_name(), _phase); } _collector->resetTimer(); _wallclock.start(); --- 2847,2864 ---- } }; CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector, const char *phase, bool print_cr) : ! _collector(collector), _phase(phase), _print_cr(print_cr) { if (PrintCMSStatistics != 0) { _collector->resetYields(); } if (PrintGCDetails) { ! gclog_or_tty->gclog_stamp(); gclog_or_tty->print_cr("[%s-concurrent-%s-start]", _collector->cmsGen()->short_name(), _phase); } _collector->resetTimer(); _wallclock.start();
*** 2870,2880 **** CMSPhaseAccounting::~CMSPhaseAccounting() { assert(_wallclock.is_active(), "Wall clock should not have stopped"); _collector->stopTimer(); _wallclock.stop(); if (PrintGCDetails) { ! gclog_or_tty->gclog_stamp(_gc_id); gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]", _collector->cmsGen()->short_name(), _phase, _collector->timerValue(), _wallclock.seconds()); if (_print_cr) { gclog_or_tty->cr(); --- 2868,2878 ---- CMSPhaseAccounting::~CMSPhaseAccounting() { assert(_wallclock.is_active(), "Wall clock should not have stopped"); _collector->stopTimer(); _wallclock.stop(); if (PrintGCDetails) { ! gclog_or_tty->gclog_stamp(); gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]", _collector->cmsGen()->short_name(), _phase, _collector->timerValue(), _wallclock.seconds()); if (_print_cr) { gclog_or_tty->cr();
*** 2949,2959 **** // Setup the verification and class unloading state for this // CMS collection cycle. setup_cms_unloading_and_verification_state(); NOT_PRODUCT(GCTraceTime t("\ncheckpointRootsInitialWork", ! PrintGCDetails && Verbose, true, _gc_timer_cm, _gc_tracer_cm->gc_id());) // Reset all the PLAB chunk arrays if necessary. if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) { reset_survivor_plab_arrays(); } --- 2947,2957 ---- // Setup the verification and class unloading state for this // CMS collection cycle. setup_cms_unloading_and_verification_state(); NOT_PRODUCT(GCTraceTime t("\ncheckpointRootsInitialWork", ! PrintGCDetails && Verbose, true, _gc_timer_cm);) // Reset all the PLAB chunk arrays if necessary. if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) { reset_survivor_plab_arrays(); }
*** 3052,3062 **** // refs in this generation concurrent (but interleaved) with // weak ref discovery by the young generation collector. CMSTokenSyncWithLocks ts(true, bitMapLock()); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! CMSPhaseAccounting pa(this, "mark", _gc_tracer_cm->gc_id(), !PrintGCDetails); bool res = markFromRootsWork(); if (res) { _collectorState = Precleaning; } else { // We failed and a foreground collection wants to take over assert(_foregroundGCIsActive, "internal state inconsistency"); --- 3050,3060 ---- // refs in this generation concurrent (but interleaved) with // weak ref discovery by the young generation collector. CMSTokenSyncWithLocks ts(true, bitMapLock()); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! CMSPhaseAccounting pa(this, "mark", !PrintGCDetails); bool res = markFromRootsWork(); if (res) { _collectorState = Precleaning; } else { // We failed and a foreground collection wants to take over assert(_foregroundGCIsActive, "internal state inconsistency");
*** 3749,3759 **** _start_sampling = true; } else { _start_sampling = false; } TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! CMSPhaseAccounting pa(this, "preclean", _gc_tracer_cm->gc_id(), !PrintGCDetails); preclean_work(CMSPrecleanRefLists1, CMSPrecleanSurvivors1); } CMSTokenSync x(true); // is cms thread if (CMSPrecleaningEnabled) { sample_eden(); --- 3747,3757 ---- _start_sampling = true; } else { _start_sampling = false; } TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! CMSPhaseAccounting pa(this, "preclean", !PrintGCDetails); preclean_work(CMSPrecleanRefLists1, CMSPrecleanSurvivors1); } CMSTokenSync x(true); // is cms thread if (CMSPrecleaningEnabled) { sample_eden();
*** 3778,3788 **** // schedule the pause as described above. By choosing // CMSScheduleRemarkEdenSizeThreshold >= max eden size // we will never do an actual abortable preclean cycle. if (get_eden_used() > CMSScheduleRemarkEdenSizeThreshold) { TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! CMSPhaseAccounting pa(this, "abortable-preclean", _gc_tracer_cm->gc_id(), !PrintGCDetails); // We need more smarts in the abortable preclean // loop below to deal with cases where allocation // in young gen is very very slow, and our precleaning // is running a losing race against a horde of // mutators intent on flooding us with CMS updates --- 3776,3786 ---- // schedule the pause as described above. By choosing // CMSScheduleRemarkEdenSizeThreshold >= max eden size // we will never do an actual abortable preclean cycle. if (get_eden_used() > CMSScheduleRemarkEdenSizeThreshold) { TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! CMSPhaseAccounting pa(this, "abortable-preclean", !PrintGCDetails); // We need more smarts in the abortable preclean // loop below to deal with cases where allocation // in young gen is very very slow, and our precleaning // is running a losing race against a horde of // mutators intent on flooding us with CMS updates
*** 3923,3933 **** // tweaking for better performance and some restructuring // for cleaner interfaces. GCTimer *gc_timer = NULL; // Currently not tracing concurrent phases rp->preclean_discovered_references( rp->is_alive_non_header(), &keep_alive, &complete_trace, &yield_cl, ! gc_timer, _gc_tracer_cm->gc_id()); } if (clean_survivor) { // preclean the active survivor space(s) PushAndMarkClosure pam_cl(this, _span, ref_processor(), &_markBitMap, &_modUnionTable, --- 3921,3931 ---- // tweaking for better performance and some restructuring // for cleaner interfaces. GCTimer *gc_timer = NULL; // Currently not tracing concurrent phases rp->preclean_discovered_references( rp->is_alive_non_header(), &keep_alive, &complete_trace, &yield_cl, ! gc_timer); } if (clean_survivor) { // preclean the active survivor space(s) PushAndMarkClosure pam_cl(this, _span, ref_processor(), &_markBitMap, &_modUnionTable,
*** 4259,4269 **** GenCollectedHeap* gch = GenCollectedHeap::heap(); // Temporarily set flag to false, GCH->do_collection will // expect it to be false and set to true FlagSetting fl(gch->_is_gc_active, false); NOT_PRODUCT(GCTraceTime t("Scavenge-Before-Remark", ! PrintGCDetails && Verbose, true, _gc_timer_cm, _gc_tracer_cm->gc_id());) gch->do_collection(true, // full (i.e. force, see below) false, // !clear_all_soft_refs 0, // size false, // is_tlab GenCollectedHeap::YoungGen // type --- 4257,4267 ---- GenCollectedHeap* gch = GenCollectedHeap::heap(); // Temporarily set flag to false, GCH->do_collection will // expect it to be false and set to true FlagSetting fl(gch->_is_gc_active, false); NOT_PRODUCT(GCTraceTime t("Scavenge-Before-Remark", ! PrintGCDetails && Verbose, true, _gc_timer_cm);) gch->do_collection(true, // full (i.e. force, see below) false, // !clear_all_soft_refs 0, // size false, // is_tlab GenCollectedHeap::YoungGen // type
*** 4277,4287 **** verify_work_stacks_empty(); verify_overflow_empty(); } void CMSCollector::checkpointRootsFinalWork() { ! NOT_PRODUCT(GCTraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());) assert(haveFreelistLocks(), "must have free list locks"); assert_lock_strong(bitMapLock()); ResourceMark rm; --- 4275,4285 ---- verify_work_stacks_empty(); verify_overflow_empty(); } void CMSCollector::checkpointRootsFinalWork() { ! NOT_PRODUCT(GCTraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, _gc_timer_cm);) assert(haveFreelistLocks(), "must have free list locks"); assert_lock_strong(bitMapLock()); ResourceMark rm;
*** 4327,4349 **** // are detected via the mod union table which is the set of all cards // dirtied since the first checkpoint in this GC cycle and prior to // the most recent young generation GC, minus those cleaned up by the // concurrent precleaning. if (CMSParallelRemarkEnabled) { ! GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id()); do_remark_parallel(); } else { ! GCTraceTime t("Rescan (non-parallel) ", PrintGCDetails, false, ! _gc_timer_cm, _gc_tracer_cm->gc_id()); do_remark_non_parallel(); } } verify_work_stacks_empty(); verify_overflow_empty(); { ! NOT_PRODUCT(GCTraceTime ts("refProcessingWork", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id());) refProcessingWork(); } verify_work_stacks_empty(); verify_overflow_empty(); --- 4325,4346 ---- // are detected via the mod union table which is the set of all cards // dirtied since the first checkpoint in this GC cycle and prior to // the most recent young generation GC, minus those cleaned up by the // concurrent precleaning. if (CMSParallelRemarkEnabled) { ! GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm); do_remark_parallel(); } else { ! GCTraceTime t("Rescan (non-parallel) ", PrintGCDetails, false, _gc_timer_cm); do_remark_non_parallel(); } } verify_work_stacks_empty(); verify_overflow_empty(); { ! NOT_PRODUCT(GCTraceTime ts("refProcessingWork", PrintGCDetails, false, _gc_timer_cm);) refProcessingWork(); } verify_work_stacks_empty(); verify_overflow_empty();
*** 5114,5124 **** MarkFromDirtyCardsClosure markFromDirtyCardsClosure(this, _span, NULL, // space is set further below &_markBitMap, &_markStack, &mrias_cl); { ! GCTraceTime t("grey object rescan", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id()); // Iterate over the dirty cards, setting the corresponding bits in the // mod union table. { ModUnionClosure modUnionClosure(&_modUnionTable); _ct->ct_bs()->dirty_card_iterate( --- 5111,5121 ---- MarkFromDirtyCardsClosure markFromDirtyCardsClosure(this, _span, NULL, // space is set further below &_markBitMap, &_markStack, &mrias_cl); { ! GCTraceTime t("grey object rescan", PrintGCDetails, false, _gc_timer_cm); // Iterate over the dirty cards, setting the corresponding bits in the // mod union table. { ModUnionClosure modUnionClosure(&_modUnionTable); _ct->ct_bs()->dirty_card_iterate(
*** 5151,5161 **** GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) { HandleMark hm; // Discard invalid handles created during verification Universe::verify(); } { ! GCTraceTime t("root rescan", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id()); verify_work_stacks_empty(); gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. StrongRootsScope srs(1); --- 5148,5158 ---- GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) { HandleMark hm; // Discard invalid handles created during verification Universe::verify(); } { ! GCTraceTime t("root rescan", PrintGCDetails, false, _gc_timer_cm); verify_work_stacks_empty(); gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. StrongRootsScope srs(1);
*** 5173,5183 **** || (roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache), "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops"); } { ! GCTraceTime t("visit unhandled CLDs", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id()); verify_work_stacks_empty(); // Scan all class loader data objects that might have been introduced // during concurrent marking. --- 5170,5180 ---- || (roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache), "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops"); } { ! GCTraceTime t("visit unhandled CLDs", PrintGCDetails, false, _gc_timer_cm); verify_work_stacks_empty(); // Scan all class loader data objects that might have been introduced // during concurrent marking.
*** 5192,5202 **** verify_work_stacks_empty(); } { ! GCTraceTime t("dirty klass scan", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id()); verify_work_stacks_empty(); RemarkKlassClosure remark_klass_closure(&mrias_cl); ClassLoaderDataGraph::classes_do(&remark_klass_closure); --- 5189,5199 ---- verify_work_stacks_empty(); } { ! GCTraceTime t("dirty klass scan", PrintGCDetails, false, _gc_timer_cm); verify_work_stacks_empty(); RemarkKlassClosure remark_klass_closure(&mrias_cl); ClassLoaderDataGraph::classes_do(&remark_klass_closure);
*** 5401,5411 **** &_markStack, false /* !preclean */); CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this, _span, &_markBitMap, &_markStack, &cmsKeepAliveClosure, false /* !preclean */); { ! GCTraceTime t("weak refs processing", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id()); ReferenceProcessorStats stats; if (rp->processing_is_mt()) { // Set the degree of MT here. If the discovery is done MT, there // may have been a different number of threads doing the discovery --- 5398,5408 ---- &_markStack, false /* !preclean */); CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this, _span, &_markBitMap, &_markStack, &cmsKeepAliveClosure, false /* !preclean */); { ! GCTraceTime t("weak refs processing", PrintGCDetails, false, _gc_timer_cm); ReferenceProcessorStats stats; if (rp->processing_is_mt()) { // Set the degree of MT here. If the discovery is done MT, there // may have been a different number of threads doing the discovery
*** 5426,5455 **** CMSRefProcTaskExecutor task_executor(*this); stats = rp->process_discovered_references(&_is_alive_closure, &cmsKeepAliveClosure, &cmsDrainMarkingStackClosure, &task_executor, ! _gc_timer_cm, ! _gc_tracer_cm->gc_id()); } else { stats = rp->process_discovered_references(&_is_alive_closure, &cmsKeepAliveClosure, &cmsDrainMarkingStackClosure, NULL, ! _gc_timer_cm, ! _gc_tracer_cm->gc_id()); } _gc_tracer_cm->report_gc_reference_stats(stats); } // This is the point where the entire marking should have completed. verify_work_stacks_empty(); if (should_unload_classes()) { { ! GCTraceTime t("class unloading", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id()); // Unload classes and purge the SystemDictionary. bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure); // Unload nmethods. --- 5423,5450 ---- CMSRefProcTaskExecutor task_executor(*this); stats = rp->process_discovered_references(&_is_alive_closure, &cmsKeepAliveClosure, &cmsDrainMarkingStackClosure, &task_executor, ! _gc_timer_cm); } else { stats = rp->process_discovered_references(&_is_alive_closure, &cmsKeepAliveClosure, &cmsDrainMarkingStackClosure, NULL, ! _gc_timer_cm); } _gc_tracer_cm->report_gc_reference_stats(stats); } // This is the point where the entire marking should have completed. verify_work_stacks_empty(); if (should_unload_classes()) { { ! GCTraceTime t("class unloading", PrintGCDetails, false, _gc_timer_cm); // Unload classes and purge the SystemDictionary. bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure); // Unload nmethods.
*** 5458,5474 **** // Prune dead klasses from subklass/sibling/implementor lists. Klass::clean_weak_klass_links(&_is_alive_closure); } { ! GCTraceTime t("scrub symbol table", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id()); // Clean up unreferenced symbols in symbol table. SymbolTable::unlink(); } { ! GCTraceTime t("scrub string table", PrintGCDetails, false, _gc_timer_cm, _gc_tracer_cm->gc_id()); // Delete entries for dead interned strings. StringTable::unlink(&_is_alive_closure); } } --- 5453,5469 ---- // Prune dead klasses from subklass/sibling/implementor lists. Klass::clean_weak_klass_links(&_is_alive_closure); } { ! GCTraceTime t("scrub symbol table", PrintGCDetails, false, _gc_timer_cm); // Clean up unreferenced symbols in symbol table. SymbolTable::unlink(); } { ! GCTraceTime t("scrub string table", PrintGCDetails, false, _gc_timer_cm); // Delete entries for dead interned strings. StringTable::unlink(&_is_alive_closure); } }
*** 5532,5542 **** assert(!_intra_sweep_timer.is_active(), "Should not be active"); _intra_sweep_timer.reset(); _intra_sweep_timer.start(); { TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! CMSPhaseAccounting pa(this, "sweep", _gc_tracer_cm->gc_id(), !PrintGCDetails); // First sweep the old gen { CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(), bitMapLock()); sweepWork(_cmsGen); --- 5527,5537 ---- assert(!_intra_sweep_timer.is_active(), "Should not be active"); _intra_sweep_timer.reset(); _intra_sweep_timer.start(); { TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! CMSPhaseAccounting pa(this, "sweep", !PrintGCDetails); // First sweep the old gen { CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(), bitMapLock()); sweepWork(_cmsGen);
*** 5717,5727 **** } // Clear the mark bitmap (no grey objects to start with) // for the next cycle. TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! CMSPhaseAccounting cmspa(this, "reset", _gc_tracer_cm->gc_id(), !PrintGCDetails); HeapWord* curAddr = _markBitMap.startWord(); while (curAddr < _markBitMap.endWord()) { size_t remaining = pointer_delta(_markBitMap.endWord(), curAddr); MemRegion chunk(curAddr, MIN2(CMSBitMapYieldQuantum, remaining)); --- 5712,5722 ---- } // Clear the mark bitmap (no grey objects to start with) // for the next cycle. TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! CMSPhaseAccounting cmspa(this, "reset", !PrintGCDetails); HeapWord* curAddr = _markBitMap.startWord(); while (curAddr < _markBitMap.endWord()) { size_t remaining = pointer_delta(_markBitMap.endWord(), curAddr); MemRegion chunk(curAddr, MIN2(CMSBitMapYieldQuantum, remaining));
*** 5769,5779 **** register_gc_end(); } void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) { TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL, _gc_tracer_cm->gc_id()); TraceCollectorStats tcs(counters()); switch (op) { case CMS_op_checkpointRootsInitial: { SvcGCMarker sgcm(SvcGCMarker::OTHER); --- 5764,5774 ---- register_gc_end(); } void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) { TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); ! GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL); TraceCollectorStats tcs(counters()); switch (op) { case CMS_op_checkpointRootsInitial: { SvcGCMarker sgcm(SvcGCMarker::OTHER);
< prev index next >