src/hotspot/share/code/nmethod.cpp
changeset 52781 436097b038a1
parent 52661 4f45c682eab0
child 52800 8613f3fdbdae
equal deleted inserted replaced
52780:be588be89f68 52781:436097b038a1
  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 }