hotspot/src/share/vm/runtime/sweeper.cpp
changeset 27420 04e6f914cce1
parent 27017 bae5d661dd4b
child 27917 c5937f7b4e8b
equal deleted inserted replaced
27419:a934f24b4dcf 27420:04e6f914cce1
    50 #define SWEEP(nm) record_sweep(nm, __LINE__)
    50 #define SWEEP(nm) record_sweep(nm, __LINE__)
    51 // Sweeper logging code
    51 // Sweeper logging code
    52 class SweeperRecord {
    52 class SweeperRecord {
    53  public:
    53  public:
    54   int traversal;
    54   int traversal;
    55   int invocation;
       
    56   int compile_id;
    55   int compile_id;
    57   long traversal_mark;
    56   long traversal_mark;
    58   int state;
    57   int state;
    59   const char* kind;
    58   const char* kind;
    60   address vep;
    59   address vep;
    61   address uep;
    60   address uep;
    62   int line;
    61   int line;
    63 
    62 
    64   void print() {
    63   void print() {
    65       tty->print_cr("traversal = %d invocation = %d compile_id = %d %s uep = " PTR_FORMAT " vep = "
    64       tty->print_cr("traversal = %d compile_id = %d %s uep = " PTR_FORMAT " vep = "
    66                     PTR_FORMAT " state = %d traversal_mark %d line = %d",
    65                     PTR_FORMAT " state = %d traversal_mark %d line = %d",
    67                     traversal,
    66                     traversal,
    68                     invocation,
       
    69                     compile_id,
    67                     compile_id,
    70                     kind == NULL ? "" : kind,
    68                     kind == NULL ? "" : kind,
    71                     uep,
    69                     uep,
    72                     vep,
    70                     vep,
    73                     state,
    71                     state,
   115 
   113 
   116 void NMethodSweeper::record_sweep(nmethod* nm, int line) {
   114 void NMethodSweeper::record_sweep(nmethod* nm, int line) {
   117   if (_records != NULL) {
   115   if (_records != NULL) {
   118     _records[_sweep_index].traversal = _traversals;
   116     _records[_sweep_index].traversal = _traversals;
   119     _records[_sweep_index].traversal_mark = nm->_stack_traversal_mark;
   117     _records[_sweep_index].traversal_mark = nm->_stack_traversal_mark;
   120     _records[_sweep_index].invocation = _sweep_fractions_left;
       
   121     _records[_sweep_index].compile_id = nm->compile_id();
   118     _records[_sweep_index].compile_id = nm->compile_id();
   122     _records[_sweep_index].kind = nm->compile_kind();
   119     _records[_sweep_index].kind = nm->compile_kind();
   123     _records[_sweep_index].state = nm->_state;
   120     _records[_sweep_index].state = nm->_state;
   124     _records[_sweep_index].vep = nm->verified_entry_point();
   121     _records[_sweep_index].vep = nm->verified_entry_point();
   125     _records[_sweep_index].uep = nm->entry_point();
   122     _records[_sweep_index].uep = nm->entry_point();
   126     _records[_sweep_index].line = line;
   123     _records[_sweep_index].line = line;
   127     _sweep_index = (_sweep_index + 1) % SweeperLogEntries;
   124     _sweep_index = (_sweep_index + 1) % SweeperLogEntries;
       
   125   }
       
   126 }
       
   127 
       
   128 void NMethodSweeper::init_sweeper_log() {
       
   129  if (LogSweeper && _records == NULL) {
       
   130    // Create the ring buffer for the logging code
       
   131    _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC);
       
   132    memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries);
   128   }
   133   }
   129 }
   134 }
   130 #else
   135 #else
   131 #define SWEEP(nm)
   136 #define SWEEP(nm)
   132 #endif
   137 #endif
   140 int      NMethodSweeper::_flushed_count                = 0;    // Nof. nmethods flushed in current sweep
   145 int      NMethodSweeper::_flushed_count                = 0;    // Nof. nmethods flushed in current sweep
   141 int      NMethodSweeper::_zombified_count              = 0;    // Nof. nmethods made zombie in current sweep
   146 int      NMethodSweeper::_zombified_count              = 0;    // Nof. nmethods made zombie in current sweep
   142 int      NMethodSweeper::_marked_for_reclamation_count = 0;    // Nof. nmethods marked for reclaim in current sweep
   147 int      NMethodSweeper::_marked_for_reclamation_count = 0;    // Nof. nmethods marked for reclaim in current sweep
   143 
   148 
   144 volatile bool NMethodSweeper::_should_sweep            = true; // Indicates if we should invoke the sweeper
   149 volatile bool NMethodSweeper::_should_sweep            = true; // Indicates if we should invoke the sweeper
   145 volatile int  NMethodSweeper::_sweep_fractions_left    = 0;    // Nof. invocations left until we are completed with this pass
       
   146 volatile int  NMethodSweeper::_sweep_started           = 0;    // Flag to control conc sweeper
       
   147 volatile int  NMethodSweeper::_bytes_changed           = 0;    // Counts the total nmethod size if the nmethod changed from:
   150 volatile int  NMethodSweeper::_bytes_changed           = 0;    // Counts the total nmethod size if the nmethod changed from:
   148                                                                //   1) alive       -> not_entrant
   151                                                                //   1) alive       -> not_entrant
   149                                                                //   2) not_entrant -> zombie
   152                                                                //   2) not_entrant -> zombie
   150                                                                //   3) zombie      -> marked_for_reclamation
   153                                                                //   3) zombie      -> marked_for_reclamation
   151 int    NMethodSweeper::_hotness_counter_reset_val       = 0;
   154 int    NMethodSweeper::_hotness_counter_reset_val       = 0;
   188   if (_hotness_counter_reset_val == 0) {
   191   if (_hotness_counter_reset_val == 0) {
   189     _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
   192     _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
   190   }
   193   }
   191   return _hotness_counter_reset_val;
   194   return _hotness_counter_reset_val;
   192 }
   195 }
   193 bool NMethodSweeper::sweep_in_progress() {
   196 bool NMethodSweeper::wait_for_stack_scanning() {
   194   return !_current.end();
   197   return _current.end();
   195 }
   198 }
   196 
   199 
   197 // Scans the stacks of all Java threads and marks activations of not-entrant methods.
   200 /**
   198 // No need to synchronize access, since 'mark_active_nmethods' is always executed at a
   201   * Scans the stacks of all Java threads and marks activations of not-entrant methods.
   199 // safepoint.
   202   * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
       
   203   * safepoint.
       
   204   */
   200 void NMethodSweeper::mark_active_nmethods() {
   205 void NMethodSweeper::mark_active_nmethods() {
   201   assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
   206   assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
   202   // If we do not want to reclaim not-entrant or zombie methods there is no need
   207   // If we do not want to reclaim not-entrant or zombie methods there is no need
   203   // to scan stacks
   208   // to scan stacks
   204   if (!MethodFlushing) {
   209   if (!MethodFlushing) {
   208   // Increase time so that we can estimate when to invoke the sweeper again.
   213   // Increase time so that we can estimate when to invoke the sweeper again.
   209   _time_counter++;
   214   _time_counter++;
   210 
   215 
   211   // Check for restart
   216   // Check for restart
   212   assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
   217   assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
   213   if (!sweep_in_progress()) {
   218   if (wait_for_stack_scanning()) {
   214     _seen = 0;
   219     _seen = 0;
   215     _sweep_fractions_left = NmethodSweepFraction;
       
   216     _current = NMethodIterator();
   220     _current = NMethodIterator();
   217     // Initialize to first nmethod
   221     // Initialize to first nmethod
   218     _current.next();
   222     _current.next();
   219     _traversals += 1;
   223     _traversals += 1;
   220     _total_time_this_sweep = Tickspan();
   224     _total_time_this_sweep = Tickspan();
   229     Threads::nmethods_do(&set_hotness_closure);
   233     Threads::nmethods_do(&set_hotness_closure);
   230   }
   234   }
   231 
   235 
   232   OrderAccess::storestore();
   236   OrderAccess::storestore();
   233 }
   237 }
       
   238 
       
   239 /**
       
   240   * This function triggers a VM operation that does stack scanning of active
       
   241   * methods. Stack scanning is mandatory for the sweeper to make progress.
       
   242   */
       
   243 void NMethodSweeper::do_stack_scanning() {
       
   244   assert(!CodeCache_lock->owned_by_self(), "just checking");
       
   245   if (wait_for_stack_scanning()) {
       
   246     VM_MarkActiveNMethods op;
       
   247     VMThread::execute(&op);
       
   248     _should_sweep = true;
       
   249   }
       
   250 }
       
   251 
       
   252 void NMethodSweeper::sweeper_loop() {
       
   253   bool timeout;
       
   254   while (true) {
       
   255     {
       
   256       ThreadBlockInVM tbivm(JavaThread::current());
       
   257       MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
       
   258       const long wait_time = 60*60*24 * 1000;
       
   259       timeout = CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, wait_time);
       
   260     }
       
   261     if (!timeout) {
       
   262       possibly_sweep();
       
   263     }
       
   264   }
       
   265 }
       
   266 
       
   267 /**
       
   268   * Wakes up the sweeper thread to possibly sweep.
       
   269   */
       
   270 void NMethodSweeper::notify(int code_blob_type) {
       
   271   // Makes sure that we do not invoke the sweeper too often during startup.
       
   272   double start_threshold = 100.0 / (double)StartAggressiveSweepingAt;
       
   273   double aggressive_sweep_threshold = MIN2(start_threshold, 1.1);
       
   274   if (CodeCache::reverse_free_ratio(code_blob_type) >= aggressive_sweep_threshold) {
       
   275     assert_locked_or_safepoint(CodeCache_lock);
       
   276     CodeCache_lock->notify();
       
   277   }
       
   278 }
       
   279 
       
   280 /**
       
   281  * Handle a safepoint request
       
   282  */
       
   283 void NMethodSweeper::handle_safepoint_request() {
       
   284   if (SafepointSynchronize::is_synchronizing()) {
       
   285     if (PrintMethodFlushing && Verbose) {
       
   286       tty->print_cr("### Sweep at %d out of %d, yielding to safepoint", _seen, CodeCache::nof_nmethods());
       
   287     }
       
   288     MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
       
   289 
       
   290     JavaThread* thread = JavaThread::current();
       
   291     ThreadBlockInVM tbivm(thread);
       
   292     thread->java_suspend_self();
       
   293   }
       
   294 }
       
   295 
   234 /**
   296 /**
   235  * This function invokes the sweeper if at least one of the three conditions is met:
   297  * This function invokes the sweeper if at least one of the three conditions is met:
   236  *    (1) The code cache is getting full
   298  *    (1) The code cache is getting full
   237  *    (2) There are sufficient state changes in/since the last sweep.
   299  *    (2) There are sufficient state changes in/since the last sweep.
   238  *    (3) We have not been sweeping for 'some time'
   300  *    (3) We have not been sweeping for 'some time'
   239  */
   301  */
   240 void NMethodSweeper::possibly_sweep() {
   302 void NMethodSweeper::possibly_sweep() {
   241   assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode");
   303   assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode");
   242   // Only compiler threads are allowed to sweep
       
   243   if (!MethodFlushing || !sweep_in_progress() || !Thread::current()->is_Compiler_thread()) {
       
   244     return;
       
   245   }
       
   246 
       
   247   // If there was no state change while nmethod sweeping, 'should_sweep' will be false.
   304   // If there was no state change while nmethod sweeping, 'should_sweep' will be false.
   248   // This is one of the two places where should_sweep can be set to true. The general
   305   // This is one of the two places where should_sweep can be set to true. The general
   249   // idea is as follows: If there is enough free space in the code cache, there is no
   306   // idea is as follows: If there is enough free space in the code cache, there is no
   250   // need to invoke the sweeper. The following formula (which determines whether to invoke
   307   // need to invoke the sweeper. The following formula (which determines whether to invoke
   251   // the sweeper or not) depends on the assumption that for larger ReservedCodeCacheSizes
   308   // the sweeper or not) depends on the assumption that for larger ReservedCodeCacheSizes
   278     if ((wait_until_next_sweep <= 0.0) || !CompileBroker::should_compile_new_jobs()) {
   335     if ((wait_until_next_sweep <= 0.0) || !CompileBroker::should_compile_new_jobs()) {
   279       _should_sweep = true;
   336       _should_sweep = true;
   280     }
   337     }
   281   }
   338   }
   282 
   339 
   283   if (_should_sweep && _sweep_fractions_left > 0) {
   340   // Force stack scanning if there is only 10% free space in the code cache.
   284     // Only one thread at a time will sweep
   341   // We force stack scanning only non-profiled code heap gets full, since critical
   285     jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 );
   342   // allocation go to the non-profiled heap and we must be make sure that there is
   286     if (old != 0) {
   343   // enough space.
   287       return;
   344   double free_percent = 1 / CodeCache::reverse_free_ratio(CodeBlobType::MethodNonProfiled) * 100;
   288     }
   345   if (free_percent <= StartAggressiveSweepingAt) {
   289 #ifdef ASSERT
   346     do_stack_scanning();
   290     if (LogSweeper && _records == NULL) {
   347   }
   291       // Create the ring buffer for the logging code
   348 
   292       _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC);
   349   if (_should_sweep) {
   293       memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries);
   350     init_sweeper_log();
   294     }
   351     sweep_code_cache();
   295 #endif
   352   }
   296 
   353 
   297     if (_sweep_fractions_left > 0) {
   354   // We are done with sweeping the code cache once.
   298       sweep_code_cache();
   355   _total_nof_code_cache_sweeps++;
   299       _sweep_fractions_left--;
   356   _last_sweep = _time_counter;
   300     }
   357   // Reset flag; temporarily disables sweeper
   301 
   358   _should_sweep = false;
   302     // We are done with sweeping the code cache once.
   359   // If there was enough state change, 'possibly_enable_sweeper()'
   303     if (_sweep_fractions_left == 0) {
   360   // sets '_should_sweep' to true
   304       _total_nof_code_cache_sweeps++;
   361    possibly_enable_sweeper();
   305       _last_sweep = _time_counter;
   362   // Reset _bytes_changed only if there was enough state change. _bytes_changed
   306       // Reset flag; temporarily disables sweeper
   363   // can further increase by calls to 'report_state_change'.
   307       _should_sweep = false;
   364   if (_should_sweep) {
   308       // If there was enough state change, 'possibly_enable_sweeper()'
   365     _bytes_changed = 0;
   309       // sets '_should_sweep' to true
       
   310       possibly_enable_sweeper();
       
   311       // Reset _bytes_changed only if there was enough state change. _bytes_changed
       
   312       // can further increase by calls to 'report_state_change'.
       
   313       if (_should_sweep) {
       
   314         _bytes_changed = 0;
       
   315       }
       
   316     }
       
   317     // Release work, because another compiler thread could continue.
       
   318     OrderAccess::release_store((int*)&_sweep_started, 0);
       
   319   }
   366   }
   320 }
   367 }
   321 
   368 
   322 void NMethodSweeper::sweep_code_cache() {
   369 void NMethodSweeper::sweep_code_cache() {
       
   370   ResourceMark rm;
   323   Ticks sweep_start_counter = Ticks::now();
   371   Ticks sweep_start_counter = Ticks::now();
   324 
   372 
   325   _flushed_count                = 0;
   373   _flushed_count                = 0;
   326   _zombified_count              = 0;
   374   _zombified_count              = 0;
   327   _marked_for_reclamation_count = 0;
   375   _marked_for_reclamation_count = 0;
   328 
   376 
   329   if (PrintMethodFlushing && Verbose) {
   377   if (PrintMethodFlushing && Verbose) {
   330     tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _sweep_fractions_left);
   378     tty->print_cr("### Sweep at %d out of %d", _seen, CodeCache::nof_nmethods());
   331   }
   379   }
   332 
   380 
   333   if (!CompileBroker::should_compile_new_jobs()) {
       
   334     // If we have turned off compilations we might as well do full sweeps
       
   335     // in order to reach the clean state faster. Otherwise the sleeping compiler
       
   336     // threads will slow down sweeping.
       
   337     _sweep_fractions_left = 1;
       
   338   }
       
   339 
       
   340   // We want to visit all nmethods after NmethodSweepFraction
       
   341   // invocations so divide the remaining number of nmethods by the
       
   342   // remaining number of invocations.  This is only an estimate since
       
   343   // the number of nmethods changes during the sweep so the final
       
   344   // stage must iterate until it there are no more nmethods.
       
   345   int todo = (CodeCache::nof_nmethods() - _seen) / _sweep_fractions_left;
       
   346   int swept_count = 0;
   381   int swept_count = 0;
   347 
       
   348 
       
   349   assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
   382   assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
   350   assert(!CodeCache_lock->owned_by_self(), "just checking");
   383   assert(!CodeCache_lock->owned_by_self(), "just checking");
   351 
   384 
   352   int freed_memory = 0;
   385   int freed_memory = 0;
   353   {
   386   {
   354     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   387     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   355 
   388 
   356     // The last invocation iterates until there are no more nmethods
   389     // The last invocation iterates until there are no more nmethods
   357     while ((swept_count < todo || _sweep_fractions_left == 1) && !_current.end()) {
   390     while (!_current.end()) {
   358       swept_count++;
   391       swept_count++;
   359       if (SafepointSynchronize::is_synchronizing()) { // Safepoint request
   392       handle_safepoint_request();
   360         if (PrintMethodFlushing && Verbose) {
       
   361           tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _sweep_fractions_left);
       
   362         }
       
   363         MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
       
   364 
       
   365         assert(Thread::current()->is_Java_thread(), "should be java thread");
       
   366         JavaThread* thread = (JavaThread*)Thread::current();
       
   367         ThreadBlockInVM tbivm(thread);
       
   368         thread->java_suspend_self();
       
   369       }
       
   370       // Since we will give up the CodeCache_lock, always skip ahead
   393       // Since we will give up the CodeCache_lock, always skip ahead
   371       // to the next nmethod.  Other blobs can be deleted by other
   394       // to the next nmethod.  Other blobs can be deleted by other
   372       // threads but nmethods are only reclaimed by the sweeper.
   395       // threads but nmethods are only reclaimed by the sweeper.
   373       nmethod* nm = _current.method();
   396       nmethod* nm = _current.method();
   374       _current.next();
   397       _current.next();
   380       }
   403       }
   381       _seen++;
   404       _seen++;
   382     }
   405     }
   383   }
   406   }
   384 
   407 
   385   assert(_sweep_fractions_left > 1 || _current.end(), "must have scanned the whole cache");
   408   assert(_current.end(), "must have scanned the whole cache");
   386 
   409 
   387   const Ticks sweep_end_counter = Ticks::now();
   410   const Ticks sweep_end_counter = Ticks::now();
   388   const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
   411   const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
   389   _total_time_sweeping  += sweep_time;
   412   _total_time_sweeping  += sweep_time;
   390   _total_time_this_sweep += sweep_time;
   413   _total_time_this_sweep += sweep_time;
   395   EventSweepCodeCache event(UNTIMED);
   418   EventSweepCodeCache event(UNTIMED);
   396   if (event.should_commit()) {
   419   if (event.should_commit()) {
   397     event.set_starttime(sweep_start_counter);
   420     event.set_starttime(sweep_start_counter);
   398     event.set_endtime(sweep_end_counter);
   421     event.set_endtime(sweep_end_counter);
   399     event.set_sweepIndex(_traversals);
   422     event.set_sweepIndex(_traversals);
   400     event.set_sweepFractionIndex(NmethodSweepFraction - _sweep_fractions_left + 1);
       
   401     event.set_sweptCount(swept_count);
   423     event.set_sweptCount(swept_count);
   402     event.set_flushedCount(_flushed_count);
   424     event.set_flushedCount(_flushed_count);
   403     event.set_markedCount(_marked_for_reclamation_count);
   425     event.set_markedCount(_marked_for_reclamation_count);
   404     event.set_zombifiedCount(_zombified_count);
   426     event.set_zombifiedCount(_zombified_count);
   405     event.commit();
   427     event.commit();
   406   }
   428   }
   407 
   429 
   408 #ifdef ASSERT
   430 #ifdef ASSERT
   409   if(PrintMethodFlushing) {
   431   if(PrintMethodFlushing) {
   410     tty->print_cr("### sweeper:      sweep time(%d): "
   432     tty->print_cr("### sweeper:      sweep time(%d): ", (jlong)sweep_time.value());
   411       INT64_FORMAT, _sweep_fractions_left, (jlong)sweep_time.value());
       
   412   }
   433   }
   413 #endif
   434 #endif
   414 
   435 
   415   if (_sweep_fractions_left == 1) {
   436   _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
   416     _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
   437   log_sweep("finished");
   417     log_sweep("finished");
       
   418   }
       
   419 
   438 
   420   // Sweeper is the only case where memory is released, check here if it
   439   // Sweeper is the only case where memory is released, check here if it
   421   // is time to restart the compiler. Only checking if there is a certain
   440   // is time to restart the compiler. Only checking if there is a certain
   422   // amount of free memory in the code cache might lead to re-enabling
   441   // amount of free memory in the code cache might lead to re-enabling
   423   // compilation although no memory has been released. For example, there are
   442   // compilation although no memory has been released. For example, there are
   457   }
   476   }
   458 }
   477 }
   459 
   478 
   460 class NMethodMarker: public StackObj {
   479 class NMethodMarker: public StackObj {
   461  private:
   480  private:
   462   CompilerThread* _thread;
   481   CodeCacheSweeperThread* _thread;
   463  public:
   482  public:
   464   NMethodMarker(nmethod* nm) {
   483   NMethodMarker(nmethod* nm) {
   465     _thread = CompilerThread::current();
   484     JavaThread* current = JavaThread::current();
       
   485     assert (current->is_Code_cache_sweeper_thread(), "Must be");
       
   486     _thread = (CodeCacheSweeperThread*)JavaThread::current();
   466     if (!nm->is_zombie() && !nm->is_unloaded()) {
   487     if (!nm->is_zombie() && !nm->is_unloaded()) {
   467       // Only expose live nmethods for scanning
   488       // Only expose live nmethods for scanning
   468       _thread->set_scanned_nmethod(nm);
   489       _thread->set_scanned_nmethod(nm);
   469     }
   490     }
   470   }
   491   }
   471   ~NMethodMarker() {
   492   ~NMethodMarker() {
   472     _thread->set_scanned_nmethod(NULL);
   493     _thread->set_scanned_nmethod(NULL);
   473   }
   494   }
   474 };
   495 };
   475 
   496 
   476 void NMethodSweeper::release_nmethod(nmethod *nm) {
   497 void NMethodSweeper::release_nmethod(nmethod* nm) {
   477   // Clean up any CompiledICHolders
   498   // Clean up any CompiledICHolders
   478   {
   499   {
   479     ResourceMark rm;
   500     ResourceMark rm;
   480     MutexLocker ml_patch(CompiledIC_lock);
   501     MutexLocker ml_patch(CompiledIC_lock);
   481     RelocIterator iter(nm);
   502     RelocIterator iter(nm);
   488 
   509 
   489   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   510   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   490   nm->flush();
   511   nm->flush();
   491 }
   512 }
   492 
   513 
   493 int NMethodSweeper::process_nmethod(nmethod *nm) {
   514 int NMethodSweeper::process_nmethod(nmethod* nm) {
   494   assert(!CodeCache_lock->owned_by_self(), "just checking");
   515   assert(!CodeCache_lock->owned_by_self(), "just checking");
   495 
   516 
   496   int freed_memory = 0;
   517   int freed_memory = 0;
   497   // Make sure this nmethod doesn't get unloaded during the scan,
   518   // Make sure this nmethod doesn't get unloaded during the scan,
   498   // since safepoints may happen during acquired below locks.
   519   // since safepoints may happen during acquired below locks.