hotspot/src/share/vm/runtime/sweeper.cpp
changeset 27917 c5937f7b4e8b
parent 27420 04e6f914cce1
child 28163 322d55d167be
equal deleted inserted replaced
27916:6db2a04e72b1 27917:c5937f7b4e8b
   140 long     NMethodSweeper::_traversals                   = 0;    // Stack scan count, also sweep ID.
   140 long     NMethodSweeper::_traversals                   = 0;    // Stack scan count, also sweep ID.
   141 long     NMethodSweeper::_total_nof_code_cache_sweeps  = 0;    // Total number of full sweeps of the code cache
   141 long     NMethodSweeper::_total_nof_code_cache_sweeps  = 0;    // Total number of full sweeps of the code cache
   142 long     NMethodSweeper::_time_counter                 = 0;    // Virtual time used to periodically invoke sweeper
   142 long     NMethodSweeper::_time_counter                 = 0;    // Virtual time used to periodically invoke sweeper
   143 long     NMethodSweeper::_last_sweep                   = 0;    // Value of _time_counter when the last sweep happened
   143 long     NMethodSweeper::_last_sweep                   = 0;    // Value of _time_counter when the last sweep happened
   144 int      NMethodSweeper::_seen                         = 0;    // Nof. nmethod we have currently processed in current pass of CodeCache
   144 int      NMethodSweeper::_seen                         = 0;    // Nof. nmethod we have currently processed in current pass of CodeCache
   145 int      NMethodSweeper::_flushed_count                = 0;    // Nof. nmethods flushed in current sweep
       
   146 int      NMethodSweeper::_zombified_count              = 0;    // Nof. nmethods made zombie in current sweep
       
   147 int      NMethodSweeper::_marked_for_reclamation_count = 0;    // Nof. nmethods marked for reclaim in current sweep
       
   148 
   145 
   149 volatile bool NMethodSweeper::_should_sweep            = true; // Indicates if we should invoke the sweeper
   146 volatile bool NMethodSweeper::_should_sweep            = true; // Indicates if we should invoke the sweeper
   150 volatile int  NMethodSweeper::_bytes_changed           = 0;    // Counts the total nmethod size if the nmethod changed from:
   147 volatile int  NMethodSweeper::_bytes_changed           = 0;    // Counts the total nmethod size if the nmethod changed from:
   151                                                                //   1) alive       -> not_entrant
   148                                                                //   1) alive       -> not_entrant
   152                                                                //   2) not_entrant -> zombie
   149                                                                //   2) not_entrant -> zombie
   159 Tickspan NMethodSweeper::_total_time_sweeping;                 // Accumulated time sweeping
   156 Tickspan NMethodSweeper::_total_time_sweeping;                 // Accumulated time sweeping
   160 Tickspan NMethodSweeper::_total_time_this_sweep;               // Total time this sweep
   157 Tickspan NMethodSweeper::_total_time_this_sweep;               // Total time this sweep
   161 Tickspan NMethodSweeper::_peak_sweep_time;                     // Peak time for a full sweep
   158 Tickspan NMethodSweeper::_peak_sweep_time;                     // Peak time for a full sweep
   162 Tickspan NMethodSweeper::_peak_sweep_fraction_time;            // Peak time sweeping one fraction
   159 Tickspan NMethodSweeper::_peak_sweep_fraction_time;            // Peak time sweeping one fraction
   163 
   160 
       
   161 Monitor* NMethodSweeper::_stat_lock = new Monitor(Mutex::special, "Sweeper::Statistics", true);
   164 
   162 
   165 class MarkActivationClosure: public CodeBlobClosure {
   163 class MarkActivationClosure: public CodeBlobClosure {
   166 public:
   164 public:
   167   virtual void do_code_blob(CodeBlob* cb) {
   165   virtual void do_code_blob(CodeBlob* cb) {
   168     assert(cb->is_nmethod(), "CodeBlob should be nmethod");
   166     assert(cb->is_nmethod(), "CodeBlob should be nmethod");
   368 
   366 
   369 void NMethodSweeper::sweep_code_cache() {
   367 void NMethodSweeper::sweep_code_cache() {
   370   ResourceMark rm;
   368   ResourceMark rm;
   371   Ticks sweep_start_counter = Ticks::now();
   369   Ticks sweep_start_counter = Ticks::now();
   372 
   370 
   373   _flushed_count                = 0;
   371   int flushed_count                = 0;
   374   _zombified_count              = 0;
   372   int zombified_count              = 0;
   375   _marked_for_reclamation_count = 0;
   373   int marked_for_reclamation_count = 0;
       
   374   int flushed_c2_count     = 0;
   376 
   375 
   377   if (PrintMethodFlushing && Verbose) {
   376   if (PrintMethodFlushing && Verbose) {
   378     tty->print_cr("### Sweep at %d out of %d", _seen, CodeCache::nof_nmethods());
   377     tty->print_cr("### Sweep at %d out of %d", _seen, CodeCache::nof_nmethods());
   379   }
   378   }
   380 
   379 
   384 
   383 
   385   int freed_memory = 0;
   384   int freed_memory = 0;
   386   {
   385   {
   387     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   386     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   388 
   387 
   389     // The last invocation iterates until there are no more nmethods
       
   390     while (!_current.end()) {
   388     while (!_current.end()) {
   391       swept_count++;
   389       swept_count++;
   392       handle_safepoint_request();
       
   393       // Since we will give up the CodeCache_lock, always skip ahead
   390       // Since we will give up the CodeCache_lock, always skip ahead
   394       // to the next nmethod.  Other blobs can be deleted by other
   391       // to the next nmethod.  Other blobs can be deleted by other
   395       // threads but nmethods are only reclaimed by the sweeper.
   392       // threads but nmethods are only reclaimed by the sweeper.
   396       nmethod* nm = _current.method();
   393       nmethod* nm = _current.method();
   397       _current.next();
   394       _current.next();
   398 
   395 
   399       // Now ready to process nmethod and give up CodeCache_lock
   396       // Now ready to process nmethod and give up CodeCache_lock
   400       {
   397       {
   401         MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   398         MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   402         freed_memory += process_nmethod(nm);
   399         int size = nm->total_size();
       
   400         bool is_c2_method = nm->is_compiled_by_c2();
       
   401 
       
   402         MethodStateChange type = process_nmethod(nm);
       
   403         switch (type) {
       
   404           case Flushed:
       
   405             freed_memory += size;
       
   406             ++flushed_count;
       
   407             if (is_c2_method) {
       
   408               ++flushed_c2_count;
       
   409             }
       
   410             break;
       
   411           case MarkedForReclamation:
       
   412             ++marked_for_reclamation_count;
       
   413             break;
       
   414           case MadeZombie:
       
   415             ++zombified_count;
       
   416             break;
       
   417           case None:
       
   418             break;
       
   419           default:
       
   420            ShouldNotReachHere();
       
   421         }
   403       }
   422       }
   404       _seen++;
   423       _seen++;
       
   424       handle_safepoint_request();
   405     }
   425     }
   406   }
   426   }
   407 
   427 
   408   assert(_current.end(), "must have scanned the whole cache");
   428   assert(_current.end(), "must have scanned the whole cache");
   409 
   429 
   410   const Ticks sweep_end_counter = Ticks::now();
   430   const Ticks sweep_end_counter = Ticks::now();
   411   const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
   431   const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
   412   _total_time_sweeping  += sweep_time;
   432   {
   413   _total_time_this_sweep += sweep_time;
   433     MutexLockerEx mu(_stat_lock, Mutex::_no_safepoint_check_flag);
   414   _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
   434     _total_time_sweeping  += sweep_time;
   415   _total_flushed_size += freed_memory;
   435     _total_time_this_sweep += sweep_time;
   416   _total_nof_methods_reclaimed += _flushed_count;
   436     _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
   417 
   437     _total_flushed_size += freed_memory;
       
   438     _total_nof_methods_reclaimed += flushed_count;
       
   439     _total_nof_c2_methods_reclaimed += flushed_c2_count;
       
   440     _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
       
   441   }
   418   EventSweepCodeCache event(UNTIMED);
   442   EventSweepCodeCache event(UNTIMED);
   419   if (event.should_commit()) {
   443   if (event.should_commit()) {
   420     event.set_starttime(sweep_start_counter);
   444     event.set_starttime(sweep_start_counter);
   421     event.set_endtime(sweep_end_counter);
   445     event.set_endtime(sweep_end_counter);
   422     event.set_sweepIndex(_traversals);
   446     event.set_sweepIndex(_traversals);
   423     event.set_sweptCount(swept_count);
   447     event.set_sweptCount(swept_count);
   424     event.set_flushedCount(_flushed_count);
   448     event.set_flushedCount(flushed_count);
   425     event.set_markedCount(_marked_for_reclamation_count);
   449     event.set_markedCount(marked_for_reclamation_count);
   426     event.set_zombifiedCount(_zombified_count);
   450     event.set_zombifiedCount(zombified_count);
   427     event.commit();
   451     event.commit();
   428   }
   452   }
   429 
   453 
   430 #ifdef ASSERT
   454 #ifdef ASSERT
   431   if(PrintMethodFlushing) {
   455   if(PrintMethodFlushing) {
   432     tty->print_cr("### sweeper:      sweep time(%d): ", (jlong)sweep_time.value());
   456     tty->print_cr("### sweeper:      sweep time(%d): ", (jlong)sweep_time.value());
   433   }
   457   }
   434 #endif
   458 #endif
   435 
   459 
   436   _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
       
   437   log_sweep("finished");
   460   log_sweep("finished");
   438 
   461 
   439   // Sweeper is the only case where memory is released, check here if it
   462   // Sweeper is the only case where memory is released, check here if it
   440   // is time to restart the compiler. Only checking if there is a certain
   463   // is time to restart the compiler. Only checking if there is a certain
   441   // amount of free memory in the code cache might lead to re-enabling
   464   // amount of free memory in the code cache might lead to re-enabling
   509 
   532 
   510   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   533   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   511   nm->flush();
   534   nm->flush();
   512 }
   535 }
   513 
   536 
   514 int NMethodSweeper::process_nmethod(nmethod* nm) {
   537 NMethodSweeper::MethodStateChange NMethodSweeper::process_nmethod(nmethod* nm) {
       
   538   assert(nm != NULL, "sanity");
   515   assert(!CodeCache_lock->owned_by_self(), "just checking");
   539   assert(!CodeCache_lock->owned_by_self(), "just checking");
   516 
   540 
   517   int freed_memory = 0;
   541   MethodStateChange result = None;
   518   // Make sure this nmethod doesn't get unloaded during the scan,
   542   // Make sure this nmethod doesn't get unloaded during the scan,
   519   // since safepoints may happen during acquired below locks.
   543   // since safepoints may happen during acquired below locks.
   520   NMethodMarker nmm(nm);
   544   NMethodMarker nmm(nm);
   521   SWEEP(nm);
   545   SWEEP(nm);
   522 
   546 
   527       // Clean inline caches that point to zombie/non-entrant methods
   551       // Clean inline caches that point to zombie/non-entrant methods
   528       MutexLocker cl(CompiledIC_lock);
   552       MutexLocker cl(CompiledIC_lock);
   529       nm->cleanup_inline_caches();
   553       nm->cleanup_inline_caches();
   530       SWEEP(nm);
   554       SWEEP(nm);
   531     }
   555     }
   532     return freed_memory;
   556     return result;
   533   }
   557   }
   534 
   558 
   535   if (nm->is_zombie()) {
   559   if (nm->is_zombie()) {
   536     // If it is the first time we see nmethod then we mark it. Otherwise,
   560     // If it is the first time we see nmethod then we mark it. Otherwise,
   537     // we reclaim it. When we have seen a zombie method twice, we know that
   561     // we reclaim it. When we have seen a zombie method twice, we know that
   539     if (nm->is_marked_for_reclamation()) {
   563     if (nm->is_marked_for_reclamation()) {
   540       assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
   564       assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
   541       if (PrintMethodFlushing && Verbose) {
   565       if (PrintMethodFlushing && Verbose) {
   542         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
   566         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
   543       }
   567       }
   544       freed_memory = nm->total_size();
       
   545       if (nm->is_compiled_by_c2()) {
       
   546         _total_nof_c2_methods_reclaimed++;
       
   547       }
       
   548       release_nmethod(nm);
   568       release_nmethod(nm);
   549       _flushed_count++;
   569       assert(result == None, "sanity");
       
   570       result = Flushed;
   550     } else {
   571     } else {
   551       if (PrintMethodFlushing && Verbose) {
   572       if (PrintMethodFlushing && Verbose) {
   552         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
   573         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
   553       }
   574       }
   554       nm->mark_for_reclamation();
   575       nm->mark_for_reclamation();
   555       // Keep track of code cache state change
   576       // Keep track of code cache state change
   556       _bytes_changed += nm->total_size();
   577       _bytes_changed += nm->total_size();
   557       _marked_for_reclamation_count++;
       
   558       SWEEP(nm);
   578       SWEEP(nm);
       
   579       assert(result == None, "sanity");
       
   580       result = MarkedForReclamation;
   559     }
   581     }
   560   } else if (nm->is_not_entrant()) {
   582   } else if (nm->is_not_entrant()) {
   561     // If there are no current activations of this method on the
   583     // If there are no current activations of this method on the
   562     // stack we can safely convert it to a zombie method
   584     // stack we can safely convert it to a zombie method
   563     if (nm->can_not_entrant_be_converted()) {
   585     if (nm->can_not_entrant_be_converted()) {
   574         if (PrintMethodFlushing && Verbose) {
   596         if (PrintMethodFlushing && Verbose) {
   575           tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
   597           tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
   576         }
   598         }
   577         // Code cache state change is tracked in make_zombie()
   599         // Code cache state change is tracked in make_zombie()
   578         nm->make_zombie();
   600         nm->make_zombie();
   579         _zombified_count++;
       
   580         SWEEP(nm);
   601         SWEEP(nm);
       
   602         assert(result == None, "sanity");
       
   603         result = MadeZombie;
   581       }
   604       }
   582       assert(nm->is_zombie(), "nmethod must be zombie");
   605       assert(nm->is_zombie(), "nmethod must be zombie");
   583     } else {
   606     } else {
   584       // Still alive, clean up its inline caches
   607       // Still alive, clean up its inline caches
   585       MutexLocker cl(CompiledIC_lock);
   608       MutexLocker cl(CompiledIC_lock);
   592       tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
   615       tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
   593     }
   616     }
   594     if (nm->is_osr_method()) {
   617     if (nm->is_osr_method()) {
   595       SWEEP(nm);
   618       SWEEP(nm);
   596       // No inline caches will ever point to osr methods, so we can just remove it
   619       // No inline caches will ever point to osr methods, so we can just remove it
   597       freed_memory = nm->total_size();
       
   598       if (nm->is_compiled_by_c2()) {
       
   599         _total_nof_c2_methods_reclaimed++;
       
   600       }
       
   601       release_nmethod(nm);
   620       release_nmethod(nm);
   602       _flushed_count++;
   621       assert(result == None, "sanity");
       
   622       result = Flushed;
   603     } else {
   623     } else {
   604       // Code cache state change is tracked in make_zombie()
   624       // Code cache state change is tracked in make_zombie()
   605       nm->make_zombie();
   625       nm->make_zombie();
   606       _zombified_count++;
       
   607       SWEEP(nm);
   626       SWEEP(nm);
       
   627       assert(result == None, "sanity");
       
   628       result = MadeZombie;
   608     }
   629     }
   609   } else {
   630   } else {
   610     possibly_flush(nm);
   631     possibly_flush(nm);
   611     // Clean-up all inline caches that point to zombie/non-reentrant methods
   632     // Clean-up all inline caches that point to zombie/non-reentrant methods
   612     MutexLocker cl(CompiledIC_lock);
   633     MutexLocker cl(CompiledIC_lock);
   613     nm->cleanup_inline_caches();
   634     nm->cleanup_inline_caches();
   614     SWEEP(nm);
   635     SWEEP(nm);
   615   }
   636   }
   616   return freed_memory;
   637   return result;
   617 }
   638 }
   618 
   639 
   619 
   640 
   620 void NMethodSweeper::possibly_flush(nmethod* nm) {
   641 void NMethodSweeper::possibly_flush(nmethod* nm) {
   621   if (UseCodeCacheFlushing) {
   642   if (UseCodeCacheFlushing) {