1 /*
  2  * Copyright (c) 1997, 2021, 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  */
 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 "gc/shared/collectedHeap.hpp"
 32 #include "gc/shared/workgroup.hpp"
 33 #include "jfr/jfrEvents.hpp"
 34 #include "logging/log.hpp"
 35 #include "logging/logStream.hpp"
 36 #include "memory/allocation.inline.hpp"
 37 #include "memory/resourceArea.hpp"
 38 #include "memory/universe.hpp"
 39 #include "oops/method.hpp"
 40 #include "runtime/interfaceSupport.inline.hpp"
 41 #include "runtime/handshake.hpp"
 42 #include "runtime/mutexLocker.hpp"
 43 #include "runtime/orderAccess.hpp"
 44 #include "runtime/os.hpp"
 45 #include "runtime/sweeper.hpp"
 46 #include "runtime/thread.inline.hpp"
 47 #include "runtime/vmOperations.hpp"
 48 #include "runtime/vmThread.hpp"
 49 #include "utilities/events.hpp"
 50 #include "utilities/xmlstream.hpp"
 51 
 52 #ifdef ASSERT
 53 
 54 #define SWEEP(nm) record_sweep(nm, __LINE__)
 55 // Sweeper logging code
 56 class SweeperRecord {
 57  public:
 58   int traversal;
 59   int compile_id;
 60   long traversal_mark;
 61   int state;
 62   const char* kind;
 63   address vep;
 64   address uep;
 65   int line;
 66 
 67   void print() {
 68       tty->print_cr("traversal = %d compile_id = %d %s uep = " PTR_FORMAT " vep = "
 69                     PTR_FORMAT " state = %d traversal_mark %ld line = %d",
 70                     traversal,
 71                     compile_id,
 72                     kind == NULL ? "" : kind,
 73                     p2i(uep),
 74                     p2i(vep),
 75                     state,
 76                     traversal_mark,
 77                     line);
 78   }
 79 };
 80 
 81 static int _sweep_index = 0;
 82 static SweeperRecord* _records = NULL;
 83 
 84 void NMethodSweeper::record_sweep(CompiledMethod* nm, int line) {
 85   if (_records != NULL) {
 86     _records[_sweep_index].traversal = _traversals;
 87     _records[_sweep_index].traversal_mark = nm->is_nmethod() ? ((nmethod*)nm)->stack_traversal_mark() : 0;
 88     _records[_sweep_index].compile_id = nm->compile_id();
 89     _records[_sweep_index].kind = nm->compile_kind();
 90     _records[_sweep_index].state = nm->get_state();
 91     _records[_sweep_index].vep = nm->verified_entry_point();
 92     _records[_sweep_index].uep = nm->entry_point();
 93     _records[_sweep_index].line = line;
 94     _sweep_index = (_sweep_index + 1) % SweeperLogEntries;
 95   }
 96 }
 97 
 98 void NMethodSweeper::init_sweeper_log() {
 99  if (LogSweeper && _records == NULL) {
100    // Create the ring buffer for the logging code
101    _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC);
102    memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries);
103   }
104 }
105 #else
106 #define SWEEP(nm)
107 #endif
108 
109 CompiledMethodIterator NMethodSweeper::_current(CompiledMethodIterator::all_blobs); // Current compiled method
110 long     NMethodSweeper::_traversals                   = 0;    // Stack scan count, also sweep ID.
111 long     NMethodSweeper::_total_nof_code_cache_sweeps  = 0;    // Total number of full sweeps of the code cache
112 int      NMethodSweeper::_seen                         = 0;    // Nof. nmethod we have currently processed in current pass of CodeCache
113 size_t   NMethodSweeper::_sweep_threshold_bytes        = 0;    // Threshold for when to sweep. Updated after ergonomics
114 
115 volatile bool NMethodSweeper::_should_sweep            = false;// Indicates if a normal sweep will be done
116 volatile bool NMethodSweeper::_force_sweep             = false;// Indicates if a forced sweep will be done
117 volatile size_t NMethodSweeper::_bytes_changed         = 0;    // Counts the total nmethod size if the nmethod changed from:
118                                                                //   1) alive       -> not_entrant
119                                                                //   2) not_entrant -> zombie
120 int    NMethodSweeper::_hotness_counter_reset_val       = 0;
121 
122 long   NMethodSweeper::_total_nof_methods_reclaimed     = 0;   // Accumulated nof methods flushed
123 long   NMethodSweeper::_total_nof_c2_methods_reclaimed  = 0;   // Accumulated nof methods flushed
124 size_t NMethodSweeper::_total_flushed_size              = 0;   // Total number of bytes flushed from the code cache
125 Tickspan NMethodSweeper::_total_time_sweeping;                 // Accumulated time sweeping
126 Tickspan NMethodSweeper::_total_time_this_sweep;               // Total time this sweep
127 Tickspan NMethodSweeper::_peak_sweep_time;                     // Peak time for a full sweep
128 Tickspan NMethodSweeper::_peak_sweep_fraction_time;            // Peak time sweeping one fraction
129 
130 class MarkActivationClosure: public CodeBlobClosure {
131 public:
132   virtual void do_code_blob(CodeBlob* cb) {
133     assert(cb->is_nmethod(), "CodeBlob should be nmethod");
134     nmethod* nm = (nmethod*)cb;
135     nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
136     // If we see an activation belonging to a non_entrant nmethod, we mark it.
137     if (nm->is_not_entrant()) {
138       nm->mark_as_seen_on_stack();
139     }
140   }
141 };
142 static MarkActivationClosure mark_activation_closure;
143 
144 int NMethodSweeper::hotness_counter_reset_val() {
145   if (_hotness_counter_reset_val == 0) {
146     _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
147   }
148   return _hotness_counter_reset_val;
149 }
150 bool NMethodSweeper::wait_for_stack_scanning() {
151   return _current.end();
152 }
153 
154 class NMethodMarkingClosure : public HandshakeClosure {
155 private:
156   CodeBlobClosure* _cl;
157 public:
158   NMethodMarkingClosure(CodeBlobClosure* cl) : HandshakeClosure("NMethodMarking"), _cl(cl) {}
159   void do_thread(Thread* thread) {
160     if (thread->is_Java_thread() && ! thread->is_Code_cache_sweeper_thread()) {
161       JavaThread::cast(thread)->nmethods_do(_cl);
162     }
163   }
164 };
165 
166 CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
167 #ifdef ASSERT
168   assert(Thread::current()->is_Code_cache_sweeper_thread(), "must be executed under CodeCache_lock and in sweeper thread");
169   assert_lock_strong(CodeCache_lock);
170 #endif
171 
172   // If we do not want to reclaim not-entrant or zombie methods there is no need
173   // to scan stacks
174   if (!MethodFlushing) {
175     return NULL;
176   }
177 
178   // Check for restart
179   assert(_current.method() == NULL, "should only happen between sweeper cycles");
180   assert(wait_for_stack_scanning(), "should only happen between sweeper cycles");
181 
182   _seen = 0;
183   _current = CompiledMethodIterator(CompiledMethodIterator::all_blobs);
184   // Initialize to first nmethod
185   _current.next();
186   _traversals += 1;
187   _total_time_this_sweep = Tickspan();
188 
189   if (PrintMethodFlushing) {
190     tty->print_cr("### Sweep: stack traversal %ld", _traversals);
191   }
192   return &mark_activation_closure;
193 }
194 
195 /**
196   * This function triggers a VM operation that does stack scanning of active
197   * methods. Stack scanning is mandatory for the sweeper to make progress.
198   */
199 void NMethodSweeper::do_stack_scanning() {
200   assert(!CodeCache_lock->owned_by_self(), "just checking");
201   if (wait_for_stack_scanning()) {
202     CodeBlobClosure* code_cl;
203     {
204       MutexLocker ccl(CodeCache_lock, Mutex::_no_safepoint_check_flag);
205       code_cl = prepare_mark_active_nmethods();
206     }
207     if (code_cl != NULL) {
208       NMethodMarkingClosure nm_cl(code_cl);
209       Handshake::execute(&nm_cl);
210     }
211   }
212 }
213 
214 void NMethodSweeper::sweeper_loop() {
215   bool timeout;
216   while (true) {
217     {
218       ThreadBlockInVM tbivm(JavaThread::current());
219       MonitorLocker waiter(CodeSweeper_lock, Mutex::_no_safepoint_check_flag);
220       const long wait_time = 60*60*24 * 1000;
221       timeout = waiter.wait(wait_time);
222     }
223     if (!timeout && (_should_sweep || _force_sweep)) {
224       sweep();
225     }
226   }
227 }
228 
229 /**
230   * Wakes up the sweeper thread to sweep if code cache space runs low
231   */
232 void NMethodSweeper::report_allocation(int code_blob_type) {
233   if (should_start_aggressive_sweep(code_blob_type)) {
234     MonitorLocker waiter(CodeSweeper_lock, Mutex::_no_safepoint_check_flag);
235     _should_sweep = true;
236     CodeSweeper_lock->notify();
237   }
238 }
239 
240 bool NMethodSweeper::should_start_aggressive_sweep(int code_blob_type) {
241   // Makes sure that we do not invoke the sweeper too often during startup.
242   double start_threshold = 100.0 / (double)StartAggressiveSweepingAt;
243   double aggressive_sweep_threshold = MAX2(start_threshold, 1.1);
244   return (CodeCache::reverse_free_ratio(code_blob_type) >= aggressive_sweep_threshold);
245 }
246 
247 /**
248   * Wakes up the sweeper thread and forces a sweep. Blocks until it finished.
249   */
250 void NMethodSweeper::force_sweep() {
251   ThreadBlockInVM tbivm(JavaThread::current());
252   MonitorLocker waiter(CodeSweeper_lock, Mutex::_no_safepoint_check_flag);
253   // Request forced sweep
254   _force_sweep = true;
255   while (_force_sweep) {
256     // Notify sweeper that we want to force a sweep and wait for completion.
257     // In case a sweep currently takes place we timeout and try again because
258     // we want to enforce a full sweep.
259     CodeSweeper_lock->notify();
260     waiter.wait(1000);
261   }
262 }
263 
264 /**
265  * Handle a safepoint request
266  */
267 void NMethodSweeper::handle_safepoint_request() {
268   JavaThread* thread = JavaThread::current();
269   if (SafepointMechanism::should_process(thread)) {
270     if (PrintMethodFlushing && Verbose) {
271       tty->print_cr("### Sweep at %d out of %d, yielding to safepoint", _seen, CodeCache::nmethod_count());
272     }
273     MutexUnlocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
274 
275     ThreadBlockInVM tbivm(thread);
276   }
277 }
278 
279 void NMethodSweeper::sweep() {
280   assert(_should_sweep || _force_sweep, "must have been set");
281   assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode");
282   Atomic::store(&_bytes_changed, static_cast<size_t>(0)); // reset regardless of sleep reason
283   if (_should_sweep) {
284     MutexLocker mu(CodeSweeper_lock, Mutex::_no_safepoint_check_flag);
285     _should_sweep = false;
286   }
287 
288   do_stack_scanning();
289 
290   init_sweeper_log();
291   sweep_code_cache();
292 
293   // We are done with sweeping the code cache once.
294   _total_nof_code_cache_sweeps++;
295 
296   if (_force_sweep) {
297     // Notify requester that forced sweep finished
298     MutexLocker mu(CodeSweeper_lock, Mutex::_no_safepoint_check_flag);
299     _force_sweep = false;
300     CodeSweeper_lock->notify();
301   }
302 }
303 
304 static void post_sweep_event(EventSweepCodeCache* event,
305                              const Ticks& start,
306                              const Ticks& end,
307                              s4 traversals,
308                              int swept,
309                              int flushed,
310                              int zombified) {
311   assert(event != NULL, "invariant");
312   assert(event->should_commit(), "invariant");
313   event->set_starttime(start);
314   event->set_endtime(end);
315   event->set_sweepId(traversals);
316   event->set_sweptCount(swept);
317   event->set_flushedCount(flushed);
318   event->set_zombifiedCount(zombified);
319   event->commit();
320 }
321 
322 void NMethodSweeper::sweep_code_cache() {
323   ResourceMark rm;
324   Ticks sweep_start_counter = Ticks::now();
325 
326   log_debug(codecache, sweep, start)("CodeCache flushing");
327 
328   int flushed_count                = 0;
329   int zombified_count              = 0;
330   int flushed_c2_count     = 0;
331 
332   if (PrintMethodFlushing && Verbose) {
333     tty->print_cr("### Sweep at %d out of %d", _seen, CodeCache::nmethod_count());
334   }
335 
336   int swept_count = 0;
337   assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
338   assert(!CodeCache_lock->owned_by_self(), "just checking");
339 
340   int freed_memory = 0;
341   {
342     MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
343 
344     while (!_current.end()) {
345       swept_count++;
346       // Since we will give up the CodeCache_lock, always skip ahead
347       // to the next nmethod.  Other blobs can be deleted by other
348       // threads but nmethods are only reclaimed by the sweeper.
349       CompiledMethod* nm = _current.method();
350       _current.next();
351 
352       // Now ready to process nmethod and give up CodeCache_lock
353       {
354         MutexUnlocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
355         // Save information before potentially flushing the nmethod
356         // Only flushing nmethods so size only matters for them.
357         int size = nm->is_nmethod() ? ((nmethod*)nm)->total_size() : 0;
358         bool is_c2_method = nm->is_compiled_by_c2();
359         bool is_osr = nm->is_osr_method();
360         int compile_id = nm->compile_id();
361         intptr_t address = p2i(nm);
362         const char* state_before = nm->state();
363         const char* state_after = "";
364 
365         MethodStateChange type = process_compiled_method(nm);
366         switch (type) {
367           case Flushed:
368             state_after = "flushed";
369             freed_memory += size;
370             ++flushed_count;
371             if (is_c2_method) {
372               ++flushed_c2_count;
373             }
374             break;
375           case MadeZombie:
376             state_after = "made zombie";
377             ++zombified_count;
378             break;
379           case None:
380             break;
381           default:
382            ShouldNotReachHere();
383         }
384         if (PrintMethodFlushing && Verbose && type != None) {
385           tty->print_cr("### %s nmethod %3d/" PTR_FORMAT " (%s) %s", is_osr ? "osr" : "", compile_id, address, state_before, state_after);
386         }
387       }
388 
389       _seen++;
390       handle_safepoint_request();
391     }
392   }
393 
394   assert(_current.end(), "must have scanned the whole cache");
395 
396   const Ticks sweep_end_counter = Ticks::now();
397   const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
398   {
399     MutexLocker mu(NMethodSweeperStats_lock, Mutex::_no_safepoint_check_flag);
400     _total_time_sweeping  += sweep_time;
401     _total_time_this_sweep += sweep_time;
402     _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
403     _total_flushed_size += freed_memory;
404     _total_nof_methods_reclaimed += flushed_count;
405     _total_nof_c2_methods_reclaimed += flushed_c2_count;
406     _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
407   }
408 
409   EventSweepCodeCache event(UNTIMED);
410   if (event.should_commit()) {
411     post_sweep_event(&event, sweep_start_counter, sweep_end_counter, (s4)_traversals, swept_count, flushed_count, zombified_count);
412   }
413 
414 #ifdef ASSERT
415   if(PrintMethodFlushing) {
416     tty->print_cr("### sweeper:      sweep time(" JLONG_FORMAT "): ", sweep_time.value());
417   }
418 #endif
419 
420   Log(codecache, sweep) log;
421   if (log.is_debug()) {
422     LogStream ls(log.debug());
423     CodeCache::print_summary(&ls, false);
424   }
425   log_sweep("finished");
426 
427   // Sweeper is the only case where memory is released, check here if it
428   // is time to restart the compiler. Only checking if there is a certain
429   // amount of free memory in the code cache might lead to re-enabling
430   // compilation although no memory has been released. For example, there are
431   // cases when compilation was disabled although there is 4MB (or more) free
432   // memory in the code cache. The reason is code cache fragmentation. Therefore,
433   // it only makes sense to re-enable compilation if we have actually freed memory.
434   // Note that typically several kB are released for sweeping 16MB of the code
435   // cache. As a result, 'freed_memory' > 0 to restart the compiler.
436   if (!CompileBroker::should_compile_new_jobs() && (freed_memory > 0)) {
437     CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
438     log.debug("restart compiler");
439     log_sweep("restart_compiler");
440   }
441 }
442 
443  // This function updates the sweeper statistics that keep track of nmethods
444  // state changes. If there is 'enough' state change, the sweeper is invoked
445  // as soon as possible. Also, we are guaranteed to invoke the sweeper if
446  // the code cache gets full.
447 void NMethodSweeper::report_state_change(nmethod* nm) {
448   Atomic::add(&_bytes_changed, (size_t)nm->total_size());
449   if (Atomic::load(&_bytes_changed) > _sweep_threshold_bytes) {
450     MutexLocker mu(CodeSweeper_lock, Mutex::_no_safepoint_check_flag);
451     _should_sweep = true;
452     CodeSweeper_lock->notify(); // Wake up sweeper.
453   }
454 }
455 
456 class CompiledMethodMarker: public StackObj {
457  private:
458   CodeCacheSweeperThread* _thread;
459  public:
460   CompiledMethodMarker(CompiledMethod* cm) {
461     JavaThread* current = JavaThread::current();
462     assert (current->is_Code_cache_sweeper_thread(), "Must be");
463     _thread = (CodeCacheSweeperThread*)current;
464     if (!cm->is_zombie() && !cm->is_unloading()) {
465       // Only expose live nmethods for scanning
466       _thread->set_scanned_compiled_method(cm);
467     }
468   }
469   ~CompiledMethodMarker() {
470     _thread->set_scanned_compiled_method(NULL);
471   }
472 };
473 
474 NMethodSweeper::MethodStateChange NMethodSweeper::process_compiled_method(CompiledMethod* cm) {
475   assert(cm != NULL, "sanity");
476   assert(!CodeCache_lock->owned_by_self(), "just checking");
477 
478   MethodStateChange result = None;
479   // Make sure this nmethod doesn't get unloaded during the scan,
480   // since safepoints may happen during acquired below locks.
481   CompiledMethodMarker nmm(cm);
482   SWEEP(cm);
483 
484   // Skip methods that are currently referenced by the VM
485   if (cm->is_locked_by_vm()) {
486     // But still remember to clean-up inline caches for alive nmethods
487     if (cm->is_alive()) {
488       // Clean inline caches that point to zombie/non-entrant/unloaded nmethods
489       cm->cleanup_inline_caches(false);
490       SWEEP(cm);
491     }
492     return result;
493   }
494 
495   if (cm->is_zombie()) {
496     // All inline caches that referred to this nmethod were cleaned in the
497     // previous sweeper cycle. Now flush the nmethod from the code cache.
498     assert(!cm->is_locked_by_vm(), "must not flush locked Compiled Methods");
499     cm->flush();
500     assert(result == None, "sanity");
501     result = Flushed;
502   } else if (cm->is_not_entrant()) {
503     // If there are no current activations of this method on the
504     // stack we can safely convert it to a zombie method
505     OrderAccess::loadload(); // _stack_traversal_mark and _state
506     if (cm->can_convert_to_zombie()) {
507       // Code cache state change is tracked in make_zombie()
508       cm->make_zombie();
509       SWEEP(cm);
510       assert(result == None, "sanity");
511       result = MadeZombie;
512       assert(cm->is_zombie(), "nmethod must be zombie");
513     } else {
514       // Still alive, clean up its inline caches
515       cm->cleanup_inline_caches(false);
516       SWEEP(cm);
517     }
518   } else if (cm->is_unloaded()) {
519     // Code is unloaded, so there are no activations on the stack.
520     // Convert the nmethod to zombie.
521     // Code cache state change is tracked in make_zombie()
522     cm->make_zombie();
523     SWEEP(cm);
524     assert(result == None, "sanity");
525     result = MadeZombie;
526   } else {
527     if (cm->is_nmethod()) {
528       possibly_flush((nmethod*)cm);
529     }
530     // Clean inline caches that point to zombie/non-entrant/unloaded nmethods
531     cm->cleanup_inline_caches(false);
532     SWEEP(cm);
533   }
534   return result;
535 }
536 
537 
538 void NMethodSweeper::possibly_flush(nmethod* nm) {
539   if (UseCodeCacheFlushing) {
540     if (!nm->is_locked_by_vm() && !nm->is_native_method() && !nm->is_not_installed() && !nm->is_unloading()) {
541       bool make_not_entrant = false;
542 
543       // Do not make native methods not-entrant
544       nm->dec_hotness_counter();
545       // Get the initial value of the hotness counter. This value depends on the
546       // ReservedCodeCacheSize
547       int reset_val = hotness_counter_reset_val();
548       int time_since_reset = reset_val - nm->hotness_counter();
549       int code_blob_type = CodeCache::get_code_blob_type(nm);
550       double threshold = -reset_val + (CodeCache::reverse_free_ratio(code_blob_type) * NmethodSweepActivity);
551       // The less free space in the code cache we have - the bigger reverse_free_ratio() is.
552       // I.e., 'threshold' increases with lower available space in the code cache and a higher
553       // NmethodSweepActivity. If the current hotness counter - which decreases from its initial
554       // value until it is reset by stack walking - is smaller than the computed threshold, the
555       // corresponding nmethod is considered for removal.
556       if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > MinPassesBeforeFlush)) {
557         // A method is marked as not-entrant if the method is
558         // 1) 'old enough': nm->hotness_counter() < threshold
559         // 2) The method was in_use for a minimum amount of time: (time_since_reset > MinPassesBeforeFlush)
560         //    The second condition is necessary if we are dealing with very small code cache
561         //    sizes (e.g., <10m) and the code cache size is too small to hold all hot methods.
562         //    The second condition ensures that methods are not immediately made not-entrant
563         //    after compilation.
564         make_not_entrant = true;
565       }
566 
567       // The stack-scanning low-cost detection may not see the method was used (which can happen for
568       // flat profiles). Check the age counter for possible data.
569       if (UseCodeAging && make_not_entrant && (nm->is_compiled_by_c2() || nm->is_compiled_by_c1())) {
570         MethodCounters* mc = nm->method()->get_method_counters(Thread::current());
571         if (mc != NULL) {
572           // Snapshot the value as it's changed concurrently
573           int age = mc->nmethod_age();
574           if (MethodCounters::is_nmethod_hot(age)) {
575             // The method has gone through flushing, and it became relatively hot that it deopted
576             // before we could take a look at it. Give it more time to appear in the stack traces,
577             // proportional to the number of deopts.
578             MethodData* md = nm->method()->method_data();
579             if (md != NULL && time_since_reset > (int)(MinPassesBeforeFlush * (md->tenure_traps() + 1))) {
580               // It's been long enough, we still haven't seen it on stack.
581               // Try to flush it, but enable counters the next time.
582               mc->reset_nmethod_age();
583             } else {
584               make_not_entrant = false;
585             }
586           } else if (MethodCounters::is_nmethod_warm(age)) {
587             // Method has counters enabled, and the method was used within
588             // previous MinPassesBeforeFlush sweeps. Reset the counter. Stay in the existing
589             // compiled state.
590             mc->reset_nmethod_age();
591             // delay the next check
592             nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
593             make_not_entrant = false;
594           } else if (MethodCounters::is_nmethod_age_unset(age)) {
595             // No counters were used before. Set the counters to the detection
596             // limit value. If the method is going to be used again it will be compiled
597             // with counters that we're going to use for analysis the the next time.
598             mc->reset_nmethod_age();
599           } else {
600             // Method was totally idle for 10 sweeps
601             // The counter already has the initial value, flush it and may be recompile
602             // later with counters
603           }
604         }
605       }
606 
607       if (make_not_entrant) {
608         nm->make_not_entrant();
609 
610         // Code cache state change is tracked in make_not_entrant()
611         if (PrintMethodFlushing && Verbose) {
612           tty->print_cr("### Nmethod %d/" PTR_FORMAT "made not-entrant: hotness counter %d/%d threshold %f",
613               nm->compile_id(), p2i(nm), nm->hotness_counter(), reset_val, threshold);
614         }
615       }
616     }
617   }
618 }
619 
620 // Print out some state information about the current sweep and the
621 // state of the code cache if it's requested.
622 void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
623   if (PrintMethodFlushing) {
624     ResourceMark rm;
625     stringStream s;
626     // Dump code cache state into a buffer before locking the tty,
627     // because log_state() will use locks causing lock conflicts.
628     CodeCache::log_state(&s);
629 
630     ttyLocker ttyl;
631     tty->print("### sweeper: %s ", msg);
632     if (format != NULL) {
633       va_list ap;
634       va_start(ap, format);
635       tty->vprint(format, ap);
636       va_end(ap);
637     }
638     tty->print_cr("%s", s.as_string());
639   }
640 
641   if (LogCompilation && (xtty != NULL)) {
642     ResourceMark rm;
643     stringStream s;
644     // Dump code cache state into a buffer before locking the tty,
645     // because log_state() will use locks causing lock conflicts.
646     CodeCache::log_state(&s);
647 
648     ttyLocker ttyl;
649     xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count());
650     if (format != NULL) {
651       va_list ap;
652       va_start(ap, format);
653       xtty->vprint(format, ap);
654       va_end(ap);
655     }
656     xtty->print("%s", s.as_string());
657     xtty->stamp();
658     xtty->end_elem();
659   }
660 }
661 
662 void NMethodSweeper::print(outputStream* out) {
663   ttyLocker ttyl;
664   out = (out == NULL) ? tty : out;
665   out->print_cr("Code cache sweeper statistics:");
666   out->print_cr("  Total sweep time:                %1.0lf ms", (double)_total_time_sweeping.value()/1000000);
667   out->print_cr("  Total number of full sweeps:     %ld", _total_nof_code_cache_sweeps);
668   out->print_cr("  Total number of flushed methods: %ld (thereof %ld C2 methods)", _total_nof_methods_reclaimed,
669                                                     _total_nof_c2_methods_reclaimed);
670   out->print_cr("  Total size of flushed methods:   " SIZE_FORMAT " kB", _total_flushed_size/K);
671 }