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(),