230 /**
231 * Scans the stacks of all Java threads and marks activations of not-entrant methods.
232 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
233 * safepoint.
234 */
235 void NMethodSweeper::mark_active_nmethods() {
236 CodeBlobClosure* cl = prepare_mark_active_nmethods();
237 if (cl != NULL) {
238 WorkGang* workers = Universe::heap()->get_safepoint_workers();
239 if (workers != NULL) {
240 ThreadToCodeBlobClosure tcl(cl);
241 NMethodMarkingTask task(&tcl);
242 workers->run_task(&task);
243 } else {
244 Threads::nmethods_do(cl);
245 }
246 }
247 }
248
249 CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
250 // If we do not want to reclaim not-entrant or zombie methods there is no need
251 // to scan stacks
252 if (!MethodFlushing) {
253 return NULL;
254 }
255
256 // Increase time so that we can estimate when to invoke the sweeper again.
257 _time_counter++;
258
259 // Check for restart
260 if (_current.method() != NULL) {
261 if (_current.method()->is_nmethod()) {
262 assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
263 } else if (_current.method()->is_aot()) {
264 assert(CodeCache::find_blob_unsafe(_current.method()->code_begin()) == _current.method(), "Sweeper AOT method cached state invalid");
265 } else {
266 ShouldNotReachHere();
267 }
268 }
269
278 if (PrintMethodFlushing) {
279 tty->print_cr("### Sweep: stack traversal %ld", _traversals);
280 }
281 return &mark_activation_closure;
282
283 } else {
284 // Only set hotness counter
285 return &set_hotness_closure;
286 }
287
288 }
289
290 /**
291 * This function triggers a VM operation that does stack scanning of active
292 * methods. Stack scanning is mandatory for the sweeper to make progress.
293 */
294 void NMethodSweeper::do_stack_scanning() {
295 assert(!CodeCache_lock->owned_by_self(), "just checking");
296 if (wait_for_stack_scanning()) {
297 if (ThreadLocalHandshakes) {
298 CodeBlobClosure* code_cl = prepare_mark_active_nmethods();
299 if (code_cl != NULL) {
300 ThreadToCodeBlobClosure tcl(code_cl);
301 Handshake::execute(&tcl);
302 }
303 } else {
304 VM_MarkActiveNMethods op;
305 VMThread::execute(&op);
306 }
307 _should_sweep = true;
308 }
309 }
310
311 void NMethodSweeper::sweeper_loop() {
312 bool timeout;
313 while (true) {
314 {
315 ThreadBlockInVM tbivm(JavaThread::current());
316 MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
317 const long wait_time = 60*60*24 * 1000;
318 timeout = CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, wait_time);
|
230 /**
231 * Scans the stacks of all Java threads and marks activations of not-entrant methods.
232 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
233 * safepoint.
234 */
235 void NMethodSweeper::mark_active_nmethods() {
236 CodeBlobClosure* cl = prepare_mark_active_nmethods();
237 if (cl != NULL) {
238 WorkGang* workers = Universe::heap()->get_safepoint_workers();
239 if (workers != NULL) {
240 ThreadToCodeBlobClosure tcl(cl);
241 NMethodMarkingTask task(&tcl);
242 workers->run_task(&task);
243 } else {
244 Threads::nmethods_do(cl);
245 }
246 }
247 }
248
249 CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
250 #ifdef ASSERT
251 if (ThreadLocalHandshakes) {
252 assert(Thread::current()->is_Code_cache_sweeper_thread(), "must be executed under CodeCache_lock and in sweeper thread");
253 assert_lock_strong(CodeCache_lock);
254 } else {
255 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
256 }
257 #endif
258
259 // If we do not want to reclaim not-entrant or zombie methods there is no need
260 // to scan stacks
261 if (!MethodFlushing) {
262 return NULL;
263 }
264
265 // Increase time so that we can estimate when to invoke the sweeper again.
266 _time_counter++;
267
268 // Check for restart
269 if (_current.method() != NULL) {
270 if (_current.method()->is_nmethod()) {
271 assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
272 } else if (_current.method()->is_aot()) {
273 assert(CodeCache::find_blob_unsafe(_current.method()->code_begin()) == _current.method(), "Sweeper AOT method cached state invalid");
274 } else {
275 ShouldNotReachHere();
276 }
277 }
278
287 if (PrintMethodFlushing) {
288 tty->print_cr("### Sweep: stack traversal %ld", _traversals);
289 }
290 return &mark_activation_closure;
291
292 } else {
293 // Only set hotness counter
294 return &set_hotness_closure;
295 }
296
297 }
298
299 /**
300 * This function triggers a VM operation that does stack scanning of active
301 * methods. Stack scanning is mandatory for the sweeper to make progress.
302 */
303 void NMethodSweeper::do_stack_scanning() {
304 assert(!CodeCache_lock->owned_by_self(), "just checking");
305 if (wait_for_stack_scanning()) {
306 if (ThreadLocalHandshakes) {
307 CodeBlobClosure* code_cl;
308 {
309 MutexLockerEx ccl(CodeCache_lock, Mutex::_no_safepoint_check_flag);
310 code_cl = prepare_mark_active_nmethods();
311 }
312 if (code_cl != NULL) {
313 ThreadToCodeBlobClosure tcl(code_cl);
314 Handshake::execute(&tcl);
315 }
316 } else {
317 VM_MarkActiveNMethods op;
318 VMThread::execute(&op);
319 }
320 _should_sweep = true;
321 }
322 }
323
324 void NMethodSweeper::sweeper_loop() {
325 bool timeout;
326 while (true) {
327 {
328 ThreadBlockInVM tbivm(JavaThread::current());
329 MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
330 const long wait_time = 60*60*24 * 1000;
331 timeout = CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, wait_time);
|