< prev index next >

src/share/vm/runtime/sweeper.cpp

Print this page




  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  */
  24 
  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/orderAccess.inline.hpp"
  37 #include "runtime/os.hpp"
  38 #include "runtime/sweeper.hpp"
  39 #include "runtime/thread.inline.hpp"
  40 #include "runtime/vm_operations.hpp"
  41 #include "trace/tracing.hpp"
  42 #include "utilities/events.hpp"
  43 #include "utilities/ticks.inline.hpp"
  44 #include "utilities/xmlstream.hpp"
  45 
  46 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  47 
  48 #ifdef ASSERT
  49 
  50 #define SWEEP(nm) record_sweep(nm, __LINE__)
  51 // Sweeper logging code
  52 class SweeperRecord {
  53  public:
  54   int traversal;
  55   int invocation;
  56   int compile_id;
  57   long traversal_mark;
  58   int state;
  59   const char* kind;
  60   address vep;
  61   address uep;
  62   int line;
  63 


 301     // We are done with sweeping the code cache once.
 302     if (_sweep_fractions_left == 0) {
 303       _total_nof_code_cache_sweeps++;
 304       _last_sweep = _time_counter;
 305       // Reset flag; temporarily disables sweeper
 306       _should_sweep = false;
 307       // If there was enough state change, 'possibly_enable_sweeper()'
 308       // sets '_should_sweep' to true
 309       possibly_enable_sweeper();
 310       // Reset _bytes_changed only if there was enough state change. _bytes_changed
 311       // can further increase by calls to 'report_state_change'.
 312       if (_should_sweep) {
 313         _bytes_changed = 0;
 314       }
 315     }
 316     // Release work, because another compiler thread could continue.
 317     OrderAccess::release_store((int*)&_sweep_started, 0);
 318   }
 319 }
 320 


















 321 void NMethodSweeper::sweep_code_cache() {
 322   ResourceMark rm;
 323   Ticks sweep_start_counter = Ticks::now();
 324 
 325   _flushed_count                = 0;
 326   _zombified_count              = 0;
 327   _marked_for_reclamation_count = 0;
 328 
 329   if (PrintMethodFlushing && Verbose) {
 330     tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _sweep_fractions_left);
 331   }
 332 
 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


 377         MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
 378         freed_memory += process_nmethod(_current);
 379       }
 380       _seen++;
 381       _current = next;
 382     }
 383   }
 384 
 385   assert(_sweep_fractions_left > 1 || _current == NULL, "must have scanned the whole cache");
 386 
 387   const Ticks sweep_end_counter = Ticks::now();
 388   const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
 389   _total_time_sweeping  += sweep_time;
 390   _total_time_this_sweep += sweep_time;
 391   _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
 392   _total_flushed_size += freed_memory;
 393   _total_nof_methods_reclaimed += _flushed_count;
 394 
 395   EventSweepCodeCache event(UNTIMED);
 396   if (event.should_commit()) {
 397     event.set_starttime(sweep_start_counter);
 398     event.set_endtime(sweep_end_counter);
 399     event.set_sweepIndex(_traversals);
 400     event.set_sweepFractionIndex(NmethodSweepFraction - _sweep_fractions_left + 1);
 401     event.set_sweptCount(swept_count);
 402     event.set_flushedCount(_flushed_count);
 403     event.set_markedCount(_marked_for_reclamation_count);
 404     event.set_zombifiedCount(_zombified_count);
 405     event.commit();
 406   }
 407 
 408 #ifdef ASSERT
 409   if(PrintMethodFlushing) {
 410     tty->print_cr("### sweeper:      sweep time(%d): "
 411       INT64_FORMAT, _sweep_fractions_left, (jlong)sweep_time.value());
 412   }
 413 #endif
 414 
 415   if (_sweep_fractions_left == 1) {
 416     _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
 417     log_sweep("finished");
 418   }
 419 
 420   // 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
 422   // 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
 424   // cases when compilation was disabled although there is 4MB (or more) free
 425   // memory in the code cache. The reason is code cache fragmentation. Therefore,




  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  */
  24 
  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 "jfr/jfrEvents.hpp"
  32 #include "memory/resourceArea.hpp"
  33 #include "oops/method.hpp"
  34 #include "runtime/atomic.hpp"
  35 #include "runtime/compilationPolicy.hpp"
  36 #include "runtime/mutexLocker.hpp"
  37 #include "runtime/orderAccess.inline.hpp"
  38 #include "runtime/os.hpp"
  39 #include "runtime/sweeper.hpp"
  40 #include "runtime/thread.inline.hpp"
  41 #include "runtime/vm_operations.hpp"

  42 #include "utilities/events.hpp"
  43 #include "utilities/ticks.hpp"
  44 #include "utilities/xmlstream.hpp"
  45 
  46 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  47 
  48 #ifdef ASSERT
  49 
  50 #define SWEEP(nm) record_sweep(nm, __LINE__)
  51 // Sweeper logging code
  52 class SweeperRecord {
  53  public:
  54   int traversal;
  55   int invocation;
  56   int compile_id;
  57   long traversal_mark;
  58   int state;
  59   const char* kind;
  60   address vep;
  61   address uep;
  62   int line;
  63 


 301     // We are done with sweeping the code cache once.
 302     if (_sweep_fractions_left == 0) {
 303       _total_nof_code_cache_sweeps++;
 304       _last_sweep = _time_counter;
 305       // Reset flag; temporarily disables sweeper
 306       _should_sweep = false;
 307       // If there was enough state change, 'possibly_enable_sweeper()'
 308       // sets '_should_sweep' to true
 309       possibly_enable_sweeper();
 310       // Reset _bytes_changed only if there was enough state change. _bytes_changed
 311       // can further increase by calls to 'report_state_change'.
 312       if (_should_sweep) {
 313         _bytes_changed = 0;
 314       }
 315     }
 316     // Release work, because another compiler thread could continue.
 317     OrderAccess::release_store((int*)&_sweep_started, 0);
 318   }
 319 }
 320 
 321 static void post_sweep_event(EventSweepCodeCache* event,
 322                              const Ticks& start,
 323                              const Ticks& end,
 324                              s4 traversals,
 325                              int swept,
 326                              int flushed,
 327                              int zombified) {
 328   assert(event != NULL, "invariant");
 329   assert(event->should_commit(), "invariant");
 330   event->set_starttime(start);
 331   event->set_endtime(end);
 332   event->set_sweepId(traversals);
 333   event->set_sweptCount(swept);
 334   event->set_flushedCount(flushed);
 335   event->set_zombifiedCount(zombified);
 336   event->commit();
 337 }
 338 
 339 void NMethodSweeper::sweep_code_cache() {
 340   ResourceMark rm;
 341   Ticks sweep_start_counter = Ticks::now();
 342 
 343   _flushed_count                = 0;
 344   _zombified_count              = 0;
 345   _marked_for_reclamation_count = 0;
 346 
 347   if (PrintMethodFlushing && Verbose) {
 348     tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _sweep_fractions_left);
 349   }
 350 
 351   if (!CompileBroker::should_compile_new_jobs()) {
 352     // If we have turned off compilations we might as well do full sweeps
 353     // in order to reach the clean state faster. Otherwise the sleeping compiler
 354     // threads will slow down sweeping.
 355     _sweep_fractions_left = 1;
 356   }
 357 
 358   // We want to visit all nmethods after NmethodSweepFraction


 395         MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
 396         freed_memory += process_nmethod(_current);
 397       }
 398       _seen++;
 399       _current = next;
 400     }
 401   }
 402 
 403   assert(_sweep_fractions_left > 1 || _current == NULL, "must have scanned the whole cache");
 404 
 405   const Ticks sweep_end_counter = Ticks::now();
 406   const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
 407   _total_time_sweeping  += sweep_time;
 408   _total_time_this_sweep += sweep_time;
 409   _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
 410   _total_flushed_size += freed_memory;
 411   _total_nof_methods_reclaimed += _flushed_count;
 412 
 413   EventSweepCodeCache event(UNTIMED);
 414   if (event.should_commit()) {
 415     post_sweep_event(&event, sweep_start_counter, sweep_end_counter, (s4)_traversals, swept_count, _flushed_count, _zombified_count);








 416   }
 417 
 418 #ifdef ASSERT
 419   if(PrintMethodFlushing) {
 420     tty->print_cr("### sweeper:      sweep time(%d): "
 421       INT64_FORMAT, _sweep_fractions_left, (jlong)sweep_time.value());
 422   }
 423 #endif
 424 
 425   if (_sweep_fractions_left == 1) {
 426     _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
 427     log_sweep("finished");
 428   }
 429 
 430   // Sweeper is the only case where memory is released, check here if it
 431   // is time to restart the compiler. Only checking if there is a certain
 432   // amount of free memory in the code cache might lead to re-enabling
 433   // compilation although no memory has been released. For example, there are
 434   // cases when compilation was disabled although there is 4MB (or more) free
 435   // memory in the code cache. The reason is code cache fragmentation. Therefore,


< prev index next >