25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.inline.hpp" |
26 #include "classfile/javaClasses.inline.hpp" |
27 #include "classfile/stringTable.hpp" |
27 #include "classfile/stringTable.hpp" |
28 #include "code/codeCache.hpp" |
28 #include "code/codeCache.hpp" |
29 #include "code/codeCacheExtensions.hpp" |
29 #include "code/codeCacheExtensions.hpp" |
|
30 #include "code/dependencyContext.hpp" |
30 #include "compiler/compileBroker.hpp" |
31 #include "compiler/compileBroker.hpp" |
31 #include "interpreter/interpreter.hpp" |
32 #include "interpreter/interpreter.hpp" |
32 #include "interpreter/oopMapCache.hpp" |
33 #include "interpreter/oopMapCache.hpp" |
33 #include "interpreter/linkResolver.hpp" |
34 #include "interpreter/linkResolver.hpp" |
34 #include "memory/allocation.inline.hpp" |
35 #include "memory/allocation.inline.hpp" |
943 |
944 |
944 // return number of elements we at leasted wanted to initialize |
945 // return number of elements we at leasted wanted to initialize |
945 return rfill + overflow; |
946 return rfill + overflow; |
946 } |
947 } |
947 |
948 |
|
949 // Is it safe to remove stale entries from a dependency list? |
|
950 static bool safe_to_expunge() { |
|
951 // Since parallel GC threads can concurrently iterate over a dependency |
|
952 // list during safepoint, it is safe to remove entries only when |
|
953 // CodeCache lock is held. |
|
954 return CodeCache_lock->owned_by_self(); |
|
955 } |
|
956 |
948 void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) { |
957 void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) { |
949 assert_locked_or_safepoint(CodeCache_lock); |
958 assert_locked_or_safepoint(CodeCache_lock); |
950 |
959 |
951 oop context = java_lang_invoke_CallSite::context(call_site); |
960 oop context = java_lang_invoke_CallSite::context(call_site); |
952 nmethodBucket* deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
961 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
953 |
962 // Try to purge stale entries on updates. |
954 nmethodBucket* new_deps = nmethodBucket::add_dependent_nmethod(deps, nm); |
963 // Since GC doesn't clean dependency contexts rooted at CallSiteContext objects, |
955 if (deps != new_deps) { |
964 // in order to avoid memory leak, stale entries are purged whenever a dependency list |
956 java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context, new_deps); |
965 // is changed (both on addition and removal). Though memory reclamation is delayed, |
957 } |
966 // it avoids indefinite memory usage growth. |
|
967 deps.add_dependent_nmethod(nm, /*expunge_stale_entries=*/safe_to_expunge()); |
958 } |
968 } |
959 |
969 |
960 void MethodHandles::remove_dependent_nmethod(oop call_site, nmethod* nm) { |
970 void MethodHandles::remove_dependent_nmethod(oop call_site, nmethod* nm) { |
961 assert_locked_or_safepoint(CodeCache_lock); |
971 assert_locked_or_safepoint(CodeCache_lock); |
962 |
972 |
963 oop context = java_lang_invoke_CallSite::context(call_site); |
973 oop context = java_lang_invoke_CallSite::context(call_site); |
964 nmethodBucket* deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
974 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
965 |
975 deps.remove_dependent_nmethod(nm, /*expunge_stale_entries=*/safe_to_expunge()); |
966 if (nmethodBucket::remove_dependent_nmethod(deps, nm)) { |
|
967 nmethodBucket* new_deps = nmethodBucket::clean_dependent_nmethods(deps); |
|
968 if (deps != new_deps) { |
|
969 java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context, new_deps); |
|
970 } |
|
971 } |
|
972 } |
976 } |
973 |
977 |
974 void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) { |
978 void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) { |
975 assert_lock_strong(Compile_lock); |
979 assert_lock_strong(Compile_lock); |
976 |
980 |
977 int marked = 0; |
981 int marked = 0; |
978 CallSiteDepChange changes(call_site(), target()); |
982 CallSiteDepChange changes(call_site(), target()); |
979 { |
983 { |
|
984 No_Safepoint_Verifier nsv; |
980 MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
985 MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
981 |
986 |
982 oop context = java_lang_invoke_CallSite::context(call_site()); |
987 oop context = java_lang_invoke_CallSite::context(call_site()); |
983 nmethodBucket* deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
988 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
984 |
989 marked = deps.mark_dependent_nmethods(changes); |
985 marked = nmethodBucket::mark_dependent_nmethods(deps, changes); |
|
986 if (marked > 0) { |
|
987 nmethodBucket* new_deps = nmethodBucket::clean_dependent_nmethods(deps); |
|
988 if (deps != new_deps) { |
|
989 java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context, new_deps); |
|
990 } |
|
991 } |
|
992 } |
990 } |
993 if (marked > 0) { |
991 if (marked > 0) { |
994 // At least one nmethod has been marked for deoptimization |
992 // At least one nmethod has been marked for deoptimization. |
995 VM_Deoptimize op; |
993 VM_Deoptimize op; |
996 VMThread::execute(&op); |
994 VMThread::execute(&op); |
997 } |
995 } |
998 } |
996 } |
999 |
997 |
1329 java_lang_invoke_CallSite::set_target_volatile(call_site(), target()); |
1327 java_lang_invoke_CallSite::set_target_volatile(call_site(), target()); |
1330 } |
1328 } |
1331 } |
1329 } |
1332 JVM_END |
1330 JVM_END |
1333 |
1331 |
|
1332 // It is called by a Cleaner object which ensures that dropped CallSites properly |
|
1333 // deallocate their dependency information. |
1334 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) { |
1334 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) { |
1335 Handle context(THREAD, JNIHandles::resolve_non_null(context_jh)); |
1335 Handle context(THREAD, JNIHandles::resolve_non_null(context_jh)); |
1336 { |
1336 { |
1337 // Walk all nmethods depending on this call site. |
1337 // Walk all nmethods depending on this call site. |
1338 MutexLocker mu1(Compile_lock, thread); |
1338 MutexLocker mu1(Compile_lock, thread); |
1339 |
1339 |
1340 int marked = 0; |
1340 int marked = 0; |
1341 { |
1341 { |
|
1342 No_Safepoint_Verifier nsv; |
1342 MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
1343 MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
1343 nmethodBucket* b = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context()); |
1344 assert(safe_to_expunge(), "removal is not safe"); |
1344 while(b != NULL) { |
1345 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context()); |
1345 nmethod* nm = b->get_nmethod(); |
1346 marked = deps.remove_all_dependents(); |
1346 if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization()) { |
|
1347 nm->mark_for_deoptimization(); |
|
1348 marked++; |
|
1349 } |
|
1350 nmethodBucket* next = b->next(); |
|
1351 delete b; |
|
1352 b = next; |
|
1353 } |
|
1354 java_lang_invoke_MethodHandleNatives_CallSiteContext::set_vmdependencies(context(), NULL); // reset context |
|
1355 } |
1347 } |
1356 if (marked > 0) { |
1348 if (marked > 0) { |
1357 // At least one nmethod has been marked for deoptimization |
1349 // At least one nmethod has been marked for deoptimization |
1358 VM_Deoptimize op; |
1350 VM_Deoptimize op; |
1359 VMThread::execute(&op); |
1351 VMThread::execute(&op); |