src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp

Sat, 01 Dec 2007 00:00:00 +0000

author
duke
date
Sat, 01 Dec 2007 00:00:00 +0000
changeset 435
a61af66fc99e
child 448
183f41cf8bfe
permissions
-rw-r--r--

Initial load

     1 /*
     2  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
     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  *
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 # include "incls/_precompiled.incl"
    26 # include "incls/_psYoungGen.cpp.incl"
    28 PSYoungGen::PSYoungGen(size_t        initial_size,
    29                        size_t        min_size,
    30                        size_t        max_size) :
    31   _init_gen_size(initial_size),
    32   _min_gen_size(min_size),
    33   _max_gen_size(max_size)
    34 {}
    36 void PSYoungGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) {
    37   assert(_init_gen_size != 0, "Should have a finite size");
    38   _virtual_space = new PSVirtualSpace(rs, alignment);
    39   if (!_virtual_space->expand_by(_init_gen_size)) {
    40     vm_exit_during_initialization("Could not reserve enough space for "
    41                                   "object heap");
    42   }
    43 }
    45 void PSYoungGen::initialize(ReservedSpace rs, size_t alignment) {
    46   initialize_virtual_space(rs, alignment);
    47   initialize_work();
    48 }
    50 void PSYoungGen::initialize_work() {
    52   _reserved = MemRegion((HeapWord*)_virtual_space->low_boundary(),
    53                         (HeapWord*)_virtual_space->high_boundary());
    55   MemRegion cmr((HeapWord*)_virtual_space->low(),
    56                 (HeapWord*)_virtual_space->high());
    57   Universe::heap()->barrier_set()->resize_covered_region(cmr);
    59   if (UseNUMA) {
    60     _eden_space = new MutableNUMASpace();
    61   } else {
    62     _eden_space = new MutableSpace();
    63   }
    64   _from_space = new MutableSpace();
    65   _to_space   = new MutableSpace();
    67   if (_eden_space == NULL || _from_space == NULL || _to_space == NULL) {
    68     vm_exit_during_initialization("Could not allocate a young gen space");
    69   }
    71   // Allocate the mark sweep views of spaces
    72   _eden_mark_sweep =
    73       new PSMarkSweepDecorator(_eden_space, NULL, MarkSweepDeadRatio);
    74   _from_mark_sweep =
    75       new PSMarkSweepDecorator(_from_space, NULL, MarkSweepDeadRatio);
    76   _to_mark_sweep =
    77       new PSMarkSweepDecorator(_to_space, NULL, MarkSweepDeadRatio);
    79   if (_eden_mark_sweep == NULL ||
    80       _from_mark_sweep == NULL ||
    81       _to_mark_sweep == NULL) {
    82     vm_exit_during_initialization("Could not complete allocation"
    83                                   " of the young generation");
    84   }
    86   // Generation Counters - generation 0, 3 subspaces
    87   _gen_counters = new PSGenerationCounters("new", 0, 3, _virtual_space);
    89   // Compute maximum space sizes for performance counters
    90   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
    91   size_t alignment = heap->intra_generation_alignment();
    92   size_t size = _virtual_space->reserved_size();
    94   size_t max_survivor_size;
    95   size_t max_eden_size;
    97   if (UseAdaptiveSizePolicy) {
    98     max_survivor_size = size / MinSurvivorRatio;
   100     // round the survivor space size down to the nearest alignment
   101     // and make sure its size is greater than 0.
   102     max_survivor_size = align_size_down(max_survivor_size, alignment);
   103     max_survivor_size = MAX2(max_survivor_size, alignment);
   105     // set the maximum size of eden to be the size of the young gen
   106     // less two times the minimum survivor size. The minimum survivor
   107     // size for UseAdaptiveSizePolicy is one alignment.
   108     max_eden_size = size - 2 * alignment;
   109   } else {
   110     max_survivor_size = size / InitialSurvivorRatio;
   112     // round the survivor space size down to the nearest alignment
   113     // and make sure its size is greater than 0.
   114     max_survivor_size = align_size_down(max_survivor_size, alignment);
   115     max_survivor_size = MAX2(max_survivor_size, alignment);
   117     // set the maximum size of eden to be the size of the young gen
   118     // less two times the survivor size when the generation is 100%
   119     // committed. The minimum survivor size for -UseAdaptiveSizePolicy
   120     // is dependent on the committed portion (current capacity) of the
   121     // generation - the less space committed, the smaller the survivor
   122     // space, possibly as small as an alignment. However, we are interested
   123     // in the case where the young generation is 100% committed, as this
   124     // is the point where eden reachs its maximum size. At this point,
   125     // the size of a survivor space is max_survivor_size.
   126     max_eden_size = size - 2 * max_survivor_size;
   127   }
   129   _eden_counters = new SpaceCounters("eden", 0, max_eden_size, _eden_space,
   130                                      _gen_counters);
   131   _from_counters = new SpaceCounters("s0", 1, max_survivor_size, _from_space,
   132                                      _gen_counters);
   133   _to_counters = new SpaceCounters("s1", 2, max_survivor_size, _to_space,
   134                                    _gen_counters);
   136   compute_initial_space_boundaries();
   137 }
   139 void PSYoungGen::compute_initial_space_boundaries() {
   140   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
   141   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
   143   // Compute sizes
   144   size_t alignment = heap->intra_generation_alignment();
   145   size_t size = _virtual_space->committed_size();
   147   size_t survivor_size = size / InitialSurvivorRatio;
   148   survivor_size = align_size_down(survivor_size, alignment);
   149   // ... but never less than an alignment
   150   survivor_size = MAX2(survivor_size, alignment);
   152   // Young generation is eden + 2 survivor spaces
   153   size_t eden_size = size - (2 * survivor_size);
   155   // Now go ahead and set 'em.
   156   set_space_boundaries(eden_size, survivor_size);
   157   space_invariants();
   159   if (UsePerfData) {
   160     _eden_counters->update_capacity();
   161     _from_counters->update_capacity();
   162     _to_counters->update_capacity();
   163   }
   164 }
   166 void PSYoungGen::set_space_boundaries(size_t eden_size, size_t survivor_size) {
   167   assert(eden_size < _virtual_space->committed_size(), "just checking");
   168   assert(eden_size > 0  && survivor_size > 0, "just checking");
   170   // Initial layout is Eden, to, from. After swapping survivor spaces,
   171   // that leaves us with Eden, from, to, which is step one in our two
   172   // step resize-with-live-data procedure.
   173   char *eden_start = _virtual_space->low();
   174   char *to_start   = eden_start + eden_size;
   175   char *from_start = to_start   + survivor_size;
   176   char *from_end   = from_start + survivor_size;
   178   assert(from_end == _virtual_space->high(), "just checking");
   179   assert(is_object_aligned((intptr_t)eden_start), "checking alignment");
   180   assert(is_object_aligned((intptr_t)to_start),   "checking alignment");
   181   assert(is_object_aligned((intptr_t)from_start), "checking alignment");
   183   MemRegion eden_mr((HeapWord*)eden_start, (HeapWord*)to_start);
   184   MemRegion to_mr  ((HeapWord*)to_start, (HeapWord*)from_start);
   185   MemRegion from_mr((HeapWord*)from_start, (HeapWord*)from_end);
   187   eden_space()->initialize(eden_mr, true);
   188     to_space()->initialize(to_mr  , true);
   189   from_space()->initialize(from_mr, true);
   190 }
   192 #ifndef PRODUCT
   193 void PSYoungGen::space_invariants() {
   194   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
   195   const size_t alignment = heap->intra_generation_alignment();
   197   // Currently, our eden size cannot shrink to zero
   198   guarantee(eden_space()->capacity_in_bytes() >= alignment, "eden too small");
   199   guarantee(from_space()->capacity_in_bytes() >= alignment, "from too small");
   200   guarantee(to_space()->capacity_in_bytes() >= alignment, "to too small");
   202   // Relationship of spaces to each other
   203   char* eden_start = (char*)eden_space()->bottom();
   204   char* eden_end   = (char*)eden_space()->end();
   205   char* from_start = (char*)from_space()->bottom();
   206   char* from_end   = (char*)from_space()->end();
   207   char* to_start   = (char*)to_space()->bottom();
   208   char* to_end     = (char*)to_space()->end();
   210   guarantee(eden_start >= _virtual_space->low(), "eden bottom");
   211   guarantee(eden_start < eden_end, "eden space consistency");
   212   guarantee(from_start < from_end, "from space consistency");
   213   guarantee(to_start < to_end, "to space consistency");
   215   // Check whether from space is below to space
   216   if (from_start < to_start) {
   217     // Eden, from, to
   218     guarantee(eden_end <= from_start, "eden/from boundary");
   219     guarantee(from_end <= to_start,   "from/to boundary");
   220     guarantee(to_end <= _virtual_space->high(), "to end");
   221   } else {
   222     // Eden, to, from
   223     guarantee(eden_end <= to_start, "eden/to boundary");
   224     guarantee(to_end <= from_start, "to/from boundary");
   225     guarantee(from_end <= _virtual_space->high(), "from end");
   226   }
   228   // More checks that the virtual space is consistent with the spaces
   229   assert(_virtual_space->committed_size() >=
   230     (eden_space()->capacity_in_bytes() +
   231      to_space()->capacity_in_bytes() +
   232      from_space()->capacity_in_bytes()), "Committed size is inconsistent");
   233   assert(_virtual_space->committed_size() <= _virtual_space->reserved_size(),
   234     "Space invariant");
   235   char* eden_top = (char*)eden_space()->top();
   236   char* from_top = (char*)from_space()->top();
   237   char* to_top = (char*)to_space()->top();
   238   assert(eden_top <= _virtual_space->high(), "eden top");
   239   assert(from_top <= _virtual_space->high(), "from top");
   240   assert(to_top <= _virtual_space->high(), "to top");
   242   _virtual_space->verify();
   243 }
   244 #endif
   246 void PSYoungGen::resize(size_t eden_size, size_t survivor_size) {
   247   // Resize the generation if needed. If the generation resize
   248   // reports false, do not attempt to resize the spaces.
   249   if (resize_generation(eden_size, survivor_size)) {
   250     // Then we lay out the spaces inside the generation
   251     resize_spaces(eden_size, survivor_size);
   253     space_invariants();
   255     if (PrintAdaptiveSizePolicy && Verbose) {
   256       gclog_or_tty->print_cr("Young generation size: "
   257         "desired eden: " SIZE_FORMAT " survivor: " SIZE_FORMAT
   258         " used: " SIZE_FORMAT " capacity: " SIZE_FORMAT
   259         " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
   260         eden_size, survivor_size, used_in_bytes(), capacity_in_bytes(),
   261         _max_gen_size, min_gen_size());
   262     }
   263   }
   264 }
   267 bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) {
   268   const size_t alignment = _virtual_space->alignment();
   269   size_t orig_size = _virtual_space->committed_size();
   270   bool size_changed = false;
   272   // There used to be this guarantee there.
   273   // guarantee ((eden_size + 2*survivor_size)  <= _max_gen_size, "incorrect input arguments");
   274   // Code below forces this requirement.  In addition the desired eden
   275   // size and disired survivor sizes are desired goals and may
   276   // exceed the total generation size.
   278   assert(min_gen_size() <= orig_size && orig_size <= max_size(), "just checking");
   280   // Adjust new generation size
   281   const size_t eden_plus_survivors =
   282           align_size_up(eden_size + 2 * survivor_size, alignment);
   283   size_t desired_size = MAX2(MIN2(eden_plus_survivors, max_size()),
   284                              min_gen_size());
   285   assert(desired_size <= max_size(), "just checking");
   287   if (desired_size > orig_size) {
   288     // Grow the generation
   289     size_t change = desired_size - orig_size;
   290     assert(change % alignment == 0, "just checking");
   291     if (!_virtual_space->expand_by(change)) {
   292       return false; // Error if we fail to resize!
   293     }
   295     size_changed = true;
   296   } else if (desired_size < orig_size) {
   297     size_t desired_change = orig_size - desired_size;
   298     assert(desired_change % alignment == 0, "just checking");
   300     desired_change = limit_gen_shrink(desired_change);
   302     if (desired_change > 0) {
   303       virtual_space()->shrink_by(desired_change);
   304       reset_survivors_after_shrink();
   306       size_changed = true;
   307     }
   308   } else {
   309     if (Verbose && PrintGC) {
   310       if (orig_size == gen_size_limit()) {
   311         gclog_or_tty->print_cr("PSYoung generation size at maximum: "
   312           SIZE_FORMAT "K", orig_size/K);
   313       } else if (orig_size == min_gen_size()) {
   314         gclog_or_tty->print_cr("PSYoung generation size at minium: "
   315           SIZE_FORMAT "K", orig_size/K);
   316       }
   317     }
   318   }
   320   if (size_changed) {
   321     post_resize();
   323     if (Verbose && PrintGC) {
   324       size_t current_size  = _virtual_space->committed_size();
   325       gclog_or_tty->print_cr("PSYoung generation size changed: "
   326                              SIZE_FORMAT "K->" SIZE_FORMAT "K",
   327                              orig_size/K, current_size/K);
   328     }
   329   }
   331   guarantee(eden_plus_survivors <= _virtual_space->committed_size() ||
   332             _virtual_space->committed_size() == max_size(), "Sanity");
   334   return true;
   335 }
   338 void PSYoungGen::resize_spaces(size_t requested_eden_size,
   339                                size_t requested_survivor_size) {
   340   assert(UseAdaptiveSizePolicy, "sanity check");
   341   assert(requested_eden_size > 0  && requested_survivor_size > 0,
   342          "just checking");
   344   // We require eden and to space to be empty
   345   if ((!eden_space()->is_empty()) || (!to_space()->is_empty())) {
   346     return;
   347   }
   349   if (PrintAdaptiveSizePolicy && Verbose) {
   350     gclog_or_tty->print_cr("PSYoungGen::resize_spaces(requested_eden_size: "
   351                   SIZE_FORMAT
   352                   ", requested_survivor_size: " SIZE_FORMAT ")",
   353                   requested_eden_size, requested_survivor_size);
   354     gclog_or_tty->print_cr("    eden: [" PTR_FORMAT ".." PTR_FORMAT ") "
   355                   SIZE_FORMAT,
   356                   eden_space()->bottom(),
   357                   eden_space()->end(),
   358                   pointer_delta(eden_space()->end(),
   359                                 eden_space()->bottom(),
   360                                 sizeof(char)));
   361     gclog_or_tty->print_cr("    from: [" PTR_FORMAT ".." PTR_FORMAT ") "
   362                   SIZE_FORMAT,
   363                   from_space()->bottom(),
   364                   from_space()->end(),
   365                   pointer_delta(from_space()->end(),
   366                                 from_space()->bottom(),
   367                                 sizeof(char)));
   368     gclog_or_tty->print_cr("      to: [" PTR_FORMAT ".." PTR_FORMAT ") "
   369                   SIZE_FORMAT,
   370                   to_space()->bottom(),
   371                   to_space()->end(),
   372                   pointer_delta(  to_space()->end(),
   373                                   to_space()->bottom(),
   374                                   sizeof(char)));
   375   }
   377   // There's nothing to do if the new sizes are the same as the current
   378   if (requested_survivor_size == to_space()->capacity_in_bytes() &&
   379       requested_survivor_size == from_space()->capacity_in_bytes() &&
   380       requested_eden_size == eden_space()->capacity_in_bytes()) {
   381     if (PrintAdaptiveSizePolicy && Verbose) {
   382       gclog_or_tty->print_cr("    capacities are the right sizes, returning");
   383     }
   384     return;
   385   }
   387   char* eden_start = (char*)eden_space()->bottom();
   388   char* eden_end   = (char*)eden_space()->end();
   389   char* from_start = (char*)from_space()->bottom();
   390   char* from_end   = (char*)from_space()->end();
   391   char* to_start   = (char*)to_space()->bottom();
   392   char* to_end     = (char*)to_space()->end();
   394   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
   395   const size_t alignment = heap->intra_generation_alignment();
   396   const bool maintain_minimum =
   397     (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
   399   // Check whether from space is below to space
   400   if (from_start < to_start) {
   401     // Eden, from, to
   402     if (PrintAdaptiveSizePolicy && Verbose) {
   403       gclog_or_tty->print_cr("  Eden, from, to:");
   404     }
   406     // Set eden
   407     // "requested_eden_size" is a goal for the size of eden
   408     // and may not be attainable.  "eden_size" below is
   409     // calculated based on the location of from-space and
   410     // the goal for the size of eden.  from-space is
   411     // fixed in place because it contains live data.
   412     // The calculation is done this way to avoid 32bit
   413     // overflow (i.e., eden_start + requested_eden_size
   414     // may too large for representation in 32bits).
   415     size_t eden_size;
   416     if (maintain_minimum) {
   417       // Only make eden larger than the requested size if
   418       // the minimum size of the generation has to be maintained.
   419       // This could be done in general but policy at a higher
   420       // level is determining a requested size for eden and that
   421       // should be honored unless there is a fundamental reason.
   422       eden_size = pointer_delta(from_start,
   423                                 eden_start,
   424                                 sizeof(char));
   425     } else {
   426       eden_size = MIN2(requested_eden_size,
   427                        pointer_delta(from_start, eden_start, sizeof(char)));
   428     }
   430     eden_end = eden_start + eden_size;
   431     assert(eden_end >= eden_start, "addition overflowed")
   433     // To may resize into from space as long as it is clear of live data.
   434     // From space must remain page aligned, though, so we need to do some
   435     // extra calculations.
   437     // First calculate an optimal to-space
   438     to_end   = (char*)_virtual_space->high();
   439     to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size,
   440                                     sizeof(char));
   442     // Does the optimal to-space overlap from-space?
   443     if (to_start < (char*)from_space()->end()) {
   444       assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
   446       // Calculate the minimum offset possible for from_end
   447       size_t from_size = pointer_delta(from_space()->top(), from_start, sizeof(char));
   449       // Should we be in this method if from_space is empty? Why not the set_space method? FIX ME!
   450       if (from_size == 0) {
   451         from_size = alignment;
   452       } else {
   453         from_size = align_size_up(from_size, alignment);
   454       }
   456       from_end = from_start + from_size;
   457       assert(from_end > from_start, "addition overflow or from_size problem");
   459       guarantee(from_end <= (char*)from_space()->end(), "from_end moved to the right");
   461       // Now update to_start with the new from_end
   462       to_start = MAX2(from_end, to_start);
   463     }
   465     guarantee(to_start != to_end, "to space is zero sized");
   467     if (PrintAdaptiveSizePolicy && Verbose) {
   468       gclog_or_tty->print_cr("    [eden_start .. eden_end): "
   469                     "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
   470                     eden_start,
   471                     eden_end,
   472                     pointer_delta(eden_end, eden_start, sizeof(char)));
   473       gclog_or_tty->print_cr("    [from_start .. from_end): "
   474                     "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
   475                     from_start,
   476                     from_end,
   477                     pointer_delta(from_end, from_start, sizeof(char)));
   478       gclog_or_tty->print_cr("    [  to_start ..   to_end): "
   479                     "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
   480                     to_start,
   481                     to_end,
   482                     pointer_delta(  to_end,   to_start, sizeof(char)));
   483     }
   484   } else {
   485     // Eden, to, from
   486     if (PrintAdaptiveSizePolicy && Verbose) {
   487       gclog_or_tty->print_cr("  Eden, to, from:");
   488     }
   490     // To space gets priority over eden resizing. Note that we position
   491     // to space as if we were able to resize from space, even though from
   492     // space is not modified.
   493     // Giving eden priority was tried and gave poorer performance.
   494     to_end   = (char*)pointer_delta(_virtual_space->high(),
   495                                     (char*)requested_survivor_size,
   496                                     sizeof(char));
   497     to_end   = MIN2(to_end, from_start);
   498     to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size,
   499                                     sizeof(char));
   500     // if the space sizes are to be increased by several times then
   501     // 'to_start' will point beyond the young generation. In this case
   502     // 'to_start' should be adjusted.
   503     to_start = MAX2(to_start, eden_start + alignment);
   505     // Compute how big eden can be, then adjust end.
   506     // See  comments above on calculating eden_end.
   507     size_t eden_size;
   508     if (maintain_minimum) {
   509       eden_size = pointer_delta(to_start, eden_start, sizeof(char));
   510     } else {
   511       eden_size = MIN2(requested_eden_size,
   512                        pointer_delta(to_start, eden_start, sizeof(char)));
   513     }
   514     eden_end = eden_start + eden_size;
   515     assert(eden_end >= eden_start, "addition overflowed")
   517     // Could choose to not let eden shrink
   518     // to_start = MAX2(to_start, eden_end);
   520     // Don't let eden shrink down to 0 or less.
   521     eden_end = MAX2(eden_end, eden_start + alignment);
   522     to_start = MAX2(to_start, eden_end);
   524     if (PrintAdaptiveSizePolicy && Verbose) {
   525       gclog_or_tty->print_cr("    [eden_start .. eden_end): "
   526                     "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
   527                     eden_start,
   528                     eden_end,
   529                     pointer_delta(eden_end, eden_start, sizeof(char)));
   530       gclog_or_tty->print_cr("    [  to_start ..   to_end): "
   531                     "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
   532                     to_start,
   533                     to_end,
   534                     pointer_delta(  to_end,   to_start, sizeof(char)));
   535       gclog_or_tty->print_cr("    [from_start .. from_end): "
   536                     "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
   537                     from_start,
   538                     from_end,
   539                     pointer_delta(from_end, from_start, sizeof(char)));
   540     }
   541   }
   544   guarantee((HeapWord*)from_start <= from_space()->bottom(),
   545             "from start moved to the right");
   546   guarantee((HeapWord*)from_end >= from_space()->top(),
   547             "from end moved into live data");
   548   assert(is_object_aligned((intptr_t)eden_start), "checking alignment");
   549   assert(is_object_aligned((intptr_t)from_start), "checking alignment");
   550   assert(is_object_aligned((intptr_t)to_start), "checking alignment");
   552   MemRegion edenMR((HeapWord*)eden_start, (HeapWord*)eden_end);
   553   MemRegion toMR  ((HeapWord*)to_start,   (HeapWord*)to_end);
   554   MemRegion fromMR((HeapWord*)from_start, (HeapWord*)from_end);
   556   // Let's make sure the call to initialize doesn't reset "top"!
   557   HeapWord* old_from_top = from_space()->top();
   559   // For PrintAdaptiveSizePolicy block  below
   560   size_t old_from = from_space()->capacity_in_bytes();
   561   size_t old_to   = to_space()->capacity_in_bytes();
   563   eden_space()->initialize(edenMR, true);
   564     to_space()->initialize(toMR  , true);
   565   from_space()->initialize(fromMR, false);     // Note, not cleared!
   567   assert(from_space()->top() == old_from_top, "from top changed!");
   569   if (PrintAdaptiveSizePolicy) {
   570     ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
   571     assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
   573     gclog_or_tty->print("AdaptiveSizePolicy::survivor space sizes: "
   574                   "collection: %d "
   575                   "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> "
   576                   "(" SIZE_FORMAT ", " SIZE_FORMAT ") ",
   577                   heap->total_collections(),
   578                   old_from, old_to,
   579                   from_space()->capacity_in_bytes(),
   580                   to_space()->capacity_in_bytes());
   581     gclog_or_tty->cr();
   582   }
   583 }
   585 void PSYoungGen::swap_spaces() {
   586   MutableSpace* s    = from_space();
   587   _from_space        = to_space();
   588   _to_space          = s;
   590   // Now update the decorators.
   591   PSMarkSweepDecorator* md = from_mark_sweep();
   592   _from_mark_sweep           = to_mark_sweep();
   593   _to_mark_sweep             = md;
   595   assert(from_mark_sweep()->space() == from_space(), "Sanity");
   596   assert(to_mark_sweep()->space() == to_space(), "Sanity");
   597 }
   599 size_t PSYoungGen::capacity_in_bytes() const {
   600   return eden_space()->capacity_in_bytes()
   601        + from_space()->capacity_in_bytes();  // to_space() is only used during scavenge
   602 }
   605 size_t PSYoungGen::used_in_bytes() const {
   606   return eden_space()->used_in_bytes()
   607        + from_space()->used_in_bytes();      // to_space() is only used during scavenge
   608 }
   611 size_t PSYoungGen::free_in_bytes() const {
   612   return eden_space()->free_in_bytes()
   613        + from_space()->free_in_bytes();      // to_space() is only used during scavenge
   614 }
   616 size_t PSYoungGen::capacity_in_words() const {
   617   return eden_space()->capacity_in_words()
   618        + from_space()->capacity_in_words();  // to_space() is only used during scavenge
   619 }
   622 size_t PSYoungGen::used_in_words() const {
   623   return eden_space()->used_in_words()
   624        + from_space()->used_in_words();      // to_space() is only used during scavenge
   625 }
   628 size_t PSYoungGen::free_in_words() const {
   629   return eden_space()->free_in_words()
   630        + from_space()->free_in_words();      // to_space() is only used during scavenge
   631 }
   633 void PSYoungGen::object_iterate(ObjectClosure* blk) {
   634   eden_space()->object_iterate(blk);
   635   from_space()->object_iterate(blk);
   636   to_space()->object_iterate(blk);
   637 }
   639 void PSYoungGen::precompact() {
   640   eden_mark_sweep()->precompact();
   641   from_mark_sweep()->precompact();
   642   to_mark_sweep()->precompact();
   643 }
   645 void PSYoungGen::adjust_pointers() {
   646   eden_mark_sweep()->adjust_pointers();
   647   from_mark_sweep()->adjust_pointers();
   648   to_mark_sweep()->adjust_pointers();
   649 }
   651 void PSYoungGen::compact() {
   652   eden_mark_sweep()->compact(ZapUnusedHeapArea);
   653   from_mark_sweep()->compact(ZapUnusedHeapArea);
   654   // Mark sweep stores preserved markOops in to space, don't disturb!
   655   to_mark_sweep()->compact(false);
   656 }
   658 void PSYoungGen::move_and_update(ParCompactionManager* cm) {
   659   PSParallelCompact::move_and_update(cm, PSParallelCompact::eden_space_id);
   660   PSParallelCompact::move_and_update(cm, PSParallelCompact::from_space_id);
   661   PSParallelCompact::move_and_update(cm, PSParallelCompact::to_space_id);
   662 }
   664 void PSYoungGen::print() const { print_on(tty); }
   665 void PSYoungGen::print_on(outputStream* st) const {
   666   st->print(" %-15s", "PSYoungGen");
   667   if (PrintGCDetails && Verbose) {
   668     st->print(" total " SIZE_FORMAT ", used " SIZE_FORMAT,
   669                capacity_in_bytes(), used_in_bytes());
   670   } else {
   671     st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
   672                capacity_in_bytes()/K, used_in_bytes()/K);
   673   }
   674   _virtual_space->print_space_boundaries_on(st);
   675   st->print("  eden"); eden_space()->print_on(st);
   676   st->print("  from"); from_space()->print_on(st);
   677   st->print("  to  "); to_space()->print_on(st);
   678 }
   680 void PSYoungGen::print_used_change(size_t prev_used) const {
   681   gclog_or_tty->print(" [%s:", name());
   682   gclog_or_tty->print(" "  SIZE_FORMAT "K"
   683                       "->" SIZE_FORMAT "K"
   684                       "("  SIZE_FORMAT "K)",
   685                       prev_used / K, used_in_bytes() / K,
   686                       capacity_in_bytes() / K);
   687   gclog_or_tty->print("]");
   688 }
   690 size_t PSYoungGen::available_for_expansion() {
   691   ShouldNotReachHere();
   692   return 0;
   693 }
   695 size_t PSYoungGen::available_for_contraction() {
   696   ShouldNotReachHere();
   697   return 0;
   698 }
   700 size_t PSYoungGen::available_to_min_gen() {
   701   assert(virtual_space()->committed_size() >= min_gen_size(), "Invariant");
   702   return virtual_space()->committed_size() - min_gen_size();
   703 }
   705 // This method assumes that from-space has live data and that
   706 // any shrinkage of the young gen is limited by location of
   707 // from-space.
   708 size_t PSYoungGen::available_to_live() {
   709   size_t delta_in_survivor = 0;
   710   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
   711   const size_t space_alignment = heap->intra_generation_alignment();
   712   const size_t gen_alignment = heap->young_gen_alignment();
   714   MutableSpace* space_shrinking = NULL;
   715   if (from_space()->end() > to_space()->end()) {
   716     space_shrinking = from_space();
   717   } else {
   718     space_shrinking = to_space();
   719   }
   721   // Include any space that is committed but not included in
   722   // the survivor spaces.
   723   assert(((HeapWord*)virtual_space()->high()) >= space_shrinking->end(),
   724     "Survivor space beyond high end");
   725   size_t unused_committed = pointer_delta(virtual_space()->high(),
   726     space_shrinking->end(), sizeof(char));
   728   if (space_shrinking->is_empty()) {
   729     // Don't let the space shrink to 0
   730     assert(space_shrinking->capacity_in_bytes() >= space_alignment,
   731       "Space is too small");
   732     delta_in_survivor = space_shrinking->capacity_in_bytes() - space_alignment;
   733   } else {
   734     delta_in_survivor = pointer_delta(space_shrinking->end(),
   735                                       space_shrinking->top(),
   736                                       sizeof(char));
   737   }
   739   size_t delta_in_bytes = unused_committed + delta_in_survivor;
   740   delta_in_bytes = align_size_down(delta_in_bytes, gen_alignment);
   741   return delta_in_bytes;
   742 }
   744 // Return the number of bytes available for resizing down the young
   745 // generation.  This is the minimum of
   746 //      input "bytes"
   747 //      bytes to the minimum young gen size
   748 //      bytes to the size currently being used + some small extra
   749 size_t PSYoungGen::limit_gen_shrink(size_t bytes) {
   750   // Allow shrinkage into the current eden but keep eden large enough
   751   // to maintain the minimum young gen size
   752   bytes = MIN3(bytes, available_to_min_gen(), available_to_live());
   753   return align_size_down(bytes, virtual_space()->alignment());
   754 }
   756 void PSYoungGen::reset_after_change() {
   757   ShouldNotReachHere();
   758 }
   760 void PSYoungGen::reset_survivors_after_shrink() {
   761   _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(),
   762                         (HeapWord*)virtual_space()->high_boundary());
   763   PSScavenge::reference_processor()->set_span(_reserved);
   765   MutableSpace* space_shrinking = NULL;
   766   if (from_space()->end() > to_space()->end()) {
   767     space_shrinking = from_space();
   768   } else {
   769     space_shrinking = to_space();
   770   }
   772   HeapWord* new_end = (HeapWord*)virtual_space()->high();
   773   assert(new_end >= space_shrinking->bottom(), "Shrink was too large");
   774   // Was there a shrink of the survivor space?
   775   if (new_end < space_shrinking->end()) {
   776     MemRegion mr(space_shrinking->bottom(), new_end);
   777     space_shrinking->initialize(mr, false /* clear */);
   778   }
   779 }
   781 // This method currently does not expect to expand into eden (i.e.,
   782 // the virtual space boundaries is expected to be consistent
   783 // with the eden boundaries..
   784 void PSYoungGen::post_resize() {
   785   assert_locked_or_safepoint(Heap_lock);
   786   assert((eden_space()->bottom() < to_space()->bottom()) &&
   787          (eden_space()->bottom() < from_space()->bottom()),
   788          "Eden is assumed to be below the survivor spaces");
   790   MemRegion cmr((HeapWord*)virtual_space()->low(),
   791                 (HeapWord*)virtual_space()->high());
   792   Universe::heap()->barrier_set()->resize_covered_region(cmr);
   793   space_invariants();
   794 }
   798 void PSYoungGen::update_counters() {
   799   if (UsePerfData) {
   800     _eden_counters->update_all();
   801     _from_counters->update_all();
   802     _to_counters->update_all();
   803     _gen_counters->update_all();
   804   }
   805 }
   807 void PSYoungGen::verify(bool allow_dirty) {
   808   eden_space()->verify(allow_dirty);
   809   from_space()->verify(allow_dirty);
   810   to_space()->verify(allow_dirty);
   811 }

mercurial