src/share/vm/runtime/sweeper.cpp

Mon, 29 Apr 2013 13:20:19 +0200

author
neliasso
date
Mon, 29 Apr 2013 13:20:19 +0200
changeset 5038
0cfa93c2fcc4
parent 4037
da91efe96a93
child 5237
f2110083203d
permissions
-rw-r--r--

8012547: Code cache flushing can get stuck reclaming of memory
Summary: Keep sweeping regardless of if we are flushing
Reviewed-by: kvn, twisti

     1 /*
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "code/codeCache.hpp"
    27 #include "code/compiledIC.hpp"
    28 #include "code/icBuffer.hpp"
    29 #include "code/nmethod.hpp"
    30 #include "compiler/compileBroker.hpp"
    31 #include "memory/resourceArea.hpp"
    32 #include "oops/method.hpp"
    33 #include "runtime/atomic.hpp"
    34 #include "runtime/compilationPolicy.hpp"
    35 #include "runtime/mutexLocker.hpp"
    36 #include "runtime/os.hpp"
    37 #include "runtime/sweeper.hpp"
    38 #include "runtime/vm_operations.hpp"
    39 #include "utilities/events.hpp"
    40 #include "utilities/xmlstream.hpp"
    42 #ifdef ASSERT
    44 #define SWEEP(nm) record_sweep(nm, __LINE__)
    45 // Sweeper logging code
    46 class SweeperRecord {
    47  public:
    48   int traversal;
    49   int invocation;
    50   int compile_id;
    51   long traversal_mark;
    52   int state;
    53   const char* kind;
    54   address vep;
    55   address uep;
    56   int line;
    58   void print() {
    59       tty->print_cr("traversal = %d invocation = %d compile_id = %d %s uep = " PTR_FORMAT " vep = "
    60                     PTR_FORMAT " state = %d traversal_mark %d line = %d",
    61                     traversal,
    62                     invocation,
    63                     compile_id,
    64                     kind == NULL ? "" : kind,
    65                     uep,
    66                     vep,
    67                     state,
    68                     traversal_mark,
    69                     line);
    70   }
    71 };
    73 static int _sweep_index = 0;
    74 static SweeperRecord* _records = NULL;
    76 void NMethodSweeper::report_events(int id, address entry) {
    77   if (_records != NULL) {
    78     for (int i = _sweep_index; i < SweeperLogEntries; i++) {
    79       if (_records[i].uep == entry ||
    80           _records[i].vep == entry ||
    81           _records[i].compile_id == id) {
    82         _records[i].print();
    83       }
    84     }
    85     for (int i = 0; i < _sweep_index; i++) {
    86       if (_records[i].uep == entry ||
    87           _records[i].vep == entry ||
    88           _records[i].compile_id == id) {
    89         _records[i].print();
    90       }
    91     }
    92   }
    93 }
    95 void NMethodSweeper::report_events() {
    96   if (_records != NULL) {
    97     for (int i = _sweep_index; i < SweeperLogEntries; i++) {
    98       // skip empty records
    99       if (_records[i].vep == NULL) continue;
   100       _records[i].print();
   101     }
   102     for (int i = 0; i < _sweep_index; i++) {
   103       // skip empty records
   104       if (_records[i].vep == NULL) continue;
   105       _records[i].print();
   106     }
   107   }
   108 }
   110 void NMethodSweeper::record_sweep(nmethod* nm, int line) {
   111   if (_records != NULL) {
   112     _records[_sweep_index].traversal = _traversals;
   113     _records[_sweep_index].traversal_mark = nm->_stack_traversal_mark;
   114     _records[_sweep_index].invocation = _invocations;
   115     _records[_sweep_index].compile_id = nm->compile_id();
   116     _records[_sweep_index].kind = nm->compile_kind();
   117     _records[_sweep_index].state = nm->_state;
   118     _records[_sweep_index].vep = nm->verified_entry_point();
   119     _records[_sweep_index].uep = nm->entry_point();
   120     _records[_sweep_index].line = line;
   122     _sweep_index = (_sweep_index + 1) % SweeperLogEntries;
   123   }
   124 }
   125 #else
   126 #define SWEEP(nm)
   127 #endif
   130 long      NMethodSweeper::_traversals = 0;   // No. of stack traversals performed
   131 nmethod*  NMethodSweeper::_current = NULL;   // Current nmethod
   132 int       NMethodSweeper::_seen = 0 ;        // No. of nmethods we have currently processed in current pass of CodeCache
   134 volatile int NMethodSweeper::_invocations = 0;   // No. of invocations left until we are completed with this pass
   135 volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress.
   137 jint      NMethodSweeper::_locked_seen = 0;
   138 jint      NMethodSweeper::_not_entrant_seen_on_stack = 0;
   139 bool      NMethodSweeper::_resweep = false;
   140 jint      NMethodSweeper::_flush_token = 0;
   141 jlong     NMethodSweeper::_last_full_flush_time = 0;
   142 int       NMethodSweeper::_highest_marked = 0;
   143 int       NMethodSweeper::_dead_compile_ids = 0;
   144 long      NMethodSweeper::_last_flush_traversal_id = 0;
   146 class MarkActivationClosure: public CodeBlobClosure {
   147 public:
   148   virtual void do_code_blob(CodeBlob* cb) {
   149     // If we see an activation belonging to a non_entrant nmethod, we mark it.
   150     if (cb->is_nmethod() && ((nmethod*)cb)->is_not_entrant()) {
   151       ((nmethod*)cb)->mark_as_seen_on_stack();
   152     }
   153   }
   154 };
   155 static MarkActivationClosure mark_activation_closure;
   157 bool NMethodSweeper::sweep_in_progress() {
   158   return (_current != NULL);
   159 }
   161 void NMethodSweeper::scan_stacks() {
   162   assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
   163   if (!MethodFlushing) return;
   165   // No need to synchronize access, since this is always executed at a
   166   // safepoint.
   168   // Make sure CompiledIC_lock in unlocked, since we might update some
   169   // inline caches. If it is, we just bail-out and try later.
   170   if (CompiledIC_lock->is_locked() || Patching_lock->is_locked()) return;
   172   // Check for restart
   173   assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid");
   174   if (!sweep_in_progress() && _resweep) {
   175     _seen        = 0;
   176     _invocations = NmethodSweepFraction;
   177     _current     = CodeCache::first_nmethod();
   178     _traversals  += 1;
   179     if (PrintMethodFlushing) {
   180       tty->print_cr("### Sweep: stack traversal %d", _traversals);
   181     }
   182     Threads::nmethods_do(&mark_activation_closure);
   184     // reset the flags since we started a scan from the beginning.
   185     _resweep = false;
   186     _locked_seen = 0;
   187     _not_entrant_seen_on_stack = 0;
   188   }
   190   if (UseCodeCacheFlushing) {
   191     // only allow new flushes after the interval is complete.
   192     jlong now           = os::javaTimeMillis();
   193     jlong max_interval  = (jlong)MinCodeCacheFlushingInterval * (jlong)1000;
   194     jlong curr_interval = now - _last_full_flush_time;
   195     if (curr_interval > max_interval) {
   196       _flush_token = 0;
   197     }
   199     if (!CodeCache::needs_flushing() && !CompileBroker::should_compile_new_jobs()) {
   200       CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
   201       log_sweep("restart_compiler");
   202     }
   203   }
   204 }
   206 void NMethodSweeper::possibly_sweep() {
   207   assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode");
   208   if (!MethodFlushing || !sweep_in_progress()) return;
   210   if (_invocations > 0) {
   211     // Only one thread at a time will sweep
   212     jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 );
   213     if (old != 0) {
   214       return;
   215     }
   216 #ifdef ASSERT
   217     if (LogSweeper && _records == NULL) {
   218       // Create the ring buffer for the logging code
   219       _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC);
   220       memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries);
   221     }
   222 #endif
   223     if (_invocations > 0) {
   224       sweep_code_cache();
   225       _invocations--;
   226     }
   227     _sweep_started = 0;
   228   }
   229 }
   231 void NMethodSweeper::sweep_code_cache() {
   232 #ifdef ASSERT
   233   jlong sweep_start;
   234   if (PrintMethodFlushing) {
   235     sweep_start = os::javaTimeMillis();
   236   }
   237 #endif
   238   if (PrintMethodFlushing && Verbose) {
   239     tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations);
   240   }
   242   if (!CompileBroker::should_compile_new_jobs()) {
   243     // If we have turned off compilations we might as well do full sweeps
   244     // in order to reach the clean state faster. Otherwise the sleeping compiler
   245     // threads will slow down sweeping. After a few iterations the cache
   246     // will be clean and sweeping stops (_resweep will not be set)
   247     _invocations = 1;
   248   }
   250   // We want to visit all nmethods after NmethodSweepFraction
   251   // invocations so divide the remaining number of nmethods by the
   252   // remaining number of invocations.  This is only an estimate since
   253   // the number of nmethods changes during the sweep so the final
   254   // stage must iterate until it there are no more nmethods.
   255   int todo = (CodeCache::nof_nmethods() - _seen) / _invocations;
   257   assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
   258   assert(!CodeCache_lock->owned_by_self(), "just checking");
   260   {
   261     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   263     // The last invocation iterates until there are no more nmethods
   264     for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) {
   265       if (SafepointSynchronize::is_synchronizing()) { // Safepoint request
   266         if (PrintMethodFlushing && Verbose) {
   267           tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _invocations);
   268         }
   269         MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   271         assert(Thread::current()->is_Java_thread(), "should be java thread");
   272         JavaThread* thread = (JavaThread*)Thread::current();
   273         ThreadBlockInVM tbivm(thread);
   274         thread->java_suspend_self();
   275       }
   276       // Since we will give up the CodeCache_lock, always skip ahead
   277       // to the next nmethod.  Other blobs can be deleted by other
   278       // threads but nmethods are only reclaimed by the sweeper.
   279       nmethod* next = CodeCache::next_nmethod(_current);
   281       // Now ready to process nmethod and give up CodeCache_lock
   282       {
   283         MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   284         process_nmethod(_current);
   285       }
   286       _seen++;
   287       _current = next;
   288     }
   289   }
   291   assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache");
   293   if (!sweep_in_progress() && !_resweep && (_locked_seen || _not_entrant_seen_on_stack)) {
   294     // we've completed a scan without making progress but there were
   295     // nmethods we were unable to process either because they were
   296     // locked or were still on stack.  We don't have to aggresively
   297     // clean them up so just stop scanning.  We could scan once more
   298     // but that complicates the control logic and it's unlikely to
   299     // matter much.
   300     if (PrintMethodFlushing) {
   301       tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep");
   302     }
   303   }
   305 #ifdef ASSERT
   306   if(PrintMethodFlushing) {
   307     jlong sweep_end             = os::javaTimeMillis();
   308     tty->print_cr("### sweeper:      sweep time(%d): " INT64_FORMAT, _invocations, sweep_end - sweep_start);
   309   }
   310 #endif
   312   if (_invocations == 1) {
   313     log_sweep("finished");
   314   }
   316   // Sweeper is the only case where memory is released,
   317   // check here if it is time to restart the compiler.
   318   if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs() && !CodeCache::needs_flushing()) {
   319     CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
   320     log_sweep("restart_compiler");
   321   }
   322 }
   324 class NMethodMarker: public StackObj {
   325  private:
   326   CompilerThread* _thread;
   327  public:
   328   NMethodMarker(nmethod* nm) {
   329     _thread = CompilerThread::current();
   330     if (!nm->is_zombie() && !nm->is_unloaded()) {
   331       // Only expose live nmethods for scanning
   332     _thread->set_scanned_nmethod(nm);
   333   }
   334   }
   335   ~NMethodMarker() {
   336     _thread->set_scanned_nmethod(NULL);
   337   }
   338 };
   340 void NMethodSweeper::release_nmethod(nmethod *nm) {
   341   // Clean up any CompiledICHolders
   342   {
   343     ResourceMark rm;
   344     MutexLocker ml_patch(CompiledIC_lock);
   345     RelocIterator iter(nm);
   346     while (iter.next()) {
   347       if (iter.type() == relocInfo::virtual_call_type) {
   348         CompiledIC::cleanup_call_site(iter.virtual_call_reloc());
   349       }
   350     }
   351   }
   353   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   354   nm->flush();
   355 }
   357 void NMethodSweeper::process_nmethod(nmethod *nm) {
   358   assert(!CodeCache_lock->owned_by_self(), "just checking");
   360   // Make sure this nmethod doesn't get unloaded during the scan,
   361   // since the locks acquired below might safepoint.
   362   NMethodMarker nmm(nm);
   364   SWEEP(nm);
   366   // Skip methods that are currently referenced by the VM
   367   if (nm->is_locked_by_vm()) {
   368     // But still remember to clean-up inline caches for alive nmethods
   369     if (nm->is_alive()) {
   370       // Clean-up all inline caches that points to zombie/non-reentrant methods
   371       MutexLocker cl(CompiledIC_lock);
   372       nm->cleanup_inline_caches();
   373       SWEEP(nm);
   374     } else {
   375       _locked_seen++;
   376       SWEEP(nm);
   377     }
   378     return;
   379   }
   381   if (nm->is_zombie()) {
   382     // If it is first time, we see nmethod then we mark it. Otherwise,
   383     // we reclame it. When we have seen a zombie method twice, we know that
   384     // there are no inline caches that refer to it.
   385     if (nm->is_marked_for_reclamation()) {
   386       assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
   387       if (PrintMethodFlushing && Verbose) {
   388         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
   389       }
   390       release_nmethod(nm);
   391     } else {
   392       if (PrintMethodFlushing && Verbose) {
   393         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
   394       }
   395       nm->mark_for_reclamation();
   396       _resweep = true;
   397       SWEEP(nm);
   398     }
   399   } else if (nm->is_not_entrant()) {
   400     // If there is no current activations of this method on the
   401     // stack we can safely convert it to a zombie method
   402     if (nm->can_not_entrant_be_converted()) {
   403       if (PrintMethodFlushing && Verbose) {
   404         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
   405       }
   406       nm->make_zombie();
   407       _resweep = true;
   408       SWEEP(nm);
   409     } else {
   410       // Still alive, clean up its inline caches
   411       MutexLocker cl(CompiledIC_lock);
   412       nm->cleanup_inline_caches();
   413       // we coudn't transition this nmethod so don't immediately
   414       // request a rescan.  If this method stays on the stack for a
   415       // long time we don't want to keep rescanning the code cache.
   416       _not_entrant_seen_on_stack++;
   417       SWEEP(nm);
   418     }
   419   } else if (nm->is_unloaded()) {
   420     // Unloaded code, just make it a zombie
   421     if (PrintMethodFlushing && Verbose)
   422       tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
   423     if (nm->is_osr_method()) {
   424       SWEEP(nm);
   425       // No inline caches will ever point to osr methods, so we can just remove it
   426       release_nmethod(nm);
   427     } else {
   428       nm->make_zombie();
   429       _resweep = true;
   430       SWEEP(nm);
   431     }
   432   } else {
   433     assert(nm->is_alive(), "should be alive");
   435     if (UseCodeCacheFlushing) {
   436       if (nm->is_speculatively_disconnected() && !nm->is_locked_by_vm() && !nm->is_osr_method() &&
   437           (_traversals > _last_flush_traversal_id + 2) && (nm->compile_id() < _highest_marked)) {
   438         // This method has not been called since the forced cleanup happened
   439         nm->make_not_entrant();
   440       }
   441     }
   443     // Clean-up all inline caches that points to zombie/non-reentrant methods
   444     MutexLocker cl(CompiledIC_lock);
   445     nm->cleanup_inline_caches();
   446     SWEEP(nm);
   447   }
   448 }
   450 // Code cache unloading: when compilers notice the code cache is getting full,
   451 // they will call a vm op that comes here. This code attempts to speculatively
   452 // unload the oldest half of the nmethods (based on the compile job id) by
   453 // saving the old code in a list in the CodeCache. Then
   454 // execution resumes. If a method so marked is not called by the second sweeper
   455 // stack traversal after the current one, the nmethod will be marked non-entrant and
   456 // got rid of by normal sweeping. If the method is called, the Method*'s
   457 // _code field is restored and the Method*/nmethod
   458 // go back to their normal state.
   459 void NMethodSweeper::handle_full_code_cache(bool is_full) {
   461   if (is_full) {
   462     // Since code cache is full, immediately stop new compiles
   463     if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
   464       log_sweep("disable_compiler");
   465     }
   466   }
   468   // Make sure only one thread can flush
   469   // The token is reset after CodeCacheMinimumFlushInterval in scan stacks,
   470   // no need to check the timeout here.
   471   jint old = Atomic::cmpxchg( 1, &_flush_token, 0 );
   472   if (old != 0) {
   473     return;
   474   }
   476   VM_HandleFullCodeCache op(is_full);
   477   VMThread::execute(&op);
   479   // resweep again as soon as possible
   480   _resweep = true;
   481 }
   483 void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
   484   // If there was a race in detecting full code cache, only run
   485   // one vm op for it or keep the compiler shut off
   487   debug_only(jlong start = os::javaTimeMillis();)
   489   // Traverse the code cache trying to dump the oldest nmethods
   490   int curr_max_comp_id = CompileBroker::get_compilation_id();
   491   int flush_target = ((curr_max_comp_id - _dead_compile_ids) / CodeCacheFlushingFraction) + _dead_compile_ids;
   493   log_sweep("start_cleaning");
   495   nmethod* nm = CodeCache::alive_nmethod(CodeCache::first());
   496   jint disconnected = 0;
   497   jint made_not_entrant  = 0;
   498   jint nmethod_count = 0;
   500   while ((nm != NULL)){
   501     int curr_comp_id = nm->compile_id();
   503     // OSR methods cannot be flushed like this. Also, don't flush native methods
   504     // since they are part of the JDK in most cases
   505     if (!nm->is_osr_method() && !nm->is_locked_by_vm() && !nm->is_native_method()) {
   507       // only count methods that can be speculatively disconnected
   508       nmethod_count++;
   510       if (nm->is_in_use() && (curr_comp_id < flush_target)) {
   511         if ((nm->method()->code() == nm)) {
   512           // This method has not been previously considered for
   513           // unloading or it was restored already
   514           CodeCache::speculatively_disconnect(nm);
   515           disconnected++;
   516         } else if (nm->is_speculatively_disconnected()) {
   517           // This method was previously considered for preemptive unloading and was not called since then
   518           CompilationPolicy::policy()->delay_compilation(nm->method());
   519           nm->make_not_entrant();
   520           made_not_entrant++;
   521         }
   523         if (curr_comp_id > _highest_marked) {
   524           _highest_marked = curr_comp_id;
   525         }
   526       }
   527     }
   528     nm = CodeCache::alive_nmethod(CodeCache::next(nm));
   529   }
   531   // remember how many compile_ids wheren't seen last flush.
   532   _dead_compile_ids = curr_max_comp_id - nmethod_count;
   534   log_sweep("stop_cleaning",
   535                        "disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "'",
   536                        disconnected, made_not_entrant);
   538   // Shut off compiler. Sweeper will start over with a new stack scan and
   539   // traversal cycle and turn it back on if it clears enough space.
   540   if (is_full) {
   541     _last_full_flush_time = os::javaTimeMillis();
   542   }
   544   // After two more traversals the sweeper will get rid of unrestored nmethods
   545   _last_flush_traversal_id = _traversals;
   546   _resweep = true;
   547 #ifdef ASSERT
   548   jlong end = os::javaTimeMillis();
   549   if(PrintMethodFlushing && Verbose) {
   550     tty->print_cr("### sweeper: unload time: " INT64_FORMAT, end-start);
   551   }
   552 #endif
   553 }
   556 // Print out some state information about the current sweep and the
   557 // state of the code cache if it's requested.
   558 void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
   559   if (PrintMethodFlushing) {
   560     stringStream s;
   561     // Dump code cache state into a buffer before locking the tty,
   562     // because log_state() will use locks causing lock conflicts.
   563     CodeCache::log_state(&s);
   565     ttyLocker ttyl;
   566     tty->print("### sweeper: %s ", msg);
   567     if (format != NULL) {
   568       va_list ap;
   569       va_start(ap, format);
   570       tty->vprint(format, ap);
   571       va_end(ap);
   572     }
   573     tty->print_cr(s.as_string());
   574   }
   576   if (LogCompilation && (xtty != NULL)) {
   577     stringStream s;
   578     // Dump code cache state into a buffer before locking the tty,
   579     // because log_state() will use locks causing lock conflicts.
   580     CodeCache::log_state(&s);
   582     ttyLocker ttyl;
   583     xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count());
   584     if (format != NULL) {
   585       va_list ap;
   586       va_start(ap, format);
   587       xtty->vprint(format, ap);
   588       va_end(ap);
   589     }
   590     xtty->print(s.as_string());
   591     xtty->stamp();
   592     xtty->end_elem();
   593   }
   594 }

mercurial