115 |
113 |
116 void NMethodSweeper::record_sweep(nmethod* nm, int line) { |
114 void NMethodSweeper::record_sweep(nmethod* nm, int line) { |
117 if (_records != NULL) { |
115 if (_records != NULL) { |
118 _records[_sweep_index].traversal = _traversals; |
116 _records[_sweep_index].traversal = _traversals; |
119 _records[_sweep_index].traversal_mark = nm->_stack_traversal_mark; |
117 _records[_sweep_index].traversal_mark = nm->_stack_traversal_mark; |
120 _records[_sweep_index].invocation = _sweep_fractions_left; |
|
121 _records[_sweep_index].compile_id = nm->compile_id(); |
118 _records[_sweep_index].compile_id = nm->compile_id(); |
122 _records[_sweep_index].kind = nm->compile_kind(); |
119 _records[_sweep_index].kind = nm->compile_kind(); |
123 _records[_sweep_index].state = nm->_state; |
120 _records[_sweep_index].state = nm->_state; |
124 _records[_sweep_index].vep = nm->verified_entry_point(); |
121 _records[_sweep_index].vep = nm->verified_entry_point(); |
125 _records[_sweep_index].uep = nm->entry_point(); |
122 _records[_sweep_index].uep = nm->entry_point(); |
126 _records[_sweep_index].line = line; |
123 _records[_sweep_index].line = line; |
127 _sweep_index = (_sweep_index + 1) % SweeperLogEntries; |
124 _sweep_index = (_sweep_index + 1) % SweeperLogEntries; |
|
125 } |
|
126 } |
|
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); |
128 } |
133 } |
129 } |
134 } |
130 #else |
135 #else |
131 #define SWEEP(nm) |
136 #define SWEEP(nm) |
132 #endif |
137 #endif |
140 int NMethodSweeper::_flushed_count = 0; // Nof. nmethods flushed in current sweep |
145 int NMethodSweeper::_flushed_count = 0; // Nof. nmethods flushed in current sweep |
141 int NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep |
146 int NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep |
142 int NMethodSweeper::_marked_for_reclamation_count = 0; // Nof. nmethods marked for reclaim in current sweep |
147 int NMethodSweeper::_marked_for_reclamation_count = 0; // Nof. nmethods marked for reclaim in current sweep |
143 |
148 |
144 volatile bool NMethodSweeper::_should_sweep = true; // Indicates if we should invoke the sweeper |
149 volatile bool NMethodSweeper::_should_sweep = true; // Indicates if we should invoke the sweeper |
145 volatile int NMethodSweeper::_sweep_fractions_left = 0; // Nof. invocations left until we are completed with this pass |
|
146 volatile int NMethodSweeper::_sweep_started = 0; // Flag to control conc sweeper |
|
147 volatile int NMethodSweeper::_bytes_changed = 0; // Counts the total nmethod size if the nmethod changed from: |
150 volatile int NMethodSweeper::_bytes_changed = 0; // Counts the total nmethod size if the nmethod changed from: |
148 // 1) alive -> not_entrant |
151 // 1) alive -> not_entrant |
149 // 2) not_entrant -> zombie |
152 // 2) not_entrant -> zombie |
150 // 3) zombie -> marked_for_reclamation |
153 // 3) zombie -> marked_for_reclamation |
151 int NMethodSweeper::_hotness_counter_reset_val = 0; |
154 int NMethodSweeper::_hotness_counter_reset_val = 0; |
188 if (_hotness_counter_reset_val == 0) { |
191 if (_hotness_counter_reset_val == 0) { |
189 _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2; |
192 _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2; |
190 } |
193 } |
191 return _hotness_counter_reset_val; |
194 return _hotness_counter_reset_val; |
192 } |
195 } |
193 bool NMethodSweeper::sweep_in_progress() { |
196 bool NMethodSweeper::wait_for_stack_scanning() { |
194 return !_current.end(); |
197 return _current.end(); |
195 } |
198 } |
196 |
199 |
197 // Scans the stacks of all Java threads and marks activations of not-entrant methods. |
200 /** |
198 // No need to synchronize access, since 'mark_active_nmethods' is always executed at a |
201 * Scans the stacks of all Java threads and marks activations of not-entrant methods. |
199 // safepoint. |
202 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a |
|
203 * safepoint. |
|
204 */ |
200 void NMethodSweeper::mark_active_nmethods() { |
205 void NMethodSweeper::mark_active_nmethods() { |
201 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint"); |
206 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint"); |
202 // If we do not want to reclaim not-entrant or zombie methods there is no need |
207 // If we do not want to reclaim not-entrant or zombie methods there is no need |
203 // to scan stacks |
208 // to scan stacks |
204 if (!MethodFlushing) { |
209 if (!MethodFlushing) { |
229 Threads::nmethods_do(&set_hotness_closure); |
233 Threads::nmethods_do(&set_hotness_closure); |
230 } |
234 } |
231 |
235 |
232 OrderAccess::storestore(); |
236 OrderAccess::storestore(); |
233 } |
237 } |
|
238 |
|
239 /** |
|
240 * This function triggers a VM operation that does stack scanning of active |
|
241 * methods. Stack scanning is mandatory for the sweeper to make progress. |
|
242 */ |
|
243 void NMethodSweeper::do_stack_scanning() { |
|
244 assert(!CodeCache_lock->owned_by_self(), "just checking"); |
|
245 if (wait_for_stack_scanning()) { |
|
246 VM_MarkActiveNMethods op; |
|
247 VMThread::execute(&op); |
|
248 _should_sweep = true; |
|
249 } |
|
250 } |
|
251 |
|
252 void NMethodSweeper::sweeper_loop() { |
|
253 bool timeout; |
|
254 while (true) { |
|
255 { |
|
256 ThreadBlockInVM tbivm(JavaThread::current()); |
|
257 MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
|
258 const long wait_time = 60*60*24 * 1000; |
|
259 timeout = CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, wait_time); |
|
260 } |
|
261 if (!timeout) { |
|
262 possibly_sweep(); |
|
263 } |
|
264 } |
|
265 } |
|
266 |
|
267 /** |
|
268 * Wakes up the sweeper thread to possibly sweep. |
|
269 */ |
|
270 void NMethodSweeper::notify(int code_blob_type) { |
|
271 // Makes sure that we do not invoke the sweeper too often during startup. |
|
272 double start_threshold = 100.0 / (double)StartAggressiveSweepingAt; |
|
273 double aggressive_sweep_threshold = MIN2(start_threshold, 1.1); |
|
274 if (CodeCache::reverse_free_ratio(code_blob_type) >= aggressive_sweep_threshold) { |
|
275 assert_locked_or_safepoint(CodeCache_lock); |
|
276 CodeCache_lock->notify(); |
|
277 } |
|
278 } |
|
279 |
|
280 /** |
|
281 * Handle a safepoint request |
|
282 */ |
|
283 void NMethodSweeper::handle_safepoint_request() { |
|
284 if (SafepointSynchronize::is_synchronizing()) { |
|
285 if (PrintMethodFlushing && Verbose) { |
|
286 tty->print_cr("### Sweep at %d out of %d, yielding to safepoint", _seen, CodeCache::nof_nmethods()); |
|
287 } |
|
288 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
|
289 |
|
290 JavaThread* thread = JavaThread::current(); |
|
291 ThreadBlockInVM tbivm(thread); |
|
292 thread->java_suspend_self(); |
|
293 } |
|
294 } |
|
295 |
234 /** |
296 /** |
235 * This function invokes the sweeper if at least one of the three conditions is met: |
297 * This function invokes the sweeper if at least one of the three conditions is met: |
236 * (1) The code cache is getting full |
298 * (1) The code cache is getting full |
237 * (2) There are sufficient state changes in/since the last sweep. |
299 * (2) There are sufficient state changes in/since the last sweep. |
238 * (3) We have not been sweeping for 'some time' |
300 * (3) We have not been sweeping for 'some time' |
239 */ |
301 */ |
240 void NMethodSweeper::possibly_sweep() { |
302 void NMethodSweeper::possibly_sweep() { |
241 assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); |
303 assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); |
242 // Only compiler threads are allowed to sweep |
|
243 if (!MethodFlushing || !sweep_in_progress() || !Thread::current()->is_Compiler_thread()) { |
|
244 return; |
|
245 } |
|
246 |
|
247 // If there was no state change while nmethod sweeping, 'should_sweep' will be false. |
304 // If there was no state change while nmethod sweeping, 'should_sweep' will be false. |
248 // This is one of the two places where should_sweep can be set to true. The general |
305 // This is one of the two places where should_sweep can be set to true. The general |
249 // idea is as follows: If there is enough free space in the code cache, there is no |
306 // idea is as follows: If there is enough free space in the code cache, there is no |
250 // need to invoke the sweeper. The following formula (which determines whether to invoke |
307 // need to invoke the sweeper. The following formula (which determines whether to invoke |
251 // the sweeper or not) depends on the assumption that for larger ReservedCodeCacheSizes |
308 // the sweeper or not) depends on the assumption that for larger ReservedCodeCacheSizes |
278 if ((wait_until_next_sweep <= 0.0) || !CompileBroker::should_compile_new_jobs()) { |
335 if ((wait_until_next_sweep <= 0.0) || !CompileBroker::should_compile_new_jobs()) { |
279 _should_sweep = true; |
336 _should_sweep = true; |
280 } |
337 } |
281 } |
338 } |
282 |
339 |
283 if (_should_sweep && _sweep_fractions_left > 0) { |
340 // Force stack scanning if there is only 10% free space in the code cache. |
284 // Only one thread at a time will sweep |
341 // We force stack scanning only non-profiled code heap gets full, since critical |
285 jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 ); |
342 // allocation go to the non-profiled heap and we must be make sure that there is |
286 if (old != 0) { |
343 // enough space. |
287 return; |
344 double free_percent = 1 / CodeCache::reverse_free_ratio(CodeBlobType::MethodNonProfiled) * 100; |
288 } |
345 if (free_percent <= StartAggressiveSweepingAt) { |
289 #ifdef ASSERT |
346 do_stack_scanning(); |
290 if (LogSweeper && _records == NULL) { |
347 } |
291 // Create the ring buffer for the logging code |
348 |
292 _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC); |
349 if (_should_sweep) { |
293 memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries); |
350 init_sweeper_log(); |
294 } |
351 sweep_code_cache(); |
295 #endif |
352 } |
296 |
353 |
297 if (_sweep_fractions_left > 0) { |
354 // We are done with sweeping the code cache once. |
298 sweep_code_cache(); |
355 _total_nof_code_cache_sweeps++; |
299 _sweep_fractions_left--; |
356 _last_sweep = _time_counter; |
300 } |
357 // Reset flag; temporarily disables sweeper |
301 |
358 _should_sweep = false; |
302 // We are done with sweeping the code cache once. |
359 // If there was enough state change, 'possibly_enable_sweeper()' |
303 if (_sweep_fractions_left == 0) { |
360 // sets '_should_sweep' to true |
304 _total_nof_code_cache_sweeps++; |
361 possibly_enable_sweeper(); |
305 _last_sweep = _time_counter; |
362 // Reset _bytes_changed only if there was enough state change. _bytes_changed |
306 // Reset flag; temporarily disables sweeper |
363 // can further increase by calls to 'report_state_change'. |
307 _should_sweep = false; |
364 if (_should_sweep) { |
308 // If there was enough state change, 'possibly_enable_sweeper()' |
365 _bytes_changed = 0; |
309 // sets '_should_sweep' to true |
|
310 possibly_enable_sweeper(); |
|
311 // Reset _bytes_changed only if there was enough state change. _bytes_changed |
|
312 // can further increase by calls to 'report_state_change'. |
|
313 if (_should_sweep) { |
|
314 _bytes_changed = 0; |
|
315 } |
|
316 } |
|
317 // Release work, because another compiler thread could continue. |
|
318 OrderAccess::release_store((int*)&_sweep_started, 0); |
|
319 } |
366 } |
320 } |
367 } |
321 |
368 |
322 void NMethodSweeper::sweep_code_cache() { |
369 void NMethodSweeper::sweep_code_cache() { |
|
370 ResourceMark rm; |
323 Ticks sweep_start_counter = Ticks::now(); |
371 Ticks sweep_start_counter = Ticks::now(); |
324 |
372 |
325 _flushed_count = 0; |
373 _flushed_count = 0; |
326 _zombified_count = 0; |
374 _zombified_count = 0; |
327 _marked_for_reclamation_count = 0; |
375 _marked_for_reclamation_count = 0; |
328 |
376 |
329 if (PrintMethodFlushing && Verbose) { |
377 if (PrintMethodFlushing && Verbose) { |
330 tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _sweep_fractions_left); |
378 tty->print_cr("### Sweep at %d out of %d", _seen, CodeCache::nof_nmethods()); |
331 } |
379 } |
332 |
380 |
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 |
|
341 // invocations so divide the remaining number of nmethods by the |
|
342 // remaining number of invocations. This is only an estimate since |
|
343 // the number of nmethods changes during the sweep so the final |
|
344 // stage must iterate until it there are no more nmethods. |
|
345 int todo = (CodeCache::nof_nmethods() - _seen) / _sweep_fractions_left; |
|
346 int swept_count = 0; |
381 int swept_count = 0; |
347 |
|
348 |
|
349 assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); |
382 assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); |
350 assert(!CodeCache_lock->owned_by_self(), "just checking"); |
383 assert(!CodeCache_lock->owned_by_self(), "just checking"); |
351 |
384 |
352 int freed_memory = 0; |
385 int freed_memory = 0; |
353 { |
386 { |
354 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
387 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
355 |
388 |
356 // The last invocation iterates until there are no more nmethods |
389 // The last invocation iterates until there are no more nmethods |
357 while ((swept_count < todo || _sweep_fractions_left == 1) && !_current.end()) { |
390 while (!_current.end()) { |
358 swept_count++; |
391 swept_count++; |
359 if (SafepointSynchronize::is_synchronizing()) { // Safepoint request |
392 handle_safepoint_request(); |
360 if (PrintMethodFlushing && Verbose) { |
|
361 tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _sweep_fractions_left); |
|
362 } |
|
363 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
|
364 |
|
365 assert(Thread::current()->is_Java_thread(), "should be java thread"); |
|
366 JavaThread* thread = (JavaThread*)Thread::current(); |
|
367 ThreadBlockInVM tbivm(thread); |
|
368 thread->java_suspend_self(); |
|
369 } |
|
370 // Since we will give up the CodeCache_lock, always skip ahead |
393 // Since we will give up the CodeCache_lock, always skip ahead |
371 // to the next nmethod. Other blobs can be deleted by other |
394 // to the next nmethod. Other blobs can be deleted by other |
372 // threads but nmethods are only reclaimed by the sweeper. |
395 // threads but nmethods are only reclaimed by the sweeper. |
373 nmethod* nm = _current.method(); |
396 nmethod* nm = _current.method(); |
374 _current.next(); |
397 _current.next(); |
395 EventSweepCodeCache event(UNTIMED); |
418 EventSweepCodeCache event(UNTIMED); |
396 if (event.should_commit()) { |
419 if (event.should_commit()) { |
397 event.set_starttime(sweep_start_counter); |
420 event.set_starttime(sweep_start_counter); |
398 event.set_endtime(sweep_end_counter); |
421 event.set_endtime(sweep_end_counter); |
399 event.set_sweepIndex(_traversals); |
422 event.set_sweepIndex(_traversals); |
400 event.set_sweepFractionIndex(NmethodSweepFraction - _sweep_fractions_left + 1); |
|
401 event.set_sweptCount(swept_count); |
423 event.set_sweptCount(swept_count); |
402 event.set_flushedCount(_flushed_count); |
424 event.set_flushedCount(_flushed_count); |
403 event.set_markedCount(_marked_for_reclamation_count); |
425 event.set_markedCount(_marked_for_reclamation_count); |
404 event.set_zombifiedCount(_zombified_count); |
426 event.set_zombifiedCount(_zombified_count); |
405 event.commit(); |
427 event.commit(); |
406 } |
428 } |
407 |
429 |
408 #ifdef ASSERT |
430 #ifdef ASSERT |
409 if(PrintMethodFlushing) { |
431 if(PrintMethodFlushing) { |
410 tty->print_cr("### sweeper: sweep time(%d): " |
432 tty->print_cr("### sweeper: sweep time(%d): ", (jlong)sweep_time.value()); |
411 INT64_FORMAT, _sweep_fractions_left, (jlong)sweep_time.value()); |
|
412 } |
433 } |
413 #endif |
434 #endif |
414 |
435 |
415 if (_sweep_fractions_left == 1) { |
436 _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep); |
416 _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep); |
437 log_sweep("finished"); |
417 log_sweep("finished"); |
|
418 } |
|
419 |
438 |
420 // Sweeper is the only case where memory is released, check here if it |
439 // 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 |
440 // 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 |
441 // 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 |
442 // compilation although no memory has been released. For example, there are |
457 } |
476 } |
458 } |
477 } |
459 |
478 |
460 class NMethodMarker: public StackObj { |
479 class NMethodMarker: public StackObj { |
461 private: |
480 private: |
462 CompilerThread* _thread; |
481 CodeCacheSweeperThread* _thread; |
463 public: |
482 public: |
464 NMethodMarker(nmethod* nm) { |
483 NMethodMarker(nmethod* nm) { |
465 _thread = CompilerThread::current(); |
484 JavaThread* current = JavaThread::current(); |
|
485 assert (current->is_Code_cache_sweeper_thread(), "Must be"); |
|
486 _thread = (CodeCacheSweeperThread*)JavaThread::current(); |
466 if (!nm->is_zombie() && !nm->is_unloaded()) { |
487 if (!nm->is_zombie() && !nm->is_unloaded()) { |
467 // Only expose live nmethods for scanning |
488 // Only expose live nmethods for scanning |
468 _thread->set_scanned_nmethod(nm); |
489 _thread->set_scanned_nmethod(nm); |
469 } |
490 } |
470 } |
491 } |
471 ~NMethodMarker() { |
492 ~NMethodMarker() { |
472 _thread->set_scanned_nmethod(NULL); |
493 _thread->set_scanned_nmethod(NULL); |
473 } |
494 } |
474 }; |
495 }; |
475 |
496 |
476 void NMethodSweeper::release_nmethod(nmethod *nm) { |
497 void NMethodSweeper::release_nmethod(nmethod* nm) { |
477 // Clean up any CompiledICHolders |
498 // Clean up any CompiledICHolders |
478 { |
499 { |
479 ResourceMark rm; |
500 ResourceMark rm; |
480 MutexLocker ml_patch(CompiledIC_lock); |
501 MutexLocker ml_patch(CompiledIC_lock); |
481 RelocIterator iter(nm); |
502 RelocIterator iter(nm); |