Mercurial > hg > graal-compiler
comparison src/share/vm/memory/collectorPolicy.cpp @ 13060:8f07aa079343
8016309: assert(eden_size > 0 && survivor_size > 0) failed: just checking
7057939: jmap shows MaxNewSize=4GB when Java is using parallel collector
Summary: Major cleanup of the collectorpolicy classes
Reviewed-by: tschatzl, jcoomes
author | jwilhelm |
---|---|
date | Fri, 01 Nov 2013 17:09:38 +0100 |
parents | 46d7652b223c |
children | 3ad2b68d107e |
comparison
equal
deleted
inserted
replaced
13059:46d7652b223c | 13060:8f07aa079343 |
---|---|
45 #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp" | 45 #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp" |
46 #endif // INCLUDE_ALL_GCS | 46 #endif // INCLUDE_ALL_GCS |
47 | 47 |
48 // CollectorPolicy methods. | 48 // CollectorPolicy methods. |
49 | 49 |
50 CollectorPolicy::CollectorPolicy() : | |
51 _space_alignment(0), | |
52 _heap_alignment(0), | |
53 _initial_heap_byte_size(InitialHeapSize), | |
54 _max_heap_byte_size(MaxHeapSize), | |
55 _min_heap_byte_size(Arguments::min_heap_size()), | |
56 _max_heap_size_cmdline(false), | |
57 _size_policy(NULL), | |
58 _should_clear_all_soft_refs(false), | |
59 _all_soft_refs_clear(false) | |
60 {} | |
61 | |
62 #ifdef ASSERT | |
63 void CollectorPolicy::assert_flags() { | |
64 assert(InitialHeapSize <= MaxHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes"); | |
65 assert(InitialHeapSize % _heap_alignment == 0, "InitialHeapSize alignment"); | |
66 assert(MaxHeapSize % _heap_alignment == 0, "MaxHeapSize alignment"); | |
67 } | |
68 | |
69 void CollectorPolicy::assert_size_info() { | |
70 assert(InitialHeapSize == _initial_heap_byte_size, "Discrepancy between InitialHeapSize flag and local storage"); | |
71 assert(MaxHeapSize == _max_heap_byte_size, "Discrepancy between MaxHeapSize flag and local storage"); | |
72 assert(_max_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible minimum and maximum heap sizes"); | |
73 assert(_initial_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible initial and minimum heap sizes"); | |
74 assert(_max_heap_byte_size >= _initial_heap_byte_size, "Ergonomics decided on incompatible initial and maximum heap sizes"); | |
75 assert(_min_heap_byte_size % _heap_alignment == 0, "min_heap_byte_size alignment"); | |
76 assert(_initial_heap_byte_size % _heap_alignment == 0, "initial_heap_byte_size alignment"); | |
77 assert(_max_heap_byte_size % _heap_alignment == 0, "max_heap_byte_size alignment"); | |
78 } | |
79 #endif // ASSERT | |
80 | |
50 void CollectorPolicy::initialize_flags() { | 81 void CollectorPolicy::initialize_flags() { |
51 assert(_max_alignment >= _min_alignment, | 82 assert(_space_alignment != 0, "Space alignment not set up properly"); |
52 err_msg("max_alignment: " SIZE_FORMAT " less than min_alignment: " SIZE_FORMAT, | 83 assert(_heap_alignment != 0, "Heap alignment not set up properly"); |
53 _max_alignment, _min_alignment)); | 84 assert(_heap_alignment >= _space_alignment, |
54 assert(_max_alignment % _min_alignment == 0, | 85 err_msg("heap_alignment: " SIZE_FORMAT " less than space_alignment: " SIZE_FORMAT, |
55 err_msg("max_alignment: " SIZE_FORMAT " not aligned by min_alignment: " SIZE_FORMAT, | 86 _heap_alignment, _space_alignment)); |
56 _max_alignment, _min_alignment)); | 87 assert(_heap_alignment % _space_alignment == 0, |
57 | 88 err_msg("heap_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT, |
58 if (MaxHeapSize < InitialHeapSize) { | 89 _heap_alignment, _space_alignment)); |
59 vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); | 90 |
60 } | 91 if (FLAG_IS_CMDLINE(MaxHeapSize)) { |
61 | 92 if (FLAG_IS_CMDLINE(InitialHeapSize) && InitialHeapSize > MaxHeapSize) { |
62 MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, _min_alignment); | 93 vm_exit_during_initialization("Initial heap size set to a larger value than the maximum heap size"); |
63 } | 94 } |
64 | 95 if (_min_heap_byte_size != 0 && MaxHeapSize < _min_heap_byte_size) { |
65 void CollectorPolicy::initialize_size_info() { | 96 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified"); |
66 // User inputs from -mx and ms must be aligned | 97 } |
67 _min_heap_byte_size = align_size_up(Arguments::min_heap_size(), _min_alignment); | 98 _max_heap_size_cmdline = true; |
68 _initial_heap_byte_size = align_size_up(InitialHeapSize, _min_alignment); | 99 } |
69 _max_heap_byte_size = align_size_up(MaxHeapSize, _max_alignment); | |
70 | 100 |
71 // Check heap parameter properties | 101 // Check heap parameter properties |
72 if (_initial_heap_byte_size < M) { | 102 if (InitialHeapSize < M) { |
73 vm_exit_during_initialization("Too small initial heap"); | 103 vm_exit_during_initialization("Too small initial heap"); |
74 } | 104 } |
75 // Check heap parameter properties | |
76 if (_min_heap_byte_size < M) { | 105 if (_min_heap_byte_size < M) { |
77 vm_exit_during_initialization("Too small minimum heap"); | 106 vm_exit_during_initialization("Too small minimum heap"); |
78 } | 107 } |
79 if (_initial_heap_byte_size <= NewSize) { | 108 |
80 // make sure there is at least some room in old space | 109 // User inputs from -Xmx and -Xms must be aligned |
81 vm_exit_during_initialization("Too small initial heap for new size specified"); | 110 _min_heap_byte_size = align_size_up(_min_heap_byte_size, _heap_alignment); |
82 } | 111 uintx aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment); |
83 if (_max_heap_byte_size < _min_heap_byte_size) { | 112 uintx aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment); |
84 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified"); | 113 |
85 } | 114 // Write back to flags if the values changed |
86 if (_initial_heap_byte_size < _min_heap_byte_size) { | 115 if (aligned_initial_heap_size != InitialHeapSize) { |
116 FLAG_SET_ERGO(uintx, InitialHeapSize, aligned_initial_heap_size); | |
117 } | |
118 if (aligned_max_heap_size != MaxHeapSize) { | |
119 FLAG_SET_ERGO(uintx, MaxHeapSize, aligned_max_heap_size); | |
120 } | |
121 | |
122 if (FLAG_IS_CMDLINE(InitialHeapSize) && _min_heap_byte_size != 0 && | |
123 InitialHeapSize < _min_heap_byte_size) { | |
87 vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified"); | 124 vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified"); |
88 } | 125 } |
89 if (_max_heap_byte_size < _initial_heap_byte_size) { | 126 if (!FLAG_IS_DEFAULT(InitialHeapSize) && InitialHeapSize > MaxHeapSize) { |
90 vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); | 127 FLAG_SET_ERGO(uintx, MaxHeapSize, InitialHeapSize); |
91 } | 128 } else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) { |
92 | 129 FLAG_SET_ERGO(uintx, InitialHeapSize, MaxHeapSize); |
130 if (InitialHeapSize < _min_heap_byte_size) { | |
131 _min_heap_byte_size = InitialHeapSize; | |
132 } | |
133 } | |
134 | |
135 _initial_heap_byte_size = InitialHeapSize; | |
136 _max_heap_byte_size = MaxHeapSize; | |
137 | |
138 FLAG_SET_ERGO(uintx, MinHeapDeltaBytes, align_size_up(MinHeapDeltaBytes, _space_alignment)); | |
139 | |
140 DEBUG_ONLY(CollectorPolicy::assert_flags();) | |
141 } | |
142 | |
143 void CollectorPolicy::initialize_size_info() { | |
93 if (PrintGCDetails && Verbose) { | 144 if (PrintGCDetails && Verbose) { |
94 gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap " | 145 gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap " |
95 SIZE_FORMAT " Maximum heap " SIZE_FORMAT, | 146 SIZE_FORMAT " Maximum heap " SIZE_FORMAT, |
96 _min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size); | 147 _min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size); |
97 } | 148 } |
149 | |
150 DEBUG_ONLY(CollectorPolicy::assert_size_info();) | |
98 } | 151 } |
99 | 152 |
100 bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) { | 153 bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) { |
101 bool result = _should_clear_all_soft_refs; | 154 bool result = _should_clear_all_soft_refs; |
102 set_should_clear_all_soft_refs(false); | 155 set_should_clear_all_soft_refs(false); |
116 _should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near(); | 169 _should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near(); |
117 } | 170 } |
118 _all_soft_refs_clear = true; | 171 _all_soft_refs_clear = true; |
119 } | 172 } |
120 | 173 |
121 size_t CollectorPolicy::compute_max_alignment() { | 174 size_t CollectorPolicy::compute_heap_alignment() { |
122 // The card marking array and the offset arrays for old generations are | 175 // The card marking array and the offset arrays for old generations are |
123 // committed in os pages as well. Make sure they are entirely full (to | 176 // committed in os pages as well. Make sure they are entirely full (to |
124 // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 | 177 // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 |
125 // byte entry and the os page size is 4096, the maximum heap size should | 178 // byte entry and the os page size is 4096, the maximum heap size should |
126 // be 512*4096 = 2MB aligned. | 179 // be 512*4096 = 2MB aligned. |
143 return alignment; | 196 return alignment; |
144 } | 197 } |
145 | 198 |
146 // GenCollectorPolicy methods. | 199 // GenCollectorPolicy methods. |
147 | 200 |
201 GenCollectorPolicy::GenCollectorPolicy() : | |
202 _min_gen0_size(0), | |
203 _initial_gen0_size(0), | |
204 _max_gen0_size(0), | |
205 _gen_alignment(0), | |
206 _generations(NULL) | |
207 {} | |
208 | |
148 size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) { | 209 size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) { |
149 return align_size_down_bounded(base_size / (NewRatio + 1), _min_alignment); | 210 return align_size_down_bounded(base_size / (NewRatio + 1), _gen_alignment); |
150 } | 211 } |
151 | 212 |
152 size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size, | 213 size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size, |
153 size_t maximum_size) { | 214 size_t maximum_size) { |
154 size_t alignment = _min_alignment; | 215 size_t max_minus = maximum_size - _gen_alignment; |
155 size_t max_minus = maximum_size - alignment; | |
156 return desired_size < max_minus ? desired_size : max_minus; | 216 return desired_size < max_minus ? desired_size : max_minus; |
157 } | 217 } |
158 | 218 |
159 | 219 |
160 void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size, | 220 void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size, |
166 init_survivor_size, | 226 init_survivor_size, |
167 max_gc_pause_sec, | 227 max_gc_pause_sec, |
168 GCTimeRatio); | 228 GCTimeRatio); |
169 } | 229 } |
170 | 230 |
231 size_t GenCollectorPolicy::young_gen_size_lower_bound() { | |
232 // The young generation must be aligned and have room for eden + two survivors | |
233 return align_size_up(3 * _space_alignment, _gen_alignment); | |
234 } | |
235 | |
236 #ifdef ASSERT | |
237 void GenCollectorPolicy::assert_flags() { | |
238 CollectorPolicy::assert_flags(); | |
239 assert(NewSize >= _min_gen0_size, "Ergonomics decided on a too small young gen size"); | |
240 assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes"); | |
241 assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young gen and heap sizes"); | |
242 assert(NewSize % _gen_alignment == 0, "NewSize alignment"); | |
243 assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize % _gen_alignment == 0, "MaxNewSize alignment"); | |
244 } | |
245 | |
246 void TwoGenerationCollectorPolicy::assert_flags() { | |
247 GenCollectorPolicy::assert_flags(); | |
248 assert(OldSize + NewSize <= MaxHeapSize, "Ergonomics decided on incompatible generation and heap sizes"); | |
249 assert(OldSize % _gen_alignment == 0, "OldSize alignment"); | |
250 } | |
251 | |
252 void GenCollectorPolicy::assert_size_info() { | |
253 CollectorPolicy::assert_size_info(); | |
254 // GenCollectorPolicy::initialize_size_info may update the MaxNewSize | |
255 assert(MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young and heap sizes"); | |
256 assert(NewSize == _initial_gen0_size, "Discrepancy between NewSize flag and local storage"); | |
257 assert(MaxNewSize == _max_gen0_size, "Discrepancy between MaxNewSize flag and local storage"); | |
258 assert(_min_gen0_size <= _initial_gen0_size, "Ergonomics decided on incompatible minimum and initial young gen sizes"); | |
259 assert(_initial_gen0_size <= _max_gen0_size, "Ergonomics decided on incompatible initial and maximum young gen sizes"); | |
260 assert(_min_gen0_size % _gen_alignment == 0, "_min_gen0_size alignment"); | |
261 assert(_initial_gen0_size % _gen_alignment == 0, "_initial_gen0_size alignment"); | |
262 assert(_max_gen0_size % _gen_alignment == 0, "_max_gen0_size alignment"); | |
263 } | |
264 | |
265 void TwoGenerationCollectorPolicy::assert_size_info() { | |
266 GenCollectorPolicy::assert_size_info(); | |
267 assert(OldSize == _initial_gen1_size, "Discrepancy between OldSize flag and local storage"); | |
268 assert(_min_gen1_size <= _initial_gen1_size, "Ergonomics decided on incompatible minimum and initial old gen sizes"); | |
269 assert(_initial_gen1_size <= _max_gen1_size, "Ergonomics decided on incompatible initial and maximum old gen sizes"); | |
270 assert(_max_gen1_size % _gen_alignment == 0, "_max_gen1_size alignment"); | |
271 assert(_initial_gen1_size % _gen_alignment == 0, "_initial_gen1_size alignment"); | |
272 assert(_max_heap_byte_size <= (_max_gen0_size + _max_gen1_size), "Total maximum heap sizes must be sum of generation maximum sizes"); | |
273 } | |
274 #endif // ASSERT | |
275 | |
171 void GenCollectorPolicy::initialize_flags() { | 276 void GenCollectorPolicy::initialize_flags() { |
172 // All sizes must be multiples of the generation granularity. | |
173 _min_alignment = (uintx) Generation::GenGrain; | |
174 _max_alignment = compute_max_alignment(); | |
175 | |
176 CollectorPolicy::initialize_flags(); | 277 CollectorPolicy::initialize_flags(); |
177 | 278 |
178 // All generational heaps have a youngest gen; handle those flags here. | 279 assert(_gen_alignment != 0, "Generation alignment not set up properly"); |
179 | 280 assert(_heap_alignment >= _gen_alignment, |
180 // Adjust max size parameters | 281 err_msg("heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT, |
282 _heap_alignment, _gen_alignment)); | |
283 assert(_gen_alignment % _space_alignment == 0, | |
284 err_msg("gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT, | |
285 _gen_alignment, _space_alignment)); | |
286 assert(_heap_alignment % _gen_alignment == 0, | |
287 err_msg("heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT, | |
288 _heap_alignment, _gen_alignment)); | |
289 | |
290 // All generational heaps have a youngest gen; handle those flags here | |
291 | |
292 // Make sure the heap is large enough for two generations | |
293 uintx smallest_new_size = young_gen_size_lower_bound(); | |
294 uintx smallest_heap_size = align_size_up(smallest_new_size + align_size_up(_space_alignment, _gen_alignment), | |
295 _heap_alignment); | |
296 if (MaxHeapSize < smallest_heap_size) { | |
297 FLAG_SET_ERGO(uintx, MaxHeapSize, smallest_heap_size); | |
298 _max_heap_byte_size = MaxHeapSize; | |
299 } | |
300 // If needed, synchronize _min_heap_byte size and _initial_heap_byte_size | |
301 if (_min_heap_byte_size < smallest_heap_size) { | |
302 _min_heap_byte_size = smallest_heap_size; | |
303 if (InitialHeapSize < _min_heap_byte_size) { | |
304 FLAG_SET_ERGO(uintx, InitialHeapSize, smallest_heap_size); | |
305 _initial_heap_byte_size = smallest_heap_size; | |
306 } | |
307 } | |
308 | |
309 // Now take the actual NewSize into account. We will silently increase NewSize | |
310 // if the user specified a smaller value. | |
311 smallest_new_size = MAX2(smallest_new_size, (uintx)align_size_down(NewSize, _gen_alignment)); | |
312 if (smallest_new_size != NewSize) { | |
313 FLAG_SET_ERGO(uintx, NewSize, smallest_new_size); | |
314 } | |
315 _initial_gen0_size = NewSize; | |
316 | |
317 if (!FLAG_IS_DEFAULT(MaxNewSize)) { | |
318 uintx min_new_size = MAX2(_gen_alignment, _min_gen0_size); | |
319 | |
320 if (MaxNewSize >= MaxHeapSize) { | |
321 // Make sure there is room for an old generation | |
322 uintx smaller_max_new_size = MaxHeapSize - _gen_alignment; | |
323 if (FLAG_IS_CMDLINE(MaxNewSize)) { | |
324 warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire " | |
325 "heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.", | |
326 MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K); | |
327 } | |
328 FLAG_SET_ERGO(uintx, MaxNewSize, smaller_max_new_size); | |
329 if (NewSize > MaxNewSize) { | |
330 FLAG_SET_ERGO(uintx, NewSize, MaxNewSize); | |
331 _initial_gen0_size = NewSize; | |
332 } | |
333 } else if (MaxNewSize < min_new_size) { | |
334 FLAG_SET_ERGO(uintx, MaxNewSize, min_new_size); | |
335 } else if (!is_size_aligned(MaxNewSize, _gen_alignment)) { | |
336 FLAG_SET_ERGO(uintx, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment)); | |
337 } | |
338 _max_gen0_size = MaxNewSize; | |
339 } | |
340 | |
181 if (NewSize > MaxNewSize) { | 341 if (NewSize > MaxNewSize) { |
182 MaxNewSize = NewSize; | 342 // At this point this should only happen if the user specifies a large NewSize and/or |
183 } | 343 // a small (but not too small) MaxNewSize. |
184 NewSize = align_size_down(NewSize, _min_alignment); | 344 if (FLAG_IS_CMDLINE(MaxNewSize)) { |
185 MaxNewSize = align_size_down(MaxNewSize, _min_alignment); | 345 warning("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). " |
186 | 346 "A new max generation size of " SIZE_FORMAT "k will be used.", |
187 // Check validity of heap flags | 347 NewSize/K, MaxNewSize/K, NewSize/K); |
188 assert(NewSize % _min_alignment == 0, "eden space alignment"); | 348 } |
189 assert(MaxNewSize % _min_alignment == 0, "survivor space alignment"); | 349 FLAG_SET_ERGO(uintx, MaxNewSize, NewSize); |
190 | 350 _max_gen0_size = MaxNewSize; |
191 if (NewSize < 3 * _min_alignment) { | |
192 // make sure there room for eden and two survivor spaces | |
193 vm_exit_during_initialization("Too small new size specified"); | |
194 } | 351 } |
195 | 352 |
196 if (SurvivorRatio < 1 || NewRatio < 1) { | 353 if (SurvivorRatio < 1 || NewRatio < 1) { |
197 vm_exit_during_initialization("Invalid young gen ratio specified"); | 354 vm_exit_during_initialization("Invalid young gen ratio specified"); |
198 } | 355 } |
356 | |
357 DEBUG_ONLY(GenCollectorPolicy::assert_flags();) | |
199 } | 358 } |
200 | 359 |
201 void TwoGenerationCollectorPolicy::initialize_flags() { | 360 void TwoGenerationCollectorPolicy::initialize_flags() { |
202 GenCollectorPolicy::initialize_flags(); | 361 GenCollectorPolicy::initialize_flags(); |
203 | 362 |
204 OldSize = align_size_down(OldSize, _min_alignment); | 363 if (!is_size_aligned(OldSize, _gen_alignment)) { |
205 | 364 FLAG_SET_ERGO(uintx, OldSize, align_size_down(OldSize, _gen_alignment)); |
206 if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(NewSize)) { | 365 } |
366 | |
367 if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) { | |
207 // NewRatio will be used later to set the young generation size so we use | 368 // NewRatio will be used later to set the young generation size so we use |
208 // it to calculate how big the heap should be based on the requested OldSize | 369 // it to calculate how big the heap should be based on the requested OldSize |
209 // and NewRatio. | 370 // and NewRatio. |
210 assert(NewRatio > 0, "NewRatio should have been set up earlier"); | 371 assert(NewRatio > 0, "NewRatio should have been set up earlier"); |
211 size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1); | 372 size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1); |
212 | 373 |
213 calculated_heapsize = align_size_up(calculated_heapsize, _max_alignment); | 374 calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment); |
214 MaxHeapSize = calculated_heapsize; | 375 FLAG_SET_ERGO(uintx, MaxHeapSize, calculated_heapsize); |
215 InitialHeapSize = calculated_heapsize; | 376 _max_heap_byte_size = MaxHeapSize; |
216 } | 377 FLAG_SET_ERGO(uintx, InitialHeapSize, calculated_heapsize); |
217 MaxHeapSize = align_size_up(MaxHeapSize, _max_alignment); | 378 _initial_heap_byte_size = InitialHeapSize; |
379 } | |
218 | 380 |
219 // adjust max heap size if necessary | 381 // adjust max heap size if necessary |
220 if (NewSize + OldSize > MaxHeapSize) { | 382 if (NewSize + OldSize > MaxHeapSize) { |
221 if (FLAG_IS_CMDLINE(MaxHeapSize)) { | 383 if (_max_heap_size_cmdline) { |
222 // somebody set a maximum heap size with the intention that we should not | 384 // somebody set a maximum heap size with the intention that we should not |
223 // exceed it. Adjust New/OldSize as necessary. | 385 // exceed it. Adjust New/OldSize as necessary. |
224 uintx calculated_size = NewSize + OldSize; | 386 uintx calculated_size = NewSize + OldSize; |
225 double shrink_factor = (double) MaxHeapSize / calculated_size; | 387 double shrink_factor = (double) MaxHeapSize / calculated_size; |
226 // align | 388 uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment); |
227 NewSize = align_size_down((uintx) (NewSize * shrink_factor), _min_alignment); | 389 FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size)); |
390 _initial_gen0_size = NewSize; | |
391 | |
228 // OldSize is already aligned because above we aligned MaxHeapSize to | 392 // OldSize is already aligned because above we aligned MaxHeapSize to |
229 // _max_alignment, and we just made sure that NewSize is aligned to | 393 // _heap_alignment, and we just made sure that NewSize is aligned to |
230 // _min_alignment. In initialize_flags() we verified that _max_alignment | 394 // _gen_alignment. In initialize_flags() we verified that _heap_alignment |
231 // is a multiple of _min_alignment. | 395 // is a multiple of _gen_alignment. |
232 OldSize = MaxHeapSize - NewSize; | 396 FLAG_SET_ERGO(uintx, OldSize, MaxHeapSize - NewSize); |
233 } else { | 397 } else { |
234 MaxHeapSize = NewSize + OldSize; | 398 FLAG_SET_ERGO(uintx, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment)); |
235 } | 399 _max_heap_byte_size = MaxHeapSize; |
236 } | 400 } |
237 // need to do this again | 401 } |
238 MaxHeapSize = align_size_up(MaxHeapSize, _max_alignment); | |
239 | |
240 // adjust max heap size if necessary | |
241 if (NewSize + OldSize > MaxHeapSize) { | |
242 if (FLAG_IS_CMDLINE(MaxHeapSize)) { | |
243 // somebody set a maximum heap size with the intention that we should not | |
244 // exceed it. Adjust New/OldSize as necessary. | |
245 uintx calculated_size = NewSize + OldSize; | |
246 double shrink_factor = (double) MaxHeapSize / calculated_size; | |
247 // align | |
248 NewSize = align_size_down((uintx) (NewSize * shrink_factor), _min_alignment); | |
249 // OldSize is already aligned because above we aligned MaxHeapSize to | |
250 // _max_alignment, and we just made sure that NewSize is aligned to | |
251 // _min_alignment. In initialize_flags() we verified that _max_alignment | |
252 // is a multiple of _min_alignment. | |
253 OldSize = MaxHeapSize - NewSize; | |
254 } else { | |
255 MaxHeapSize = NewSize + OldSize; | |
256 } | |
257 } | |
258 // need to do this again | |
259 MaxHeapSize = align_size_up(MaxHeapSize, _max_alignment); | |
260 | 402 |
261 always_do_update_barrier = UseConcMarkSweepGC; | 403 always_do_update_barrier = UseConcMarkSweepGC; |
262 | 404 |
263 // Check validity of heap flags | 405 DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_flags();) |
264 assert(OldSize % _min_alignment == 0, "old space alignment"); | |
265 assert(MaxHeapSize % _max_alignment == 0, "maximum heap alignment"); | |
266 } | 406 } |
267 | 407 |
268 // Values set on the command line win over any ergonomically | 408 // Values set on the command line win over any ergonomically |
269 // set command line parameters. | 409 // set command line parameters. |
270 // Ergonomic choice of parameters are done before this | 410 // Ergonomic choice of parameters are done before this |
275 // In the absence of explicitly set command line flags, policies | 415 // In the absence of explicitly set command line flags, policies |
276 // such as the use of NewRatio are used to size the generation. | 416 // such as the use of NewRatio are used to size the generation. |
277 void GenCollectorPolicy::initialize_size_info() { | 417 void GenCollectorPolicy::initialize_size_info() { |
278 CollectorPolicy::initialize_size_info(); | 418 CollectorPolicy::initialize_size_info(); |
279 | 419 |
280 // _min_alignment is used for alignment within a generation. | 420 // _space_alignment is used for alignment within a generation. |
281 // There is additional alignment done down stream for some | 421 // There is additional alignment done down stream for some |
282 // collectors that sometimes causes unwanted rounding up of | 422 // collectors that sometimes causes unwanted rounding up of |
283 // generations sizes. | 423 // generations sizes. |
284 | 424 |
285 // Determine maximum size of gen0 | 425 // Determine maximum size of gen0 |
286 | 426 |
287 size_t max_new_size = 0; | 427 size_t max_new_size = 0; |
288 if (FLAG_IS_CMDLINE(MaxNewSize) || FLAG_IS_ERGO(MaxNewSize)) { | 428 if (!FLAG_IS_DEFAULT(MaxNewSize)) { |
289 if (MaxNewSize < _min_alignment) { | 429 max_new_size = MaxNewSize; |
290 max_new_size = _min_alignment; | |
291 } | |
292 if (MaxNewSize >= _max_heap_byte_size) { | |
293 max_new_size = align_size_down(_max_heap_byte_size - _min_alignment, | |
294 _min_alignment); | |
295 warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or " | |
296 "greater than the entire heap (" SIZE_FORMAT "k). A " | |
297 "new generation size of " SIZE_FORMAT "k will be used.", | |
298 MaxNewSize/K, _max_heap_byte_size/K, max_new_size/K); | |
299 } else { | |
300 max_new_size = align_size_down(MaxNewSize, _min_alignment); | |
301 } | |
302 | |
303 // The case for FLAG_IS_ERGO(MaxNewSize) could be treated | |
304 // specially at this point to just use an ergonomically set | |
305 // MaxNewSize to set max_new_size. For cases with small | |
306 // heaps such a policy often did not work because the MaxNewSize | |
307 // was larger than the entire heap. The interpretation given | |
308 // to ergonomically set flags is that the flags are set | |
309 // by different collectors for their own special needs but | |
310 // are not allowed to badly shape the heap. This allows the | |
311 // different collectors to decide what's best for themselves | |
312 // without having to factor in the overall heap shape. It | |
313 // can be the case in the future that the collectors would | |
314 // only make "wise" ergonomics choices and this policy could | |
315 // just accept those choices. The choices currently made are | |
316 // not always "wise". | |
317 } else { | 430 } else { |
318 max_new_size = scale_by_NewRatio_aligned(_max_heap_byte_size); | 431 max_new_size = scale_by_NewRatio_aligned(_max_heap_byte_size); |
319 // Bound the maximum size by NewSize below (since it historically | 432 // Bound the maximum size by NewSize below (since it historically |
320 // would have been NewSize and because the NewRatio calculation could | 433 // would have been NewSize and because the NewRatio calculation could |
321 // yield a size that is too small) and bound it by MaxNewSize above. | 434 // yield a size that is too small) and bound it by MaxNewSize above. |
380 _min_gen0_size = MIN2(_min_gen0_size, _max_gen0_size); | 493 _min_gen0_size = MIN2(_min_gen0_size, _max_gen0_size); |
381 _initial_gen0_size = MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size); | 494 _initial_gen0_size = MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size); |
382 _min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size); | 495 _min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size); |
383 } | 496 } |
384 | 497 |
498 // Write back to flags if necessary | |
499 if (NewSize != _initial_gen0_size) { | |
500 FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size); | |
501 } | |
502 | |
503 if (MaxNewSize != _max_gen0_size) { | |
504 FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size); | |
505 } | |
506 | |
385 if (PrintGCDetails && Verbose) { | 507 if (PrintGCDetails && Verbose) { |
386 gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 " | 508 gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 " |
387 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, | 509 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, |
388 _min_gen0_size, _initial_gen0_size, _max_gen0_size); | 510 _min_gen0_size, _initial_gen0_size, _max_gen0_size); |
389 } | 511 } |
512 | |
513 DEBUG_ONLY(GenCollectorPolicy::assert_size_info();) | |
390 } | 514 } |
391 | 515 |
392 // Call this method during the sizing of the gen1 to make | 516 // Call this method during the sizing of the gen1 to make |
393 // adjustments to gen0 because of gen1 sizing policy. gen0 initially has | 517 // adjustments to gen0 because of gen1 sizing policy. gen0 initially has |
394 // the most freedom in sizing because it is done before the | 518 // the most freedom in sizing because it is done before the |
402 const size_t heap_size, | 526 const size_t heap_size, |
403 const size_t min_gen1_size) { | 527 const size_t min_gen1_size) { |
404 bool result = false; | 528 bool result = false; |
405 | 529 |
406 if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) { | 530 if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) { |
531 uintx smallest_new_size = young_gen_size_lower_bound(); | |
407 if ((heap_size < (*gen0_size_ptr + min_gen1_size)) && | 532 if ((heap_size < (*gen0_size_ptr + min_gen1_size)) && |
408 (heap_size >= min_gen1_size + _min_alignment)) { | 533 (heap_size >= min_gen1_size + smallest_new_size)) { |
409 // Adjust gen0 down to accommodate min_gen1_size | 534 // Adjust gen0 down to accommodate min_gen1_size |
410 *gen0_size_ptr = align_size_down_bounded(heap_size - min_gen1_size, _min_alignment); | 535 *gen0_size_ptr = align_size_down_bounded(heap_size - min_gen1_size, _gen_alignment); |
411 assert(*gen0_size_ptr > 0, "Min gen0 is too large"); | 536 assert(*gen0_size_ptr > 0, "Min gen0 is too large"); |
412 result = true; | 537 result = true; |
413 } else { | 538 } else { |
414 *gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _min_alignment); | 539 *gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _gen_alignment); |
415 } | 540 } |
416 } | 541 } |
417 return result; | 542 return result; |
418 } | 543 } |
419 | 544 |
430 // At this point the minimum, initial and maximum sizes | 555 // At this point the minimum, initial and maximum sizes |
431 // of the overall heap and of gen0 have been determined. | 556 // of the overall heap and of gen0 have been determined. |
432 // The maximum gen1 size can be determined from the maximum gen0 | 557 // The maximum gen1 size can be determined from the maximum gen0 |
433 // and maximum heap size since no explicit flags exits | 558 // and maximum heap size since no explicit flags exits |
434 // for setting the gen1 maximum. | 559 // for setting the gen1 maximum. |
435 _max_gen1_size = _max_heap_byte_size - _max_gen0_size; | 560 _max_gen1_size = MAX2(_max_heap_byte_size - _max_gen0_size, _gen_alignment); |
436 _max_gen1_size = | 561 |
437 MAX2((uintx)align_size_down(_max_gen1_size, _min_alignment), _min_alignment); | |
438 // If no explicit command line flag has been set for the | 562 // If no explicit command line flag has been set for the |
439 // gen1 size, use what is left for gen1. | 563 // gen1 size, use what is left for gen1. |
440 if (FLAG_IS_DEFAULT(OldSize) || FLAG_IS_ERGO(OldSize)) { | 564 if (!FLAG_IS_CMDLINE(OldSize)) { |
441 // The user has not specified any value or ergonomics | 565 // The user has not specified any value but the ergonomics |
442 // has chosen a value (which may or may not be consistent | 566 // may have chosen a value (which may or may not be consistent |
443 // with the overall heap size). In either case make | 567 // with the overall heap size). In either case make |
444 // the minimum, maximum and initial sizes consistent | 568 // the minimum, maximum and initial sizes consistent |
445 // with the gen0 sizes and the overall heap sizes. | 569 // with the gen0 sizes and the overall heap sizes. |
446 assert(_min_heap_byte_size > _min_gen0_size, | 570 _min_gen1_size = MAX2(_min_heap_byte_size - _min_gen0_size, _gen_alignment); |
447 "gen0 has an unexpected minimum size"); | 571 _initial_gen1_size = MAX2(_initial_heap_byte_size - _initial_gen0_size, _gen_alignment); |
448 _min_gen1_size = _min_heap_byte_size - _min_gen0_size; | 572 // _max_gen1_size has already been made consistent above |
449 _min_gen1_size = | 573 FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size); |
450 MAX2((uintx)align_size_down(_min_gen1_size, _min_alignment), _min_alignment); | |
451 _initial_gen1_size = _initial_heap_byte_size - _initial_gen0_size; | |
452 _initial_gen1_size = | |
453 MAX2((uintx)align_size_down(_initial_gen1_size, _min_alignment), _min_alignment); | |
454 } else { | 574 } else { |
455 // It's been explicitly set on the command line. Use the | 575 // It's been explicitly set on the command line. Use the |
456 // OldSize and then determine the consequences. | 576 // OldSize and then determine the consequences. |
457 _min_gen1_size = OldSize; | 577 _min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size); |
458 _initial_gen1_size = OldSize; | 578 _initial_gen1_size = OldSize; |
459 | 579 |
460 // If the user has explicitly set an OldSize that is inconsistent | 580 // If the user has explicitly set an OldSize that is inconsistent |
461 // with other command line flags, issue a warning. | 581 // with other command line flags, issue a warning. |
462 // The generation minimums and the overall heap mimimum should | 582 // The generation minimums and the overall heap mimimum should |
463 // be within one heap alignment. | 583 // be within one generation alignment. |
464 if ((_min_gen1_size + _min_gen0_size + _min_alignment) < _min_heap_byte_size) { | 584 if ((_min_gen1_size + _min_gen0_size + _gen_alignment) < _min_heap_byte_size) { |
465 warning("Inconsistency between minimum heap size and minimum " | 585 warning("Inconsistency between minimum heap size and minimum " |
466 "generation sizes: using minimum heap = " SIZE_FORMAT, | 586 "generation sizes: using minimum heap = " SIZE_FORMAT, |
467 _min_heap_byte_size); | 587 _min_heap_byte_size); |
468 } | 588 } |
469 if (OldSize > _max_gen1_size) { | 589 if (OldSize > _max_gen1_size) { |
473 _max_heap_byte_size); | 593 _max_heap_byte_size); |
474 } | 594 } |
475 // If there is an inconsistency between the OldSize and the minimum and/or | 595 // If there is an inconsistency between the OldSize and the minimum and/or |
476 // initial size of gen0, since OldSize was explicitly set, OldSize wins. | 596 // initial size of gen0, since OldSize was explicitly set, OldSize wins. |
477 if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size, | 597 if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size, |
478 _min_heap_byte_size, OldSize)) { | 598 _min_heap_byte_size, _min_gen1_size)) { |
479 if (PrintGCDetails && Verbose) { | 599 if (PrintGCDetails && Verbose) { |
480 gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 " | 600 gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 " |
481 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, | 601 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, |
482 _min_gen0_size, _initial_gen0_size, _max_gen0_size); | 602 _min_gen0_size, _initial_gen0_size, _max_gen0_size); |
483 } | 603 } |
484 } | 604 } |
485 // Initial size | 605 // Initial size |
486 if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size, | 606 if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size, |
487 _initial_heap_byte_size, OldSize)) { | 607 _initial_heap_byte_size, _initial_gen1_size)) { |
488 if (PrintGCDetails && Verbose) { | 608 if (PrintGCDetails && Verbose) { |
489 gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 " | 609 gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 " |
490 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, | 610 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, |
491 _min_gen0_size, _initial_gen0_size, _max_gen0_size); | 611 _min_gen0_size, _initial_gen0_size, _max_gen0_size); |
492 } | 612 } |
497 | 617 |
498 // Check that min gen1 <= initial gen1 <= max gen1 | 618 // Check that min gen1 <= initial gen1 <= max gen1 |
499 _initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size); | 619 _initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size); |
500 _initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size); | 620 _initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size); |
501 | 621 |
622 // Write back to flags if necessary | |
623 if (NewSize != _initial_gen0_size) { | |
624 FLAG_SET_ERGO(uintx, NewSize, _max_gen0_size); | |
625 } | |
626 | |
627 if (MaxNewSize != _max_gen0_size) { | |
628 FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size); | |
629 } | |
630 | |
631 if (OldSize != _initial_gen1_size) { | |
632 FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size); | |
633 } | |
634 | |
502 if (PrintGCDetails && Verbose) { | 635 if (PrintGCDetails && Verbose) { |
503 gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 " | 636 gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 " |
504 SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT, | 637 SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT, |
505 _min_gen1_size, _initial_gen1_size, _max_gen1_size); | 638 _min_gen1_size, _initial_gen1_size, _max_gen1_size); |
506 } | 639 } |
640 | |
641 DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_size_info();) | |
507 } | 642 } |
508 | 643 |
509 HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size, | 644 HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size, |
510 bool is_tlab, | 645 bool is_tlab, |
511 bool* gc_overhead_limit_was_exceeded) { | 646 bool* gc_overhead_limit_was_exceeded) { |
824 | 959 |
825 // | 960 // |
826 // MarkSweepPolicy methods | 961 // MarkSweepPolicy methods |
827 // | 962 // |
828 | 963 |
829 MarkSweepPolicy::MarkSweepPolicy() { | 964 void MarkSweepPolicy::initialize_alignments() { |
830 initialize_all(); | 965 _space_alignment = _gen_alignment = (uintx)Generation::GenGrain; |
966 _heap_alignment = compute_heap_alignment(); | |
831 } | 967 } |
832 | 968 |
833 void MarkSweepPolicy::initialize_generations() { | 969 void MarkSweepPolicy::initialize_generations() { |
834 _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL); | 970 _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL); |
835 if (_generations == NULL) { | 971 if (_generations == NULL) { |