# HG changeset patch # User sangheki # Date 1460068461 25200 # Node ID f8fd0bcc60af3a0295970318f22211de4dced248 # Parent 4a57933cebfa0f0eba9b7a87ffacdeb5bc837a5b 8152182: Possible overflow in initialzation of _rescan_task_size and _marking_task_size Summary: Add constraints for CMSRescanMultiple and CMSConcMarkMultiple flags Reviewed-by: jwilhelm, jmasa diff -r 4a57933cebfa -r f8fd0bcc60af hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp --- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp Thu Apr 07 15:33:25 2016 -0700 +++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp Thu Apr 07 15:34:21 2016 -0700 @@ -2836,6 +2836,11 @@ par_get_chunk_of_blocks_dictionary(word_sz, n, fl); } +const size_t CompactibleFreeListSpace::max_flag_size_for_task_size() const { + const size_t ergo_max = _old_gen->reserved().word_size() / (CardTableModRefBS::card_size_in_words * BitsPerWord); + return ergo_max; +} + // Set up the space's par_seq_tasks structure for work claiming // for parallel rescan. See CMSParRemarkTask where this is currently used. // XXX Need to suitably abstract and generalize this and the next diff -r 4a57933cebfa -r f8fd0bcc60af hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp --- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp Thu Apr 07 15:33:25 2016 -0700 +++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp Thu Apr 07 15:34:21 2016 -0700 @@ -345,6 +345,8 @@ // Support for parallelization of rescan and marking. const size_t rescan_task_size() const { return _rescan_task_size; } const size_t marking_task_size() const { return _marking_task_size; } + // Return ergonomic max size for CMSRescanMultiple and CMSConcMarkMultiple. + const size_t max_flag_size_for_task_size() const; SequentialSubTasksDone* conc_par_seq_tasks() {return &_conc_par_seq_tasks; } void initialize_sequential_subtasks_for_rescan(int n_threads); void initialize_sequential_subtasks_for_marking(int n_threads, diff -r 4a57933cebfa -r f8fd0bcc60af hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp --- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp Thu Apr 07 15:33:25 2016 -0700 +++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp Thu Apr 07 15:34:21 2016 -0700 @@ -457,6 +457,51 @@ } } +static Flag::Error CMSReservedAreaConstraintFunc(const char* name, size_t value, bool verbose) { +#if INCLUDE_ALL_GCS + if (UseConcMarkSweepGC) { + ConcurrentMarkSweepGeneration* cms = (ConcurrentMarkSweepGeneration*)GenCollectedHeap::heap()->old_gen(); + const size_t ergo_max = cms->cmsSpace()->max_flag_size_for_task_size(); + if (value > ergo_max) { + CommandLineError::print(verbose, + "%s (" SIZE_FORMAT ") must be " + "less than or equal to ergonomic maximum (" SIZE_FORMAT ") " + "which is based on the maximum size of the old generation of the Java heap\n", + name, value, ergo_max); + return Flag::VIOLATES_CONSTRAINT; + } + } +#endif + + return Flag::SUCCESS; +} + +Flag::Error CMSRescanMultipleConstraintFunc(size_t value, bool verbose) { + Flag::Error status = CMSReservedAreaConstraintFunc("CMSRescanMultiple", value, verbose); + +#if INCLUDE_ALL_GCS + if (status == Flag::SUCCESS && UseConcMarkSweepGC) { + // CMSParRemarkTask::do_dirty_card_rescan_tasks requires CompactibleFreeListSpace::rescan_task_size() + // to be aligned to CardTableModRefBS::card_size * BitsPerWord. + // Note that rescan_task_size() will be aligned if CMSRescanMultiple is a multiple of 'HeapWordSize' + // because rescan_task_size() is CardTableModRefBS::card_size / HeapWordSize * BitsPerWord. + if (value % HeapWordSize != 0) { + CommandLineError::print(verbose, + "CMSRescanMultiple (" SIZE_FORMAT ") must be " + "a multiple of " SIZE_FORMAT "\n", + value, HeapWordSize); + status = Flag::VIOLATES_CONSTRAINT; + } + } +#endif + + return status; +} + +Flag::Error CMSConcMarkMultipleConstraintFunc(size_t value, bool verbose) { + return CMSReservedAreaConstraintFunc("CMSConcMarkMultiple", value, verbose); +} + Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose) { #if INCLUDE_ALL_GCS if (UseConcMarkSweepGC && (value <= CMSPrecleanNumerator)) { diff -r 4a57933cebfa -r f8fd0bcc60af hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp --- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp Thu Apr 07 15:33:25 2016 -0700 +++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp Thu Apr 07 15:34:21 2016 -0700 @@ -60,6 +60,8 @@ Flag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose); Flag::Error CMSOldPLABMaxConstraintFunc(size_t value, bool verbose); Flag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose); +Flag::Error CMSRescanMultipleConstraintFunc(size_t value, bool verbose); +Flag::Error CMSConcMarkMultipleConstraintFunc(size_t value, bool verbose); Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose); Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose); Flag::Error CMSSamplingGrainConstraintFunc(uintx value, bool verbose); diff -r 4a57933cebfa -r f8fd0bcc60af hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Thu Apr 07 15:33:25 2016 -0700 +++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Apr 07 15:34:21 2016 -0700 @@ -1806,13 +1806,17 @@ "enough work per iteration") \ range(0, max_intx) \ \ + /* 4096 = CardTableModRefBS::card_size_in_words * BitsPerWord */ \ product(size_t, CMSRescanMultiple, 32, \ "Size (in cards) of CMS parallel rescan task") \ - range(1, max_uintx) \ - \ + range(1, SIZE_MAX / 4096) \ + constraint(CMSRescanMultipleConstraintFunc,AfterMemoryInit) \ + \ + /* 4096 = CardTableModRefBS::card_size_in_words * BitsPerWord */ \ product(size_t, CMSConcMarkMultiple, 32, \ "Size (in cards) of CMS concurrent MT marking task") \ - range(1, max_uintx) \ + range(1, SIZE_MAX / 4096) \ + constraint(CMSConcMarkMultipleConstraintFunc,AfterMemoryInit) \ \ product(bool, CMSAbortSemantics, false, \ "Whether abort-on-overflow semantics is implemented") \