1370 // traversing the dependency information in unsafe. In that case this |
1370 // traversing the dependency information in unsafe. In that case this |
1371 // function is called with a boolean argument and this function only |
1371 // function is called with a boolean argument and this function only |
1372 // notifies instanceKlasses that are reachable |
1372 // notifies instanceKlasses that are reachable |
1373 |
1373 |
1374 void nmethod::flush_dependencies(bool delete_immediately) { |
1374 void nmethod::flush_dependencies(bool delete_immediately) { |
1375 assert_locked_or_safepoint(CodeCache_lock); |
1375 DEBUG_ONLY(bool called_by_gc = Universe::heap()->is_gc_active() || Thread::current()->is_ConcurrentGC_thread();) |
1376 assert(Universe::heap()->is_gc_active() != delete_immediately, |
1376 assert(called_by_gc != delete_immediately, |
1377 "delete_immediately is false if and only if we are called during GC"); |
1377 "delete_immediately is false if and only if we are called during GC"); |
1378 if (!has_flushed_dependencies()) { |
1378 if (!has_flushed_dependencies()) { |
1379 set_has_flushed_dependencies(); |
1379 set_has_flushed_dependencies(); |
1380 for (Dependencies::DepStream deps(this); deps.next(); ) { |
1380 for (Dependencies::DepStream deps(this); deps.next(); ) { |
1381 if (deps.type() == Dependencies::call_site_target_value) { |
1381 if (deps.type() == Dependencies::call_site_target_value) { |
1382 // CallSite dependencies are managed on per-CallSite instance basis. |
1382 // CallSite dependencies are managed on per-CallSite instance basis. |
1383 oop call_site = deps.argument_oop(0); |
1383 oop call_site = deps.argument_oop(0); |
1384 MethodHandles::remove_dependent_nmethod(call_site, this); |
1384 if (delete_immediately) { |
|
1385 assert_locked_or_safepoint(CodeCache_lock); |
|
1386 MethodHandles::remove_dependent_nmethod(call_site, this); |
|
1387 } else { |
|
1388 MethodHandles::clean_dependency_context(call_site); |
|
1389 } |
1385 } else { |
1390 } else { |
1386 Klass* klass = deps.context_type(); |
1391 Klass* klass = deps.context_type(); |
1387 if (klass == NULL) { |
1392 if (klass == NULL) { |
1388 continue; // ignore things like evol_method |
1393 continue; // ignore things like evol_method |
1389 } |
1394 } |
1390 // During GC delete_immediately is false, and liveness |
1395 // During GC delete_immediately is false, and liveness |
1391 // of dependee determines class that needs to be updated. |
1396 // of dependee determines class that needs to be updated. |
1392 if (delete_immediately || klass->is_loader_alive()) { |
1397 if (delete_immediately) { |
1393 // The GC defers deletion of this entry, since there might be multiple threads |
1398 assert_locked_or_safepoint(CodeCache_lock); |
1394 // iterating over the _dependencies graph. Other call paths are single-threaded |
1399 InstanceKlass::cast(klass)->remove_dependent_nmethod(this); |
1395 // and may delete it immediately. |
1400 } else if (klass->is_loader_alive()) { |
1396 InstanceKlass::cast(klass)->remove_dependent_nmethod(this, delete_immediately); |
1401 // The GC may clean dependency contexts concurrently and in parallel. |
|
1402 InstanceKlass::cast(klass)->clean_dependency_context(); |
1397 } |
1403 } |
1398 } |
1404 } |
1399 } |
1405 } |
1400 } |
1406 } |
1401 } |
1407 } |