1.1 --- a/src/share/vm/memory/defNewGeneration.cpp Fri Jun 27 19:12:11 2008 -0700 1.2 +++ b/src/share/vm/memory/defNewGeneration.cpp Wed Jul 09 15:08:55 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();