src/share/vm/memory/defNewGeneration.cpp

changeset 704
850fdf70db2b
parent 631
d1605aabd0a1
parent 698
12eea04c8b06
child 791
1ee8caae33af
     1.1 --- a/src/share/vm/memory/defNewGeneration.cpp	Fri Jul 25 11:29:03 2008 -0700
     1.2 +++ b/src/share/vm/memory/defNewGeneration.cpp	Mon Jul 28 15:30:23 2008 -0700
     1.3 @@ -172,15 +172,25 @@
     1.4    _to_counters = new CSpaceCounters("s1", 2, _max_survivor_size, _to_space,
     1.5                                      _gen_counters);
     1.6  
     1.7 -  compute_space_boundaries(0);
     1.8 +  compute_space_boundaries(0, SpaceDecorator::Clear, SpaceDecorator::Mangle);
     1.9    update_counters();
    1.10    _next_gen = NULL;
    1.11    _tenuring_threshold = MaxTenuringThreshold;
    1.12    _pretenure_size_threshold_words = PretenureSizeThreshold >> LogHeapWordSize;
    1.13  }
    1.14  
    1.15 -void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size) {
    1.16 -  uintx alignment = GenCollectedHeap::heap()->collector_policy()->min_alignment();
    1.17 +void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size,
    1.18 +                                                bool clear_space,
    1.19 +                                                bool mangle_space) {
    1.20 +  uintx alignment =
    1.21 +    GenCollectedHeap::heap()->collector_policy()->min_alignment();
    1.22 +
    1.23 +  // If the spaces are being cleared (only done at heap initialization
    1.24 +  // currently), the survivor spaces need not be empty.
    1.25 +  // Otherwise, no care is taken for used areas in the survivor spaces
    1.26 +  // so check.
    1.27 +  assert(clear_space || (to()->is_empty() && from()->is_empty()),
    1.28 +    "Initialization of the survivor spaces assumes these are empty");
    1.29  
    1.30    // Compute sizes
    1.31    uintx size = _virtual_space.committed_size();
    1.32 @@ -214,16 +224,41 @@
    1.33    MemRegion fromMR((HeapWord*)from_start, (HeapWord*)to_start);
    1.34    MemRegion toMR  ((HeapWord*)to_start, (HeapWord*)to_end);
    1.35  
    1.36 -  eden()->initialize(edenMR, (minimum_eden_size == 0));
    1.37 -  // If minumum_eden_size != 0, we will not have cleared any
    1.38 +  // A minimum eden size implies that there is a part of eden that
    1.39 +  // is being used and that affects the initialization of any
    1.40 +  // newly formed eden.
    1.41 +  bool live_in_eden = minimum_eden_size > 0;
    1.42 +
    1.43 +  // If not clearing the spaces, do some checking to verify that
    1.44 +  // the space are already mangled.
    1.45 +  if (!clear_space) {
    1.46 +    // Must check mangling before the spaces are reshaped.  Otherwise,
    1.47 +    // the bottom or end of one space may have moved into another
    1.48 +    // a failure of the check may not correctly indicate which space
    1.49 +    // is not properly mangled.
    1.50 +    if (ZapUnusedHeapArea) {
    1.51 +      HeapWord* limit = (HeapWord*) _virtual_space.high();
    1.52 +      eden()->check_mangled_unused_area(limit);
    1.53 +      from()->check_mangled_unused_area(limit);
    1.54 +        to()->check_mangled_unused_area(limit);
    1.55 +    }
    1.56 +  }
    1.57 +
    1.58 +  // Reset the spaces for their new regions.
    1.59 +  eden()->initialize(edenMR,
    1.60 +                     clear_space && !live_in_eden,
    1.61 +                     SpaceDecorator::Mangle);
    1.62 +  // If clear_space and live_in_eden, we will not have cleared any
    1.63    // portion of eden above its top. This can cause newly
    1.64    // expanded space not to be mangled if using ZapUnusedHeapArea.
    1.65    // We explicitly do such mangling here.
    1.66 -  if (ZapUnusedHeapArea && (minimum_eden_size != 0)) {
    1.67 +  if (ZapUnusedHeapArea && clear_space && live_in_eden && mangle_space) {
    1.68      eden()->mangle_unused_area();
    1.69    }
    1.70 -  from()->initialize(fromMR, true);
    1.71 -    to()->initialize(toMR  , true);
    1.72 +  from()->initialize(fromMR, clear_space, mangle_space);
    1.73 +  to()->initialize(toMR, clear_space, mangle_space);
    1.74 +
    1.75 +  // Set next compaction spaces.
    1.76    eden()->set_next_compaction_space(from());
    1.77    // The to-space is normally empty before a compaction so need
    1.78    // not be considered.  The exception is during promotion
    1.79 @@ -250,7 +285,16 @@
    1.80  
    1.81  bool DefNewGeneration::expand(size_t bytes) {
    1.82    MutexLocker x(ExpandHeap_lock);
    1.83 +  HeapWord* prev_high = (HeapWord*) _virtual_space.high();
    1.84    bool success = _virtual_space.expand_by(bytes);
    1.85 +  if (success && ZapUnusedHeapArea) {
    1.86 +    // Mangle newly committed space immediately because it
    1.87 +    // can be done here more simply that after the new
    1.88 +    // spaces have been computed.
    1.89 +    HeapWord* new_high = (HeapWord*) _virtual_space.high();
    1.90 +    MemRegion mangle_region(prev_high, new_high);
    1.91 +    SpaceMangler::mangle_region(mangle_region);
    1.92 +  }
    1.93  
    1.94    // Do not attempt an expand-to-the reserve size.  The
    1.95    // request should properly observe the maximum size of
    1.96 @@ -262,7 +306,8 @@
    1.97    // value.
    1.98    if (GC_locker::is_active()) {
    1.99      if (PrintGC && Verbose) {
   1.100 -      gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
   1.101 +      gclog_or_tty->print_cr("Garbage collection disabled, "
   1.102 +        "expanded heap instead");
   1.103      }
   1.104    }
   1.105  
   1.106 @@ -326,16 +371,24 @@
   1.107      changed = true;
   1.108    }
   1.109    if (changed) {
   1.110 -    compute_space_boundaries(eden()->used());
   1.111 -    MemRegion cmr((HeapWord*)_virtual_space.low(), (HeapWord*)_virtual_space.high());
   1.112 +    // The spaces have already been mangled at this point but
   1.113 +    // may not have been cleared (set top = bottom) and should be.
   1.114 +    // Mangling was done when the heap was being expanded.
   1.115 +    compute_space_boundaries(eden()->used(),
   1.116 +                             SpaceDecorator::Clear,
   1.117 +                             SpaceDecorator::DontMangle);
   1.118 +    MemRegion cmr((HeapWord*)_virtual_space.low(),
   1.119 +                  (HeapWord*)_virtual_space.high());
   1.120      Universe::heap()->barrier_set()->resize_covered_region(cmr);
   1.121      if (Verbose && PrintGC) {
   1.122        size_t new_size_after  = _virtual_space.committed_size();
   1.123        size_t eden_size_after = eden()->capacity();
   1.124        size_t survivor_size_after = from()->capacity();
   1.125 -      gclog_or_tty->print("New generation size " SIZE_FORMAT "K->" SIZE_FORMAT "K [eden="
   1.126 +      gclog_or_tty->print("New generation size " SIZE_FORMAT "K->"
   1.127 +        SIZE_FORMAT "K [eden="
   1.128          SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]",
   1.129 -        new_size_before/K, new_size_after/K, eden_size_after/K, survivor_size_after/K);
   1.130 +        new_size_before/K, new_size_after/K,
   1.131 +        eden_size_after/K, survivor_size_after/K);
   1.132        if (WizardMode) {
   1.133          gclog_or_tty->print("[allowed " SIZE_FORMAT "K extra for %d threads]",
   1.134            thread_increase_size/K, threads_count);
   1.135 @@ -480,7 +533,7 @@
   1.136    ScanWeakRefClosure scan_weak_ref(this);
   1.137  
   1.138    age_table()->clear();
   1.139 -  to()->clear();
   1.140 +  to()->clear(SpaceDecorator::Mangle);
   1.141  
   1.142    gch->rem_set()->prepare_for_younger_refs_iterate(false);
   1.143  
   1.144 @@ -525,8 +578,18 @@
   1.145      soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers, NULL);
   1.146    if (!promotion_failed()) {
   1.147      // Swap the survivor spaces.
   1.148 -    eden()->clear();
   1.149 -    from()->clear();
   1.150 +    eden()->clear(SpaceDecorator::Mangle);
   1.151 +    from()->clear(SpaceDecorator::Mangle);
   1.152 +    if (ZapUnusedHeapArea) {
   1.153 +      // This is now done here because of the piece-meal mangling which
   1.154 +      // can check for valid mangling at intermediate points in the
   1.155 +      // collection(s).  When a minor collection fails to collect
   1.156 +      // sufficient space resizing of the young generation can occur
   1.157 +      // an redistribute the spaces in the young generation.  Mangle
   1.158 +      // here so that unzapped regions don't get distributed to
   1.159 +      // other spaces.
   1.160 +      to()->mangle_unused_area();
   1.161 +    }
   1.162      swap_spaces();
   1.163  
   1.164      assert(to()->is_empty(), "to space should be empty now");
   1.165 @@ -753,6 +816,15 @@
   1.166    }
   1.167  }
   1.168  
   1.169 +void DefNewGeneration::reset_scratch() {
   1.170 +  // If contributing scratch in to_space, mangle all of
   1.171 +  // to_space if ZapUnusedHeapArea.  This is needed because
   1.172 +  // top is not maintained while using to-space as scratch.
   1.173 +  if (ZapUnusedHeapArea) {
   1.174 +    to()->mangle_unused_area_complete();
   1.175 +  }
   1.176 +}
   1.177 +
   1.178  bool DefNewGeneration::collection_attempt_is_safe() {
   1.179    if (!to()->is_empty()) {
   1.180      return false;
   1.181 @@ -806,11 +878,25 @@
   1.182      }
   1.183    }
   1.184  
   1.185 +  if (ZapUnusedHeapArea) {
   1.186 +    eden()->check_mangled_unused_area_complete();
   1.187 +    from()->check_mangled_unused_area_complete();
   1.188 +    to()->check_mangled_unused_area_complete();
   1.189 +  }
   1.190 +
   1.191    // update the generation and space performance counters
   1.192    update_counters();
   1.193    gch->collector_policy()->counters()->update_counters();
   1.194  }
   1.195  
   1.196 +void DefNewGeneration::record_spaces_top() {
   1.197 +  assert(ZapUnusedHeapArea, "Not mangling unused space");
   1.198 +  eden()->set_top_for_allocations();
   1.199 +  to()->set_top_for_allocations();
   1.200 +  from()->set_top_for_allocations();
   1.201 +}
   1.202 +
   1.203 +
   1.204  void DefNewGeneration::update_counters() {
   1.205    if (UsePerfData) {
   1.206      _eden_counters->update_all();

mercurial