196 /**
197 * Scans the stacks of all Java threads and marks activations of not-entrant methods.
198 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
199 * safepoint.
200 */
201 void NMethodSweeper::mark_active_nmethods() {
202 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
203 // If we do not want to reclaim not-entrant or zombie methods there is no need
204 // to scan stacks
205 if (!MethodFlushing) {
206 return;
207 }
208
209 // Increase time so that we can estimate when to invoke the sweeper again.
210 _time_counter++;
211
212 // Check for restart
213 if (_current.method() != NULL) {
214 if (_current.method()->is_nmethod()) {
215 assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
216 } else {
217 ShouldNotReachHere();
218 }
219 }
220
221 if (wait_for_stack_scanning()) {
222 _seen = 0;
223 _current = CompiledMethodIterator();
224 // Initialize to first nmethod
225 _current.next();
226 _traversals += 1;
227 _total_time_this_sweep = Tickspan();
228
229 if (PrintMethodFlushing) {
230 tty->print_cr("### Sweep: stack traversal %ld", _traversals);
231 }
232 Threads::nmethods_do(&mark_activation_closure);
233
234 } else {
235 // Only set hotness counter
553 _thread->set_scanned_compiled_method(cm);
554 }
555 }
556 ~CompiledMethodMarker() {
557 _thread->set_scanned_compiled_method(NULL);
558 }
559 };
560
561 void NMethodSweeper::release_compiled_method(CompiledMethod* nm) {
562 // Make sure the released nmethod is no longer referenced by the sweeper thread
563 CodeCacheSweeperThread* thread = (CodeCacheSweeperThread*)JavaThread::current();
564 thread->set_scanned_compiled_method(NULL);
565
566 // Clean up any CompiledICHolders
567 {
568 ResourceMark rm;
569 MutexLocker ml_patch(CompiledIC_lock);
570 RelocIterator iter(nm);
571 while (iter.next()) {
572 if (iter.type() == relocInfo::virtual_call_type) {
573 CompiledIC::cleanup_call_site(iter.virtual_call_reloc());
574 }
575 }
576 }
577
578 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
579 nm->flush();
580 }
581
582 NMethodSweeper::MethodStateChange NMethodSweeper::process_compiled_method(CompiledMethod* cm) {
583 assert(cm != NULL, "sanity");
584 assert(!CodeCache_lock->owned_by_self(), "just checking");
585
586 MethodStateChange result = None;
587 // Make sure this nmethod doesn't get unloaded during the scan,
588 // since safepoints may happen during acquired below locks.
589 CompiledMethodMarker nmm(cm);
590 SWEEP(cm);
591
592 // Skip methods that are currently referenced by the VM
593 if (cm->is_locked_by_vm()) {
|
196 /**
197 * Scans the stacks of all Java threads and marks activations of not-entrant methods.
198 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
199 * safepoint.
200 */
201 void NMethodSweeper::mark_active_nmethods() {
202 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
203 // If we do not want to reclaim not-entrant or zombie methods there is no need
204 // to scan stacks
205 if (!MethodFlushing) {
206 return;
207 }
208
209 // Increase time so that we can estimate when to invoke the sweeper again.
210 _time_counter++;
211
212 // Check for restart
213 if (_current.method() != NULL) {
214 if (_current.method()->is_nmethod()) {
215 assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
216 } else if (_current.method()->is_aot()) {
217 assert(CodeCache::find_blob_unsafe(_current.method()->code_begin()) == _current.method(), "Sweeper AOT method cached state invalid");
218 } else {
219 ShouldNotReachHere();
220 }
221 }
222
223 if (wait_for_stack_scanning()) {
224 _seen = 0;
225 _current = CompiledMethodIterator();
226 // Initialize to first nmethod
227 _current.next();
228 _traversals += 1;
229 _total_time_this_sweep = Tickspan();
230
231 if (PrintMethodFlushing) {
232 tty->print_cr("### Sweep: stack traversal %ld", _traversals);
233 }
234 Threads::nmethods_do(&mark_activation_closure);
235
236 } else {
237 // Only set hotness counter
555 _thread->set_scanned_compiled_method(cm);
556 }
557 }
558 ~CompiledMethodMarker() {
559 _thread->set_scanned_compiled_method(NULL);
560 }
561 };
562
563 void NMethodSweeper::release_compiled_method(CompiledMethod* nm) {
564 // Make sure the released nmethod is no longer referenced by the sweeper thread
565 CodeCacheSweeperThread* thread = (CodeCacheSweeperThread*)JavaThread::current();
566 thread->set_scanned_compiled_method(NULL);
567
568 // Clean up any CompiledICHolders
569 {
570 ResourceMark rm;
571 MutexLocker ml_patch(CompiledIC_lock);
572 RelocIterator iter(nm);
573 while (iter.next()) {
574 if (iter.type() == relocInfo::virtual_call_type) {
575 CompiledIC::cleanup_call_site(iter.virtual_call_reloc(), nm);
576 }
577 }
578 }
579
580 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
581 nm->flush();
582 }
583
584 NMethodSweeper::MethodStateChange NMethodSweeper::process_compiled_method(CompiledMethod* cm) {
585 assert(cm != NULL, "sanity");
586 assert(!CodeCache_lock->owned_by_self(), "just checking");
587
588 MethodStateChange result = None;
589 // Make sure this nmethod doesn't get unloaded during the scan,
590 // since safepoints may happen during acquired below locks.
591 CompiledMethodMarker nmm(cm);
592 SWEEP(cm);
593
594 // Skip methods that are currently referenced by the VM
595 if (cm->is_locked_by_vm()) {
|