src/share/vm/prims/methodHandles.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/prims/methodHandles.cpp

src/share/vm/prims/methodHandles.cpp

Print this page

        

*** 943,999 **** // return number of elements we at leasted wanted to initialize return rfill + overflow; } void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) { assert_locked_or_safepoint(CodeCache_lock); oop context = java_lang_invoke_CallSite::context(call_site); ! nmethodBucket* deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); ! nmethodBucket* new_deps = nmethodBucket::add_dependent_nmethod(deps, nm); ! if (deps != new_deps) { ! java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context, new_deps); } } void MethodHandles::remove_dependent_nmethod(oop call_site, nmethod* nm) { assert_locked_or_safepoint(CodeCache_lock); oop context = java_lang_invoke_CallSite::context(call_site); ! nmethodBucket* deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); ! if (nmethodBucket::remove_dependent_nmethod(deps, nm)) { ! nmethodBucket* new_deps = nmethodBucket::clean_dependent_nmethods(deps); ! if (deps != new_deps) { ! java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context, new_deps); ! } } } void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) { assert_lock_strong(Compile_lock); int marked = 0; CallSiteDepChange changes(call_site(), target()); { MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag); oop context = java_lang_invoke_CallSite::context(call_site()); ! nmethodBucket* deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); ! ! marked = nmethodBucket::mark_dependent_nmethods(deps, changes); ! if (marked > 0) { ! nmethodBucket* new_deps = nmethodBucket::clean_dependent_nmethods(deps); ! if (deps != new_deps) { ! java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context, new_deps); ! } ! } } if (marked > 0) { ! // At least one nmethod has been marked for deoptimization VM_Deoptimize op; VMThread::execute(&op); } } --- 943,1005 ---- // return number of elements we at leasted wanted to initialize return rfill + overflow; } + // Is it safe to remove stale entries from a dependency list? + static bool safe_to_purge() { + // Since parallel GC threads can concurrently iterate over a dependency + // list during safepoint, it is safe to remove entries only when + // CodeCache lock is held. + return CodeCache_lock->owned_by_self(); + } + void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) { assert_locked_or_safepoint(CodeCache_lock); oop context = java_lang_invoke_CallSite::context(call_site); ! DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); ! deps.add_dependent_nmethod(nm); ! // Try to purge stale entries. ! // Since GC doesn't clean dependency contexts rooted at CallSiteContext objects, ! // in order to avoid memory leak, stale entries are purged whenever a dependency list ! // is changed (both on addition and removal). Though memory reclamation is delayed, ! // it avoids indefinite memory usage growth. ! if (deps.has_unloaded_dependent() && safe_to_purge()) { ! deps.purge(); } } void MethodHandles::remove_dependent_nmethod(oop call_site, nmethod* nm) { assert_locked_or_safepoint(CodeCache_lock); oop context = java_lang_invoke_CallSite::context(call_site); ! DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); ! deps.remove_dependent_nmethod(nm); ! // Try to purge stale entries. ! if (deps.has_unloaded_dependent() && safe_to_purge()) { ! deps.purge(); } } void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) { assert_lock_strong(Compile_lock); int marked = 0; CallSiteDepChange changes(call_site(), target()); { + No_Safepoint_Verifier nsv; MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag); oop context = java_lang_invoke_CallSite::context(call_site()); ! DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); ! marked = deps.mark_dependent_nmethods(changes); } if (marked > 0) { ! // At least one nmethod has been marked for deoptimization. VM_Deoptimize op; VMThread::execute(&op); } }
*** 1337,1359 **** // Walk all nmethods depending on this call site. MutexLocker mu1(Compile_lock, thread); int marked = 0; { MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag); ! nmethodBucket* b = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context()); ! while(b != NULL) { ! nmethod* nm = b->get_nmethod(); ! if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization()) { ! nm->mark_for_deoptimization(); ! marked++; ! } ! nmethodBucket* next = b->next(); ! delete b; ! b = next; ! } ! java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context(), NULL); // reset context } if (marked > 0) { // At least one nmethod has been marked for deoptimization VM_Deoptimize op; VMThread::execute(&op); --- 1343,1356 ---- // Walk all nmethods depending on this call site. MutexLocker mu1(Compile_lock, thread); int marked = 0; { + No_Safepoint_Verifier nsv; MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag); ! DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context()); ! marked = deps.clear(); } if (marked > 0) { // At least one nmethod has been marked for deoptimization VM_Deoptimize op; VMThread::execute(&op);
src/share/vm/prims/methodHandles.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File