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

changeset 698
12eea04c8b06
parent 448
183f41cf8bfe
child 704
850fdf70db2b
     1.1 --- a/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp	Fri Jun 27 19:12:11 2008 -0700
     1.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp	Wed Jul 09 15:08:55 2008 -0700
     1.3 @@ -170,9 +170,20 @@
     1.4    if (desired_size > orig_size) {
     1.5      // Grow the generation
     1.6      size_t change = desired_size - orig_size;
     1.7 +    HeapWord* prev_low = (HeapWord*) virtual_space()->low();
     1.8      if (!virtual_space()->expand_by(change)) {
     1.9        return false;
    1.10      }
    1.11 +    if (ZapUnusedHeapArea) {
    1.12 +      // Mangle newly committed space immediately because it
    1.13 +      // can be done here more simply that after the new
    1.14 +      // spaces have been computed.
    1.15 +      HeapWord* new_low = (HeapWord*) virtual_space()->low();
    1.16 +      assert(new_low < prev_low, "Did not grow");
    1.17 +
    1.18 +      MemRegion mangle_region(new_low, prev_low);
    1.19 +      SpaceMangler::mangle_region(mangle_region);
    1.20 +    }
    1.21      size_changed = true;
    1.22    } else if (desired_size < orig_size) {
    1.23      size_t desired_change = orig_size - desired_size;
    1.24 @@ -215,8 +226,10 @@
    1.25  //  current implementation does not allow holes between the spaces
    1.26  //  _young_generation_boundary has to be reset because it changes.
    1.27  //  so additional verification
    1.28 +
    1.29  void ASPSYoungGen::resize_spaces(size_t requested_eden_size,
    1.30                                   size_t requested_survivor_size) {
    1.31 +  assert(UseAdaptiveSizePolicy, "sanity check");
    1.32    assert(requested_eden_size > 0 && requested_survivor_size > 0,
    1.33           "just checking");
    1.34  
    1.35 @@ -276,22 +289,42 @@
    1.36  
    1.37    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
    1.38    const size_t alignment = heap->intra_heap_alignment();
    1.39 +  const bool maintain_minimum =
    1.40 +    (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
    1.41  
    1.42 +  bool eden_from_to_order = from_start < to_start;
    1.43    // Check whether from space is below to space
    1.44 -  if (from_start < to_start) {
    1.45 +  if (eden_from_to_order) {
    1.46      // Eden, from, to
    1.47 +
    1.48      if (PrintAdaptiveSizePolicy && Verbose) {
    1.49        gclog_or_tty->print_cr("  Eden, from, to:");
    1.50      }
    1.51  
    1.52      // Set eden
    1.53 -    // Compute how big eden can be, then adjust end.
    1.54 -    // See comment in PSYoungGen::resize_spaces() on
    1.55 -    // calculating eden_end.
    1.56 -    const size_t eden_size = MIN2(requested_eden_size,
    1.57 -                                  pointer_delta(from_start,
    1.58 -                                                eden_start,
    1.59 -                                                sizeof(char)));
    1.60 +    // "requested_eden_size" is a goal for the size of eden
    1.61 +    // and may not be attainable.  "eden_size" below is
    1.62 +    // calculated based on the location of from-space and
    1.63 +    // the goal for the size of eden.  from-space is
    1.64 +    // fixed in place because it contains live data.
    1.65 +    // The calculation is done this way to avoid 32bit
    1.66 +    // overflow (i.e., eden_start + requested_eden_size
    1.67 +    // may too large for representation in 32bits).
    1.68 +    size_t eden_size;
    1.69 +    if (maintain_minimum) {
    1.70 +      // Only make eden larger than the requested size if
    1.71 +      // the minimum size of the generation has to be maintained.
    1.72 +      // This could be done in general but policy at a higher
    1.73 +      // level is determining a requested size for eden and that
    1.74 +      // should be honored unless there is a fundamental reason.
    1.75 +      eden_size = pointer_delta(from_start,
    1.76 +                                eden_start,
    1.77 +                                sizeof(char));
    1.78 +    } else {
    1.79 +      eden_size = MIN2(requested_eden_size,
    1.80 +                       pointer_delta(from_start, eden_start, sizeof(char)));
    1.81 +    }
    1.82 +
    1.83      eden_end = eden_start + eden_size;
    1.84      assert(eden_end >= eden_start, "addition overflowed")
    1.85  
    1.86 @@ -371,12 +404,14 @@
    1.87      to_start = MAX2(to_start, eden_start + alignment);
    1.88  
    1.89      // Compute how big eden can be, then adjust end.
    1.90 -    // See comment in PSYoungGen::resize_spaces() on
    1.91 -    // calculating eden_end.
    1.92 -    const size_t eden_size = MIN2(requested_eden_size,
    1.93 -                                  pointer_delta(to_start,
    1.94 -                                                eden_start,
    1.95 -                                                sizeof(char)));
    1.96 +    // See  comments above on calculating eden_end.
    1.97 +    size_t eden_size;
    1.98 +    if (maintain_minimum) {
    1.99 +      eden_size = pointer_delta(to_start, eden_start, sizeof(char));
   1.100 +    } else {
   1.101 +      eden_size = MIN2(requested_eden_size,
   1.102 +                       pointer_delta(to_start, eden_start, sizeof(char)));
   1.103 +    }
   1.104      eden_end = eden_start + eden_size;
   1.105      assert(eden_end >= eden_start, "addition overflowed")
   1.106  
   1.107 @@ -423,9 +458,47 @@
   1.108    size_t old_from = from_space()->capacity_in_bytes();
   1.109    size_t old_to   = to_space()->capacity_in_bytes();
   1.110  
   1.111 -  eden_space()->initialize(edenMR, true);
   1.112 -    to_space()->initialize(toMR  , true);
   1.113 -  from_space()->initialize(fromMR, false);     // Note, not cleared!
   1.114 +  if (ZapUnusedHeapArea) {
   1.115 +    // NUMA is a special case because a numa space is not mangled
   1.116 +    // in order to not prematurely bind its address to memory to
   1.117 +    // the wrong memory (i.e., don't want the GC thread to first
   1.118 +    // touch the memory).  The survivor spaces are not numa
   1.119 +    // spaces and are mangled.
   1.120 +    if (UseNUMA) {
   1.121 +      if (eden_from_to_order) {
   1.122 +        mangle_survivors(from_space(), fromMR, to_space(), toMR);
   1.123 +      } else {
   1.124 +        mangle_survivors(to_space(), toMR, from_space(), fromMR);
   1.125 +      }
   1.126 +    }
   1.127 +
   1.128 +    // If not mangling the spaces, do some checking to verify that
   1.129 +    // the spaces are already mangled.
   1.130 +    // The spaces should be correctly mangled at this point so
   1.131 +    // do some checking here. Note that they are not being mangled
   1.132 +    // in the calls to initialize().
   1.133 +    // Must check mangling before the spaces are reshaped.  Otherwise,
   1.134 +    // the bottom or end of one space may have moved into an area
   1.135 +    // covered by another space and a failure of the check may
   1.136 +    // not correctly indicate which space is not properly mangled.
   1.137 +
   1.138 +    HeapWord* limit = (HeapWord*) virtual_space()->high();
   1.139 +    eden_space()->check_mangled_unused_area(limit);
   1.140 +    from_space()->check_mangled_unused_area(limit);
   1.141 +      to_space()->check_mangled_unused_area(limit);
   1.142 +  }
   1.143 +  // When an existing space is being initialized, it is not
   1.144 +  // mangled because the space has been previously mangled.
   1.145 +  eden_space()->initialize(edenMR,
   1.146 +                           SpaceDecorator::Clear,
   1.147 +                           SpaceDecorator::DontMangle);
   1.148 +    to_space()->initialize(toMR,
   1.149 +                           SpaceDecorator::Clear,
   1.150 +                           SpaceDecorator::DontMangle);
   1.151 +  from_space()->initialize(fromMR,
   1.152 +                           SpaceDecorator::DontClear,
   1.153 +                           SpaceDecorator::DontMangle);
   1.154 +
   1.155    PSScavenge::set_young_generation_boundary(eden_space()->bottom());
   1.156  
   1.157    assert(from_space()->top() == old_from_top, "from top changed!");
   1.158 @@ -446,7 +519,6 @@
   1.159    }
   1.160    space_invariants();
   1.161  }
   1.162 -
   1.163  void ASPSYoungGen::reset_after_change() {
   1.164    assert_locked_or_safepoint(Heap_lock);
   1.165  
   1.166 @@ -458,7 +530,9 @@
   1.167    HeapWord* eden_bottom = eden_space()->bottom();
   1.168    if (new_eden_bottom != eden_bottom) {
   1.169      MemRegion eden_mr(new_eden_bottom, eden_space()->end());
   1.170 -    eden_space()->initialize(eden_mr, true);
   1.171 +    eden_space()->initialize(eden_mr,
   1.172 +                             SpaceDecorator::Clear,
   1.173 +                             SpaceDecorator::Mangle);
   1.174      PSScavenge::set_young_generation_boundary(eden_space()->bottom());
   1.175    }
   1.176    MemRegion cmr((HeapWord*)virtual_space()->low(),

mercurial