< prev index next >

src/hotspot/share/code/nmethod.cpp


*** 1370,1401 **** // traversing the dependency information in unsafe. In that case this // function is called with a boolean argument and this function only // notifies instanceKlasses that are reachable void nmethod::flush_dependencies(bool delete_immediately) { ! assert_locked_or_safepoint(CodeCache_lock); ! assert(Universe::heap()->is_gc_active() != delete_immediately, "delete_immediately is false if and only if we are called during GC"); if (!has_flushed_dependencies()) { set_has_flushed_dependencies(); for (Dependencies::DepStream deps(this); deps.next(); ) { if (deps.type() == Dependencies::call_site_target_value) { // CallSite dependencies are managed on per-CallSite instance basis. oop call_site = deps.argument_oop(0); ! MethodHandles::remove_dependent_nmethod(call_site, this); } else { Klass* klass = deps.context_type(); if (klass == NULL) { continue; // ignore things like evol_method } // During GC delete_immediately is false, and liveness // of dependee determines class that needs to be updated. ! if (delete_immediately || klass->is_loader_alive()) { ! // The GC defers deletion of this entry, since there might be multiple threads ! // iterating over the _dependencies graph. Other call paths are single-threaded ! // and may delete it immediately. ! InstanceKlass::cast(klass)->remove_dependent_nmethod(this, delete_immediately); } } } } } --- 1370,1407 ---- // traversing the dependency information in unsafe. In that case this // function is called with a boolean argument and this function only // notifies instanceKlasses that are reachable void nmethod::flush_dependencies(bool delete_immediately) { ! DEBUG_ONLY(bool called_by_gc = Universe::heap()->is_gc_active() || Thread::current()->is_ConcurrentGC_thread();) ! assert(called_by_gc != delete_immediately, "delete_immediately is false if and only if we are called during GC"); if (!has_flushed_dependencies()) { set_has_flushed_dependencies(); for (Dependencies::DepStream deps(this); deps.next(); ) { if (deps.type() == Dependencies::call_site_target_value) { // CallSite dependencies are managed on per-CallSite instance basis. oop call_site = deps.argument_oop(0); ! if (delete_immediately) { ! assert_locked_or_safepoint(CodeCache_lock); ! MethodHandles::remove_dependent_nmethod(call_site, this); ! } else { ! MethodHandles::clean_dependency_context(call_site); ! } } else { Klass* klass = deps.context_type(); if (klass == NULL) { continue; // ignore things like evol_method } // During GC delete_immediately is false, and liveness // of dependee determines class that needs to be updated. ! if (delete_immediately) { ! assert_locked_or_safepoint(CodeCache_lock); ! InstanceKlass::cast(klass)->remove_dependent_nmethod(this); ! } else if (klass->is_loader_alive()) { ! // The GC may clean dependency contexts concurrently and in parallel. ! InstanceKlass::cast(klass)->clean_dependency_context(); } } } } }
< prev index next >