< prev index next >

src/share/vm/runtime/sweeper.cpp

Print this page




 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);
 133   }
 134 }
 135 #else
 136 #define SWEEP(nm)
 137 #endif
 138 
 139 NMethodIterator NMethodSweeper::_current;                      // Current nmethod
 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
 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
 144 int      NMethodSweeper::_seen                         = 0;    // Nof. nmethod we have currently processed in current pass of CodeCache
 145 
 146 volatile bool NMethodSweeper::_should_sweep            = true; // Indicates if we should invoke the sweeper

 147 volatile int  NMethodSweeper::_bytes_changed           = 0;    // Counts the total nmethod size if the nmethod changed from:
 148                                                                //   1) alive       -> not_entrant
 149                                                                //   2) not_entrant -> zombie
 150                                                                //   3) zombie      -> marked_for_reclamation
 151 int    NMethodSweeper::_hotness_counter_reset_val       = 0;
 152 
 153 long   NMethodSweeper::_total_nof_methods_reclaimed     = 0;   // Accumulated nof methods flushed
 154 long   NMethodSweeper::_total_nof_c2_methods_reclaimed  = 0;   // Accumulated nof methods flushed
 155 size_t NMethodSweeper::_total_flushed_size              = 0;   // Total number of bytes flushed from the code cache
 156 Tickspan NMethodSweeper::_total_time_sweeping;                 // Accumulated time sweeping
 157 Tickspan NMethodSweeper::_total_time_this_sweep;               // Total time this sweep
 158 Tickspan NMethodSweeper::_peak_sweep_time;                     // Peak time for a full sweep
 159 Tickspan NMethodSweeper::_peak_sweep_fraction_time;            // Peak time sweeping one fraction
 160 
 161 Monitor* NMethodSweeper::_stat_lock = new Monitor(Mutex::special, "Sweeper::Statistics", true, Monitor::_safepoint_check_sometimes);
 162 
 163 class MarkActivationClosure: public CodeBlobClosure {
 164 public:
 165   virtual void do_code_blob(CodeBlob* cb) {
 166     assert(cb->is_nmethod(), "CodeBlob should be nmethod");


 259     if (!timeout) {
 260       possibly_sweep();
 261     }
 262   }
 263 }
 264 
 265 /**
 266   * Wakes up the sweeper thread to possibly sweep.
 267   */
 268 void NMethodSweeper::notify(int code_blob_type) {
 269   // Makes sure that we do not invoke the sweeper too often during startup.
 270   double start_threshold = 100.0 / (double)StartAggressiveSweepingAt;
 271   double aggressive_sweep_threshold = MIN2(start_threshold, 1.1);
 272   if (CodeCache::reverse_free_ratio(code_blob_type) >= aggressive_sweep_threshold) {
 273     assert_locked_or_safepoint(CodeCache_lock);
 274     CodeCache_lock->notify();
 275   }
 276 }
 277 
 278 /**

















 279  * Handle a safepoint request
 280  */
 281 void NMethodSweeper::handle_safepoint_request() {
 282   if (SafepointSynchronize::is_synchronizing()) {
 283     if (PrintMethodFlushing && Verbose) {
 284       tty->print_cr("### Sweep at %d out of %d, yielding to safepoint", _seen, CodeCache::nof_nmethods());
 285     }
 286     MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
 287 
 288     JavaThread* thread = JavaThread::current();
 289     ThreadBlockInVM tbivm(thread);
 290     thread->java_suspend_self();
 291   }
 292 }
 293 
 294 /**
 295  * This function invokes the sweeper if at least one of the three conditions is met:
 296  *    (1) The code cache is getting full
 297  *    (2) There are sufficient state changes in/since the last sweep.
 298  *    (3) We have not been sweeping for 'some time'


 318   //                                              15 invocations of 'mark_active_nmethods.
 319   // Large ReservedCodeCacheSize:   (e.g., 256M + code Cache is 90% full). The formula
 320   //                                              computes: (256 / 16) - 10 = 6.
 321   if (!_should_sweep) {
 322     const int time_since_last_sweep = _time_counter - _last_sweep;
 323     // ReservedCodeCacheSize has an 'unsigned' type. We need a 'signed' type for max_wait_time,
 324     // since 'time_since_last_sweep' can be larger than 'max_wait_time'. If that happens using
 325     // an unsigned type would cause an underflow (wait_until_next_sweep becomes a large positive
 326     // value) that disables the intended periodic sweeps.
 327     const int max_wait_time = ReservedCodeCacheSize / (16 * M);
 328     double wait_until_next_sweep = max_wait_time - time_since_last_sweep -
 329         MAX2(CodeCache::reverse_free_ratio(CodeBlobType::MethodProfiled),
 330              CodeCache::reverse_free_ratio(CodeBlobType::MethodNonProfiled));
 331     assert(wait_until_next_sweep <= (double)max_wait_time, "Calculation of code cache sweeper interval is incorrect");
 332 
 333     if ((wait_until_next_sweep <= 0.0) || !CompileBroker::should_compile_new_jobs()) {
 334       _should_sweep = true;
 335     }
 336   }
 337 



 338   // Force stack scanning if there is only 10% free space in the code cache.
 339   // We force stack scanning only non-profiled code heap gets full, since critical
 340   // allocation go to the non-profiled heap and we must be make sure that there is
 341   // enough space.
 342   double free_percent = 1 / CodeCache::reverse_free_ratio(CodeBlobType::MethodNonProfiled) * 100;
 343   if (free_percent <= StartAggressiveSweepingAt) {
 344     do_stack_scanning();
 345   }
 346 
 347   if (_should_sweep) {
 348     init_sweeper_log();
 349     sweep_code_cache();
 350   }
 351 
 352   // We are done with sweeping the code cache once.
 353   _total_nof_code_cache_sweeps++;
 354   _last_sweep = _time_counter;
 355   // Reset flag; temporarily disables sweeper
 356   _should_sweep = false;
 357   // If there was enough state change, 'possibly_enable_sweeper()'
 358   // sets '_should_sweep' to true
 359    possibly_enable_sweeper();
 360   // Reset _bytes_changed only if there was enough state change. _bytes_changed
 361   // can further increase by calls to 'report_state_change'.
 362   if (_should_sweep) {
 363     _bytes_changed = 0;








 364   }
 365 }
 366 
 367 void NMethodSweeper::sweep_code_cache() {
 368   ResourceMark rm;
 369   Ticks sweep_start_counter = Ticks::now();
 370 
 371   int flushed_count                = 0;
 372   int zombified_count              = 0;
 373   int marked_for_reclamation_count = 0;
 374   int flushed_c2_count     = 0;
 375 
 376   if (PrintMethodFlushing && Verbose) {
 377     tty->print_cr("### Sweep at %d out of %d", _seen, CodeCache::nof_nmethods());
 378   }
 379 
 380   int swept_count = 0;
 381   assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
 382   assert(!CodeCache_lock->owned_by_self(), "just checking");
 383 




 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);
 133   }
 134 }
 135 #else
 136 #define SWEEP(nm)
 137 #endif
 138 
 139 NMethodIterator NMethodSweeper::_current;                      // Current nmethod
 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
 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
 144 int      NMethodSweeper::_seen                         = 0;    // Nof. nmethod we have currently processed in current pass of CodeCache
 145 
 146 volatile bool NMethodSweeper::_should_sweep            = true; // Indicates if we should invoke the sweeper
 147 volatile bool NMethodSweeper::_force_sweep             = false;// Indicates if we should force a sweep
 148 volatile int  NMethodSweeper::_bytes_changed           = 0;    // Counts the total nmethod size if the nmethod changed from:
 149                                                                //   1) alive       -> not_entrant
 150                                                                //   2) not_entrant -> zombie
 151                                                                //   3) zombie      -> marked_for_reclamation
 152 int    NMethodSweeper::_hotness_counter_reset_val       = 0;
 153 
 154 long   NMethodSweeper::_total_nof_methods_reclaimed     = 0;   // Accumulated nof methods flushed
 155 long   NMethodSweeper::_total_nof_c2_methods_reclaimed  = 0;   // Accumulated nof methods flushed
 156 size_t NMethodSweeper::_total_flushed_size              = 0;   // Total number of bytes flushed from the code cache
 157 Tickspan NMethodSweeper::_total_time_sweeping;                 // Accumulated time sweeping
 158 Tickspan NMethodSweeper::_total_time_this_sweep;               // Total time this sweep
 159 Tickspan NMethodSweeper::_peak_sweep_time;                     // Peak time for a full sweep
 160 Tickspan NMethodSweeper::_peak_sweep_fraction_time;            // Peak time sweeping one fraction
 161 
 162 Monitor* NMethodSweeper::_stat_lock = new Monitor(Mutex::special, "Sweeper::Statistics", true, Monitor::_safepoint_check_sometimes);
 163 
 164 class MarkActivationClosure: public CodeBlobClosure {
 165 public:
 166   virtual void do_code_blob(CodeBlob* cb) {
 167     assert(cb->is_nmethod(), "CodeBlob should be nmethod");


 260     if (!timeout) {
 261       possibly_sweep();
 262     }
 263   }
 264 }
 265 
 266 /**
 267   * Wakes up the sweeper thread to possibly sweep.
 268   */
 269 void NMethodSweeper::notify(int code_blob_type) {
 270   // Makes sure that we do not invoke the sweeper too often during startup.
 271   double start_threshold = 100.0 / (double)StartAggressiveSweepingAt;
 272   double aggressive_sweep_threshold = MIN2(start_threshold, 1.1);
 273   if (CodeCache::reverse_free_ratio(code_blob_type) >= aggressive_sweep_threshold) {
 274     assert_locked_or_safepoint(CodeCache_lock);
 275     CodeCache_lock->notify();
 276   }
 277 }
 278 
 279 /**
 280   * Wakes up the sweeper thread and forces a sweep. Blocks until it finished.
 281   */
 282 void NMethodSweeper::force_sweep() {
 283   ThreadBlockInVM tbivm(JavaThread::current());
 284   MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
 285   // Request forced sweep
 286   _force_sweep = true;
 287   while (_force_sweep) {
 288     // Notify sweeper that we want to force a sweep and wait for completion.
 289     // In case a sweep currently takes place we timeout and try again because
 290     // we want to enforce a full sweep.
 291     CodeCache_lock->notify();
 292     CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, 1000);
 293   }
 294 }
 295 
 296 /**
 297  * Handle a safepoint request
 298  */
 299 void NMethodSweeper::handle_safepoint_request() {
 300   if (SafepointSynchronize::is_synchronizing()) {
 301     if (PrintMethodFlushing && Verbose) {
 302       tty->print_cr("### Sweep at %d out of %d, yielding to safepoint", _seen, CodeCache::nof_nmethods());
 303     }
 304     MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
 305 
 306     JavaThread* thread = JavaThread::current();
 307     ThreadBlockInVM tbivm(thread);
 308     thread->java_suspend_self();
 309   }
 310 }
 311 
 312 /**
 313  * This function invokes the sweeper if at least one of the three conditions is met:
 314  *    (1) The code cache is getting full
 315  *    (2) There are sufficient state changes in/since the last sweep.
 316  *    (3) We have not been sweeping for 'some time'


 336   //                                              15 invocations of 'mark_active_nmethods.
 337   // Large ReservedCodeCacheSize:   (e.g., 256M + code Cache is 90% full). The formula
 338   //                                              computes: (256 / 16) - 10 = 6.
 339   if (!_should_sweep) {
 340     const int time_since_last_sweep = _time_counter - _last_sweep;
 341     // ReservedCodeCacheSize has an 'unsigned' type. We need a 'signed' type for max_wait_time,
 342     // since 'time_since_last_sweep' can be larger than 'max_wait_time'. If that happens using
 343     // an unsigned type would cause an underflow (wait_until_next_sweep becomes a large positive
 344     // value) that disables the intended periodic sweeps.
 345     const int max_wait_time = ReservedCodeCacheSize / (16 * M);
 346     double wait_until_next_sweep = max_wait_time - time_since_last_sweep -
 347         MAX2(CodeCache::reverse_free_ratio(CodeBlobType::MethodProfiled),
 348              CodeCache::reverse_free_ratio(CodeBlobType::MethodNonProfiled));
 349     assert(wait_until_next_sweep <= (double)max_wait_time, "Calculation of code cache sweeper interval is incorrect");
 350 
 351     if ((wait_until_next_sweep <= 0.0) || !CompileBroker::should_compile_new_jobs()) {
 352       _should_sweep = true;
 353     }
 354   }
 355 
 356   // Remember if this was a forced sweep
 357   bool forced = _force_sweep;
 358 
 359   // Force stack scanning if there is only 10% free space in the code cache.
 360   // We force stack scanning only non-profiled code heap gets full, since critical
 361   // allocation go to the non-profiled heap and we must be make sure that there is
 362   // enough space.
 363   double free_percent = 1 / CodeCache::reverse_free_ratio(CodeBlobType::MethodNonProfiled) * 100;
 364   if (free_percent <= StartAggressiveSweepingAt) {
 365     do_stack_scanning();
 366   }
 367 
 368   if (_should_sweep || forced) {
 369     init_sweeper_log();
 370     sweep_code_cache();
 371   }
 372 
 373   // We are done with sweeping the code cache once.
 374   _total_nof_code_cache_sweeps++;
 375   _last_sweep = _time_counter;
 376   // Reset flag; temporarily disables sweeper
 377   _should_sweep = false;
 378   // If there was enough state change, 'possibly_enable_sweeper()'
 379   // sets '_should_sweep' to true
 380   possibly_enable_sweeper();
 381   // Reset _bytes_changed only if there was enough state change. _bytes_changed
 382   // can further increase by calls to 'report_state_change'.
 383   if (_should_sweep) {
 384     _bytes_changed = 0;
 385   }
 386 
 387   if (forced) {
 388     // Notify requester that forced sweep finished
 389     assert(_force_sweep, "Should be a forced sweep");
 390     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
 391     _force_sweep = false;
 392     CodeCache_lock->notify();
 393   }
 394 }
 395 
 396 void NMethodSweeper::sweep_code_cache() {
 397   ResourceMark rm;
 398   Ticks sweep_start_counter = Ticks::now();
 399 
 400   int flushed_count                = 0;
 401   int zombified_count              = 0;
 402   int marked_for_reclamation_count = 0;
 403   int flushed_c2_count     = 0;
 404 
 405   if (PrintMethodFlushing && Verbose) {
 406     tty->print_cr("### Sweep at %d out of %d", _seen, CodeCache::nof_nmethods());
 407   }
 408 
 409   int swept_count = 0;
 410   assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
 411   assert(!CodeCache_lock->owned_by_self(), "just checking");
 412 


< prev index next >