25 # include "incls/_precompiled.incl" |
25 # include "incls/_precompiled.incl" |
26 # include "incls/_sweeper.cpp.incl" |
26 # include "incls/_sweeper.cpp.incl" |
27 |
27 |
28 long NMethodSweeper::_traversals = 0; // No. of stack traversals performed |
28 long NMethodSweeper::_traversals = 0; // No. of stack traversals performed |
29 nmethod* NMethodSweeper::_current = NULL; // Current nmethod |
29 nmethod* NMethodSweeper::_current = NULL; // Current nmethod |
30 int NMethodSweeper::_seen = 0 ; // No. of blobs we have currently processed in current pass of CodeCache |
30 int NMethodSweeper::_seen = 0 ; // No. of nmethods we have currently processed in current pass of CodeCache |
31 int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass |
31 |
|
32 volatile int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass |
|
33 volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress. |
32 |
34 |
33 jint NMethodSweeper::_locked_seen = 0; |
35 jint NMethodSweeper::_locked_seen = 0; |
34 jint NMethodSweeper::_not_entrant_seen_on_stack = 0; |
36 jint NMethodSweeper::_not_entrant_seen_on_stack = 0; |
35 bool NMethodSweeper::_rescan = false; |
37 bool NMethodSweeper::_rescan = false; |
36 bool NMethodSweeper::_do_sweep = false; |
38 bool NMethodSweeper::_do_sweep = false; |
37 jint NMethodSweeper::_sweep_started = 0; |
|
38 bool NMethodSweeper::_was_full = false; |
39 bool NMethodSweeper::_was_full = false; |
39 jint NMethodSweeper::_advise_to_sweep = 0; |
40 jint NMethodSweeper::_advise_to_sweep = 0; |
40 jlong NMethodSweeper::_last_was_full = 0; |
41 jlong NMethodSweeper::_last_was_full = 0; |
41 uint NMethodSweeper::_highest_marked = 0; |
42 uint NMethodSweeper::_highest_marked = 0; |
42 long NMethodSweeper::_was_full_traversal = 0; |
43 long NMethodSweeper::_was_full_traversal = 0; |
106 |
107 |
107 // Update the _last_was_full time so we can tell how fast the |
108 // Update the _last_was_full time so we can tell how fast the |
108 // code cache is filling up |
109 // code cache is filling up |
109 _last_was_full = os::javaTimeMillis(); |
110 _last_was_full = os::javaTimeMillis(); |
110 |
111 |
111 if (PrintMethodFlushing) { |
112 log_sweep("restart_compiler"); |
112 tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler", |
|
113 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
114 } |
|
115 if (LogCompilation && (xtty != NULL)) { |
|
116 ttyLocker ttyl; |
|
117 xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
118 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
119 xtty->stamp(); |
|
120 xtty->end_elem(); |
|
121 } |
|
122 } |
113 } |
123 } |
114 } |
124 } |
115 } |
125 } |
116 } |
126 |
117 |
127 void NMethodSweeper::possibly_sweep() { |
118 void NMethodSweeper::possibly_sweep() { |
|
119 assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); |
128 if ((!MethodFlushing) || (!_do_sweep)) return; |
120 if ((!MethodFlushing) || (!_do_sweep)) return; |
129 |
121 |
130 if (_invocations > 0) { |
122 if (_invocations > 0) { |
131 // Only one thread at a time will sweep |
123 // Only one thread at a time will sweep |
132 jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 ); |
124 jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 ); |
133 if (old != 0) { |
125 if (old != 0) { |
134 return; |
126 return; |
135 } |
127 } |
136 sweep_code_cache(); |
128 if (_invocations > 0) { |
137 } |
129 sweep_code_cache(); |
138 _sweep_started = 0; |
130 _invocations--; |
|
131 } |
|
132 _sweep_started = 0; |
|
133 } |
139 } |
134 } |
140 |
135 |
141 void NMethodSweeper::sweep_code_cache() { |
136 void NMethodSweeper::sweep_code_cache() { |
142 #ifdef ASSERT |
137 #ifdef ASSERT |
143 jlong sweep_start; |
138 jlong sweep_start; |
144 if(PrintMethodFlushing) { |
139 if (PrintMethodFlushing) { |
145 sweep_start = os::javaTimeMillis(); |
140 sweep_start = os::javaTimeMillis(); |
146 } |
141 } |
147 #endif |
142 #endif |
148 if (PrintMethodFlushing && Verbose) { |
143 if (PrintMethodFlushing && Verbose) { |
149 tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_blobs(), _invocations); |
144 tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations); |
150 } |
145 } |
151 |
146 |
152 // We want to visit all nmethods after NmethodSweepFraction invocations. |
147 // We want to visit all nmethods after NmethodSweepFraction |
153 // If invocation is 1 we do the rest |
148 // invocations so divide the remaining number of nmethods by the |
154 int todo = CodeCache::nof_blobs(); |
149 // remaining number of invocations. This is only an estimate since |
155 if (_invocations > 1) { |
150 // the number of nmethods changes during the sweep so the final |
156 todo = (CodeCache::nof_blobs() - _seen) / _invocations; |
151 // stage must iterate until it there are no more nmethods. |
157 } |
152 int todo = (CodeCache::nof_nmethods() - _seen) / _invocations; |
158 |
|
159 // Compilers may check to sweep more often than stack scans happen, |
|
160 // don't keep trying once it is all scanned |
|
161 _invocations--; |
|
162 |
153 |
163 assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); |
154 assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); |
164 assert(!CodeCache_lock->owned_by_self(), "just checking"); |
155 assert(!CodeCache_lock->owned_by_self(), "just checking"); |
165 |
156 |
166 { |
157 { |
167 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
158 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
168 |
159 |
169 for(int i = 0; i < todo && _current != NULL; i++) { |
160 // The last invocation iterates until there are no more nmethods |
170 |
161 for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) { |
171 // Since we will give up the CodeCache_lock, always skip ahead to an nmethod. |
162 |
172 // Other blobs can be deleted by other threads |
163 // Since we will give up the CodeCache_lock, always skip ahead |
173 // Read next before we potentially delete current |
164 // to the next nmethod. Other blobs can be deleted by other |
|
165 // threads but nmethods are only reclaimed by the sweeper. |
174 nmethod* next = CodeCache::next_nmethod(_current); |
166 nmethod* next = CodeCache::next_nmethod(_current); |
175 |
167 |
176 // Now ready to process nmethod and give up CodeCache_lock |
168 // Now ready to process nmethod and give up CodeCache_lock |
177 { |
169 { |
178 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
170 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
221 } |
219 } |
222 |
220 |
223 if (nm->is_zombie()) { |
221 if (nm->is_zombie()) { |
224 // If it is first time, we see nmethod then we mark it. Otherwise, |
222 // If it is first time, we see nmethod then we mark it. Otherwise, |
225 // we reclame it. When we have seen a zombie method twice, we know that |
223 // we reclame it. When we have seen a zombie method twice, we know that |
226 // there are no inline caches that referes to it. |
224 // there are no inline caches that refer to it. |
227 if (nm->is_marked_for_reclamation()) { |
225 if (nm->is_marked_for_reclamation()) { |
228 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); |
226 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); |
229 if (PrintMethodFlushing && Verbose) { |
227 if (PrintMethodFlushing && Verbose) { |
230 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); |
228 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); |
231 } |
229 } |
318 jlong now = os::javaTimeMillis(); |
316 jlong now = os::javaTimeMillis(); |
319 jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; |
317 jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; |
320 jlong curr_interval = now - _last_was_full; |
318 jlong curr_interval = now - _last_was_full; |
321 if (curr_interval < max_interval) { |
319 if (curr_interval < max_interval) { |
322 _rescan = true; |
320 _rescan = true; |
323 if (PrintMethodFlushing) { |
321 log_sweep("disable_compiler", "flushing_interval='" UINT64_FORMAT "'", |
324 tty->print_cr("### handle full too often, turning off compiler"); |
322 curr_interval/1000); |
325 } |
|
326 if (LogCompilation && (xtty != NULL)) { |
|
327 ttyLocker ttyl; |
|
328 xtty->begin_elem("disable_compiler flushing_interval='" UINT64_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
329 curr_interval/1000, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
330 xtty->stamp(); |
|
331 xtty->end_elem(); |
|
332 } |
|
333 return; |
323 return; |
334 } |
324 } |
335 } |
325 } |
336 |
326 |
337 VM_HandleFullCodeCache op(is_full); |
327 VM_HandleFullCodeCache op(is_full); |
347 |
337 |
348 debug_only(jlong start = os::javaTimeMillis();) |
338 debug_only(jlong start = os::javaTimeMillis();) |
349 |
339 |
350 if ((!was_full()) && (is_full)) { |
340 if ((!was_full()) && (is_full)) { |
351 if (!CodeCache::needs_flushing()) { |
341 if (!CodeCache::needs_flushing()) { |
352 if (PrintMethodFlushing) { |
342 log_sweep("restart_compiler"); |
353 tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler", |
|
354 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
355 } |
|
356 if (LogCompilation && (xtty != NULL)) { |
|
357 ttyLocker ttyl; |
|
358 xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
359 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
360 xtty->stamp(); |
|
361 xtty->end_elem(); |
|
362 } |
|
363 CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); |
343 CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); |
364 return; |
344 return; |
365 } |
345 } |
366 } |
346 } |
367 |
347 |
368 // Traverse the code cache trying to dump the oldest nmethods |
348 // Traverse the code cache trying to dump the oldest nmethods |
369 uint curr_max_comp_id = CompileBroker::get_compilation_id(); |
349 uint curr_max_comp_id = CompileBroker::get_compilation_id(); |
370 uint flush_target = ((curr_max_comp_id - _highest_marked) >> 1) + _highest_marked; |
350 uint flush_target = ((curr_max_comp_id - _highest_marked) >> 1) + _highest_marked; |
371 if (PrintMethodFlushing && Verbose) { |
351 log_sweep("start_cleaning"); |
372 tty->print_cr("### Cleaning code cache: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes", |
|
373 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
374 } |
|
375 if (LogCompilation && (xtty != NULL)) { |
|
376 ttyLocker ttyl; |
|
377 xtty->begin_elem("start_cleaning_code_cache live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
378 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
379 xtty->stamp(); |
|
380 xtty->end_elem(); |
|
381 } |
|
382 |
352 |
383 nmethod* nm = CodeCache::alive_nmethod(CodeCache::first()); |
353 nmethod* nm = CodeCache::alive_nmethod(CodeCache::first()); |
384 jint disconnected = 0; |
354 jint disconnected = 0; |
385 jint made_not_entrant = 0; |
355 jint made_not_entrant = 0; |
386 while ((nm != NULL)){ |
356 while ((nm != NULL)){ |
409 } |
379 } |
410 } |
380 } |
411 nm = CodeCache::alive_nmethod(CodeCache::next(nm)); |
381 nm = CodeCache::alive_nmethod(CodeCache::next(nm)); |
412 } |
382 } |
413 |
383 |
414 if (LogCompilation && (xtty != NULL)) { |
384 log_sweep("stop_cleaning", |
415 ttyLocker ttyl; |
385 "disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "'", |
416 xtty->begin_elem("stop_cleaning_code_cache disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
386 disconnected, made_not_entrant); |
417 disconnected, made_not_entrant, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
418 xtty->stamp(); |
|
419 xtty->end_elem(); |
|
420 } |
|
421 |
387 |
422 // Shut off compiler. Sweeper will start over with a new stack scan and |
388 // Shut off compiler. Sweeper will start over with a new stack scan and |
423 // traversal cycle and turn it back on if it clears enough space. |
389 // traversal cycle and turn it back on if it clears enough space. |
424 if (was_full()) { |
390 if (was_full()) { |
425 _last_was_full = os::javaTimeMillis(); |
391 _last_was_full = os::javaTimeMillis(); |
433 if(PrintMethodFlushing && Verbose) { |
399 if(PrintMethodFlushing && Verbose) { |
434 tty->print_cr("### sweeper: unload time: " INT64_FORMAT, end-start); |
400 tty->print_cr("### sweeper: unload time: " INT64_FORMAT, end-start); |
435 } |
401 } |
436 #endif |
402 #endif |
437 } |
403 } |
|
404 |
|
405 |
|
406 // Print out some state information about the current sweep and the |
|
407 // state of the code cache if it's requested. |
|
408 void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { |
|
409 if (PrintMethodFlushing) { |
|
410 ttyLocker ttyl; |
|
411 tty->print("### sweeper: %s ", msg); |
|
412 if (format != NULL) { |
|
413 va_list ap; |
|
414 va_start(ap, format); |
|
415 tty->vprint(format, ap); |
|
416 va_end(ap); |
|
417 } |
|
418 tty->print_cr(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" |
|
419 " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
420 CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity()); |
|
421 } |
|
422 |
|
423 if (LogCompilation && (xtty != NULL)) { |
|
424 ttyLocker ttyl; |
|
425 xtty->begin_elem("sweeper state='%s' traversals=`" INTX_FORMAT "' ", msg, (intx)traversal_count()); |
|
426 if (format != NULL) { |
|
427 va_list ap; |
|
428 va_start(ap, format); |
|
429 xtty->vprint(format, ap); |
|
430 va_end(ap); |
|
431 } |
|
432 xtty->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" |
|
433 " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
434 CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity()); |
|
435 xtty->stamp(); |
|
436 xtty->end_elem(); |
|
437 } |
|
438 } |