# HG changeset patch # User ysr # Date 1264114021 28800 # Node ID 4e7f445290c731e6b7df544d0bcfc16868d1df71 # Parent ac73c07a6bf6e3f2579b03657780cb1928146d6a# Parent 25586a89c1c344938dbb3e01102844f3202ec658 Merge diff -r ac73c07a6bf6 -r 4e7f445290c7 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jan 20 12:54:25 2010 -0800 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Jan 21 14:47:01 2010 -0800 @@ -3655,9 +3655,7 @@ verify_work_stacks_empty(); verify_overflow_empty(); assert(_revisitStack.isEmpty(), "tabula rasa"); - - DEBUG_ONLY(RememberKlassesChecker cmx(CMSClassUnloadingEnabled);) - + DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());) bool result = false; if (CMSConcurrentMTEnabled && ParallelCMSThreads > 0) { result = do_marking_mt(asynch); @@ -4124,7 +4122,6 @@ void CMSConcMarkingTask::coordinator_yield() { assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(), "CMS thread should hold CMS token"); - DEBUG_ONLY(RememberKlassesChecker mux(false);) // First give up the locks, then yield, then re-lock // We should probably use a constructor/destructor idiom to @@ -4201,9 +4198,7 @@ // Mutate the Refs discovery so it is MT during the // multi-threaded marking phase. ReferenceProcessorMTMutator mt(ref_processor(), num_workers > 1); - - DEBUG_ONLY(RememberKlassesChecker cmx(CMSClassUnloadingEnabled);) - + DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());) conc_workers()->start_task(&tsk); while (tsk.yielded()) { tsk.coordinator_yield(); @@ -4472,7 +4467,7 @@ // for cleaner interfaces. rp->preclean_discovered_references( rp->is_alive_non_header(), &keep_alive, &complete_trace, - &yield_cl); + &yield_cl, should_unload_classes()); } if (clean_survivor) { // preclean the active survivor space(s) @@ -4494,7 +4489,7 @@ SurvivorSpacePrecleanClosure sss_cl(this, _span, &_markBitMap, &_markStack, &pam_cl, before_count, CMSYield); - DEBUG_ONLY(RememberKlassesChecker mx(CMSClassUnloadingEnabled);) + DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());) dng->from()->object_iterate_careful(&sss_cl); dng->to()->object_iterate_careful(&sss_cl); } @@ -4665,7 +4660,7 @@ verify_work_stacks_empty(); verify_overflow_empty(); sample_eden(); - DEBUG_ONLY(RememberKlassesChecker mx(CMSClassUnloadingEnabled);) + DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());) stop_point = gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl); } @@ -4753,7 +4748,7 @@ sample_eden(); verify_work_stacks_empty(); verify_overflow_empty(); - DEBUG_ONLY(RememberKlassesChecker mx(CMSClassUnloadingEnabled);) + DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());) HeapWord* stop_point = gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl); if (stop_point != NULL) { @@ -4853,7 +4848,7 @@ assert(haveFreelistLocks(), "must have free list locks"); assert_lock_strong(bitMapLock()); - DEBUG_ONLY(RememberKlassesChecker fmx(CMSClassUnloadingEnabled);) + DEBUG_ONLY(RememberKlassesChecker fmx(should_unload_classes());) if (!init_mark_was_synchronous) { // We might assume that we need not fill TLAB's when // CMSScavengeBeforeRemark is set, because we may have just done diff -r ac73c07a6bf6 -r 4e7f445290c7 hotspot/src/share/vm/memory/iterator.hpp --- a/hotspot/src/share/vm/memory/iterator.hpp Wed Jan 20 12:54:25 2010 -0800 +++ b/hotspot/src/share/vm/memory/iterator.hpp Thu Jan 21 14:47:01 2010 -0800 @@ -296,23 +296,32 @@ // RememberKlassesChecker can be passed "false" to turn off checking. // It is used by CMS when CMS yields to a different collector. class RememberKlassesChecker: StackObj { - bool _state; - bool _skip; + bool _saved_state; + bool _do_check; public: - RememberKlassesChecker(bool checking_on) : _state(false), _skip(false) { - _skip = !(ClassUnloading && !UseConcMarkSweepGC || - CMSClassUnloadingEnabled && UseConcMarkSweepGC); - if (_skip) { - return; + RememberKlassesChecker(bool checking_on) : _saved_state(false), + _do_check(true) { + // The ClassUnloading unloading flag affects the collectors except + // for CMS. + // CMS unloads classes if CMSClassUnloadingEnabled is true or + // if ExplicitGCInvokesConcurrentAndUnloadsClasses is true and + // the current collection is an explicit collection. Turning + // on the checking in general for + // ExplicitGCInvokesConcurrentAndUnloadsClasses and + // UseConcMarkSweepGC should not lead to false positives. + _do_check = + ClassUnloading && !UseConcMarkSweepGC || + CMSClassUnloadingEnabled && UseConcMarkSweepGC || + ExplicitGCInvokesConcurrentAndUnloadsClasses && UseConcMarkSweepGC; + if (_do_check) { + _saved_state = OopClosure::must_remember_klasses(); + OopClosure::set_must_remember_klasses(checking_on); } - _state = OopClosure::must_remember_klasses(); - OopClosure::set_must_remember_klasses(checking_on); } ~RememberKlassesChecker() { - if (_skip) { - return; + if (_do_check) { + OopClosure::set_must_remember_klasses(_saved_state); } - OopClosure::set_must_remember_klasses(_state); } }; #endif // ASSERT diff -r ac73c07a6bf6 -r 4e7f445290c7 hotspot/src/share/vm/memory/referenceProcessor.cpp --- a/hotspot/src/share/vm/memory/referenceProcessor.cpp Wed Jan 20 12:54:25 2010 -0800 +++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp Thu Jan 21 14:47:01 2010 -0800 @@ -1227,13 +1227,16 @@ BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc, - YieldClosure* yield) { + YieldClosure* yield, + bool should_unload_classes) { NOT_PRODUCT(verify_ok_to_handle_reflists()); #ifdef ASSERT bool must_remember_klasses = ClassUnloading && !UseConcMarkSweepGC || - CMSClassUnloadingEnabled && UseConcMarkSweepGC; + CMSClassUnloadingEnabled && UseConcMarkSweepGC || + ExplicitGCInvokesConcurrentAndUnloadsClasses && + UseConcMarkSweepGC && should_unload_classes; RememberKlassesChecker mx(must_remember_klasses); #endif // Soft references diff -r ac73c07a6bf6 -r 4e7f445290c7 hotspot/src/share/vm/memory/referenceProcessor.hpp --- a/hotspot/src/share/vm/memory/referenceProcessor.hpp Wed Jan 20 12:54:25 2010 -0800 +++ b/hotspot/src/share/vm/memory/referenceProcessor.hpp Thu Jan 21 14:47:01 2010 -0800 @@ -170,11 +170,13 @@ // The caller is responsible for taking care of potential // interference with concurrent operations on these lists // (or predicates involved) by other threads. Currently - // only used by the CMS collector. + // only used by the CMS collector. should_unload_classes is + // used to aid assertion checking when classes are collected. void preclean_discovered_references(BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc, - YieldClosure* yield); + YieldClosure* yield, + bool should_unload_classes); // Delete entries in the discovered lists that have // either a null referent or are not active. Such