1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)psYoungGen.cpp 1.68 07/10/04 10:49:36 JVM"
3 #endif
4 /*
5 * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
26 */
27
28 # include "incls/_precompiled.incl"
29 # include "incls/_psYoungGen.cpp.incl"
30
31 PSYoungGen::PSYoungGen(size_t initial_size,
32 size_t min_size,
33 size_t max_size) :
34 _init_gen_size(initial_size),
35 _min_gen_size(min_size),
36 _max_gen_size(max_size)
37 {}
38
39 void PSYoungGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) {
40 assert(_init_gen_size != 0, "Should have a finite size");
41 _virtual_space = new PSVirtualSpace(rs, alignment);
42 if (!_virtual_space->expand_by(_init_gen_size)) {
43 vm_exit_during_initialization("Could not reserve enough space for "
44 "object heap");
45 }
46 }
47
48 void PSYoungGen::initialize(ReservedSpace rs, size_t alignment) {
49 initialize_virtual_space(rs, alignment);
50 initialize_work();
51 }
52
53 void PSYoungGen::initialize_work() {
54
55 _reserved = MemRegion((HeapWord*)_virtual_space->low_boundary(),
56 (HeapWord*)_virtual_space->high_boundary());
57
58 MemRegion cmr((HeapWord*)_virtual_space->low(),
59 (HeapWord*)_virtual_space->high());
60 Universe::heap()->barrier_set()->resize_covered_region(cmr);
61
62 if (UseNUMA) {
63 _eden_space = new MutableNUMASpace();
64 } else {
65 _eden_space = new MutableSpace();
66 }
67 _from_space = new MutableSpace();
68 _to_space = new MutableSpace();
69
70 if (_eden_space == NULL || _from_space == NULL || _to_space == NULL) {
71 vm_exit_during_initialization("Could not allocate a young gen space");
72 }
73
74 // Allocate the mark sweep views of spaces
75 _eden_mark_sweep =
76 new PSMarkSweepDecorator(_eden_space, NULL, MarkSweepDeadRatio);
77 _from_mark_sweep =
78 new PSMarkSweepDecorator(_from_space, NULL, MarkSweepDeadRatio);
79 _to_mark_sweep =
80 new PSMarkSweepDecorator(_to_space, NULL, MarkSweepDeadRatio);
81
82 if (_eden_mark_sweep == NULL ||
83 _from_mark_sweep == NULL ||
84 _to_mark_sweep == NULL) {
85 vm_exit_during_initialization("Could not complete allocation"
86 " of the young generation");
87 }
88
89 // Generation Counters - generation 0, 3 subspaces
90 _gen_counters = new PSGenerationCounters("new", 0, 3, _virtual_space);
91
92 // Compute maximum space sizes for performance counters
93 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
94 size_t alignment = heap->intra_generation_alignment();
95 size_t size = _virtual_space->reserved_size();
96
97 size_t max_survivor_size;
98 size_t max_eden_size;
99
100 if (UseAdaptiveSizePolicy) {
101 max_survivor_size = size / MinSurvivorRatio;
102
103 // round the survivor space size down to the nearest alignment
104 // and make sure its size is greater than 0.
105 max_survivor_size = align_size_down(max_survivor_size, alignment);
106 max_survivor_size = MAX2(max_survivor_size, alignment);
107
108 // set the maximum size of eden to be the size of the young gen
109 // less two times the minimum survivor size. The minimum survivor
110 // size for UseAdaptiveSizePolicy is one alignment.
111 max_eden_size = size - 2 * alignment;
112 } else {
113 max_survivor_size = size / InitialSurvivorRatio;
114
115 // round the survivor space size down to the nearest alignment
127 // is the point where eden reachs its maximum size. At this point,
128 // the size of a survivor space is max_survivor_size.
129 max_eden_size = size - 2 * max_survivor_size;
130 }
131
132 _eden_counters = new SpaceCounters("eden", 0, max_eden_size, _eden_space,
133 _gen_counters);
134 _from_counters = new SpaceCounters("s0", 1, max_survivor_size, _from_space,
135 _gen_counters);
136 _to_counters = new SpaceCounters("s1", 2, max_survivor_size, _to_space,
137 _gen_counters);
138
139 compute_initial_space_boundaries();
140 }
141
142 void PSYoungGen::compute_initial_space_boundaries() {
143 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
144 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
145
146 // Compute sizes
147 size_t alignment = heap->intra_generation_alignment();
148 size_t size = _virtual_space->committed_size();
149
150 size_t survivor_size = size / InitialSurvivorRatio;
151 survivor_size = align_size_down(survivor_size, alignment);
152 // ... but never less than an alignment
153 survivor_size = MAX2(survivor_size, alignment);
154
155 // Young generation is eden + 2 survivor spaces
156 size_t eden_size = size - (2 * survivor_size);
157
158 // Now go ahead and set 'em.
159 set_space_boundaries(eden_size, survivor_size);
160 space_invariants();
161
162 if (UsePerfData) {
163 _eden_counters->update_capacity();
164 _from_counters->update_capacity();
165 _to_counters->update_capacity();
166 }
167 }
168
169 void PSYoungGen::set_space_boundaries(size_t eden_size, size_t survivor_size) {
170 assert(eden_size < _virtual_space->committed_size(), "just checking");
171 assert(eden_size > 0 && survivor_size > 0, "just checking");
172
173 // Initial layout is Eden, to, from. After swapping survivor spaces,
174 // that leaves us with Eden, from, to, which is step one in our two
175 // step resize-with-live-data procedure.
176 char *eden_start = _virtual_space->low();
177 char *to_start = eden_start + eden_size;
178 char *from_start = to_start + survivor_size;
179 char *from_end = from_start + survivor_size;
180
181 assert(from_end == _virtual_space->high(), "just checking");
182 assert(is_object_aligned((intptr_t)eden_start), "checking alignment");
183 assert(is_object_aligned((intptr_t)to_start), "checking alignment");
184 assert(is_object_aligned((intptr_t)from_start), "checking alignment");
185
186 MemRegion eden_mr((HeapWord*)eden_start, (HeapWord*)to_start);
187 MemRegion to_mr ((HeapWord*)to_start, (HeapWord*)from_start);
188 MemRegion from_mr((HeapWord*)from_start, (HeapWord*)from_end);
189
190 eden_space()->initialize(eden_mr, true);
191 to_space()->initialize(to_mr , true);
192 from_space()->initialize(from_mr, true);
193 }
194
195 #ifndef PRODUCT
196 void PSYoungGen::space_invariants() {
197 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
198 const size_t alignment = heap->intra_generation_alignment();
199
200 // Currently, our eden size cannot shrink to zero
201 guarantee(eden_space()->capacity_in_bytes() >= alignment, "eden too small");
202 guarantee(from_space()->capacity_in_bytes() >= alignment, "from too small");
203 guarantee(to_space()->capacity_in_bytes() >= alignment, "to too small");
204
205 // Relationship of spaces to each other
206 char* eden_start = (char*)eden_space()->bottom();
207 char* eden_end = (char*)eden_space()->end();
208 char* from_start = (char*)from_space()->bottom();
209 char* from_end = (char*)from_space()->end();
210 char* to_start = (char*)to_space()->bottom();
211 char* to_end = (char*)to_space()->end();
212
213 guarantee(eden_start >= _virtual_space->low(), "eden bottom");
214 guarantee(eden_start < eden_end, "eden space consistency");
215 guarantee(from_start < from_end, "from space consistency");
216 guarantee(to_start < to_end, "to space consistency");
217
218 // Check whether from space is below to space
219 if (from_start < to_start) {
220 // Eden, from, to
221 guarantee(eden_end <= from_start, "eden/from boundary");
222 guarantee(from_end <= to_start, "from/to boundary");
223 guarantee(to_end <= _virtual_space->high(), "to end");
224 } else {
225 // Eden, to, from
226 guarantee(eden_end <= to_start, "eden/to boundary");
227 guarantee(to_end <= from_start, "to/from boundary");
228 guarantee(from_end <= _virtual_space->high(), "from end");
229 }
230
231 // More checks that the virtual space is consistent with the spaces
232 assert(_virtual_space->committed_size() >=
233 (eden_space()->capacity_in_bytes() +
234 to_space()->capacity_in_bytes() +
235 from_space()->capacity_in_bytes()), "Committed size is inconsistent");
236 assert(_virtual_space->committed_size() <= _virtual_space->reserved_size(),
237 "Space invariant");
238 char* eden_top = (char*)eden_space()->top();
239 char* from_top = (char*)from_space()->top();
240 char* to_top = (char*)to_space()->top();
241 assert(eden_top <= _virtual_space->high(), "eden top");
242 assert(from_top <= _virtual_space->high(), "from top");
243 assert(to_top <= _virtual_space->high(), "to top");
244
245 _virtual_space->verify();
246 }
247 #endif
248
249 void PSYoungGen::resize(size_t eden_size, size_t survivor_size) {
250 // Resize the generation if needed. If the generation resize
251 // reports false, do not attempt to resize the spaces.
252 if (resize_generation(eden_size, survivor_size)) {
253 // Then we lay out the spaces inside the generation
254 resize_spaces(eden_size, survivor_size);
255
256 space_invariants();
257
258 if (PrintAdaptiveSizePolicy && Verbose) {
259 gclog_or_tty->print_cr("Young generation size: "
260 "desired eden: " SIZE_FORMAT " survivor: " SIZE_FORMAT
261 " used: " SIZE_FORMAT " capacity: " SIZE_FORMAT
262 " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
263 eden_size, survivor_size, used_in_bytes(), capacity_in_bytes(),
264 _max_gen_size, min_gen_size());
265 }
266 }
267 }
268
269
270 bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) {
271 const size_t alignment = _virtual_space->alignment();
272 size_t orig_size = _virtual_space->committed_size();
273 bool size_changed = false;
274
275 // There used to be this guarantee there.
276 // guarantee ((eden_size + 2*survivor_size) <= _max_gen_size, "incorrect input arguments");
277 // Code below forces this requirement. In addition the desired eden
278 // size and disired survivor sizes are desired goals and may
279 // exceed the total generation size.
280
281 assert(min_gen_size() <= orig_size && orig_size <= max_size(), "just checking");
282
283 // Adjust new generation size
284 const size_t eden_plus_survivors =
285 align_size_up(eden_size + 2 * survivor_size, alignment);
286 size_t desired_size = MAX2(MIN2(eden_plus_survivors, max_size()),
287 min_gen_size());
288 assert(desired_size <= max_size(), "just checking");
289
290 if (desired_size > orig_size) {
291 // Grow the generation
292 size_t change = desired_size - orig_size;
293 assert(change % alignment == 0, "just checking");
294 if (!_virtual_space->expand_by(change)) {
295 return false; // Error if we fail to resize!
296 }
297
298 size_changed = true;
299 } else if (desired_size < orig_size) {
300 size_t desired_change = orig_size - desired_size;
301 assert(desired_change % alignment == 0, "just checking");
302
303 desired_change = limit_gen_shrink(desired_change);
304
305 if (desired_change > 0) {
306 virtual_space()->shrink_by(desired_change);
307 reset_survivors_after_shrink();
308
309 size_changed = true;
310 }
311 } else {
312 if (Verbose && PrintGC) {
313 if (orig_size == gen_size_limit()) {
314 gclog_or_tty->print_cr("PSYoung generation size at maximum: "
315 SIZE_FORMAT "K", orig_size/K);
316 } else if (orig_size == min_gen_size()) {
317 gclog_or_tty->print_cr("PSYoung generation size at minium: "
318 SIZE_FORMAT "K", orig_size/K);
319 }
320 }
321 }
322
323 if (size_changed) {
324 post_resize();
325
326 if (Verbose && PrintGC) {
327 size_t current_size = _virtual_space->committed_size();
328 gclog_or_tty->print_cr("PSYoung generation size changed: "
329 SIZE_FORMAT "K->" SIZE_FORMAT "K",
330 orig_size/K, current_size/K);
331 }
332 }
333
334 guarantee(eden_plus_survivors <= _virtual_space->committed_size() ||
335 _virtual_space->committed_size() == max_size(), "Sanity");
336
337 return true;
338 }
339
340
341 void PSYoungGen::resize_spaces(size_t requested_eden_size,
342 size_t requested_survivor_size) {
343 assert(UseAdaptiveSizePolicy, "sanity check");
344 assert(requested_eden_size > 0 && requested_survivor_size > 0,
345 "just checking");
346
347 // We require eden and to space to be empty
348 if ((!eden_space()->is_empty()) || (!to_space()->is_empty())) {
349 return;
350 }
351
352 if (PrintAdaptiveSizePolicy && Verbose) {
353 gclog_or_tty->print_cr("PSYoungGen::resize_spaces(requested_eden_size: "
354 SIZE_FORMAT
355 ", requested_survivor_size: " SIZE_FORMAT ")",
356 requested_eden_size, requested_survivor_size);
357 gclog_or_tty->print_cr(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") "
358 SIZE_FORMAT,
359 eden_space()->bottom(),
378 }
379
380 // There's nothing to do if the new sizes are the same as the current
381 if (requested_survivor_size == to_space()->capacity_in_bytes() &&
382 requested_survivor_size == from_space()->capacity_in_bytes() &&
383 requested_eden_size == eden_space()->capacity_in_bytes()) {
384 if (PrintAdaptiveSizePolicy && Verbose) {
385 gclog_or_tty->print_cr(" capacities are the right sizes, returning");
386 }
387 return;
388 }
389
390 char* eden_start = (char*)eden_space()->bottom();
391 char* eden_end = (char*)eden_space()->end();
392 char* from_start = (char*)from_space()->bottom();
393 char* from_end = (char*)from_space()->end();
394 char* to_start = (char*)to_space()->bottom();
395 char* to_end = (char*)to_space()->end();
396
397 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
398 const size_t alignment = heap->intra_generation_alignment();
399 const bool maintain_minimum =
400 (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
401
402 // Check whether from space is below to space
403 if (from_start < to_start) {
404 // Eden, from, to
405 if (PrintAdaptiveSizePolicy && Verbose) {
406 gclog_or_tty->print_cr(" Eden, from, to:");
407 }
408
409 // Set eden
410 // "requested_eden_size" is a goal for the size of eden
411 // and may not be attainable. "eden_size" below is
412 // calculated based on the location of from-space and
413 // the goal for the size of eden. from-space is
414 // fixed in place because it contains live data.
415 // The calculation is done this way to avoid 32bit
416 // overflow (i.e., eden_start + requested_eden_size
417 // may too large for representation in 32bits).
418 size_t eden_size;
419 if (maintain_minimum) {
420 // Only make eden larger than the requested size if
421 // the minimum size of the generation has to be maintained.
422 // This could be done in general but policy at a higher
423 // level is determining a requested size for eden and that
424 // should be honored unless there is a fundamental reason.
425 eden_size = pointer_delta(from_start,
426 eden_start,
427 sizeof(char));
428 } else {
429 eden_size = MIN2(requested_eden_size,
430 pointer_delta(from_start, eden_start, sizeof(char)));
431 }
432
433 eden_end = eden_start + eden_size;
434 assert(eden_end >= eden_start, "addition overflowed")
435
436 // To may resize into from space as long as it is clear of live data.
437 // From space must remain page aligned, though, so we need to do some
438 // extra calculations.
439
440 // First calculate an optimal to-space
441 to_end = (char*)_virtual_space->high();
442 to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size,
443 sizeof(char));
444
445 // Does the optimal to-space overlap from-space?
446 if (to_start < (char*)from_space()->end()) {
447 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
448
449 // Calculate the minimum offset possible for from_end
450 size_t from_size = pointer_delta(from_space()->top(), from_start, sizeof(char));
451
452 // Should we be in this method if from_space is empty? Why not the set_space method? FIX ME!
453 if (from_size == 0) {
454 from_size = alignment;
455 } else {
456 from_size = align_size_up(from_size, alignment);
457 }
458
459 from_end = from_start + from_size;
460 assert(from_end > from_start, "addition overflow or from_size problem");
461
477 "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
478 from_start,
479 from_end,
480 pointer_delta(from_end, from_start, sizeof(char)));
481 gclog_or_tty->print_cr(" [ to_start .. to_end): "
482 "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
483 to_start,
484 to_end,
485 pointer_delta( to_end, to_start, sizeof(char)));
486 }
487 } else {
488 // Eden, to, from
489 if (PrintAdaptiveSizePolicy && Verbose) {
490 gclog_or_tty->print_cr(" Eden, to, from:");
491 }
492
493 // To space gets priority over eden resizing. Note that we position
494 // to space as if we were able to resize from space, even though from
495 // space is not modified.
496 // Giving eden priority was tried and gave poorer performance.
497 to_end = (char*)pointer_delta(_virtual_space->high(),
498 (char*)requested_survivor_size,
499 sizeof(char));
500 to_end = MIN2(to_end, from_start);
501 to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size,
502 sizeof(char));
503 // if the space sizes are to be increased by several times then
504 // 'to_start' will point beyond the young generation. In this case
505 // 'to_start' should be adjusted.
506 to_start = MAX2(to_start, eden_start + alignment);
507
508 // Compute how big eden can be, then adjust end.
509 // See comments above on calculating eden_end.
510 size_t eden_size;
511 if (maintain_minimum) {
512 eden_size = pointer_delta(to_start, eden_start, sizeof(char));
513 } else {
514 eden_size = MIN2(requested_eden_size,
515 pointer_delta(to_start, eden_start, sizeof(char)));
516 }
517 eden_end = eden_start + eden_size;
546
547 guarantee((HeapWord*)from_start <= from_space()->bottom(),
548 "from start moved to the right");
549 guarantee((HeapWord*)from_end >= from_space()->top(),
550 "from end moved into live data");
551 assert(is_object_aligned((intptr_t)eden_start), "checking alignment");
552 assert(is_object_aligned((intptr_t)from_start), "checking alignment");
553 assert(is_object_aligned((intptr_t)to_start), "checking alignment");
554
555 MemRegion edenMR((HeapWord*)eden_start, (HeapWord*)eden_end);
556 MemRegion toMR ((HeapWord*)to_start, (HeapWord*)to_end);
557 MemRegion fromMR((HeapWord*)from_start, (HeapWord*)from_end);
558
559 // Let's make sure the call to initialize doesn't reset "top"!
560 HeapWord* old_from_top = from_space()->top();
561
562 // For PrintAdaptiveSizePolicy block below
563 size_t old_from = from_space()->capacity_in_bytes();
564 size_t old_to = to_space()->capacity_in_bytes();
565
566 eden_space()->initialize(edenMR, true);
567 to_space()->initialize(toMR , true);
568 from_space()->initialize(fromMR, false); // Note, not cleared!
569
570 assert(from_space()->top() == old_from_top, "from top changed!");
571
572 if (PrintAdaptiveSizePolicy) {
573 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
574 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
575
576 gclog_or_tty->print("AdaptiveSizePolicy::survivor space sizes: "
577 "collection: %d "
578 "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> "
579 "(" SIZE_FORMAT ", " SIZE_FORMAT ") ",
580 heap->total_collections(),
581 old_from, old_to,
582 from_space()->capacity_in_bytes(),
583 to_space()->capacity_in_bytes());
584 gclog_or_tty->cr();
585 }
586 }
587
588 void PSYoungGen::swap_spaces() {
657 // Mark sweep stores preserved markOops in to space, don't disturb!
658 to_mark_sweep()->compact(false);
659 }
660
661 void PSYoungGen::move_and_update(ParCompactionManager* cm) {
662 PSParallelCompact::move_and_update(cm, PSParallelCompact::eden_space_id);
663 PSParallelCompact::move_and_update(cm, PSParallelCompact::from_space_id);
664 PSParallelCompact::move_and_update(cm, PSParallelCompact::to_space_id);
665 }
666
667 void PSYoungGen::print() const { print_on(tty); }
668 void PSYoungGen::print_on(outputStream* st) const {
669 st->print(" %-15s", "PSYoungGen");
670 if (PrintGCDetails && Verbose) {
671 st->print(" total " SIZE_FORMAT ", used " SIZE_FORMAT,
672 capacity_in_bytes(), used_in_bytes());
673 } else {
674 st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
675 capacity_in_bytes()/K, used_in_bytes()/K);
676 }
677 _virtual_space->print_space_boundaries_on(st);
678 st->print(" eden"); eden_space()->print_on(st);
679 st->print(" from"); from_space()->print_on(st);
680 st->print(" to "); to_space()->print_on(st);
681 }
682
683 void PSYoungGen::print_used_change(size_t prev_used) const {
684 gclog_or_tty->print(" [%s:", name());
685 gclog_or_tty->print(" " SIZE_FORMAT "K"
686 "->" SIZE_FORMAT "K"
687 "(" SIZE_FORMAT "K)",
688 prev_used / K, used_in_bytes() / K,
689 capacity_in_bytes() / K);
690 gclog_or_tty->print("]");
691 }
692
693 size_t PSYoungGen::available_for_expansion() {
694 ShouldNotReachHere();
695 return 0;
696 }
697
698 size_t PSYoungGen::available_for_contraction() {
699 ShouldNotReachHere();
700 return 0;
701 }
702
703 size_t PSYoungGen::available_to_min_gen() {
704 assert(virtual_space()->committed_size() >= min_gen_size(), "Invariant");
705 return virtual_space()->committed_size() - min_gen_size();
706 }
707
708 // This method assumes that from-space has live data and that
709 // any shrinkage of the young gen is limited by location of
710 // from-space.
711 size_t PSYoungGen::available_to_live() {
712 size_t delta_in_survivor = 0;
713 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
714 const size_t space_alignment = heap->intra_generation_alignment();
715 const size_t gen_alignment = heap->young_gen_alignment();
716
717 MutableSpace* space_shrinking = NULL;
718 if (from_space()->end() > to_space()->end()) {
719 space_shrinking = from_space();
720 } else {
721 space_shrinking = to_space();
722 }
723
724 // Include any space that is committed but not included in
725 // the survivor spaces.
726 assert(((HeapWord*)virtual_space()->high()) >= space_shrinking->end(),
727 "Survivor space beyond high end");
728 size_t unused_committed = pointer_delta(virtual_space()->high(),
729 space_shrinking->end(), sizeof(char));
730
731 if (space_shrinking->is_empty()) {
732 // Don't let the space shrink to 0
733 assert(space_shrinking->capacity_in_bytes() >= space_alignment,
734 "Space is too small");
760 ShouldNotReachHere();
761 }
762
763 void PSYoungGen::reset_survivors_after_shrink() {
764 _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(),
765 (HeapWord*)virtual_space()->high_boundary());
766 PSScavenge::reference_processor()->set_span(_reserved);
767
768 MutableSpace* space_shrinking = NULL;
769 if (from_space()->end() > to_space()->end()) {
770 space_shrinking = from_space();
771 } else {
772 space_shrinking = to_space();
773 }
774
775 HeapWord* new_end = (HeapWord*)virtual_space()->high();
776 assert(new_end >= space_shrinking->bottom(), "Shrink was too large");
777 // Was there a shrink of the survivor space?
778 if (new_end < space_shrinking->end()) {
779 MemRegion mr(space_shrinking->bottom(), new_end);
780 space_shrinking->initialize(mr, false /* clear */);
781 }
782 }
783
784 // This method currently does not expect to expand into eden (i.e.,
785 // the virtual space boundaries is expected to be consistent
786 // with the eden boundaries..
787 void PSYoungGen::post_resize() {
788 assert_locked_or_safepoint(Heap_lock);
789 assert((eden_space()->bottom() < to_space()->bottom()) &&
790 (eden_space()->bottom() < from_space()->bottom()),
791 "Eden is assumed to be below the survivor spaces");
792
793 MemRegion cmr((HeapWord*)virtual_space()->low(),
794 (HeapWord*)virtual_space()->high());
795 Universe::heap()->barrier_set()->resize_covered_region(cmr);
796 space_invariants();
797 }
798
799
800
801 void PSYoungGen::update_counters() {
802 if (UsePerfData) {
803 _eden_counters->update_all();
804 _from_counters->update_all();
805 _to_counters->update_all();
806 _gen_counters->update_all();
807 }
808 }
809
810 void PSYoungGen::verify(bool allow_dirty) {
811 eden_space()->verify(allow_dirty);
812 from_space()->verify(allow_dirty);
813 to_space()->verify(allow_dirty);
814 }
|
1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)psYoungGen.cpp 1.68 07/10/04 10:49:36 JVM"
3 #endif
4 /*
5 * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
26 */
27
28 # include "incls/_precompiled.incl"
29 # include "incls/_psYoungGen.cpp.incl"
30
31 PSYoungGen::PSYoungGen(size_t initial_size,
32 size_t min_size,
33 size_t max_size) :
34 _init_gen_size(initial_size),
35 _min_gen_size(min_size),
36 _max_gen_size(max_size)
37 {}
38
39 void PSYoungGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) {
40 assert(_init_gen_size != 0, "Should have a finite size");
41 _virtual_space = new PSVirtualSpace(rs, alignment);
42 if (!virtual_space()->expand_by(_init_gen_size)) {
43 vm_exit_during_initialization("Could not reserve enough space for "
44 "object heap");
45 }
46 }
47
48 void PSYoungGen::initialize(ReservedSpace rs, size_t alignment) {
49 initialize_virtual_space(rs, alignment);
50 initialize_work();
51 }
52
53 void PSYoungGen::initialize_work() {
54
55 _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(),
56 (HeapWord*)virtual_space()->high_boundary());
57
58 MemRegion cmr((HeapWord*)virtual_space()->low(),
59 (HeapWord*)virtual_space()->high());
60 Universe::heap()->barrier_set()->resize_covered_region(cmr);
61
62 if (ZapUnusedHeapArea) {
63 // Mangle newly committed space immediately because it
64 // can be done here more simply that after the new
65 // spaces have been computed.
66 SpaceMangler::mangle_region(cmr);
67 }
68
69 if (UseNUMA) {
70 _eden_space = new MutableNUMASpace();
71 } else {
72 _eden_space = new MutableSpace();
73 }
74 _from_space = new MutableSpace();
75 _to_space = new MutableSpace();
76
77 if (_eden_space == NULL || _from_space == NULL || _to_space == NULL) {
78 vm_exit_during_initialization("Could not allocate a young gen space");
79 }
80
81 // Allocate the mark sweep views of spaces
82 _eden_mark_sweep =
83 new PSMarkSweepDecorator(_eden_space, NULL, MarkSweepDeadRatio);
84 _from_mark_sweep =
85 new PSMarkSweepDecorator(_from_space, NULL, MarkSweepDeadRatio);
86 _to_mark_sweep =
87 new PSMarkSweepDecorator(_to_space, NULL, MarkSweepDeadRatio);
88
89 if (_eden_mark_sweep == NULL ||
90 _from_mark_sweep == NULL ||
91 _to_mark_sweep == NULL) {
92 vm_exit_during_initialization("Could not complete allocation"
93 " of the young generation");
94 }
95
96 // Generation Counters - generation 0, 3 subspaces
97 _gen_counters = new PSGenerationCounters("new", 0, 3, _virtual_space);
98
99 // Compute maximum space sizes for performance counters
100 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
101 size_t alignment = heap->intra_heap_alignment();
102 size_t size = virtual_space()->reserved_size();
103
104 size_t max_survivor_size;
105 size_t max_eden_size;
106
107 if (UseAdaptiveSizePolicy) {
108 max_survivor_size = size / MinSurvivorRatio;
109
110 // round the survivor space size down to the nearest alignment
111 // and make sure its size is greater than 0.
112 max_survivor_size = align_size_down(max_survivor_size, alignment);
113 max_survivor_size = MAX2(max_survivor_size, alignment);
114
115 // set the maximum size of eden to be the size of the young gen
116 // less two times the minimum survivor size. The minimum survivor
117 // size for UseAdaptiveSizePolicy is one alignment.
118 max_eden_size = size - 2 * alignment;
119 } else {
120 max_survivor_size = size / InitialSurvivorRatio;
121
122 // round the survivor space size down to the nearest alignment
134 // is the point where eden reachs its maximum size. At this point,
135 // the size of a survivor space is max_survivor_size.
136 max_eden_size = size - 2 * max_survivor_size;
137 }
138
139 _eden_counters = new SpaceCounters("eden", 0, max_eden_size, _eden_space,
140 _gen_counters);
141 _from_counters = new SpaceCounters("s0", 1, max_survivor_size, _from_space,
142 _gen_counters);
143 _to_counters = new SpaceCounters("s1", 2, max_survivor_size, _to_space,
144 _gen_counters);
145
146 compute_initial_space_boundaries();
147 }
148
149 void PSYoungGen::compute_initial_space_boundaries() {
150 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
151 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
152
153 // Compute sizes
154 size_t alignment = heap->intra_heap_alignment();
155 size_t size = virtual_space()->committed_size();
156
157 size_t survivor_size = size / InitialSurvivorRatio;
158 survivor_size = align_size_down(survivor_size, alignment);
159 // ... but never less than an alignment
160 survivor_size = MAX2(survivor_size, alignment);
161
162 // Young generation is eden + 2 survivor spaces
163 size_t eden_size = size - (2 * survivor_size);
164
165 // Now go ahead and set 'em.
166 set_space_boundaries(eden_size, survivor_size);
167 space_invariants();
168
169 if (UsePerfData) {
170 _eden_counters->update_capacity();
171 _from_counters->update_capacity();
172 _to_counters->update_capacity();
173 }
174 }
175
176 void PSYoungGen::set_space_boundaries(size_t eden_size, size_t survivor_size) {
177 assert(eden_size < virtual_space()->committed_size(), "just checking");
178 assert(eden_size > 0 && survivor_size > 0, "just checking");
179
180 // Initial layout is Eden, to, from. After swapping survivor spaces,
181 // that leaves us with Eden, from, to, which is step one in our two
182 // step resize-with-live-data procedure.
183 char *eden_start = virtual_space()->low();
184 char *to_start = eden_start + eden_size;
185 char *from_start = to_start + survivor_size;
186 char *from_end = from_start + survivor_size;
187
188 assert(from_end == virtual_space()->high(), "just checking");
189 assert(is_object_aligned((intptr_t)eden_start), "checking alignment");
190 assert(is_object_aligned((intptr_t)to_start), "checking alignment");
191 assert(is_object_aligned((intptr_t)from_start), "checking alignment");
192
193 MemRegion eden_mr((HeapWord*)eden_start, (HeapWord*)to_start);
194 MemRegion to_mr ((HeapWord*)to_start, (HeapWord*)from_start);
195 MemRegion from_mr((HeapWord*)from_start, (HeapWord*)from_end);
196
197 eden_space()->initialize(eden_mr, true, ZapUnusedHeapArea);
198 to_space()->initialize(to_mr , true, ZapUnusedHeapArea);
199 from_space()->initialize(from_mr, true, ZapUnusedHeapArea);
200 }
201
202 #ifndef PRODUCT
203 void PSYoungGen::space_invariants() {
204 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
205 const size_t alignment = heap->intra_heap_alignment();
206
207 // Currently, our eden size cannot shrink to zero
208 guarantee(eden_space()->capacity_in_bytes() >= alignment, "eden too small");
209 guarantee(from_space()->capacity_in_bytes() >= alignment, "from too small");
210 guarantee(to_space()->capacity_in_bytes() >= alignment, "to too small");
211
212 // Relationship of spaces to each other
213 char* eden_start = (char*)eden_space()->bottom();
214 char* eden_end = (char*)eden_space()->end();
215 char* from_start = (char*)from_space()->bottom();
216 char* from_end = (char*)from_space()->end();
217 char* to_start = (char*)to_space()->bottom();
218 char* to_end = (char*)to_space()->end();
219
220 guarantee(eden_start >= virtual_space()->low(), "eden bottom");
221 guarantee(eden_start < eden_end, "eden space consistency");
222 guarantee(from_start < from_end, "from space consistency");
223 guarantee(to_start < to_end, "to space consistency");
224
225 // Check whether from space is below to space
226 if (from_start < to_start) {
227 // Eden, from, to
228 guarantee(eden_end <= from_start, "eden/from boundary");
229 guarantee(from_end <= to_start, "from/to boundary");
230 guarantee(to_end <= virtual_space()->high(), "to end");
231 } else {
232 // Eden, to, from
233 guarantee(eden_end <= to_start, "eden/to boundary");
234 guarantee(to_end <= from_start, "to/from boundary");
235 guarantee(from_end <= virtual_space()->high(), "from end");
236 }
237
238 // More checks that the virtual space is consistent with the spaces
239 assert(virtual_space()->committed_size() >=
240 (eden_space()->capacity_in_bytes() +
241 to_space()->capacity_in_bytes() +
242 from_space()->capacity_in_bytes()), "Committed size is inconsistent");
243 assert(virtual_space()->committed_size() <= virtual_space()->reserved_size(),
244 "Space invariant");
245 char* eden_top = (char*)eden_space()->top();
246 char* from_top = (char*)from_space()->top();
247 char* to_top = (char*)to_space()->top();
248 assert(eden_top <= virtual_space()->high(), "eden top");
249 assert(from_top <= virtual_space()->high(), "from top");
250 assert(to_top <= virtual_space()->high(), "to top");
251
252 virtual_space()->verify();
253 }
254 #endif
255
256 void PSYoungGen::resize(size_t eden_size, size_t survivor_size) {
257 // Resize the generation if needed. If the generation resize
258 // reports false, do not attempt to resize the spaces.
259 if (resize_generation(eden_size, survivor_size)) {
260 // Then we lay out the spaces inside the generation
261 resize_spaces(eden_size, survivor_size);
262
263 space_invariants();
264
265 if (PrintAdaptiveSizePolicy && Verbose) {
266 gclog_or_tty->print_cr("Young generation size: "
267 "desired eden: " SIZE_FORMAT " survivor: " SIZE_FORMAT
268 " used: " SIZE_FORMAT " capacity: " SIZE_FORMAT
269 " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
270 eden_size, survivor_size, used_in_bytes(), capacity_in_bytes(),
271 _max_gen_size, min_gen_size());
272 }
273 }
274 }
275
276
277 bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) {
278 const size_t alignment = virtual_space()->alignment();
279 size_t orig_size = virtual_space()->committed_size();
280 bool size_changed = false;
281
282 // There used to be this guarantee there.
283 // guarantee ((eden_size + 2*survivor_size) <= _max_gen_size, "incorrect input arguments");
284 // Code below forces this requirement. In addition the desired eden
285 // size and disired survivor sizes are desired goals and may
286 // exceed the total generation size.
287
288 assert(min_gen_size() <= orig_size && orig_size <= max_size(), "just checking");
289
290 // Adjust new generation size
291 const size_t eden_plus_survivors =
292 align_size_up(eden_size + 2 * survivor_size, alignment);
293 size_t desired_size = MAX2(MIN2(eden_plus_survivors, max_size()),
294 min_gen_size());
295 assert(desired_size <= max_size(), "just checking");
296
297 if (desired_size > orig_size) {
298 // Grow the generation
299 size_t change = desired_size - orig_size;
300 assert(change % alignment == 0, "just checking");
301 HeapWord* prev_high = (HeapWord*) virtual_space()->high();
302 if (!virtual_space()->expand_by(change)) {
303 return false; // Error if we fail to resize!
304 }
305 if (ZapUnusedHeapArea) {
306 // Mangle newly committed space immediately because it
307 // can be done here more simply that after the new
308 // spaces have been computed.
309 HeapWord* new_high = (HeapWord*) virtual_space()->high();
310 MemRegion mangle_region(prev_high, new_high);
311 SpaceMangler::mangle_region(mangle_region);
312 }
313 size_changed = true;
314 } else if (desired_size < orig_size) {
315 size_t desired_change = orig_size - desired_size;
316 assert(desired_change % alignment == 0, "just checking");
317
318 desired_change = limit_gen_shrink(desired_change);
319
320 if (desired_change > 0) {
321 virtual_space()->shrink_by(desired_change);
322 reset_survivors_after_shrink();
323
324 size_changed = true;
325 }
326 } else {
327 if (Verbose && PrintGC) {
328 if (orig_size == gen_size_limit()) {
329 gclog_or_tty->print_cr("PSYoung generation size at maximum: "
330 SIZE_FORMAT "K", orig_size/K);
331 } else if (orig_size == min_gen_size()) {
332 gclog_or_tty->print_cr("PSYoung generation size at minium: "
333 SIZE_FORMAT "K", orig_size/K);
334 }
335 }
336 }
337
338 if (size_changed) {
339 post_resize();
340
341 if (Verbose && PrintGC) {
342 size_t current_size = virtual_space()->committed_size();
343 gclog_or_tty->print_cr("PSYoung generation size changed: "
344 SIZE_FORMAT "K->" SIZE_FORMAT "K",
345 orig_size/K, current_size/K);
346 }
347 }
348
349 guarantee(eden_plus_survivors <= virtual_space()->committed_size() ||
350 virtual_space()->committed_size() == max_size(), "Sanity");
351
352 return true;
353 }
354
355 #ifndef PRODUCT
356 // In the numa case eden is not mangled so a survivor space
357 // moving into a region previously occupied by a survivor
358 // may find an unmangled region. Also in the PS case eden
359 // to-space and from-space may not touch (i.e., there may be
360 // gaps between them due to movement while resizing the
361 // spaces). Those gaps must be mangled.
362 void PSYoungGen::mangle_survivors(MutableSpace* s1,
363 MemRegion s1MR,
364 MutableSpace* s2,
365 MemRegion s2MR) {
366 // Check eden and gap between eden and from-space, in deciding
367 // what to mangle in from-space. Check the gap between from-space
368 // and to-space when deciding what to mangle.
369 //
370 // +--------+ +----+ +---+
371 // | eden | |s1 | |s2 |
372 // +--------+ +----+ +---+
373 // +-------+ +-----+
374 // |s1MR | |s2MR |
375 // +-------+ +-----+
376 // All of survivor-space is properly mangled so find the
377 // upper bound on the mangling for any portion above current s1.
378 HeapWord* delta_end = MIN2(s1->bottom(), s1MR.end());
379 MemRegion delta1_left;
380 if (s1MR.start() < delta_end) {
381 delta1_left = MemRegion(s1MR.start(), delta_end);
382 s1->mangle_region(delta1_left);
383 }
384 // Find any portion to the right of the current s1.
385 HeapWord* delta_start = MAX2(s1->end(), s1MR.start());
386 MemRegion delta1_right;
387 if (delta_start < s1MR.end()) {
388 delta1_right = MemRegion(delta_start, s1MR.end());
389 s1->mangle_region(delta1_right);
390 }
391
392 // Similarly for the second survivor space except that
393 // any of the new region that overlaps with the current
394 // region of the first survivor space has already been
395 // mangled.
396 delta_end = MIN2(s2->bottom(), s2MR.end());
397 delta_start = MAX2(s2MR.start(), s1->end());
398 MemRegion delta2_left;
399 if (s2MR.start() < delta_end) {
400 delta2_left = MemRegion(s2MR.start(), delta_end);
401 s2->mangle_region(delta2_left);
402 }
403 delta_start = MAX2(s2->end(), s2MR.start());
404 MemRegion delta2_right;
405 if (delta_start < s2MR.end()) {
406 s2->mangle_region(delta2_right);
407 }
408
409 if (TraceZapUnusedHeapArea) {
410 // s1
411 gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
412 "New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
413 s1->bottom(), s1->end(), s1MR.start(), s1MR.end());
414 gclog_or_tty->print_cr(" Mangle before: [" PTR_FORMAT ", "
415 PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
416 delta1_left.start(), delta1_left.end(), delta1_right.start(),
417 delta1_right.end());
418
419 // s2
420 gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
421 "New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
422 s2->bottom(), s2->end(), s2MR.start(), s2MR.end());
423 gclog_or_tty->print_cr(" Mangle before: [" PTR_FORMAT ", "
424 PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
425 delta2_left.start(), delta2_left.end(), delta2_right.start(),
426 delta2_right.end());
427 }
428
429 }
430 #endif // NOT PRODUCT
431
432 void PSYoungGen::resize_spaces(size_t requested_eden_size,
433 size_t requested_survivor_size) {
434 assert(UseAdaptiveSizePolicy, "sanity check");
435 assert(requested_eden_size > 0 && requested_survivor_size > 0,
436 "just checking");
437
438 // We require eden and to space to be empty
439 if ((!eden_space()->is_empty()) || (!to_space()->is_empty())) {
440 return;
441 }
442
443 if (PrintAdaptiveSizePolicy && Verbose) {
444 gclog_or_tty->print_cr("PSYoungGen::resize_spaces(requested_eden_size: "
445 SIZE_FORMAT
446 ", requested_survivor_size: " SIZE_FORMAT ")",
447 requested_eden_size, requested_survivor_size);
448 gclog_or_tty->print_cr(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") "
449 SIZE_FORMAT,
450 eden_space()->bottom(),
469 }
470
471 // There's nothing to do if the new sizes are the same as the current
472 if (requested_survivor_size == to_space()->capacity_in_bytes() &&
473 requested_survivor_size == from_space()->capacity_in_bytes() &&
474 requested_eden_size == eden_space()->capacity_in_bytes()) {
475 if (PrintAdaptiveSizePolicy && Verbose) {
476 gclog_or_tty->print_cr(" capacities are the right sizes, returning");
477 }
478 return;
479 }
480
481 char* eden_start = (char*)eden_space()->bottom();
482 char* eden_end = (char*)eden_space()->end();
483 char* from_start = (char*)from_space()->bottom();
484 char* from_end = (char*)from_space()->end();
485 char* to_start = (char*)to_space()->bottom();
486 char* to_end = (char*)to_space()->end();
487
488 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
489 const size_t alignment = heap->intra_heap_alignment();
490 const bool maintain_minimum =
491 (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
492
493 bool eden_from_to_order = from_start < to_start;
494 // Check whether from space is below to space
495 if (eden_from_to_order) {
496 // Eden, from, to
497 eden_from_to_order = true;
498 if (PrintAdaptiveSizePolicy && Verbose) {
499 gclog_or_tty->print_cr(" Eden, from, to:");
500 }
501
502 // Set eden
503 // "requested_eden_size" is a goal for the size of eden
504 // and may not be attainable. "eden_size" below is
505 // calculated based on the location of from-space and
506 // the goal for the size of eden. from-space is
507 // fixed in place because it contains live data.
508 // The calculation is done this way to avoid 32bit
509 // overflow (i.e., eden_start + requested_eden_size
510 // may too large for representation in 32bits).
511 size_t eden_size;
512 if (maintain_minimum) {
513 // Only make eden larger than the requested size if
514 // the minimum size of the generation has to be maintained.
515 // This could be done in general but policy at a higher
516 // level is determining a requested size for eden and that
517 // should be honored unless there is a fundamental reason.
518 eden_size = pointer_delta(from_start,
519 eden_start,
520 sizeof(char));
521 } else {
522 eden_size = MIN2(requested_eden_size,
523 pointer_delta(from_start, eden_start, sizeof(char)));
524 }
525
526 eden_end = eden_start + eden_size;
527 assert(eden_end >= eden_start, "addition overflowed")
528
529 // To may resize into from space as long as it is clear of live data.
530 // From space must remain page aligned, though, so we need to do some
531 // extra calculations.
532
533 // First calculate an optimal to-space
534 to_end = (char*)virtual_space()->high();
535 to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size,
536 sizeof(char));
537
538 // Does the optimal to-space overlap from-space?
539 if (to_start < (char*)from_space()->end()) {
540 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
541
542 // Calculate the minimum offset possible for from_end
543 size_t from_size = pointer_delta(from_space()->top(), from_start, sizeof(char));
544
545 // Should we be in this method if from_space is empty? Why not the set_space method? FIX ME!
546 if (from_size == 0) {
547 from_size = alignment;
548 } else {
549 from_size = align_size_up(from_size, alignment);
550 }
551
552 from_end = from_start + from_size;
553 assert(from_end > from_start, "addition overflow or from_size problem");
554
570 "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
571 from_start,
572 from_end,
573 pointer_delta(from_end, from_start, sizeof(char)));
574 gclog_or_tty->print_cr(" [ to_start .. to_end): "
575 "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
576 to_start,
577 to_end,
578 pointer_delta( to_end, to_start, sizeof(char)));
579 }
580 } else {
581 // Eden, to, from
582 if (PrintAdaptiveSizePolicy && Verbose) {
583 gclog_or_tty->print_cr(" Eden, to, from:");
584 }
585
586 // To space gets priority over eden resizing. Note that we position
587 // to space as if we were able to resize from space, even though from
588 // space is not modified.
589 // Giving eden priority was tried and gave poorer performance.
590 to_end = (char*)pointer_delta(virtual_space()->high(),
591 (char*)requested_survivor_size,
592 sizeof(char));
593 to_end = MIN2(to_end, from_start);
594 to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size,
595 sizeof(char));
596 // if the space sizes are to be increased by several times then
597 // 'to_start' will point beyond the young generation. In this case
598 // 'to_start' should be adjusted.
599 to_start = MAX2(to_start, eden_start + alignment);
600
601 // Compute how big eden can be, then adjust end.
602 // See comments above on calculating eden_end.
603 size_t eden_size;
604 if (maintain_minimum) {
605 eden_size = pointer_delta(to_start, eden_start, sizeof(char));
606 } else {
607 eden_size = MIN2(requested_eden_size,
608 pointer_delta(to_start, eden_start, sizeof(char)));
609 }
610 eden_end = eden_start + eden_size;
639
640 guarantee((HeapWord*)from_start <= from_space()->bottom(),
641 "from start moved to the right");
642 guarantee((HeapWord*)from_end >= from_space()->top(),
643 "from end moved into live data");
644 assert(is_object_aligned((intptr_t)eden_start), "checking alignment");
645 assert(is_object_aligned((intptr_t)from_start), "checking alignment");
646 assert(is_object_aligned((intptr_t)to_start), "checking alignment");
647
648 MemRegion edenMR((HeapWord*)eden_start, (HeapWord*)eden_end);
649 MemRegion toMR ((HeapWord*)to_start, (HeapWord*)to_end);
650 MemRegion fromMR((HeapWord*)from_start, (HeapWord*)from_end);
651
652 // Let's make sure the call to initialize doesn't reset "top"!
653 HeapWord* old_from_top = from_space()->top();
654
655 // For PrintAdaptiveSizePolicy block below
656 size_t old_from = from_space()->capacity_in_bytes();
657 size_t old_to = to_space()->capacity_in_bytes();
658
659 if (ZapUnusedHeapArea) {
660 // NUMA is a special case because a numa space is not mangled
661 // in order to not prematurely bind its address to memory to
662 // the wrong memory (i.e., don't want the GC thread to first
663 // touch the memory). The survivor spaces are not numa
664 // spaces and are mangled.
665 if (UseNUMA) {
666 if (eden_from_to_order) {
667 mangle_survivors(from_space(), fromMR, to_space(), toMR);
668 } else {
669 mangle_survivors(to_space(), toMR, from_space(), fromMR);
670 }
671 }
672
673 // If not mangling the spaces, do some checking to verify that
674 // the spaces are already mangled.
675 // The spaces should be correctly mangled at this point so
676 // do some checking here. Note that they are not being mangled
677 // in the calls to initialize().
678 // Must check mangling before the spaces are reshaped. Otherwise,
679 // the bottom or end of one space may have moved into an area
680 // covered by another space and a failure of the check may
681 // not correctly indicate which space is not properly mangled.
682 HeapWord* limit = (HeapWord*) virtual_space()->high();
683 eden_space()->check_mangled_unused_area(limit);
684 from_space()->check_mangled_unused_area(limit);
685 to_space()->check_mangled_unused_area(limit);
686 }
687 // When an existing space is being initialized, it is not
688 // mangled because the space has been previously mangled.
689 eden_space()->initialize(edenMR,
690 SpaceDecorator::Clear,
691 SpaceDecorator::DontMangle);
692 to_space()->initialize(toMR,
693 SpaceDecorator::Clear,
694 SpaceDecorator::DontMangle);
695 from_space()->initialize(fromMR,
696 SpaceDecorator::DontClear,
697 SpaceDecorator::DontMangle);
698
699 assert(from_space()->top() == old_from_top, "from top changed!");
700
701 if (PrintAdaptiveSizePolicy) {
702 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
703 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
704
705 gclog_or_tty->print("AdaptiveSizePolicy::survivor space sizes: "
706 "collection: %d "
707 "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> "
708 "(" SIZE_FORMAT ", " SIZE_FORMAT ") ",
709 heap->total_collections(),
710 old_from, old_to,
711 from_space()->capacity_in_bytes(),
712 to_space()->capacity_in_bytes());
713 gclog_or_tty->cr();
714 }
715 }
716
717 void PSYoungGen::swap_spaces() {
786 // Mark sweep stores preserved markOops in to space, don't disturb!
787 to_mark_sweep()->compact(false);
788 }
789
790 void PSYoungGen::move_and_update(ParCompactionManager* cm) {
791 PSParallelCompact::move_and_update(cm, PSParallelCompact::eden_space_id);
792 PSParallelCompact::move_and_update(cm, PSParallelCompact::from_space_id);
793 PSParallelCompact::move_and_update(cm, PSParallelCompact::to_space_id);
794 }
795
796 void PSYoungGen::print() const { print_on(tty); }
797 void PSYoungGen::print_on(outputStream* st) const {
798 st->print(" %-15s", "PSYoungGen");
799 if (PrintGCDetails && Verbose) {
800 st->print(" total " SIZE_FORMAT ", used " SIZE_FORMAT,
801 capacity_in_bytes(), used_in_bytes());
802 } else {
803 st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
804 capacity_in_bytes()/K, used_in_bytes()/K);
805 }
806 virtual_space()->print_space_boundaries_on(st);
807 st->print(" eden"); eden_space()->print_on(st);
808 st->print(" from"); from_space()->print_on(st);
809 st->print(" to "); to_space()->print_on(st);
810 }
811
812 void PSYoungGen::print_used_change(size_t prev_used) const {
813 gclog_or_tty->print(" [%s:", name());
814 gclog_or_tty->print(" " SIZE_FORMAT "K"
815 "->" SIZE_FORMAT "K"
816 "(" SIZE_FORMAT "K)",
817 prev_used / K, used_in_bytes() / K,
818 capacity_in_bytes() / K);
819 gclog_or_tty->print("]");
820 }
821
822 size_t PSYoungGen::available_for_expansion() {
823 ShouldNotReachHere();
824 return 0;
825 }
826
827 size_t PSYoungGen::available_for_contraction() {
828 ShouldNotReachHere();
829 return 0;
830 }
831
832 size_t PSYoungGen::available_to_min_gen() {
833 assert(virtual_space()->committed_size() >= min_gen_size(), "Invariant");
834 return virtual_space()->committed_size() - min_gen_size();
835 }
836
837 // This method assumes that from-space has live data and that
838 // any shrinkage of the young gen is limited by location of
839 // from-space.
840 size_t PSYoungGen::available_to_live() {
841 size_t delta_in_survivor = 0;
842 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
843 const size_t space_alignment = heap->intra_heap_alignment();
844 const size_t gen_alignment = heap->young_gen_alignment();
845
846 MutableSpace* space_shrinking = NULL;
847 if (from_space()->end() > to_space()->end()) {
848 space_shrinking = from_space();
849 } else {
850 space_shrinking = to_space();
851 }
852
853 // Include any space that is committed but not included in
854 // the survivor spaces.
855 assert(((HeapWord*)virtual_space()->high()) >= space_shrinking->end(),
856 "Survivor space beyond high end");
857 size_t unused_committed = pointer_delta(virtual_space()->high(),
858 space_shrinking->end(), sizeof(char));
859
860 if (space_shrinking->is_empty()) {
861 // Don't let the space shrink to 0
862 assert(space_shrinking->capacity_in_bytes() >= space_alignment,
863 "Space is too small");
889 ShouldNotReachHere();
890 }
891
892 void PSYoungGen::reset_survivors_after_shrink() {
893 _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(),
894 (HeapWord*)virtual_space()->high_boundary());
895 PSScavenge::reference_processor()->set_span(_reserved);
896
897 MutableSpace* space_shrinking = NULL;
898 if (from_space()->end() > to_space()->end()) {
899 space_shrinking = from_space();
900 } else {
901 space_shrinking = to_space();
902 }
903
904 HeapWord* new_end = (HeapWord*)virtual_space()->high();
905 assert(new_end >= space_shrinking->bottom(), "Shrink was too large");
906 // Was there a shrink of the survivor space?
907 if (new_end < space_shrinking->end()) {
908 MemRegion mr(space_shrinking->bottom(), new_end);
909 space_shrinking->initialize(mr,
910 SpaceDecorator::DontClear,
911 SpaceDecorator::Mangle);
912 }
913 }
914
915 // This method currently does not expect to expand into eden (i.e.,
916 // the virtual space boundaries is expected to be consistent
917 // with the eden boundaries..
918 void PSYoungGen::post_resize() {
919 assert_locked_or_safepoint(Heap_lock);
920 assert((eden_space()->bottom() < to_space()->bottom()) &&
921 (eden_space()->bottom() < from_space()->bottom()),
922 "Eden is assumed to be below the survivor spaces");
923
924 MemRegion cmr((HeapWord*)virtual_space()->low(),
925 (HeapWord*)virtual_space()->high());
926 Universe::heap()->barrier_set()->resize_covered_region(cmr);
927 space_invariants();
928 }
929
930
931
932 void PSYoungGen::update_counters() {
933 if (UsePerfData) {
934 _eden_counters->update_all();
935 _from_counters->update_all();
936 _to_counters->update_all();
937 _gen_counters->update_all();
938 }
939 }
940
941 void PSYoungGen::verify(bool allow_dirty) {
942 eden_space()->verify(allow_dirty);
943 from_space()->verify(allow_dirty);
944 to_space()->verify(allow_dirty);
945 }
946
947 #ifndef PRODUCT
948 void PSYoungGen::record_spaces_top() {
949 assert(ZapUnusedHeapArea, "Not mangling unused space");
950 eden_space()->set_top_for_allocations();
951 from_space()->set_top_for_allocations();
952 to_space()->set_top_for_allocations();
953 }
954 #endif
|