Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp @ 10185:d50cc62e94ff
8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
Summary: In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime.
Reviewed-by: twisti, johnc
Contributed-by: Martin Doerr <martin.doerr@sap.com>
author | johnc |
---|---|
date | Wed, 24 Apr 2013 14:48:43 -0700 |
parents | f95d63e2154a |
children | 14d3f71f831d |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp" | |
27 #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp" | |
28 #include "gc_implementation/parNew/asParNewGeneration.hpp" | |
29 #include "gc_implementation/parNew/parNewGeneration.hpp" | |
30 #include "gc_implementation/shared/markSweep.inline.hpp" | |
31 #include "gc_implementation/shared/spaceDecorator.hpp" | |
32 #include "memory/defNewGeneration.inline.hpp" | |
33 #include "memory/referencePolicy.hpp" | |
34 #include "oops/markOop.inline.hpp" | |
35 #include "oops/oop.pcgc.inline.hpp" | |
0 | 36 |
37 ASParNewGeneration::ASParNewGeneration(ReservedSpace rs, | |
38 size_t initial_byte_size, | |
39 size_t min_byte_size, | |
40 int level) : | |
41 ParNewGeneration(rs, initial_byte_size, level), | |
42 _min_gen_size(min_byte_size) {} | |
43 | |
44 const char* ASParNewGeneration::name() const { | |
45 return "adaptive size par new generation"; | |
46 } | |
47 | |
48 void ASParNewGeneration::adjust_desired_tenuring_threshold() { | |
49 assert(UseAdaptiveSizePolicy, | |
50 "Should only be used with UseAdaptiveSizePolicy"); | |
51 } | |
52 | |
53 void ASParNewGeneration::resize(size_t eden_size, size_t survivor_size) { | |
54 // Resize the generation if needed. If the generation resize | |
55 // reports false, do not attempt to resize the spaces. | |
56 if (resize_generation(eden_size, survivor_size)) { | |
57 // Then we lay out the spaces inside the generation | |
58 resize_spaces(eden_size, survivor_size); | |
59 | |
60 space_invariants(); | |
61 | |
62 if (PrintAdaptiveSizePolicy && Verbose) { | |
63 gclog_or_tty->print_cr("Young generation size: " | |
64 "desired eden: " SIZE_FORMAT " survivor: " SIZE_FORMAT | |
65 " used: " SIZE_FORMAT " capacity: " SIZE_FORMAT | |
66 " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT, | |
67 eden_size, survivor_size, used(), capacity(), | |
68 max_gen_size(), min_gen_size()); | |
69 } | |
70 } | |
71 } | |
72 | |
73 size_t ASParNewGeneration::available_to_min_gen() { | |
74 assert(virtual_space()->committed_size() >= min_gen_size(), "Invariant"); | |
75 return virtual_space()->committed_size() - min_gen_size(); | |
76 } | |
77 | |
78 // This method assumes that from-space has live data and that | |
79 // any shrinkage of the young gen is limited by location of | |
80 // from-space. | |
81 size_t ASParNewGeneration::available_to_live() const { | |
82 #undef SHRINKS_AT_END_OF_EDEN | |
83 #ifdef SHRINKS_AT_END_OF_EDEN | |
84 size_t delta_in_survivor = 0; | |
85 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
13
183f41cf8bfe
6557851: CMS: ergonomics defaults are not set with FLAG_SET_ERGO
jmasa
parents:
0
diff
changeset
|
86 const size_t space_alignment = heap->intra_heap_alignment(); |
183f41cf8bfe
6557851: CMS: ergonomics defaults are not set with FLAG_SET_ERGO
jmasa
parents:
0
diff
changeset
|
87 const size_t gen_alignment = heap->object_heap_alignment(); |
0 | 88 |
89 MutableSpace* space_shrinking = NULL; | |
90 if (from_space()->end() > to_space()->end()) { | |
91 space_shrinking = from_space(); | |
92 } else { | |
93 space_shrinking = to_space(); | |
94 } | |
95 | |
96 // Include any space that is committed but not included in | |
97 // the survivor spaces. | |
98 assert(((HeapWord*)virtual_space()->high()) >= space_shrinking->end(), | |
99 "Survivor space beyond high end"); | |
100 size_t unused_committed = pointer_delta(virtual_space()->high(), | |
101 space_shrinking->end(), sizeof(char)); | |
102 | |
103 if (space_shrinking->is_empty()) { | |
104 // Don't let the space shrink to 0 | |
105 assert(space_shrinking->capacity_in_bytes() >= space_alignment, | |
106 "Space is too small"); | |
107 delta_in_survivor = space_shrinking->capacity_in_bytes() - space_alignment; | |
108 } else { | |
109 delta_in_survivor = pointer_delta(space_shrinking->end(), | |
110 space_shrinking->top(), | |
111 sizeof(char)); | |
112 } | |
113 | |
114 size_t delta_in_bytes = unused_committed + delta_in_survivor; | |
115 delta_in_bytes = align_size_down(delta_in_bytes, gen_alignment); | |
116 return delta_in_bytes; | |
117 #else | |
118 // The only space available for shrinking is in to-space if it | |
119 // is above from-space. | |
120 if (to()->bottom() > from()->bottom()) { | |
121 const size_t alignment = os::vm_page_size(); | |
122 if (to()->capacity() < alignment) { | |
123 return 0; | |
124 } else { | |
125 return to()->capacity() - alignment; | |
126 } | |
127 } else { | |
128 return 0; | |
129 } | |
130 #endif | |
131 } | |
132 | |
133 // Return the number of bytes available for resizing down the young | |
134 // generation. This is the minimum of | |
135 // input "bytes" | |
136 // bytes to the minimum young gen size | |
137 // bytes to the size currently being used + some small extra | |
138 size_t ASParNewGeneration::limit_gen_shrink (size_t bytes) { | |
139 // Allow shrinkage into the current eden but keep eden large enough | |
140 // to maintain the minimum young gen size | |
141 bytes = MIN3(bytes, available_to_min_gen(), available_to_live()); | |
142 return align_size_down(bytes, os::vm_page_size()); | |
143 } | |
144 | |
145 // Note that the the alignment used is the OS page size as | |
146 // opposed to an alignment associated with the virtual space | |
147 // (as is done in the ASPSYoungGen/ASPSOldGen) | |
148 bool ASParNewGeneration::resize_generation(size_t eden_size, | |
149 size_t survivor_size) { | |
150 const size_t alignment = os::vm_page_size(); | |
151 size_t orig_size = virtual_space()->committed_size(); | |
152 bool size_changed = false; | |
153 | |
154 // There used to be this guarantee there. | |
155 // guarantee ((eden_size + 2*survivor_size) <= _max_gen_size, "incorrect input arguments"); | |
156 // Code below forces this requirement. In addition the desired eden | |
157 // size and disired survivor sizes are desired goals and may | |
158 // exceed the total generation size. | |
159 | |
160 assert(min_gen_size() <= orig_size && orig_size <= max_gen_size(), | |
161 "just checking"); | |
162 | |
163 // Adjust new generation size | |
164 const size_t eden_plus_survivors = | |
165 align_size_up(eden_size + 2 * survivor_size, alignment); | |
166 size_t desired_size = MAX2(MIN2(eden_plus_survivors, max_gen_size()), | |
167 min_gen_size()); | |
168 assert(desired_size <= max_gen_size(), "just checking"); | |
169 | |
170 if (desired_size > orig_size) { | |
171 // Grow the generation | |
172 size_t change = desired_size - orig_size; | |
173 assert(change % alignment == 0, "just checking"); | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
174 if (expand(change)) { |
0 | 175 return false; // Error if we fail to resize! |
176 } | |
177 size_changed = true; | |
178 } else if (desired_size < orig_size) { | |
179 size_t desired_change = orig_size - desired_size; | |
180 assert(desired_change % alignment == 0, "just checking"); | |
181 | |
182 desired_change = limit_gen_shrink(desired_change); | |
183 | |
184 if (desired_change > 0) { | |
185 virtual_space()->shrink_by(desired_change); | |
186 reset_survivors_after_shrink(); | |
187 | |
188 size_changed = true; | |
189 } | |
190 } else { | |
191 if (Verbose && PrintGC) { | |
192 if (orig_size == max_gen_size()) { | |
193 gclog_or_tty->print_cr("ASParNew generation size at maximum: " | |
194 SIZE_FORMAT "K", orig_size/K); | |
195 } else if (orig_size == min_gen_size()) { | |
196 gclog_or_tty->print_cr("ASParNew generation size at minium: " | |
197 SIZE_FORMAT "K", orig_size/K); | |
198 } | |
199 } | |
200 } | |
201 | |
202 if (size_changed) { | |
203 MemRegion cmr((HeapWord*)virtual_space()->low(), | |
204 (HeapWord*)virtual_space()->high()); | |
205 GenCollectedHeap::heap()->barrier_set()->resize_covered_region(cmr); | |
206 | |
207 if (Verbose && PrintGC) { | |
208 size_t current_size = virtual_space()->committed_size(); | |
209 gclog_or_tty->print_cr("ASParNew generation size changed: " | |
210 SIZE_FORMAT "K->" SIZE_FORMAT "K", | |
211 orig_size/K, current_size/K); | |
212 } | |
213 } | |
214 | |
215 guarantee(eden_plus_survivors <= virtual_space()->committed_size() || | |
216 virtual_space()->committed_size() == max_gen_size(), "Sanity"); | |
217 | |
218 return true; | |
219 } | |
220 | |
221 void ASParNewGeneration::reset_survivors_after_shrink() { | |
222 | |
223 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
224 HeapWord* new_end = (HeapWord*)virtual_space()->high(); | |
225 | |
226 if (from()->end() > to()->end()) { | |
227 assert(new_end >= from()->end(), "Shrinking past from-space"); | |
228 } else { | |
229 assert(new_end >= to()->bottom(), "Shrink was too large"); | |
230 // Was there a shrink of the survivor space? | |
231 if (new_end < to()->end()) { | |
232 MemRegion mr(to()->bottom(), new_end); | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
233 to()->initialize(mr, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
234 SpaceDecorator::DontClear, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
235 SpaceDecorator::DontMangle); |
0 | 236 } |
237 } | |
238 } | |
239 void ASParNewGeneration::resize_spaces(size_t requested_eden_size, | |
240 size_t requested_survivor_size) { | |
241 assert(UseAdaptiveSizePolicy, "sanity check"); | |
242 assert(requested_eden_size > 0 && requested_survivor_size > 0, | |
243 "just checking"); | |
244 CollectedHeap* heap = Universe::heap(); | |
245 assert(heap->kind() == CollectedHeap::GenCollectedHeap, "Sanity"); | |
246 | |
247 | |
248 // We require eden and to space to be empty | |
249 if ((!eden()->is_empty()) || (!to()->is_empty())) { | |
250 return; | |
251 } | |
252 | |
253 size_t cur_eden_size = eden()->capacity(); | |
254 | |
255 if (PrintAdaptiveSizePolicy && Verbose) { | |
256 gclog_or_tty->print_cr("ASParNew::resize_spaces(requested_eden_size: " | |
257 SIZE_FORMAT | |
258 ", requested_survivor_size: " SIZE_FORMAT ")", | |
259 requested_eden_size, requested_survivor_size); | |
260 gclog_or_tty->print_cr(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") " | |
261 SIZE_FORMAT, | |
262 eden()->bottom(), | |
263 eden()->end(), | |
264 pointer_delta(eden()->end(), | |
265 eden()->bottom(), | |
266 sizeof(char))); | |
267 gclog_or_tty->print_cr(" from: [" PTR_FORMAT ".." PTR_FORMAT ") " | |
268 SIZE_FORMAT, | |
269 from()->bottom(), | |
270 from()->end(), | |
271 pointer_delta(from()->end(), | |
272 from()->bottom(), | |
273 sizeof(char))); | |
274 gclog_or_tty->print_cr(" to: [" PTR_FORMAT ".." PTR_FORMAT ") " | |
275 SIZE_FORMAT, | |
276 to()->bottom(), | |
277 to()->end(), | |
278 pointer_delta( to()->end(), | |
279 to()->bottom(), | |
280 sizeof(char))); | |
281 } | |
282 | |
283 // There's nothing to do if the new sizes are the same as the current | |
284 if (requested_survivor_size == to()->capacity() && | |
285 requested_survivor_size == from()->capacity() && | |
286 requested_eden_size == eden()->capacity()) { | |
287 if (PrintAdaptiveSizePolicy && Verbose) { | |
288 gclog_or_tty->print_cr(" capacities are the right sizes, returning"); | |
289 } | |
290 return; | |
291 } | |
292 | |
293 char* eden_start = (char*)eden()->bottom(); | |
294 char* eden_end = (char*)eden()->end(); | |
295 char* from_start = (char*)from()->bottom(); | |
296 char* from_end = (char*)from()->end(); | |
297 char* to_start = (char*)to()->bottom(); | |
298 char* to_end = (char*)to()->end(); | |
299 | |
300 const size_t alignment = os::vm_page_size(); | |
301 const bool maintain_minimum = | |
302 (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size(); | |
303 | |
304 // Check whether from space is below to space | |
305 if (from_start < to_start) { | |
306 // Eden, from, to | |
307 if (PrintAdaptiveSizePolicy && Verbose) { | |
308 gclog_or_tty->print_cr(" Eden, from, to:"); | |
309 } | |
310 | |
311 // Set eden | |
312 // "requested_eden_size" is a goal for the size of eden | |
313 // and may not be attainable. "eden_size" below is | |
314 // calculated based on the location of from-space and | |
315 // the goal for the size of eden. from-space is | |
316 // fixed in place because it contains live data. | |
317 // The calculation is done this way to avoid 32bit | |
318 // overflow (i.e., eden_start + requested_eden_size | |
319 // may too large for representation in 32bits). | |
320 size_t eden_size; | |
321 if (maintain_minimum) { | |
322 // Only make eden larger than the requested size if | |
323 // the minimum size of the generation has to be maintained. | |
324 // This could be done in general but policy at a higher | |
325 // level is determining a requested size for eden and that | |
326 // should be honored unless there is a fundamental reason. | |
327 eden_size = pointer_delta(from_start, | |
328 eden_start, | |
329 sizeof(char)); | |
330 } else { | |
331 eden_size = MIN2(requested_eden_size, | |
332 pointer_delta(from_start, eden_start, sizeof(char))); | |
333 } | |
334 | |
335 eden_size = align_size_down(eden_size, alignment); | |
336 eden_end = eden_start + eden_size; | |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
269
diff
changeset
|
337 assert(eden_end >= eden_start, "addition overflowed"); |
0 | 338 |
339 // To may resize into from space as long as it is clear of live data. | |
340 // From space must remain page aligned, though, so we need to do some | |
341 // extra calculations. | |
342 | |
343 // First calculate an optimal to-space | |
344 to_end = (char*)virtual_space()->high(); | |
345 to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size, | |
346 sizeof(char)); | |
347 | |
348 // Does the optimal to-space overlap from-space? | |
349 if (to_start < (char*)from()->end()) { | |
350 // Calculate the minimum offset possible for from_end | |
351 size_t from_size = pointer_delta(from()->top(), from_start, sizeof(char)); | |
352 | |
353 // Should we be in this method if from_space is empty? Why not the set_space method? FIX ME! | |
354 if (from_size == 0) { | |
355 from_size = alignment; | |
356 } else { | |
357 from_size = align_size_up(from_size, alignment); | |
358 } | |
359 | |
360 from_end = from_start + from_size; | |
361 assert(from_end > from_start, "addition overflow or from_size problem"); | |
362 | |
363 guarantee(from_end <= (char*)from()->end(), "from_end moved to the right"); | |
364 | |
365 // Now update to_start with the new from_end | |
366 to_start = MAX2(from_end, to_start); | |
367 } else { | |
368 // If shrinking, move to-space down to abut the end of from-space | |
369 // so that shrinking will move to-space down. If not shrinking | |
370 // to-space is moving up to allow for growth on the next expansion. | |
371 if (requested_eden_size <= cur_eden_size) { | |
372 to_start = from_end; | |
373 if (to_start + requested_survivor_size > to_start) { | |
374 to_end = to_start + requested_survivor_size; | |
375 } | |
376 } | |
377 // else leave to_end pointing to the high end of the virtual space. | |
378 } | |
379 | |
380 guarantee(to_start != to_end, "to space is zero sized"); | |
381 | |
382 if (PrintAdaptiveSizePolicy && Verbose) { | |
383 gclog_or_tty->print_cr(" [eden_start .. eden_end): " | |
384 "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, | |
385 eden_start, | |
386 eden_end, | |
387 pointer_delta(eden_end, eden_start, sizeof(char))); | |
388 gclog_or_tty->print_cr(" [from_start .. from_end): " | |
389 "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, | |
390 from_start, | |
391 from_end, | |
392 pointer_delta(from_end, from_start, sizeof(char))); | |
393 gclog_or_tty->print_cr(" [ to_start .. to_end): " | |
394 "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, | |
395 to_start, | |
396 to_end, | |
397 pointer_delta( to_end, to_start, sizeof(char))); | |
398 } | |
399 } else { | |
400 // Eden, to, from | |
401 if (PrintAdaptiveSizePolicy && Verbose) { | |
402 gclog_or_tty->print_cr(" Eden, to, from:"); | |
403 } | |
404 | |
405 // Calculate the to-space boundaries based on | |
406 // the start of from-space. | |
407 to_end = from_start; | |
408 to_start = (char*)pointer_delta(from_start, | |
409 (char*)requested_survivor_size, | |
410 sizeof(char)); | |
411 // Calculate the ideal eden boundaries. | |
412 // eden_end is already at the bottom of the generation | |
413 assert(eden_start == virtual_space()->low(), | |
414 "Eden is not starting at the low end of the virtual space"); | |
415 if (eden_start + requested_eden_size >= eden_start) { | |
416 eden_end = eden_start + requested_eden_size; | |
417 } else { | |
418 eden_end = to_start; | |
419 } | |
420 | |
421 // Does eden intrude into to-space? to-space | |
422 // gets priority but eden is not allowed to shrink | |
423 // to 0. | |
424 if (eden_end > to_start) { | |
425 eden_end = to_start; | |
426 } | |
427 | |
428 // Don't let eden shrink down to 0 or less. | |
429 eden_end = MAX2(eden_end, eden_start + alignment); | |
430 assert(eden_start + alignment >= eden_start, "Overflow"); | |
431 | |
432 size_t eden_size; | |
433 if (maintain_minimum) { | |
434 // Use all the space available. | |
435 eden_end = MAX2(eden_end, to_start); | |
436 eden_size = pointer_delta(eden_end, eden_start, sizeof(char)); | |
437 eden_size = MIN2(eden_size, cur_eden_size); | |
438 } else { | |
439 eden_size = pointer_delta(eden_end, eden_start, sizeof(char)); | |
440 } | |
441 eden_size = align_size_down(eden_size, alignment); | |
442 assert(maintain_minimum || eden_size <= requested_eden_size, | |
443 "Eden size is too large"); | |
444 assert(eden_size >= alignment, "Eden size is too small"); | |
445 eden_end = eden_start + eden_size; | |
446 | |
447 // Move to-space down to eden. | |
448 if (requested_eden_size < cur_eden_size) { | |
449 to_start = eden_end; | |
450 if (to_start + requested_survivor_size > to_start) { | |
451 to_end = MIN2(from_start, to_start + requested_survivor_size); | |
452 } else { | |
453 to_end = from_start; | |
454 } | |
455 } | |
456 | |
457 // eden_end may have moved so again make sure | |
458 // the to-space and eden don't overlap. | |
459 to_start = MAX2(eden_end, to_start); | |
460 | |
461 // from-space | |
462 size_t from_used = from()->used(); | |
463 if (requested_survivor_size > from_used) { | |
464 if (from_start + requested_survivor_size >= from_start) { | |
465 from_end = from_start + requested_survivor_size; | |
466 } | |
467 if (from_end > virtual_space()->high()) { | |
468 from_end = virtual_space()->high(); | |
469 } | |
470 } | |
471 | |
472 assert(to_start >= eden_end, "to-space should be above eden"); | |
473 if (PrintAdaptiveSizePolicy && Verbose) { | |
474 gclog_or_tty->print_cr(" [eden_start .. eden_end): " | |
475 "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, | |
476 eden_start, | |
477 eden_end, | |
478 pointer_delta(eden_end, eden_start, sizeof(char))); | |
479 gclog_or_tty->print_cr(" [ to_start .. to_end): " | |
480 "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, | |
481 to_start, | |
482 to_end, | |
483 pointer_delta( to_end, to_start, sizeof(char))); | |
484 gclog_or_tty->print_cr(" [from_start .. from_end): " | |
485 "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, | |
486 from_start, | |
487 from_end, | |
488 pointer_delta(from_end, from_start, sizeof(char))); | |
489 } | |
490 } | |
491 | |
492 | |
493 guarantee((HeapWord*)from_start <= from()->bottom(), | |
494 "from start moved to the right"); | |
495 guarantee((HeapWord*)from_end >= from()->top(), | |
496 "from end moved into live data"); | |
497 assert(is_object_aligned((intptr_t)eden_start), "checking alignment"); | |
498 assert(is_object_aligned((intptr_t)from_start), "checking alignment"); | |
499 assert(is_object_aligned((intptr_t)to_start), "checking alignment"); | |
500 | |
501 MemRegion edenMR((HeapWord*)eden_start, (HeapWord*)eden_end); | |
502 MemRegion toMR ((HeapWord*)to_start, (HeapWord*)to_end); | |
503 MemRegion fromMR((HeapWord*)from_start, (HeapWord*)from_end); | |
504 | |
505 // Let's make sure the call to initialize doesn't reset "top"! | |
506 HeapWord* old_from_top = from()->top(); | |
507 | |
508 // For PrintAdaptiveSizePolicy block below | |
509 size_t old_from = from()->capacity(); | |
510 size_t old_to = to()->capacity(); | |
511 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
512 // If not clearing the spaces, do some checking to verify that |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
513 // the spaces are already mangled. |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
514 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
515 // Must check mangling before the spaces are reshaped. Otherwise, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
516 // the bottom or end of one space may have moved into another |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
517 // a failure of the check may not correctly indicate which space |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
518 // is not properly mangled. |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
519 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
520 HeapWord* limit = (HeapWord*) virtual_space()->high(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
521 eden()->check_mangled_unused_area(limit); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
522 from()->check_mangled_unused_area(limit); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
523 to()->check_mangled_unused_area(limit); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
524 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
525 |
0 | 526 // The call to initialize NULL's the next compaction space |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
527 eden()->initialize(edenMR, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
528 SpaceDecorator::Clear, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
529 SpaceDecorator::DontMangle); |
0 | 530 eden()->set_next_compaction_space(from()); |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
531 to()->initialize(toMR , |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
532 SpaceDecorator::Clear, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
533 SpaceDecorator::DontMangle); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
534 from()->initialize(fromMR, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
535 SpaceDecorator::DontClear, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
13
diff
changeset
|
536 SpaceDecorator::DontMangle); |
0 | 537 |
538 assert(from()->top() == old_from_top, "from top changed!"); | |
539 | |
540 if (PrintAdaptiveSizePolicy) { | |
541 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
542 assert(gch->kind() == CollectedHeap::GenCollectedHeap, "Sanity"); | |
543 | |
544 gclog_or_tty->print("AdaptiveSizePolicy::survivor space sizes: " | |
545 "collection: %d " | |
546 "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> " | |
547 "(" SIZE_FORMAT ", " SIZE_FORMAT ") ", | |
548 gch->total_collections(), | |
549 old_from, old_to, | |
550 from()->capacity(), | |
551 to()->capacity()); | |
552 gclog_or_tty->cr(); | |
553 } | |
554 } | |
555 | |
556 void ASParNewGeneration::compute_new_size() { | |
557 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
558 assert(gch->kind() == CollectedHeap::GenCollectedHeap, | |
559 "not a CMS generational heap"); | |
560 | |
561 | |
562 CMSAdaptiveSizePolicy* size_policy = | |
563 (CMSAdaptiveSizePolicy*)gch->gen_policy()->size_policy(); | |
564 assert(size_policy->is_gc_cms_adaptive_size_policy(), | |
565 "Wrong type of size policy"); | |
566 | |
567 size_t survived = from()->used(); | |
568 if (!survivor_overflow()) { | |
569 // Keep running averages on how much survived | |
570 size_policy->avg_survived()->sample(survived); | |
571 } else { | |
572 size_t promoted = | |
573 (size_t) next_gen()->gc_stats()->avg_promoted()->last_sample(); | |
574 assert(promoted < gch->capacity(), "Conversion problem?"); | |
575 size_t survived_guess = survived + promoted; | |
576 size_policy->avg_survived()->sample(survived_guess); | |
577 } | |
578 | |
579 size_t survivor_limit = max_survivor_size(); | |
580 _tenuring_threshold = | |
581 size_policy->compute_survivor_space_size_and_threshold( | |
582 _survivor_overflow, | |
583 _tenuring_threshold, | |
584 survivor_limit); | |
585 size_policy->avg_young_live()->sample(used()); | |
586 size_policy->avg_eden_live()->sample(eden()->used()); | |
587 | |
588 size_policy->compute_young_generation_free_space(eden()->capacity(), | |
589 max_gen_size()); | |
590 | |
591 resize(size_policy->calculated_eden_size_in_bytes(), | |
592 size_policy->calculated_survivor_size_in_bytes()); | |
593 | |
594 if (UsePerfData) { | |
595 CMSGCAdaptivePolicyCounters* counters = | |
596 (CMSGCAdaptivePolicyCounters*) gch->collector_policy()->counters(); | |
597 assert(counters->kind() == | |
598 GCPolicyCounters::CMSGCAdaptivePolicyCountersKind, | |
599 "Wrong kind of counters"); | |
600 counters->update_tenuring_threshold(_tenuring_threshold); | |
601 counters->update_survivor_overflowed(_survivor_overflow); | |
602 counters->update_young_capacity(capacity()); | |
603 } | |
604 } | |
605 | |
606 | |
607 #ifndef PRODUCT | |
608 // Changes from PSYoungGen version | |
609 // value of "alignment" | |
610 void ASParNewGeneration::space_invariants() { | |
611 const size_t alignment = os::vm_page_size(); | |
612 | |
613 // Currently, our eden size cannot shrink to zero | |
614 guarantee(eden()->capacity() >= alignment, "eden too small"); | |
615 guarantee(from()->capacity() >= alignment, "from too small"); | |
616 guarantee(to()->capacity() >= alignment, "to too small"); | |
617 | |
618 // Relationship of spaces to each other | |
619 char* eden_start = (char*)eden()->bottom(); | |
620 char* eden_end = (char*)eden()->end(); | |
621 char* from_start = (char*)from()->bottom(); | |
622 char* from_end = (char*)from()->end(); | |
623 char* to_start = (char*)to()->bottom(); | |
624 char* to_end = (char*)to()->end(); | |
625 | |
626 guarantee(eden_start >= virtual_space()->low(), "eden bottom"); | |
627 guarantee(eden_start < eden_end, "eden space consistency"); | |
628 guarantee(from_start < from_end, "from space consistency"); | |
629 guarantee(to_start < to_end, "to space consistency"); | |
630 | |
631 // Check whether from space is below to space | |
632 if (from_start < to_start) { | |
633 // Eden, from, to | |
634 guarantee(eden_end <= from_start, "eden/from boundary"); | |
635 guarantee(from_end <= to_start, "from/to boundary"); | |
636 guarantee(to_end <= virtual_space()->high(), "to end"); | |
637 } else { | |
638 // Eden, to, from | |
639 guarantee(eden_end <= to_start, "eden/to boundary"); | |
640 guarantee(to_end <= from_start, "to/from boundary"); | |
641 guarantee(from_end <= virtual_space()->high(), "from end"); | |
642 } | |
643 | |
644 // More checks that the virtual space is consistent with the spaces | |
645 assert(virtual_space()->committed_size() >= | |
646 (eden()->capacity() + | |
647 to()->capacity() + | |
648 from()->capacity()), "Committed size is inconsistent"); | |
649 assert(virtual_space()->committed_size() <= virtual_space()->reserved_size(), | |
650 "Space invariant"); | |
651 char* eden_top = (char*)eden()->top(); | |
652 char* from_top = (char*)from()->top(); | |
653 char* to_top = (char*)to()->top(); | |
654 assert(eden_top <= virtual_space()->high(), "eden top"); | |
655 assert(from_top <= virtual_space()->high(), "from top"); | |
656 assert(to_top <= virtual_space()->high(), "to top"); | |
657 } | |
658 #endif |