1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/memory/genMarkSweep.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,392 @@ 1.4 +/* 1.5 + * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "incls/_precompiled.incl" 1.29 +#include "incls/_genMarkSweep.cpp.incl" 1.30 + 1.31 +void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, 1.32 + bool clear_all_softrefs) { 1.33 + assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); 1.34 + 1.35 + // hook up weak ref data so it can be used during Mark-Sweep 1.36 + assert(ref_processor() == NULL, "no stomping"); 1.37 + _ref_processor = rp; 1.38 + assert(rp != NULL, "should be non-NULL"); 1.39 + 1.40 + TraceTime t1("Full GC", PrintGC && !PrintGCDetails, true, gclog_or_tty); 1.41 + 1.42 + // When collecting the permanent generation methodOops may be moving, 1.43 + // so we either have to flush all bcp data or convert it into bci. 1.44 + CodeCache::gc_prologue(); 1.45 + Threads::gc_prologue(); 1.46 + 1.47 + // Increment the invocation count for the permanent generation, since it is 1.48 + // implicitly collected whenever we do a full mark sweep collection. 1.49 + GenCollectedHeap* gch = GenCollectedHeap::heap(); 1.50 + gch->perm_gen()->stat_record()->invocations++; 1.51 + 1.52 + // Capture heap size before collection for printing. 1.53 + size_t gch_prev_used = gch->used(); 1.54 + 1.55 + // Some of the card table updates below assume that the perm gen is 1.56 + // also being collected. 1.57 + assert(level == gch->n_gens() - 1, 1.58 + "All generations are being collected, ergo perm gen too."); 1.59 + 1.60 + // Capture used regions for each generation that will be 1.61 + // subject to collection, so that card table adjustments can 1.62 + // be made intelligently (see clear / invalidate further below). 1.63 + gch->save_used_regions(level, true /* perm */); 1.64 + 1.65 + allocate_stacks(); 1.66 + 1.67 + mark_sweep_phase1(level, clear_all_softrefs); 1.68 + 1.69 + mark_sweep_phase2(); 1.70 + 1.71 + // Don't add any more derived pointers during phase3 1.72 + COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); 1.73 + COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); 1.74 + 1.75 + mark_sweep_phase3(level); 1.76 + 1.77 + VALIDATE_MARK_SWEEP_ONLY( 1.78 + if (ValidateMarkSweep) { 1.79 + guarantee(_root_refs_stack->length() == 0, 1.80 + "should be empty by now"); 1.81 + } 1.82 + ) 1.83 + 1.84 + mark_sweep_phase4(); 1.85 + 1.86 + VALIDATE_MARK_SWEEP_ONLY( 1.87 + if (ValidateMarkSweep) { 1.88 + guarantee(_live_oops->length() == _live_oops_moved_to->length(), 1.89 + "should be the same size"); 1.90 + } 1.91 + ) 1.92 + 1.93 + restore_marks(); 1.94 + 1.95 + // Set saved marks for allocation profiler (and other things? -- dld) 1.96 + // (Should this be in general part?) 1.97 + gch->save_marks(); 1.98 + 1.99 + deallocate_stacks(); 1.100 + 1.101 + // If compaction completely evacuated all generations younger than this 1.102 + // one, then we can clear the card table. Otherwise, we must invalidate 1.103 + // it (consider all cards dirty). In the future, we might consider doing 1.104 + // compaction within generations only, and doing card-table sliding. 1.105 + bool all_empty = true; 1.106 + for (int i = 0; all_empty && i < level; i++) { 1.107 + Generation* g = gch->get_gen(i); 1.108 + all_empty = all_empty && gch->get_gen(i)->used() == 0; 1.109 + } 1.110 + GenRemSet* rs = gch->rem_set(); 1.111 + // Clear/invalidate below make use of the "prev_used_regions" saved earlier. 1.112 + if (all_empty) { 1.113 + // We've evacuated all generations below us. 1.114 + Generation* g = gch->get_gen(level); 1.115 + rs->clear_into_younger(g, true /* perm */); 1.116 + } else { 1.117 + // Invalidate the cards corresponding to the currently used 1.118 + // region and clear those corresponding to the evacuated region 1.119 + // of all generations just collected (i.e. level and younger). 1.120 + rs->invalidate_or_clear(gch->get_gen(level), 1.121 + true /* younger */, 1.122 + true /* perm */); 1.123 + } 1.124 + 1.125 + Threads::gc_epilogue(); 1.126 + CodeCache::gc_epilogue(); 1.127 + 1.128 + if (PrintGC && !PrintGCDetails) { 1.129 + gch->print_heap_change(gch_prev_used); 1.130 + } 1.131 + 1.132 + // refs processing: clean slate 1.133 + _ref_processor = NULL; 1.134 + 1.135 + // Update heap occupancy information which is used as 1.136 + // input to soft ref clearing policy at the next gc. 1.137 + Universe::update_heap_info_at_gc(); 1.138 + 1.139 + // Update time of last gc for all generations we collected 1.140 + // (which curently is all the generations in the heap). 1.141 + gch->update_time_of_last_gc(os::javaTimeMillis()); 1.142 +} 1.143 + 1.144 +void GenMarkSweep::allocate_stacks() { 1.145 + GenCollectedHeap* gch = GenCollectedHeap::heap(); 1.146 + // Scratch request on behalf of oldest generation; will do no 1.147 + // allocation. 1.148 + ScratchBlock* scratch = gch->gather_scratch(gch->_gens[gch->_n_gens-1], 0); 1.149 + 1.150 + // $$$ To cut a corner, we'll only use the first scratch block, and then 1.151 + // revert to malloc. 1.152 + if (scratch != NULL) { 1.153 + _preserved_count_max = 1.154 + scratch->num_words * HeapWordSize / sizeof(PreservedMark); 1.155 + } else { 1.156 + _preserved_count_max = 0; 1.157 + } 1.158 + 1.159 + _preserved_marks = (PreservedMark*)scratch; 1.160 + _preserved_count = 0; 1.161 + _preserved_mark_stack = NULL; 1.162 + _preserved_oop_stack = NULL; 1.163 + 1.164 + _marking_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true); 1.165 + 1.166 + int size = SystemDictionary::number_of_classes() * 2; 1.167 + _revisit_klass_stack = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(size, true); 1.168 + 1.169 +#ifdef VALIDATE_MARK_SWEEP 1.170 + if (ValidateMarkSweep) { 1.171 + _root_refs_stack = new (ResourceObj::C_HEAP) GrowableArray<oop*>(100, true); 1.172 + _other_refs_stack = new (ResourceObj::C_HEAP) GrowableArray<oop*>(100, true); 1.173 + _adjusted_pointers = new (ResourceObj::C_HEAP) GrowableArray<oop*>(100, true); 1.174 + _live_oops = new (ResourceObj::C_HEAP) GrowableArray<oop>(100, true); 1.175 + _live_oops_moved_to = new (ResourceObj::C_HEAP) GrowableArray<oop>(100, true); 1.176 + _live_oops_size = new (ResourceObj::C_HEAP) GrowableArray<size_t>(100, true); 1.177 + } 1.178 + if (RecordMarkSweepCompaction) { 1.179 + if (_cur_gc_live_oops == NULL) { 1.180 + _cur_gc_live_oops = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true); 1.181 + _cur_gc_live_oops_moved_to = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true); 1.182 + _cur_gc_live_oops_size = new(ResourceObj::C_HEAP) GrowableArray<size_t>(100, true); 1.183 + _last_gc_live_oops = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true); 1.184 + _last_gc_live_oops_moved_to = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true); 1.185 + _last_gc_live_oops_size = new(ResourceObj::C_HEAP) GrowableArray<size_t>(100, true); 1.186 + } else { 1.187 + _cur_gc_live_oops->clear(); 1.188 + _cur_gc_live_oops_moved_to->clear(); 1.189 + _cur_gc_live_oops_size->clear(); 1.190 + } 1.191 + } 1.192 +#endif 1.193 +} 1.194 + 1.195 + 1.196 +void GenMarkSweep::deallocate_stacks() { 1.197 + if (_preserved_oop_stack) { 1.198 + delete _preserved_mark_stack; 1.199 + _preserved_mark_stack = NULL; 1.200 + delete _preserved_oop_stack; 1.201 + _preserved_oop_stack = NULL; 1.202 + } 1.203 + 1.204 + delete _marking_stack; 1.205 + delete _revisit_klass_stack; 1.206 + 1.207 +#ifdef VALIDATE_MARK_SWEEP 1.208 + if (ValidateMarkSweep) { 1.209 + delete _root_refs_stack; 1.210 + delete _other_refs_stack; 1.211 + delete _adjusted_pointers; 1.212 + delete _live_oops; 1.213 + delete _live_oops_size; 1.214 + delete _live_oops_moved_to; 1.215 + _live_oops_index = 0; 1.216 + _live_oops_index_at_perm = 0; 1.217 + } 1.218 +#endif 1.219 +} 1.220 + 1.221 +void GenMarkSweep::mark_sweep_phase1(int level, 1.222 + bool clear_all_softrefs) { 1.223 + // Recursively traverse all live objects and mark them 1.224 + EventMark m("1 mark object"); 1.225 + TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty); 1.226 + trace(" 1"); 1.227 + 1.228 + VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false)); 1.229 + 1.230 + GenCollectedHeap* gch = GenCollectedHeap::heap(); 1.231 + 1.232 + // Because follow_root_closure is created statically, cannot 1.233 + // use OopsInGenClosure constructor which takes a generation, 1.234 + // as the Universe has not been created when the static constructors 1.235 + // are run. 1.236 + follow_root_closure.set_orig_generation(gch->get_gen(level)); 1.237 + 1.238 + gch->gen_process_strong_roots(level, 1.239 + false, // Younger gens are not roots. 1.240 + true, // Collecting permanent generation. 1.241 + SharedHeap::SO_SystemClasses, 1.242 + &follow_root_closure, &follow_root_closure); 1.243 + 1.244 + // Process reference objects found during marking 1.245 + { 1.246 + ReferencePolicy *soft_ref_policy; 1.247 + if (clear_all_softrefs) { 1.248 + soft_ref_policy = new AlwaysClearPolicy(); 1.249 + } else { 1.250 +#ifdef COMPILER2 1.251 + soft_ref_policy = new LRUMaxHeapPolicy(); 1.252 +#else 1.253 + soft_ref_policy = new LRUCurrentHeapPolicy(); 1.254 +#endif // COMPILER2 1.255 + } 1.256 + assert(soft_ref_policy != NULL,"No soft reference policy"); 1.257 + ref_processor()->process_discovered_references( 1.258 + soft_ref_policy, &is_alive, &keep_alive, 1.259 + &follow_stack_closure, NULL); 1.260 + } 1.261 + 1.262 + // Follow system dictionary roots and unload classes 1.263 + bool purged_class = SystemDictionary::do_unloading(&is_alive); 1.264 + 1.265 + // Follow code cache roots 1.266 + CodeCache::do_unloading(&is_alive, &keep_alive, purged_class); 1.267 + follow_stack(); // Flush marking stack 1.268 + 1.269 + // Update subklass/sibling/implementor links of live klasses 1.270 + follow_weak_klass_links(); 1.271 + assert(_marking_stack->is_empty(), "just drained"); 1.272 + 1.273 + // Visit symbol and interned string tables and delete unmarked oops 1.274 + SymbolTable::unlink(&is_alive); 1.275 + StringTable::unlink(&is_alive); 1.276 + 1.277 + assert(_marking_stack->is_empty(), "stack should be empty by now"); 1.278 +} 1.279 + 1.280 + 1.281 +void GenMarkSweep::mark_sweep_phase2() { 1.282 + // Now all live objects are marked, compute the new object addresses. 1.283 + 1.284 + // It is imperative that we traverse perm_gen LAST. If dead space is 1.285 + // allowed a range of dead object may get overwritten by a dead int 1.286 + // array. If perm_gen is not traversed last a klassOop may get 1.287 + // overwritten. This is fine since it is dead, but if the class has dead 1.288 + // instances we have to skip them, and in order to find their size we 1.289 + // need the klassOop! 1.290 + // 1.291 + // It is not required that we traverse spaces in the same order in 1.292 + // phase2, phase3 and phase4, but the ValidateMarkSweep live oops 1.293 + // tracking expects us to do so. See comment under phase4. 1.294 + 1.295 + GenCollectedHeap* gch = GenCollectedHeap::heap(); 1.296 + Generation* pg = gch->perm_gen(); 1.297 + 1.298 + EventMark m("2 compute new addresses"); 1.299 + TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty); 1.300 + trace("2"); 1.301 + 1.302 + VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false)); 1.303 + 1.304 + gch->prepare_for_compaction(); 1.305 + 1.306 + VALIDATE_MARK_SWEEP_ONLY(_live_oops_index_at_perm = _live_oops_index); 1.307 + CompactPoint perm_cp(pg, NULL, NULL); 1.308 + pg->prepare_for_compaction(&perm_cp); 1.309 +} 1.310 + 1.311 +class GenAdjustPointersClosure: public GenCollectedHeap::GenClosure { 1.312 +public: 1.313 + void do_generation(Generation* gen) { 1.314 + gen->adjust_pointers(); 1.315 + } 1.316 +}; 1.317 + 1.318 +void GenMarkSweep::mark_sweep_phase3(int level) { 1.319 + GenCollectedHeap* gch = GenCollectedHeap::heap(); 1.320 + Generation* pg = gch->perm_gen(); 1.321 + 1.322 + // Adjust the pointers to reflect the new locations 1.323 + EventMark m("3 adjust pointers"); 1.324 + TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty); 1.325 + trace("3"); 1.326 + 1.327 + VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false)); 1.328 + 1.329 + // Needs to be done before the system dictionary is adjusted. 1.330 + pg->pre_adjust_pointers(); 1.331 + 1.332 + // Because the two closures below are created statically, cannot 1.333 + // use OopsInGenClosure constructor which takes a generation, 1.334 + // as the Universe has not been created when the static constructors 1.335 + // are run. 1.336 + adjust_root_pointer_closure.set_orig_generation(gch->get_gen(level)); 1.337 + adjust_pointer_closure.set_orig_generation(gch->get_gen(level)); 1.338 + 1.339 + gch->gen_process_strong_roots(level, 1.340 + false, // Younger gens are not roots. 1.341 + true, // Collecting permanent generation. 1.342 + SharedHeap::SO_AllClasses, 1.343 + &adjust_root_pointer_closure, 1.344 + &adjust_root_pointer_closure); 1.345 + 1.346 + // Now adjust pointers in remaining weak roots. (All of which should 1.347 + // have been cleared if they pointed to non-surviving objects.) 1.348 + gch->gen_process_weak_roots(&adjust_root_pointer_closure, 1.349 + &adjust_pointer_closure); 1.350 + 1.351 + adjust_marks(); 1.352 + GenAdjustPointersClosure blk; 1.353 + gch->generation_iterate(&blk, true); 1.354 + pg->adjust_pointers(); 1.355 +} 1.356 + 1.357 +class GenCompactClosure: public GenCollectedHeap::GenClosure { 1.358 +public: 1.359 + void do_generation(Generation* gen) { 1.360 + gen->compact(); 1.361 + } 1.362 +}; 1.363 + 1.364 +void GenMarkSweep::mark_sweep_phase4() { 1.365 + // All pointers are now adjusted, move objects accordingly 1.366 + 1.367 + // It is imperative that we traverse perm_gen first in phase4. All 1.368 + // classes must be allocated earlier than their instances, and traversing 1.369 + // perm_gen first makes sure that all klassOops have moved to their new 1.370 + // location before any instance does a dispatch through it's klass! 1.371 + 1.372 + // The ValidateMarkSweep live oops tracking expects us to traverse spaces 1.373 + // in the same order in phase2, phase3 and phase4. We don't quite do that 1.374 + // here (perm_gen first rather than last), so we tell the validate code 1.375 + // to use a higher index (saved from phase2) when verifying perm_gen. 1.376 + GenCollectedHeap* gch = GenCollectedHeap::heap(); 1.377 + Generation* pg = gch->perm_gen(); 1.378 + 1.379 + EventMark m("4 compact heap"); 1.380 + TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty); 1.381 + trace("4"); 1.382 + 1.383 + VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(true)); 1.384 + 1.385 + pg->compact(); 1.386 + 1.387 + VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false)); 1.388 + 1.389 + GenCompactClosure blk; 1.390 + gch->generation_iterate(&blk, true); 1.391 + 1.392 + VALIDATE_MARK_SWEEP_ONLY(compaction_complete()); 1.393 + 1.394 + pg->post_compact(); // Shared spaces verification. 1.395 +}