--- old/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2013-05-14 17:04:04.066554644 +0200 +++ new/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2013-05-14 17:04:03.986554647 +0200 @@ -62,7 +62,8 @@ // statics CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL; -bool CMSCollector::_full_gc_requested = false; +bool CMSCollector::_full_gc_requested = false; +GCCause::Cause CMSCollector::_full_gc_cause = GCCause::_no_gc; ////////////////////////////////////////////////////////////////// // In support of CMS/VM thread synchronization @@ -1683,12 +1684,13 @@ } -void CMSCollector::request_full_gc(unsigned int full_gc_count) { +void CMSCollector::request_full_gc(unsigned int full_gc_count, GCCause::Cause cause) { GenCollectedHeap* gch = GenCollectedHeap::heap(); unsigned int gc_count = gch->total_full_collections(); if (gc_count == full_gc_count) { MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag); _full_gc_requested = true; + _full_gc_cause = cause; CGC_lock->notify(); // nudge CMS thread } else { assert(gc_count > full_gc_count, "Error: causal loop"); @@ -2123,7 +2125,7 @@ // required. _collectorState = FinalMarking; } - collect_in_foreground(clear_all_soft_refs); + collect_in_foreground(clear_all_soft_refs, GenCollectedHeap::heap()->gc_cause()); // For a mark-sweep, compute_new_size() will be called // in the heap's do_collection() method. @@ -2186,7 +2188,7 @@ // one "collect" method between the background collector and the foreground // collector but the if-then-else required made it cleaner to have // separate methods. -void CMSCollector::collect_in_background(bool clear_all_soft_refs) { +void CMSCollector::collect_in_background(bool clear_all_soft_refs, GCCause::Cause cause) { assert(Thread::current()->is_ConcurrentGC_thread(), "A CMS asynchronous collection is only allowed on a CMS thread."); @@ -2205,7 +2207,7 @@ } else { assert(_collectorState == Idling, "Should be idling before start."); _collectorState = InitialMarking; - register_gc_start(GCCause::_cms_concurrent_mark); + register_gc_start(cause); // Reset the expansion cause, now that we are about to begin // a new cycle. clear_expansion_cause(); @@ -2214,6 +2216,7 @@ // ensuing concurrent GC cycle. update_should_unload_classes(); _full_gc_requested = false; // acks all outstanding full gc requests + _full_gc_cause = GCCause::_no_gc; // Signal that we are about to start a collection gch->increment_total_full_collections(); // ... starting a collection cycle _collection_count_start = gch->total_full_collections(); @@ -2460,7 +2463,7 @@ _gc_tracer_cm->report_gc_heap_summary(when, _last_heap_summary, _last_perm_gen_summary); } -void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) { +void CMSCollector::collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause) { assert(_foregroundGCIsActive && !_foregroundGCShouldWait, "Foreground collector should be waiting, not executing"); assert(Thread::current()->is_VM_thread(), "A foreground collection" @@ -2493,7 +2496,7 @@ } switch (_collectorState) { case InitialMarking: - register_foreground_gc_start(GenCollectedHeap::heap()->gc_cause()); + register_foreground_gc_start(cause); init_mark_was_synchronous = true; // fact to be exploited in re-mark checkpointRootsInitial(false); assert(_collectorState == Marking, "Collector state should have changed" --- old/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2013-05-14 17:04:04.590554626 +0200 +++ new/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2013-05-14 17:04:04.514554628 +0200 @@ -573,8 +573,9 @@ bool _completed_initialization; // In support of ExplicitGCInvokesConcurrent - static bool _full_gc_requested; - unsigned int _collection_count_start; + static bool _full_gc_requested; + static GCCause::Cause _full_gc_cause; + unsigned int _collection_count_start; // Should we unload classes this concurrent cycle? bool _should_unload_classes; @@ -905,11 +906,11 @@ bool clear_all_soft_refs, size_t size, bool tlab); - void collect_in_background(bool clear_all_soft_refs); - void collect_in_foreground(bool clear_all_soft_refs); + void collect_in_background(bool clear_all_soft_refs, GCCause::Cause cause); + void collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause); // In support of ExplicitGCInvokesConcurrent - static void request_full_gc(unsigned int full_gc_count); + static void request_full_gc(unsigned int full_gc_count, GCCause::Cause cause); // Should we unload classes in a particular concurrent cycle? bool should_unload_classes() const { return _should_unload_classes; --- old/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp 2013-05-14 17:04:04.986554611 +0200 +++ new/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp 2013-05-14 17:04:04.918554614 +0200 @@ -140,7 +140,9 @@ while (!_should_terminate) { sleepBeforeNextCycle(); if (_should_terminate) break; - _collector->collect_in_background(false); // !clear_all_soft_refs + GCCause::Cause cause = _collector->_full_gc_requested ? + _collector->_full_gc_cause : GCCause::_cms_concurrent_mark; + _collector->collect_in_background(false, cause); } assert(_should_terminate, "just checking"); // Check that the state of any protocol for synchronization --- old/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp 2013-05-14 17:04:05.358554598 +0200 +++ new/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp 2013-05-14 17:04:05.290554601 +0200 @@ -241,7 +241,7 @@ // In case CMS thread was in icms_wait(), wake it up. CMSCollector::start_icms(); // Nudge the CMS thread to start a concurrent collection. - CMSCollector::request_full_gc(_full_gc_count_before); + CMSCollector::request_full_gc(_full_gc_count_before, _gc_cause); } else { assert(_full_gc_count_before < gch->total_full_collections(), "Error"); FullGCCount_lock->notify_all(); // Inform the Java thread its work is done