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