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(). |