src/share/vm/runtime/sweeper.cpp

Fri, 29 Jan 2010 09:27:22 -0800

author
kvn
date
Fri, 29 Jan 2010 09:27:22 -0800
changeset 1637
5f24d0319e54
parent 1435
a1423fe86a18
child 1893
bfe29ec02863
permissions
-rw-r--r--

4360113: Evict nmethods when code cache gets full
Summary: Speculatively unload the oldest nmethods when code cache gets full.
Reviewed-by: never, kvn
Contributed-by: eric.caspole@amd.com

     1 /*
     2  * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 # include "incls/_precompiled.incl"
    26 # include "incls/_sweeper.cpp.incl"
    28 long      NMethodSweeper::_traversals = 0;   // No. of stack traversals performed
    29 CodeBlob* NMethodSweeper::_current = NULL;   // Current nmethod
    30 int       NMethodSweeper::_seen = 0 ;        // No. of blobs we have currently processed in current pass of CodeCache
    31 int       NMethodSweeper::_invocations = 0;  // No. of invocations left until we are completed with this pass
    33 jint      NMethodSweeper::_locked_seen = 0;
    34 jint      NMethodSweeper::_not_entrant_seen_on_stack = 0;
    35 bool      NMethodSweeper::_rescan = false;
    36 bool      NMethodSweeper::_was_full = false;
    37 jint      NMethodSweeper::_advise_to_sweep = 0;
    38 jlong     NMethodSweeper::_last_was_full = 0;
    39 uint      NMethodSweeper::_highest_marked = 0;
    40 long      NMethodSweeper::_was_full_traversal = 0;
    42 class MarkActivationClosure: public CodeBlobClosure {
    43 public:
    44   virtual void do_code_blob(CodeBlob* cb) {
    45     // If we see an activation belonging to a non_entrant nmethod, we mark it.
    46     if (cb->is_nmethod() && ((nmethod*)cb)->is_not_entrant()) {
    47       ((nmethod*)cb)->mark_as_seen_on_stack();
    48     }
    49   }
    50 };
    51 static MarkActivationClosure mark_activation_closure;
    53 void NMethodSweeper::sweep() {
    54   assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
    55   if (!MethodFlushing) return;
    57   // No need to synchronize access, since this is always executed at a
    58   // safepoint.  If we aren't in the middle of scan and a rescan
    59   // hasn't been requested then just return.
    60   if (_current == NULL && !_rescan) return;
    62   // Make sure CompiledIC_lock in unlocked, since we might update some
    63   // inline caches. If it is, we just bail-out and try later.
    64   if (CompiledIC_lock->is_locked() || Patching_lock->is_locked()) return;
    66   // Check for restart
    67   assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid");
    68   if (_current == NULL) {
    69     _seen        = 0;
    70     _invocations = NmethodSweepFraction;
    71     _current     = CodeCache::first();
    72     _traversals  += 1;
    73     if (PrintMethodFlushing) {
    74       tty->print_cr("### Sweep: stack traversal %d", _traversals);
    75     }
    76     Threads::nmethods_do(&mark_activation_closure);
    78     // reset the flags since we started a scan from the beginning.
    79     _rescan = false;
    80     _locked_seen = 0;
    81     _not_entrant_seen_on_stack = 0;
    82   }
    84   if (PrintMethodFlushing && Verbose) {
    85     tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_blobs(), _invocations);
    86   }
    88   // We want to visit all nmethods after NmethodSweepFraction invocations.
    89   // If invocation is 1 we do the rest
    90   int todo = CodeCache::nof_blobs();
    91   if (_invocations != 1) {
    92     todo = (CodeCache::nof_blobs() - _seen) / _invocations;
    93     _invocations--;
    94   }
    96   for(int i = 0; i < todo && _current != NULL; i++) {
    97     CodeBlob* next = CodeCache::next(_current); // Read next before we potentially delete current
    98     if (_current->is_nmethod()) {
    99       process_nmethod((nmethod *)_current);
   100     }
   101     _seen++;
   102     _current = next;
   103   }
   104   // Because we could stop on a codeBlob other than an nmethod we skip forward
   105   // to the next nmethod (if any). codeBlobs other than nmethods can be freed
   106   // async to us and make _current invalid while we sleep.
   107   while (_current != NULL && !_current->is_nmethod()) {
   108     _current = CodeCache::next(_current);
   109   }
   111   if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) {
   112     // we've completed a scan without making progress but there were
   113     // nmethods we were unable to process either because they were
   114     // locked or were still on stack.  We don't have to aggresively
   115     // clean them up so just stop scanning.  We could scan once more
   116     // but that complicates the control logic and it's unlikely to
   117     // matter much.
   118     if (PrintMethodFlushing) {
   119       tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep");
   120     }
   121   }
   123   if (UseCodeCacheFlushing) {
   124     if (!CodeCache::needs_flushing()) {
   125       // In a safepoint, no race with setters
   126       _advise_to_sweep = 0;
   127     }
   129     if (was_full()) {
   130       // There was some progress so attempt to restart the compiler
   131       jlong now           = os::javaTimeMillis();
   132       jlong max_interval  = (jlong)MinCodeCacheFlushingInterval * (jlong)1000;
   133       jlong curr_interval = now - _last_was_full;
   134       if ((!CodeCache::needs_flushing()) && (curr_interval > max_interval)) {
   135         CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
   136         set_was_full(false);
   138         // Update the _last_was_full time so we can tell how fast the
   139         // code cache is filling up
   140         _last_was_full = os::javaTimeMillis();
   142         if (PrintMethodFlushing) {
   143           tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler",
   144             CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
   145         }
   146         if (LogCompilation && (xtty != NULL)) {
   147           ttyLocker ttyl;
   148           xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
   149                            CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
   150           xtty->stamp();
   151           xtty->end_elem();
   152         }
   153       }
   154     }
   155   }
   156 }
   159 void NMethodSweeper::process_nmethod(nmethod *nm) {
   160   // Skip methods that are currently referenced by the VM
   161   if (nm->is_locked_by_vm()) {
   162     // But still remember to clean-up inline caches for alive nmethods
   163     if (nm->is_alive()) {
   164       // Clean-up all inline caches that points to zombie/non-reentrant methods
   165       nm->cleanup_inline_caches();
   166     } else {
   167       _locked_seen++;
   168     }
   169     return;
   170   }
   172   if (nm->is_zombie()) {
   173     // If it is first time, we see nmethod then we mark it. Otherwise,
   174     // we reclame it. When we have seen a zombie method twice, we know that
   175     // there are no inline caches that referes to it.
   176     if (nm->is_marked_for_reclamation()) {
   177       assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
   178       if (PrintMethodFlushing && Verbose) {
   179         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
   180       }
   181       nm->flush();
   182     } else {
   183       if (PrintMethodFlushing && Verbose) {
   184         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
   185       }
   186       nm->mark_for_reclamation();
   187       _rescan = true;
   188     }
   189   } else if (nm->is_not_entrant()) {
   190     // If there is no current activations of this method on the
   191     // stack we can safely convert it to a zombie method
   192     if (nm->can_not_entrant_be_converted()) {
   193       if (PrintMethodFlushing && Verbose) {
   194         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
   195       }
   196       nm->make_zombie();
   197       _rescan = true;
   198     } else {
   199       // Still alive, clean up its inline caches
   200       nm->cleanup_inline_caches();
   201       // we coudn't transition this nmethod so don't immediately
   202       // request a rescan.  If this method stays on the stack for a
   203       // long time we don't want to keep rescanning at every safepoint.
   204       _not_entrant_seen_on_stack++;
   205     }
   206   } else if (nm->is_unloaded()) {
   207     // Unloaded code, just make it a zombie
   208     if (PrintMethodFlushing && Verbose)
   209       tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
   210     if (nm->is_osr_method()) {
   211       // No inline caches will ever point to osr methods, so we can just remove it
   212       nm->flush();
   213     } else {
   214       nm->make_zombie();
   215       _rescan = true;
   216     }
   217   } else {
   218     assert(nm->is_alive(), "should be alive");
   220     if (UseCodeCacheFlushing) {
   221       if ((nm->method()->code() != nm) && !(nm->is_locked_by_vm()) && !(nm->is_osr_method()) &&
   222           (_traversals > _was_full_traversal+2) && (((uint)nm->compile_id()) < _highest_marked) &&
   223           CodeCache::needs_flushing()) {
   224         // This method has not been called since the forced cleanup happened
   225         nm->make_not_entrant();
   226       }
   227     }
   229     // Clean-up all inline caches that points to zombie/non-reentrant methods
   230     nm->cleanup_inline_caches();
   231   }
   232 }
   234 // Code cache unloading: when compilers notice the code cache is getting full,
   235 // they will call a vm op that comes here. This code attempts to speculatively
   236 // unload the oldest half of the nmethods (based on the compile job id) by
   237 // saving the old code in a list in the CodeCache. Then
   238 // execution resumes. If a method so marked is not called by the second
   239 // safepoint from the current one, the nmethod will be marked non-entrant and
   240 // got rid of by normal sweeping. If the method is called, the methodOop's
   241 // _code field is restored and the methodOop/nmethod
   242 // go back to their normal state.
   243 void NMethodSweeper::handle_full_code_cache(bool is_full) {
   244   // Only the first one to notice can advise us to start early cleaning
   245   if (!is_full){
   246     jint old = Atomic::cmpxchg( 1, &_advise_to_sweep, 0 );
   247     if (old != 0) {
   248       return;
   249     }
   250   }
   252   if (is_full) {
   253     // Since code cache is full, immediately stop new compiles
   254     bool did_set = CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation);
   255     if (!did_set) {
   256       // only the first to notice can start the cleaning,
   257       // others will go back and block
   258       return;
   259     }
   260     set_was_full(true);
   262     // If we run out within MinCodeCacheFlushingInterval of the last unload time, give up
   263     jlong now = os::javaTimeMillis();
   264     jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000;
   265     jlong curr_interval = now - _last_was_full;
   266     if (curr_interval < max_interval) {
   267       _rescan = true;
   268       if (PrintMethodFlushing) {
   269         tty->print_cr("### handle full too often, turning off compiler");
   270       }
   271       if (LogCompilation && (xtty != NULL)) {
   272         ttyLocker ttyl;
   273         xtty->begin_elem("disable_compiler flushing_interval='" UINT64_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
   274                          curr_interval/1000, CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
   275         xtty->stamp();
   276         xtty->end_elem();
   277       }
   278       return;
   279     }
   280   }
   282   VM_HandleFullCodeCache op(is_full);
   283   VMThread::execute(&op);
   285   // rescan again as soon as possible
   286   _rescan = true;
   287 }
   289 void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
   290   // If there was a race in detecting full code cache, only run
   291   // one vm op for it or keep the compiler shut off
   293   debug_only(jlong start = os::javaTimeMillis();)
   295   if ((!was_full()) && (is_full)) {
   296     if (!CodeCache::needs_flushing()) {
   297       if (PrintMethodFlushing) {
   298         tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler",
   299           CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
   300       }
   301       if (LogCompilation && (xtty != NULL)) {
   302         ttyLocker ttyl;
   303         xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
   304                          CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
   305         xtty->stamp();
   306         xtty->end_elem();
   307       }
   308       CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
   309       return;
   310     }
   311   }
   313   // Traverse the code cache trying to dump the oldest nmethods
   314   uint curr_max_comp_id = CompileBroker::get_compilation_id();
   315   uint flush_target = ((curr_max_comp_id - _highest_marked) >> 1) + _highest_marked;
   316   if (PrintMethodFlushing && Verbose) {
   317     tty->print_cr("### Cleaning code cache: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes",
   318         CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
   319   }
   320   if (LogCompilation && (xtty != NULL)) {
   321     ttyLocker ttyl;
   322     xtty->begin_elem("start_cleaning_code_cache live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
   323                       CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
   324     xtty->stamp();
   325     xtty->end_elem();
   326   }
   328   nmethod* nm = CodeCache::alive_nmethod(CodeCache::first());
   329   jint disconnected = 0;
   330   jint made_not_entrant  = 0;
   331   while ((nm != NULL)){
   332     uint curr_comp_id = nm->compile_id();
   334     // OSR methods cannot be flushed like this. Also, don't flush native methods
   335     // since they are part of the JDK in most cases
   336     if (nm->is_in_use() && (!nm->is_osr_method()) && (!nm->is_locked_by_vm()) &&
   337         (!nm->is_native_method()) && ((curr_comp_id < flush_target))) {
   339       if ((nm->method()->code() == nm)) {
   340         // This method has not been previously considered for
   341         // unloading or it was restored already
   342         CodeCache::speculatively_disconnect(nm);
   343         disconnected++;
   344       } else if (nm->is_speculatively_disconnected()) {
   345         // This method was previously considered for preemptive unloading and was not called since then
   346         nm->method()->invocation_counter()->decay();
   347         nm->method()->backedge_counter()->decay();
   348         nm->make_not_entrant();
   349         made_not_entrant++;
   350       }
   352       if (curr_comp_id > _highest_marked) {
   353         _highest_marked = curr_comp_id;
   354       }
   355     }
   356     nm = CodeCache::alive_nmethod(CodeCache::next(nm));
   357   }
   359   if (LogCompilation && (xtty != NULL)) {
   360     ttyLocker ttyl;
   361     xtty->begin_elem("stop_cleaning_code_cache disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
   362                       disconnected, made_not_entrant, CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
   363     xtty->stamp();
   364     xtty->end_elem();
   365   }
   367   // Shut off compiler. Sweeper will run exiting from this safepoint
   368   // and turn it back on if it clears enough space
   369   if (was_full()) {
   370     _last_was_full = os::javaTimeMillis();
   371     CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation);
   372   }
   374   // After two more traversals the sweeper will get rid of unrestored nmethods
   375   _was_full_traversal = _traversals;
   376 #ifdef ASSERT
   377   jlong end = os::javaTimeMillis();
   378   if(PrintMethodFlushing && Verbose) {
   379     tty->print_cr("### sweeper: unload time: " INT64_FORMAT, end-start);
   380   }
   381 #endif
   382 }

mercurial