--- old/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2013-09-23 17:51:17.230146305 -0700 +++ new/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2013-09-23 17:51:17.120144435 -0700 @@ -788,12 +788,12 @@ && _survivor_chunk_index == 0), "Error"); - // Choose what strong roots should be scanned depending on verification options + // Choose what strong roots should be scanned depending on verification options. + // If CMSClassUnloadingEnabled is on, root scanning option is set during + // setup_cms_unloading_and_verification_state() on each CMS cycle. if (!CMSClassUnloadingEnabled) { // If class unloading is disabled we want to include all classes into the root set. add_root_scanning_option(SharedHeap::SO_AllClasses); - } else { - add_root_scanning_option(SharedHeap::SO_SystemClasses); } NOT_PRODUCT(_overflow_counter = CMSMarkStackOverflowInterval;) @@ -3310,6 +3310,17 @@ || VerifyBeforeExit; const int rso = SharedHeap::SO_Strings | SharedHeap::SO_CodeCache; + // We set the proper root for this CMS cycle here. + // When class unloading is disabled, we set the default root scanning option + // once in the CMSCollector constructor. + if (CMSClassUnloadingEnabled) { + if (should_unload_classes()) { + set_root_scanning_option(SharedHeap::SO_SystemClasses); + } else { + set_root_scanning_option(SharedHeap::SO_AllClasses | rso); + } + } + if (should_unload_classes()) { // Should unload classes this cycle remove_root_scanning_option(rso); // Shrink the root set appropriately set_verifying(should_verify); // Set verification state for this cycle --- old/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2013-09-23 17:51:17.720154631 -0700 +++ new/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2013-09-23 17:51:17.620152931 -0700 @@ -591,6 +591,7 @@ // Root scanning options for perm gen int _roots_scanning_options; int roots_scanning_options() const { return _roots_scanning_options; } + void set_root_scanning_option(int o) { _roots_scanning_options = o; } void add_root_scanning_option(int o) { _roots_scanning_options |= o; } void remove_root_scanning_option(int o) { _roots_scanning_options &= ~o; }