src/hotspot/share/gc/cms/jvmFlagConstraintsCMS.cpp
changeset 50289 0195ee80e530
parent 50033 000c697c81db
child 52004 22ca7ba0c50c
equal deleted inserted replaced
50288:3831655869bc 50289:0195ee80e530
    28 #include "gc/shared/cardTableRS.hpp"
    28 #include "gc/shared/cardTableRS.hpp"
    29 #include "gc/shared/collectedHeap.hpp"
    29 #include "gc/shared/collectedHeap.hpp"
    30 #include "gc/shared/genCollectedHeap.hpp"
    30 #include "gc/shared/genCollectedHeap.hpp"
    31 #include "gc/shared/jvmFlagConstraintsGC.hpp"
    31 #include "gc/shared/jvmFlagConstraintsGC.hpp"
    32 #include "memory/universe.hpp"
    32 #include "memory/universe.hpp"
    33 #include "runtime/flags/jvmFlagRangeList.hpp"
       
    34 #include "runtime/globals_extension.hpp"
    33 #include "runtime/globals_extension.hpp"
    35 #include "utilities/globalDefinitions.hpp"
    34 #include "utilities/globalDefinitions.hpp"
    36 
    35 
    37 static JVMFlag::Error ParallelGCThreadsAndCMSWorkQueueDrainThreshold(uint threads, uintx threshold, bool verbose) {
    36 static JVMFlag::Error ParallelGCThreadsAndCMSWorkQueueDrainThreshold(uint threads, uintx threshold, bool verbose) {
    38   // CMSWorkQueueDrainThreshold is verified to be less than max_juint
    37   // CMSWorkQueueDrainThreshold is verified to be less than max_juint
    39   if (UseConcMarkSweepGC && (threads > (uint)(max_jint / (uint)threshold))) {
    38   if (UseConcMarkSweepGC && (threads > (uint)(max_jint / (uint)threshold))) {
    40     CommandLineError::print(verbose,
    39     JVMFlag::printError(verbose,
    41                             "ParallelGCThreads (" UINT32_FORMAT ") or CMSWorkQueueDrainThreshold ("
    40                         "ParallelGCThreads (" UINT32_FORMAT ") or CMSWorkQueueDrainThreshold ("
    42                             UINTX_FORMAT ") is too large\n",
    41                         UINTX_FORMAT ") is too large\n",
    43                             threads, threshold);
    42                         threads, threshold);
    44     return JVMFlag::VIOLATES_CONSTRAINT;
    43     return JVMFlag::VIOLATES_CONSTRAINT;
    45   }
    44   }
    46   return JVMFlag::SUCCESS;
    45   return JVMFlag::SUCCESS;
    47 }
    46 }
    48 
    47 
    49 JVMFlag::Error ParallelGCThreadsConstraintFuncCMS(uint value, bool verbose) {
    48 JVMFlag::Error ParallelGCThreadsConstraintFuncCMS(uint value, bool verbose) {
    50   // To avoid overflow at ParScanClosure::do_oop_work.
    49   // To avoid overflow at ParScanClosure::do_oop_work.
    51   if (UseConcMarkSweepGC && (value > (max_jint / 10))) {
    50   if (UseConcMarkSweepGC && (value > (max_jint / 10))) {
    52     CommandLineError::print(verbose,
    51     JVMFlag::printError(verbose,
    53                             "ParallelGCThreads (" UINT32_FORMAT ") must be "
    52                         "ParallelGCThreads (" UINT32_FORMAT ") must be "
    54                             "less than or equal to " UINT32_FORMAT " for CMS GC\n",
    53                         "less than or equal to " UINT32_FORMAT " for CMS GC\n",
    55                             value, (max_jint / 10));
    54                         value, (max_jint / 10));
    56     return JVMFlag::VIOLATES_CONSTRAINT;
    55     return JVMFlag::VIOLATES_CONSTRAINT;
    57   }
    56   }
    58   return ParallelGCThreadsAndCMSWorkQueueDrainThreshold(value, CMSWorkQueueDrainThreshold, verbose);
    57   return ParallelGCThreadsAndCMSWorkQueueDrainThreshold(value, CMSWorkQueueDrainThreshold, verbose);
    59 }
    58 }
    60 JVMFlag::Error ParGCStridesPerThreadConstraintFunc(uintx value, bool verbose) {
    59 JVMFlag::Error ParGCStridesPerThreadConstraintFunc(uintx value, bool verbose) {
    61   if (UseConcMarkSweepGC && (value > ((uintx)max_jint / (uintx)ParallelGCThreads))) {
    60   if (UseConcMarkSweepGC && (value > ((uintx)max_jint / (uintx)ParallelGCThreads))) {
    62     CommandLineError::print(verbose,
    61     JVMFlag::printError(verbose,
    63                             "ParGCStridesPerThread (" UINTX_FORMAT ") must be "
    62                         "ParGCStridesPerThread (" UINTX_FORMAT ") must be "
    64                             "less than or equal to ergonomic maximum (" UINTX_FORMAT ")\n",
    63                         "less than or equal to ergonomic maximum (" UINTX_FORMAT ")\n",
    65                             value, ((uintx)max_jint / (uintx)ParallelGCThreads));
    64                         value, ((uintx)max_jint / (uintx)ParallelGCThreads));
    66     return JVMFlag::VIOLATES_CONSTRAINT;
    65     return JVMFlag::VIOLATES_CONSTRAINT;
    67   }
    66   }
    68   return JVMFlag::SUCCESS;
    67   return JVMFlag::SUCCESS;
    69 }
    68 }
    70 
    69 
    74     size_t heap_size = Universe::heap()->reserved_region().word_size();
    73     size_t heap_size = Universe::heap()->reserved_region().word_size();
    75     CardTableRS* ct = GenCollectedHeap::heap()->rem_set();
    74     CardTableRS* ct = GenCollectedHeap::heap()->rem_set();
    76     size_t card_table_size = ct->cards_required(heap_size) - 1; // Valid card table size
    75     size_t card_table_size = ct->cards_required(heap_size) - 1; // Valid card table size
    77 
    76 
    78     if ((size_t)value > card_table_size) {
    77     if ((size_t)value > card_table_size) {
    79       CommandLineError::print(verbose,
    78       JVMFlag::printError(verbose,
    80                               "ParGCCardsPerStrideChunk (" INTX_FORMAT ") is too large for the heap size and "
    79                           "ParGCCardsPerStrideChunk (" INTX_FORMAT ") is too large for the heap size and "
    81                               "must be less than or equal to card table size (" SIZE_FORMAT ")\n",
    80                           "must be less than or equal to card table size (" SIZE_FORMAT ")\n",
    82                               value, card_table_size);
    81                           value, card_table_size);
    83       return JVMFlag::VIOLATES_CONSTRAINT;
    82       return JVMFlag::VIOLATES_CONSTRAINT;
    84     }
    83     }
    85 
    84 
    86     // ParGCCardsPerStrideChunk is used with n_strides(ParallelGCThreads*ParGCStridesPerThread)
    85     // ParGCCardsPerStrideChunk is used with n_strides(ParallelGCThreads*ParGCStridesPerThread)
    87     // from CardTableRS::process_stride(). Note that ParGCStridesPerThread is already checked
    86     // from CardTableRS::process_stride(). Note that ParGCStridesPerThread is already checked
    88     // not to make an overflow with ParallelGCThreads from its constraint function.
    87     // not to make an overflow with ParallelGCThreads from its constraint function.
    89     uintx n_strides = ParallelGCThreads * ParGCStridesPerThread;
    88     uintx n_strides = ParallelGCThreads * ParGCStridesPerThread;
    90     uintx ergo_max = max_uintx / n_strides;
    89     uintx ergo_max = max_uintx / n_strides;
    91     if ((uintx)value > ergo_max) {
    90     if ((uintx)value > ergo_max) {
    92       CommandLineError::print(verbose,
    91       JVMFlag::printError(verbose,
    93                               "ParGCCardsPerStrideChunk (" INTX_FORMAT ") must be "
    92                           "ParGCCardsPerStrideChunk (" INTX_FORMAT ") must be "
    94                               "less than or equal to ergonomic maximum (" UINTX_FORMAT ")\n",
    93                           "less than or equal to ergonomic maximum (" UINTX_FORMAT ")\n",
    95                               value, ergo_max);
    94                           value, ergo_max);
    96       return JVMFlag::VIOLATES_CONSTRAINT;
    95       return JVMFlag::VIOLATES_CONSTRAINT;
    97     }
    96     }
    98   }
    97   }
    99   return JVMFlag::SUCCESS;
    98   return JVMFlag::SUCCESS;
   100 }
    99 }
   102 JVMFlag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose) {
   101 JVMFlag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose) {
   103   JVMFlag::Error status = JVMFlag::SUCCESS;
   102   JVMFlag::Error status = JVMFlag::SUCCESS;
   104 
   103 
   105   if (UseConcMarkSweepGC) {
   104   if (UseConcMarkSweepGC) {
   106     if (value > CMSOldPLABMax) {
   105     if (value > CMSOldPLABMax) {
   107       CommandLineError::print(verbose,
   106       JVMFlag::printError(verbose,
   108                               "CMSOldPLABMin (" SIZE_FORMAT ") must be "
   107                           "CMSOldPLABMin (" SIZE_FORMAT ") must be "
   109                               "less than or equal to CMSOldPLABMax (" SIZE_FORMAT ")\n",
   108                           "less than or equal to CMSOldPLABMax (" SIZE_FORMAT ")\n",
   110                               value, CMSOldPLABMax);
   109                           value, CMSOldPLABMax);
   111       return JVMFlag::VIOLATES_CONSTRAINT;
   110       return JVMFlag::VIOLATES_CONSTRAINT;
   112     }
   111     }
   113     status = MaxPLABSizeBounds("CMSOldPLABMin", value, verbose);
   112     status = MaxPLABSizeBounds("CMSOldPLABMin", value, verbose);
   114   }
   113   }
   115   return status;
   114   return status;
   127 static JVMFlag::Error CMSReservedAreaConstraintFunc(const char* name, size_t value, bool verbose) {
   126 static JVMFlag::Error CMSReservedAreaConstraintFunc(const char* name, size_t value, bool verbose) {
   128   if (UseConcMarkSweepGC) {
   127   if (UseConcMarkSweepGC) {
   129     ConcurrentMarkSweepGeneration* cms = CMSHeap::heap()->old_gen();
   128     ConcurrentMarkSweepGeneration* cms = CMSHeap::heap()->old_gen();
   130     const size_t ergo_max = cms->cmsSpace()->max_flag_size_for_task_size();
   129     const size_t ergo_max = cms->cmsSpace()->max_flag_size_for_task_size();
   131     if (value > ergo_max) {
   130     if (value > ergo_max) {
   132       CommandLineError::print(verbose,
   131       JVMFlag::printError(verbose,
   133                               "%s (" SIZE_FORMAT ") must be "
   132                           "%s (" SIZE_FORMAT ") must be "
   134                               "less than or equal to ergonomic maximum (" SIZE_FORMAT ") "
   133                           "less than or equal to ergonomic maximum (" SIZE_FORMAT ") "
   135                               "which is based on the maximum size of the old generation of the Java heap\n",
   134                           "which is based on the maximum size of the old generation of the Java heap\n",
   136                               name, value, ergo_max);
   135                           name, value, ergo_max);
   137       return JVMFlag::VIOLATES_CONSTRAINT;
   136       return JVMFlag::VIOLATES_CONSTRAINT;
   138     }
   137     }
   139   }
   138   }
   140 
   139 
   141   return JVMFlag::SUCCESS;
   140   return JVMFlag::SUCCESS;
   148     // CMSParRemarkTask::do_dirty_card_rescan_tasks requires CompactibleFreeListSpace::rescan_task_size()
   147     // CMSParRemarkTask::do_dirty_card_rescan_tasks requires CompactibleFreeListSpace::rescan_task_size()
   149     // to be aligned to CardTable::card_size * BitsPerWord.
   148     // to be aligned to CardTable::card_size * BitsPerWord.
   150     // Note that rescan_task_size() will be aligned if CMSRescanMultiple is a multiple of 'HeapWordSize'
   149     // Note that rescan_task_size() will be aligned if CMSRescanMultiple is a multiple of 'HeapWordSize'
   151     // because rescan_task_size() is CardTable::card_size / HeapWordSize * BitsPerWord.
   150     // because rescan_task_size() is CardTable::card_size / HeapWordSize * BitsPerWord.
   152     if (value % HeapWordSize != 0) {
   151     if (value % HeapWordSize != 0) {
   153       CommandLineError::print(verbose,
   152       JVMFlag::printError(verbose,
   154                               "CMSRescanMultiple (" SIZE_FORMAT ") must be "
   153                           "CMSRescanMultiple (" SIZE_FORMAT ") must be "
   155                               "a multiple of " SIZE_FORMAT "\n",
   154                           "a multiple of " SIZE_FORMAT "\n",
   156                               value, HeapWordSize);
   155                           value, HeapWordSize);
   157       status = JVMFlag::VIOLATES_CONSTRAINT;
   156       status = JVMFlag::VIOLATES_CONSTRAINT;
   158     }
   157     }
   159   }
   158   }
   160 
   159 
   161   return status;
   160   return status;
   165   return CMSReservedAreaConstraintFunc("CMSConcMarkMultiple", value, verbose);
   164   return CMSReservedAreaConstraintFunc("CMSConcMarkMultiple", value, verbose);
   166 }
   165 }
   167 
   166 
   168 JVMFlag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose) {
   167 JVMFlag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose) {
   169   if (UseConcMarkSweepGC && (value <= CMSPrecleanNumerator)) {
   168   if (UseConcMarkSweepGC && (value <= CMSPrecleanNumerator)) {
   170     CommandLineError::print(verbose,
   169     JVMFlag::printError(verbose,
   171                             "CMSPrecleanDenominator (" UINTX_FORMAT ") must be "
   170                         "CMSPrecleanDenominator (" UINTX_FORMAT ") must be "
   172                             "strickly greater than CMSPrecleanNumerator (" UINTX_FORMAT ")\n",
   171                         "strickly greater than CMSPrecleanNumerator (" UINTX_FORMAT ")\n",
   173                             value, CMSPrecleanNumerator);
   172                         value, CMSPrecleanNumerator);
   174     return JVMFlag::VIOLATES_CONSTRAINT;
   173     return JVMFlag::VIOLATES_CONSTRAINT;
   175   }
   174   }
   176   return JVMFlag::SUCCESS;
   175   return JVMFlag::SUCCESS;
   177 }
   176 }
   178 
   177 
   179 JVMFlag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose) {
   178 JVMFlag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose) {
   180   if (UseConcMarkSweepGC && (value >= CMSPrecleanDenominator)) {
   179   if (UseConcMarkSweepGC && (value >= CMSPrecleanDenominator)) {
   181     CommandLineError::print(verbose,
   180     JVMFlag::printError(verbose,
   182                             "CMSPrecleanNumerator (" UINTX_FORMAT ") must be "
   181                         "CMSPrecleanNumerator (" UINTX_FORMAT ") must be "
   183                             "less than CMSPrecleanDenominator (" UINTX_FORMAT ")\n",
   182                         "less than CMSPrecleanDenominator (" UINTX_FORMAT ")\n",
   184                             value, CMSPrecleanDenominator);
   183                         value, CMSPrecleanDenominator);
   185     return JVMFlag::VIOLATES_CONSTRAINT;
   184     return JVMFlag::VIOLATES_CONSTRAINT;
   186   }
   185   }
   187   return JVMFlag::SUCCESS;
   186   return JVMFlag::SUCCESS;
   188 }
   187 }
   189 
   188 
   190 JVMFlag::Error CMSSamplingGrainConstraintFunc(uintx value, bool verbose) {
   189 JVMFlag::Error CMSSamplingGrainConstraintFunc(uintx value, bool verbose) {
   191   if (UseConcMarkSweepGC) {
   190   if (UseConcMarkSweepGC) {
   192     size_t max_capacity = CMSHeap::heap()->young_gen()->max_capacity();
   191     size_t max_capacity = CMSHeap::heap()->young_gen()->max_capacity();
   193     if (value > max_uintx - max_capacity) {
   192     if (value > max_uintx - max_capacity) {
   194     CommandLineError::print(verbose,
   193     JVMFlag::printError(verbose,
   195                             "CMSSamplingGrain (" UINTX_FORMAT ") must be "
   194                         "CMSSamplingGrain (" UINTX_FORMAT ") must be "
   196                             "less than or equal to ergonomic maximum (" SIZE_FORMAT ")\n",
   195                         "less than or equal to ergonomic maximum (" SIZE_FORMAT ")\n",
   197                             value, max_uintx - max_capacity);
   196                         value, max_uintx - max_capacity);
   198     return JVMFlag::VIOLATES_CONSTRAINT;
   197     return JVMFlag::VIOLATES_CONSTRAINT;
   199     }
   198     }
   200   }
   199   }
   201   return JVMFlag::SUCCESS;
   200   return JVMFlag::SUCCESS;
   202 }
   201 }
   214     // CMSBitMapYieldQuantum should be compared with mark bitmap size.
   213     // CMSBitMapYieldQuantum should be compared with mark bitmap size.
   215     ConcurrentMarkSweepGeneration* cms = CMSHeap::heap()->old_gen();
   214     ConcurrentMarkSweepGeneration* cms = CMSHeap::heap()->old_gen();
   216     size_t bitmap_size = cms->collector()->markBitMap()->sizeInWords();
   215     size_t bitmap_size = cms->collector()->markBitMap()->sizeInWords();
   217 
   216 
   218     if (value > bitmap_size) {
   217     if (value > bitmap_size) {
   219       CommandLineError::print(verbose,
   218       JVMFlag::printError(verbose,
   220                               "CMSBitMapYieldQuantum (" SIZE_FORMAT ") must "
   219                           "CMSBitMapYieldQuantum (" SIZE_FORMAT ") must "
   221                               "be less than or equal to bitmap size (" SIZE_FORMAT ") "
   220                           "be less than or equal to bitmap size (" SIZE_FORMAT ") "
   222                               "whose size corresponds to the size of old generation of the Java heap\n",
   221                           "whose size corresponds to the size of old generation of the Java heap\n",
   223                               value, bitmap_size);
   222                           value, bitmap_size);
   224       return JVMFlag::VIOLATES_CONSTRAINT;
   223       return JVMFlag::VIOLATES_CONSTRAINT;
   225     }
   224     }
   226   }
   225   }
   227   return JVMFlag::SUCCESS;
   226   return JVMFlag::SUCCESS;
   228 }
   227 }
   229 
   228 
   230 JVMFlag::Error OldPLABSizeConstraintFuncCMS(size_t value, bool verbose) {
   229 JVMFlag::Error OldPLABSizeConstraintFuncCMS(size_t value, bool verbose) {
   231   if (value == 0) {
   230   if (value == 0) {
   232     CommandLineError::print(verbose,
   231     JVMFlag::printError(verbose,
   233                             "OldPLABSize (" SIZE_FORMAT ") must be greater than 0",
   232                         "OldPLABSize (" SIZE_FORMAT ") must be greater than 0",
   234                             value);
   233                         value);
   235     return JVMFlag::VIOLATES_CONSTRAINT;
   234     return JVMFlag::VIOLATES_CONSTRAINT;
   236   }
   235   }
   237   // For CMS, OldPLABSize is the number of free blocks of a given size that are used when
   236   // For CMS, OldPLABSize is the number of free blocks of a given size that are used when
   238   // replenishing the local per-worker free list caches.
   237   // replenishing the local per-worker free list caches.
   239   // For more details, please refer to Arguments::set_cms_and_parnew_gc_flags().
   238   // For more details, please refer to Arguments::set_cms_and_parnew_gc_flags().