1.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Fri Jul 25 11:29:03 2008 -0700 1.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Mon Jul 28 15:30:23 2008 -0700 1.3 @@ -200,8 +200,8 @@ 1.4 for (unsigned int id = 0; id < last_space_id; ++id) { 1.5 const MutableSpace* space = _space_info[id].space(); 1.6 tty->print_cr("%u %s " 1.7 - SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10") " " 1.8 - SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10") " ", 1.9 + SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " " 1.10 + SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ", 1.11 id, space_names[id], 1.12 summary_data().addr_to_chunk_idx(space->bottom()), 1.13 summary_data().addr_to_chunk_idx(space->top()), 1.14 @@ -213,8 +213,8 @@ 1.15 void 1.16 print_generic_summary_chunk(size_t i, const ParallelCompactData::ChunkData* c) 1.17 { 1.18 -#define CHUNK_IDX_FORMAT SIZE_FORMAT_W("7") 1.19 -#define CHUNK_DATA_FORMAT SIZE_FORMAT_W("5") 1.20 +#define CHUNK_IDX_FORMAT SIZE_FORMAT_W(7) 1.21 +#define CHUNK_DATA_FORMAT SIZE_FORMAT_W(5) 1.22 1.23 ParallelCompactData& sd = PSParallelCompact::summary_data(); 1.24 size_t dci = c->destination() ? sd.addr_to_chunk_idx(c->destination()) : 0; 1.25 @@ -269,9 +269,9 @@ 1.26 const ParallelCompactData::ChunkData* c, 1.27 bool newline = true) 1.28 { 1.29 - tty->print(SIZE_FORMAT_W("5") " " PTR_FORMAT " " 1.30 - SIZE_FORMAT_W("5") " " SIZE_FORMAT_W("5") " " 1.31 - SIZE_FORMAT_W("5") " " SIZE_FORMAT_W("5") " %d", 1.32 + tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " " 1.33 + SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " 1.34 + SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d", 1.35 i, c->destination(), 1.36 c->partial_obj_size(), c->live_obj_size(), 1.37 c->data_size(), c->source_chunk(), c->destination_count()); 1.38 @@ -326,7 +326,7 @@ 1.39 } 1.40 1.41 print_initial_summary_chunk(i, c, false); 1.42 - tty->print_cr(" %12.10f " SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10"), 1.43 + tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10), 1.44 reclaimed_ratio, dead_to_right, live_to_right); 1.45 1.46 live_to_right -= c->data_size(); 1.47 @@ -338,8 +338,8 @@ 1.48 print_initial_summary_chunk(i, summary_data.chunk(i)); 1.49 } 1.50 1.51 - tty->print_cr("max: " SIZE_FORMAT_W("4") " d2r=" SIZE_FORMAT_W("10") " " 1.52 - "l2r=" SIZE_FORMAT_W("10") " max_ratio=%14.12f", 1.53 + tty->print_cr("max: " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " " 1.54 + "l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f", 1.55 max_reclaimed_ratio_chunk, max_dead_to_right, 1.56 max_live_to_right, max_reclaimed_ratio); 1.57 } 1.58 @@ -1060,6 +1060,10 @@ 1.59 1.60 ref_processor()->enqueue_discovered_references(NULL); 1.61 1.62 + if (ZapUnusedHeapArea) { 1.63 + heap->gen_mangle_unused_area(); 1.64 + } 1.65 + 1.66 // Update time of last GC 1.67 reset_millis_since_last_gc(); 1.68 } 1.69 @@ -1119,8 +1123,8 @@ 1.70 HeapWord* chunk_destination = cp->destination(); 1.71 const size_t cur_deadwood = pointer_delta(dense_prefix, chunk_destination); 1.72 if (TraceParallelOldGCDensePrefix && Verbose) { 1.73 - tty->print_cr("c#=" SIZE_FORMAT_W("04") " dst=" PTR_FORMAT " " 1.74 - "dp=" SIZE_FORMAT_W("08") " " "cdw=" SIZE_FORMAT_W("08"), 1.75 + tty->print_cr("c#=" SIZE_FORMAT_W(4) " dst=" PTR_FORMAT " " 1.76 + "dp=" SIZE_FORMAT_W(8) " " "cdw=" SIZE_FORMAT_W(8), 1.77 sd.chunk(cp), chunk_destination, 1.78 dense_prefix, cur_deadwood); 1.79 } 1.80 @@ -1145,7 +1149,7 @@ 1.81 return dense_prefix; 1.82 } 1.83 if (TraceParallelOldGCDensePrefix && Verbose) { 1.84 - tty->print_cr("backing up from c=" SIZE_FORMAT_W("4") " d2r=%10.8f " 1.85 + tty->print_cr("backing up from c=" SIZE_FORMAT_W(4) " d2r=%10.8f " 1.86 "pc_d2r=%10.8f", sd.chunk(cp), density_to_right, 1.87 prev_chunk_density_to_right); 1.88 } 1.89 @@ -1182,7 +1186,7 @@ 1.90 const size_t live_to_right = new_top - cp->destination(); 1.91 const size_t dead_to_right = space->top() - addr - live_to_right; 1.92 1.93 - tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W("05") " " 1.94 + tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W(5) " " 1.95 "spl=" SIZE_FORMAT " " 1.96 "d2l=" SIZE_FORMAT " d2l%%=%6.4f " 1.97 "d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT 1.98 @@ -1522,48 +1526,53 @@ 1.99 PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction) 1.100 { 1.101 assert(id < last_space_id, "id out of range"); 1.102 + assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom(), 1.103 + "should have been set in summarize_spaces_quick()"); 1.104 1.105 const MutableSpace* space = _space_info[id].space(); 1.106 - HeapWord** new_top_addr = _space_info[id].new_top_addr(); 1.107 - 1.108 - HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction); 1.109 - _space_info[id].set_dense_prefix(dense_prefix_end); 1.110 + if (_space_info[id].new_top() != space->bottom()) { 1.111 + HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction); 1.112 + _space_info[id].set_dense_prefix(dense_prefix_end); 1.113 1.114 #ifndef PRODUCT 1.115 - if (TraceParallelOldGCDensePrefix) { 1.116 - print_dense_prefix_stats("ratio", id, maximum_compaction, dense_prefix_end); 1.117 - HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction); 1.118 - print_dense_prefix_stats("density", id, maximum_compaction, addr); 1.119 + if (TraceParallelOldGCDensePrefix) { 1.120 + print_dense_prefix_stats("ratio", id, maximum_compaction, 1.121 + dense_prefix_end); 1.122 + HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction); 1.123 + print_dense_prefix_stats("density", id, maximum_compaction, addr); 1.124 + } 1.125 +#endif // #ifndef PRODUCT 1.126 + 1.127 + // If dead space crosses the dense prefix boundary, it is (at least 1.128 + // partially) filled with a dummy object, marked live and added to the 1.129 + // summary data. This simplifies the copy/update phase and must be done 1.130 + // before the final locations of objects are determined, to prevent leaving 1.131 + // a fragment of dead space that is too small to fill with an object. 1.132 + if (!maximum_compaction && dense_prefix_end != space->bottom()) { 1.133 + fill_dense_prefix_end(id); 1.134 + } 1.135 + 1.136 + // Compute the destination of each Chunk, and thus each object. 1.137 + _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end); 1.138 + _summary_data.summarize(dense_prefix_end, space->end(), 1.139 + dense_prefix_end, space->top(), 1.140 + _space_info[id].new_top_addr()); 1.141 } 1.142 -#endif // #ifndef PRODUCT 1.143 - 1.144 - // If dead space crosses the dense prefix boundary, it is (at least partially) 1.145 - // filled with a dummy object, marked live and added to the summary data. 1.146 - // This simplifies the copy/update phase and must be done before the final 1.147 - // locations of objects are determined, to prevent leaving a fragment of dead 1.148 - // space that is too small to fill with an object. 1.149 - if (!maximum_compaction && dense_prefix_end != space->bottom()) { 1.150 - fill_dense_prefix_end(id); 1.151 - } 1.152 - 1.153 - // Compute the destination of each Chunk, and thus each object. 1.154 - _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end); 1.155 - _summary_data.summarize(dense_prefix_end, space->end(), 1.156 - dense_prefix_end, space->top(), 1.157 - new_top_addr); 1.158 1.159 if (TraceParallelOldGCSummaryPhase) { 1.160 const size_t chunk_size = ParallelCompactData::ChunkSize; 1.161 + HeapWord* const dense_prefix_end = _space_info[id].dense_prefix(); 1.162 const size_t dp_chunk = _summary_data.addr_to_chunk_idx(dense_prefix_end); 1.163 const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom()); 1.164 - const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(*new_top_addr); 1.165 + HeapWord* const new_top = _space_info[id].new_top(); 1.166 + const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(new_top); 1.167 const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end); 1.168 tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " " 1.169 "dp_chunk=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " " 1.170 "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT, 1.171 id, space->capacity_in_words(), dense_prefix_end, 1.172 dp_chunk, dp_words / chunk_size, 1.173 - cr_words / chunk_size, *new_top_addr); 1.174 + cr_words / chunk_size, new_top); 1.175 } 1.176 } 1.177 1.178 @@ -1632,7 +1641,7 @@ 1.179 const size_t live = pointer_delta(_space_info[id].new_top(), 1.180 space->bottom()); 1.181 const size_t available = pointer_delta(target_space_end, *new_top_addr); 1.182 - if (live <= available) { 1.183 + if (live > 0 && live <= available) { 1.184 // All the live data will fit. 1.185 if (TraceParallelOldGCSummaryPhase) { 1.186 tty->print_cr("summarizing %d into old_space @ " PTR_FORMAT, 1.187 @@ -1642,16 +1651,18 @@ 1.188 space->bottom(), space->top(), 1.189 new_top_addr); 1.190 1.191 - // Reset the new_top value for the space. 1.192 - _space_info[id].set_new_top(space->bottom()); 1.193 - 1.194 // Clear the source_chunk field for each chunk in the space. 1.195 + HeapWord* const new_top = _space_info[id].new_top(); 1.196 + HeapWord* const clear_end = _summary_data.chunk_align_up(new_top); 1.197 ChunkData* beg_chunk = _summary_data.addr_to_chunk_ptr(space->bottom()); 1.198 - ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(space->top() - 1); 1.199 - while (beg_chunk <= end_chunk) { 1.200 + ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(clear_end); 1.201 + while (beg_chunk < end_chunk) { 1.202 beg_chunk->set_source_chunk(0); 1.203 ++beg_chunk; 1.204 } 1.205 + 1.206 + // Reset the new_top value for the space. 1.207 + _space_info[id].set_new_top(space->bottom()); 1.208 } 1.209 } 1.210 1.211 @@ -1961,6 +1972,11 @@ 1.212 PSPermGen* perm_gen = heap->perm_gen(); 1.213 PSAdaptiveSizePolicy* size_policy = heap->size_policy(); 1.214 1.215 + if (ZapUnusedHeapArea) { 1.216 + // Save information needed to minimize mangling 1.217 + heap->record_gen_tops_before_GC(); 1.218 + } 1.219 + 1.220 _print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes; 1.221 1.222 // Make sure data structures are sane, make the heap parsable, and do other 1.223 @@ -2129,17 +2145,19 @@ 1.224 size_t max_eden_size = young_gen->max_size() - 1.225 young_gen->from_space()->capacity_in_bytes() - 1.226 young_gen->to_space()->capacity_in_bytes(); 1.227 - size_policy->compute_generation_free_space(young_gen->used_in_bytes(), 1.228 - young_gen->eden_space()->used_in_bytes(), 1.229 - old_gen->used_in_bytes(), 1.230 - perm_gen->used_in_bytes(), 1.231 - young_gen->eden_space()->capacity_in_bytes(), 1.232 - old_gen->max_gen_size(), 1.233 - max_eden_size, 1.234 - true /* full gc*/, 1.235 - gc_cause); 1.236 - 1.237 - heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes()); 1.238 + size_policy->compute_generation_free_space( 1.239 + young_gen->used_in_bytes(), 1.240 + young_gen->eden_space()->used_in_bytes(), 1.241 + old_gen->used_in_bytes(), 1.242 + perm_gen->used_in_bytes(), 1.243 + young_gen->eden_space()->capacity_in_bytes(), 1.244 + old_gen->max_gen_size(), 1.245 + max_eden_size, 1.246 + true /* full gc*/, 1.247 + gc_cause); 1.248 + 1.249 + heap->resize_old_gen( 1.250 + size_policy->calculated_old_free_size_in_bytes()); 1.251 1.252 // Don't resize the young generation at an major collection. A 1.253 // desired young generation size may have been calculated but 1.254 @@ -2212,6 +2230,11 @@ 1.255 perm_gen->verify_object_start_array(); 1.256 } 1.257 1.258 + if (ZapUnusedHeapArea) { 1.259 + old_gen->object_space()->check_mangled_unused_area_complete(); 1.260 + perm_gen->object_space()->check_mangled_unused_area_complete(); 1.261 + } 1.262 + 1.263 NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); 1.264 1.265 collection_exit.update(); 1.266 @@ -2499,7 +2522,7 @@ 1.267 if (TraceParallelOldGCCompactionPhase && Verbose) { 1.268 const size_t count_mod_8 = fillable_chunks & 7; 1.269 if (count_mod_8 == 0) gclog_or_tty->print("fillable: "); 1.270 - gclog_or_tty->print(" " SIZE_FORMAT_W("7"), cur); 1.271 + gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur); 1.272 if (count_mod_8 == 7) gclog_or_tty->cr(); 1.273 } 1.274