1062 |
1062 |
1063 // return number of elements we at leasted wanted to initialize |
1063 // return number of elements we at leasted wanted to initialize |
1064 return rfill + overflow; |
1064 return rfill + overflow; |
1065 } |
1065 } |
1066 |
1066 |
1067 // Is it safe to remove stale entries from a dependency list? |
|
1068 static bool safe_to_expunge() { |
|
1069 // Since parallel GC threads can concurrently iterate over a dependency |
|
1070 // list during safepoint, it is safe to remove entries only when |
|
1071 // CodeCache lock is held. |
|
1072 return CodeCache_lock->owned_by_self(); |
|
1073 } |
|
1074 |
|
1075 void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) { |
1067 void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) { |
1076 assert_locked_or_safepoint(CodeCache_lock); |
1068 assert_locked_or_safepoint(CodeCache_lock); |
1077 |
1069 |
1078 oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site); |
1070 oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site); |
1079 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
1071 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
1080 // Try to purge stale entries on updates. |
1072 // Try to purge stale entries on updates. |
1081 // Since GC doesn't clean dependency contexts rooted at CallSiteContext objects, |
1073 // Since GC doesn't clean dependency contexts rooted at CallSiteContext objects, |
1082 // in order to avoid memory leak, stale entries are purged whenever a dependency list |
1074 // in order to avoid memory leak, stale entries are purged whenever a dependency list |
1083 // is changed (both on addition and removal). Though memory reclamation is delayed, |
1075 // is changed (both on addition and removal). Though memory reclamation is delayed, |
1084 // it avoids indefinite memory usage growth. |
1076 // it avoids indefinite memory usage growth. |
1085 deps.add_dependent_nmethod(nm, /*expunge_stale_entries=*/safe_to_expunge()); |
1077 deps.add_dependent_nmethod(nm); |
1086 } |
1078 } |
1087 |
1079 |
1088 void MethodHandles::remove_dependent_nmethod(oop call_site, nmethod* nm) { |
1080 void MethodHandles::remove_dependent_nmethod(oop call_site, nmethod* nm) { |
1089 assert_locked_or_safepoint(CodeCache_lock); |
1081 assert_locked_or_safepoint(CodeCache_lock); |
1090 |
1082 |
1091 oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site); |
1083 oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site); |
1092 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
1084 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
1093 deps.remove_dependent_nmethod(nm, /*expunge_stale_entries=*/safe_to_expunge()); |
1085 deps.remove_dependent_nmethod(nm); |
|
1086 } |
|
1087 |
|
1088 void MethodHandles::clean_dependency_context(oop call_site) { |
|
1089 assert_locked_or_safepoint(CodeCache_lock); |
|
1090 |
|
1091 oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site); |
|
1092 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context); |
|
1093 deps.clean_unloading_dependents(); |
1094 } |
1094 } |
1095 |
1095 |
1096 void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) { |
1096 void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) { |
1097 assert_lock_strong(Compile_lock); |
1097 assert_lock_strong(Compile_lock); |
1098 |
1098 |
1498 |
1498 |
1499 int marked = 0; |
1499 int marked = 0; |
1500 { |
1500 { |
1501 NoSafepointVerifier nsv; |
1501 NoSafepointVerifier nsv; |
1502 MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
1502 MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
1503 assert(safe_to_expunge(), "removal is not safe"); |
|
1504 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context()); |
1503 DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context()); |
1505 marked = deps.remove_all_dependents(); |
1504 marked = deps.remove_all_dependents(); |
1506 } |
1505 } |
1507 if (marked > 0) { |
1506 if (marked > 0) { |
1508 // At least one nmethod has been marked for deoptimization |
1507 // At least one nmethod has been marked for deoptimization |