JDK-8229377 : [JVMCI] Improve InstalledCode.invalidate for large code caches
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 11.0.7-oracle,14
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-08-09
  • Updated: 2020-03-23
  • Resolved: 2019-12-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 14 JDK 15
11.0.7-oracleFixed 14 b27Fixed 15Fixed
Related Reports
Duplicate :  
Description
InstalledCode.invalidate can be used for direct invalidation of an nmethod.  The current code reuses VM_Deoptimize which scans the entire code cache to find the nmethod and make it not entrant.  This is obviously inefficient for large code caches.
Comments
OpenJDK 11 updates backport will follow after larger Graal integration, see https://github.com/oracle/graal/issues/2196
11-03-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/56e1977e435a User: never Date: 2019-12-12 01:19:17 +0000
12-12-2019

I have converted this back into an enhancement since I've separated the other issue from this one.
11-12-2019

This is supposed to fix JDK-8230884 and JDK-8229961, therefore converting to a bug. ILW = Assert due to locking on zombie method, intermittent with Graal Unit Tests, disable Graal as JIT = HLM = P3
12-09-2019

I forgot that the MutexUnlocker also needs that flag. I'll add it.
23-08-2019

Yes, as in your suggestion: { // Enter critical section. Does not block for safepoint. MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag); if (nm->is_alive()) { nmethodLocker nml(nm); MutexUnlocker unlock(Patching_lock); // End of critical section. // Invalidating the HotSpotNmethod means we want the nmethod // to be deoptimized. nm->mark_for_deoptimization(); VM_Deoptimize op; VMThread::execute(&op); } }
23-08-2019

Did you use the Mutex::_no_safepoint_check_flag? Patching_lock isn't allowed to do safepoint checks.
23-08-2019

I ran tests with this and it seems we can't use Patching_lock in Java thread: # Internal Error (open/src/hotspot/share/runtime/mutex.cpp:42), pid=22056, tid=23185 # assert(!thread->is_active_Java_thread() || _safepoint_check_required != not_allowed) failed: This lock should never have a safepoint check for Java threads: Patching_lock V [libjvm.so+0x135a494] Mutex::check_safepoint_state(Thread*, bool)+0xa4 V [libjvm.so+0x135c0b1] Mutex::lock(Thread*)+0x21 V [libjvm.so+0xfeb105] JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject, JVMCIEnv*)+0x255 V [libjvm.so+0xf8b7c5] c2v_invalidateHotSpotNmethod(JNIEnv_*, _jobject*, _jobject*)+0x145 j jdk.vm.ci.hotspot.CompilerToVM.invalidateHotSpotNmethod(Ljdk/vm/ci/hotspot/HotSpotNmethod;)V+0 jdk.internal.vm.ci@14-internal j jdk.vm.ci.hotspot.HotSpotNmethod.invalidate()V+4 jdk.internal.vm.ci@14-internal j org.graalvm.compiler.hotspot.test.CompileTheWorld.compileMethod(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;ILorg/graalvm/compiler/hotspot/test/CompileTheWorld$LibGraalParams;)V+307
22-08-2019

Yes, that is what I am looked for! I will go with this solution in JDK-8229961.
22-08-2019

I don't think reordering those tests changes the race. Don't you need to lock the patching lock to ensure the nmethod state doesn't change underneath you? It seems like the code must look like this: void VM_DeoptimizeNMethod::invalidate(nmethod* nm) { // Enter critical section. Does not block for safepoint. MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); if (nm->is_alive()) { nmethodLocker nml(nm); MutexUnlocker unlock(Patching_lock); // Invalidating the HotSpotNmethod means we want the nmethod // to be deoptimized. nm->mark_for_deoptimization(); VM_DeoptimizeNMethod op(nm); VMThread::execute(&op); } }
22-08-2019

[~never] Consider moving nmethodLocker under nm->is_alive() check in VM_DeoptimizeNMethod::invalidate(). I am working on JDK-8229961 which shows that could be problem.
21-08-2019