1.1 --- a/src/share/vm/runtime/sweeper.cpp Fri Jan 29 08:33:24 2010 -0800 1.2 +++ b/src/share/vm/runtime/sweeper.cpp Fri Jan 29 09:27:22 2010 -0800 1.3 @@ -33,6 +33,11 @@ 1.4 jint NMethodSweeper::_locked_seen = 0; 1.5 jint NMethodSweeper::_not_entrant_seen_on_stack = 0; 1.6 bool NMethodSweeper::_rescan = false; 1.7 +bool NMethodSweeper::_was_full = false; 1.8 +jint NMethodSweeper::_advise_to_sweep = 0; 1.9 +jlong NMethodSweeper::_last_was_full = 0; 1.10 +uint NMethodSweeper::_highest_marked = 0; 1.11 +long NMethodSweeper::_was_full_traversal = 0; 1.12 1.13 class MarkActivationClosure: public CodeBlobClosure { 1.14 public: 1.15 @@ -114,6 +119,40 @@ 1.16 tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep"); 1.17 } 1.18 } 1.19 + 1.20 + if (UseCodeCacheFlushing) { 1.21 + if (!CodeCache::needs_flushing()) { 1.22 + // In a safepoint, no race with setters 1.23 + _advise_to_sweep = 0; 1.24 + } 1.25 + 1.26 + if (was_full()) { 1.27 + // There was some progress so attempt to restart the compiler 1.28 + jlong now = os::javaTimeMillis(); 1.29 + jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; 1.30 + jlong curr_interval = now - _last_was_full; 1.31 + if ((!CodeCache::needs_flushing()) && (curr_interval > max_interval)) { 1.32 + CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); 1.33 + set_was_full(false); 1.34 + 1.35 + // Update the _last_was_full time so we can tell how fast the 1.36 + // code cache is filling up 1.37 + _last_was_full = os::javaTimeMillis(); 1.38 + 1.39 + if (PrintMethodFlushing) { 1.40 + tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler", 1.41 + CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 1.42 + } 1.43 + if (LogCompilation && (xtty != NULL)) { 1.44 + ttyLocker ttyl; 1.45 + xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 1.46 + CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 1.47 + xtty->stamp(); 1.48 + xtty->end_elem(); 1.49 + } 1.50 + } 1.51 + } 1.52 + } 1.53 } 1.54 1.55 1.56 @@ -137,12 +176,12 @@ 1.57 if (nm->is_marked_for_reclamation()) { 1.58 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); 1.59 if (PrintMethodFlushing && Verbose) { 1.60 - tty->print_cr("### Nmethod 0x%x (marked for reclamation) being flushed", nm); 1.61 + tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); 1.62 } 1.63 nm->flush(); 1.64 } else { 1.65 if (PrintMethodFlushing && Verbose) { 1.66 - tty->print_cr("### Nmethod 0x%x (zombie) being marked for reclamation", nm); 1.67 + tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm); 1.68 } 1.69 nm->mark_for_reclamation(); 1.70 _rescan = true; 1.71 @@ -152,7 +191,7 @@ 1.72 // stack we can safely convert it to a zombie method 1.73 if (nm->can_not_entrant_be_converted()) { 1.74 if (PrintMethodFlushing && Verbose) { 1.75 - tty->print_cr("### Nmethod 0x%x (not entrant) being made zombie", nm); 1.76 + tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm); 1.77 } 1.78 nm->make_zombie(); 1.79 _rescan = true; 1.80 @@ -167,7 +206,7 @@ 1.81 } else if (nm->is_unloaded()) { 1.82 // Unloaded code, just make it a zombie 1.83 if (PrintMethodFlushing && Verbose) 1.84 - tty->print_cr("### Nmethod 0x%x (unloaded) being made zombie", nm); 1.85 + tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); 1.86 if (nm->is_osr_method()) { 1.87 // No inline caches will ever point to osr methods, so we can just remove it 1.88 nm->flush(); 1.89 @@ -177,7 +216,167 @@ 1.90 } 1.91 } else { 1.92 assert(nm->is_alive(), "should be alive"); 1.93 + 1.94 + if (UseCodeCacheFlushing) { 1.95 + if ((nm->method()->code() != nm) && !(nm->is_locked_by_vm()) && !(nm->is_osr_method()) && 1.96 + (_traversals > _was_full_traversal+2) && (((uint)nm->compile_id()) < _highest_marked) && 1.97 + CodeCache::needs_flushing()) { 1.98 + // This method has not been called since the forced cleanup happened 1.99 + nm->make_not_entrant(); 1.100 + } 1.101 + } 1.102 + 1.103 // Clean-up all inline caches that points to zombie/non-reentrant methods 1.104 nm->cleanup_inline_caches(); 1.105 } 1.106 } 1.107 + 1.108 +// Code cache unloading: when compilers notice the code cache is getting full, 1.109 +// they will call a vm op that comes here. This code attempts to speculatively 1.110 +// unload the oldest half of the nmethods (based on the compile job id) by 1.111 +// saving the old code in a list in the CodeCache. Then 1.112 +// execution resumes. If a method so marked is not called by the second 1.113 +// safepoint from the current one, the nmethod will be marked non-entrant and 1.114 +// got rid of by normal sweeping. If the method is called, the methodOop's 1.115 +// _code field is restored and the methodOop/nmethod 1.116 +// go back to their normal state. 1.117 +void NMethodSweeper::handle_full_code_cache(bool is_full) { 1.118 + // Only the first one to notice can advise us to start early cleaning 1.119 + if (!is_full){ 1.120 + jint old = Atomic::cmpxchg( 1, &_advise_to_sweep, 0 ); 1.121 + if (old != 0) { 1.122 + return; 1.123 + } 1.124 + } 1.125 + 1.126 + if (is_full) { 1.127 + // Since code cache is full, immediately stop new compiles 1.128 + bool did_set = CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation); 1.129 + if (!did_set) { 1.130 + // only the first to notice can start the cleaning, 1.131 + // others will go back and block 1.132 + return; 1.133 + } 1.134 + set_was_full(true); 1.135 + 1.136 + // If we run out within MinCodeCacheFlushingInterval of the last unload time, give up 1.137 + jlong now = os::javaTimeMillis(); 1.138 + jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; 1.139 + jlong curr_interval = now - _last_was_full; 1.140 + if (curr_interval < max_interval) { 1.141 + _rescan = true; 1.142 + if (PrintMethodFlushing) { 1.143 + tty->print_cr("### handle full too often, turning off compiler"); 1.144 + } 1.145 + if (LogCompilation && (xtty != NULL)) { 1.146 + ttyLocker ttyl; 1.147 + xtty->begin_elem("disable_compiler flushing_interval='" UINT64_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 1.148 + curr_interval/1000, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 1.149 + xtty->stamp(); 1.150 + xtty->end_elem(); 1.151 + } 1.152 + return; 1.153 + } 1.154 + } 1.155 + 1.156 + VM_HandleFullCodeCache op(is_full); 1.157 + VMThread::execute(&op); 1.158 + 1.159 + // rescan again as soon as possible 1.160 + _rescan = true; 1.161 +} 1.162 + 1.163 +void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) { 1.164 + // If there was a race in detecting full code cache, only run 1.165 + // one vm op for it or keep the compiler shut off 1.166 + 1.167 + debug_only(jlong start = os::javaTimeMillis();) 1.168 + 1.169 + if ((!was_full()) && (is_full)) { 1.170 + if (!CodeCache::needs_flushing()) { 1.171 + if (PrintMethodFlushing) { 1.172 + tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler", 1.173 + CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 1.174 + } 1.175 + if (LogCompilation && (xtty != NULL)) { 1.176 + ttyLocker ttyl; 1.177 + xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 1.178 + CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 1.179 + xtty->stamp(); 1.180 + xtty->end_elem(); 1.181 + } 1.182 + CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); 1.183 + return; 1.184 + } 1.185 + } 1.186 + 1.187 + // Traverse the code cache trying to dump the oldest nmethods 1.188 + uint curr_max_comp_id = CompileBroker::get_compilation_id(); 1.189 + uint flush_target = ((curr_max_comp_id - _highest_marked) >> 1) + _highest_marked; 1.190 + if (PrintMethodFlushing && Verbose) { 1.191 + tty->print_cr("### Cleaning code cache: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes", 1.192 + CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 1.193 + } 1.194 + if (LogCompilation && (xtty != NULL)) { 1.195 + ttyLocker ttyl; 1.196 + xtty->begin_elem("start_cleaning_code_cache live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 1.197 + CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 1.198 + xtty->stamp(); 1.199 + xtty->end_elem(); 1.200 + } 1.201 + 1.202 + nmethod* nm = CodeCache::alive_nmethod(CodeCache::first()); 1.203 + jint disconnected = 0; 1.204 + jint made_not_entrant = 0; 1.205 + while ((nm != NULL)){ 1.206 + uint curr_comp_id = nm->compile_id(); 1.207 + 1.208 + // OSR methods cannot be flushed like this. Also, don't flush native methods 1.209 + // since they are part of the JDK in most cases 1.210 + if (nm->is_in_use() && (!nm->is_osr_method()) && (!nm->is_locked_by_vm()) && 1.211 + (!nm->is_native_method()) && ((curr_comp_id < flush_target))) { 1.212 + 1.213 + if ((nm->method()->code() == nm)) { 1.214 + // This method has not been previously considered for 1.215 + // unloading or it was restored already 1.216 + CodeCache::speculatively_disconnect(nm); 1.217 + disconnected++; 1.218 + } else if (nm->is_speculatively_disconnected()) { 1.219 + // This method was previously considered for preemptive unloading and was not called since then 1.220 + nm->method()->invocation_counter()->decay(); 1.221 + nm->method()->backedge_counter()->decay(); 1.222 + nm->make_not_entrant(); 1.223 + made_not_entrant++; 1.224 + } 1.225 + 1.226 + if (curr_comp_id > _highest_marked) { 1.227 + _highest_marked = curr_comp_id; 1.228 + } 1.229 + } 1.230 + nm = CodeCache::alive_nmethod(CodeCache::next(nm)); 1.231 + } 1.232 + 1.233 + if (LogCompilation && (xtty != NULL)) { 1.234 + ttyLocker ttyl; 1.235 + xtty->begin_elem("stop_cleaning_code_cache disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 1.236 + disconnected, made_not_entrant, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 1.237 + xtty->stamp(); 1.238 + xtty->end_elem(); 1.239 + } 1.240 + 1.241 + // Shut off compiler. Sweeper will run exiting from this safepoint 1.242 + // and turn it back on if it clears enough space 1.243 + if (was_full()) { 1.244 + _last_was_full = os::javaTimeMillis(); 1.245 + CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation); 1.246 + } 1.247 + 1.248 + // After two more traversals the sweeper will get rid of unrestored nmethods 1.249 + _was_full_traversal = _traversals; 1.250 +#ifdef ASSERT 1.251 + jlong end = os::javaTimeMillis(); 1.252 + if(PrintMethodFlushing && Verbose) { 1.253 + tty->print_cr("### sweeper: unload time: " INT64_FORMAT, end-start); 1.254 + } 1.255 +#endif 1.256 +}