The two systems would now compete for unloading nmethods, and the responsibility of throwing away nmethods would blur. The sweeper was still good at throwing away nmethods faster as it only needs to scan stacks, and not do a full GC.
With the advent of Loom, the situation has gotten even worse. The stacks are now also in the Java heap. The sweeper is unable to throw away nmethods without the liveness analysis of a full GC, which also performs code cache unloading, but isn't allowed to actually delete nmethods due to races with the sweeper. In a way we have the worst of both worlds, where both the sweeper and GC are crippled, unable to unload nmethods without the help of the other. And there are a very large number of complicated races that the JVM needs to deal with, especially with concurrent code cache unloading not interfering with concurrent sweeping. And concurrent sweeping not interfering with the application.
The sweeper cycle exposes 2 flavours of nmethods that are "dead" to the system. So whenever nmethods are used, we have to know they are not dead. But we typically don't have the tools to really know they are not dead. For example, one might think grabbing the CodeCache_lock and using an iterator that only walks is_alive() nmethods would help make sure you don't get dead nmethods in your iterator. However, that is not the case, because the CodeCache_lock can't be held across the entire zombie transition due to "reasons" that are not trivial to actually change. Because of this, code has to deal with nmethods flipping around randomly to a dead state.
I propose to get out of this sad situation, by removing the sweeper. If we need a full GC anyway to remove nmethods, we might as well let the GC do everything. This removes the notion of is_zombie(), is_unloaded() and hence is_alive() from the JVM. It also removes the notion of the orthogonal but related nmethodLocker to keep nmethods around, without preventing them from dying. We instead throw away nmethods the way we throw away pretty much anything else in the unloading GC code:
1. Unlink
2. Global sync
3. Throw away
4. Profit!
This way, if you get a reference to an nmethod, it won't go away until the next safepoint poll, and will not flip around liveness due to concurrent transitions.
- is blocked by
-
JDK-8290688 Optimize x86_64 nmethod entry barriers
- Resolved
-
JDK-8290700 Optimize AArch64 nmethod entry barriers
- Resolved
- relates to
-
JDK-8336757 [JVMCI] "Hosted" JVMCI compilations should trigger JVMTI CompiledMethodLoad events
- Open
-
JDK-8294729 [s390] Implement nmethod entry barriers
- Resolved
-
JDK-8293782 Shenandoah: some tests failed on lock rank check
- Resolved
-
JDK-8295724 VirtualMachineError: Out of space in CodeCache for method handle intrinsic
- Resolved
-
JDK-8325613 CTW: Stale method cleanup requires GC after Sweeper removal
- Resolved
-
JDK-8294064 Regression ~2% in 20-b13 on SPECjvm2008-XML.validation-G1 after JDK-8290025
- Closed
-
JDK-8291302 ARM32: nmethod entry barriers support
- Resolved
-
JDK-8292972 Initialize fields if CodeBlobIterator shortcuts without heaps
- Resolved
-
JDK-8302462 [REDO] 8297487: G1 Remark: no need to keep alive oop constants of nmethods on stack
- Resolved
-
JDK-8317809 Insertion of free code blobs into code cache can be very slow during class unloading
- Resolved
-
JDK-8297864 Dead code elimination
- Resolved
-
JDK-8297487 G1 Remark: no need to keep alive oop constants of nmethods on stack
- Closed
-
JDK-8344141 [perf] sert::capacity 5% regression for jdk20+13 vs jdk20+12
- Open
-
JDK-8283849 AsyncGetCallTrace may crash JVM on guarantee
- Resolved
-
JDK-8295069 [PPC64] Performance regression after JDK-8290025
- Resolved
-
JDK-8306768 CodeCache Analytics reports wrong threshold
- Resolved
-
JDK-8288970 G1 does not keep weak nmethod oops alive
- Closed
-
JDK-8293824 gc/whitebox/TestConcMarkCycleWB.java failed "RuntimeException: assertTrue: expected true, was false"
- Closed
-
JDK-8296101 nmethod::is_unloading result unstable with concurrent unloading
- Closed
-
JDK-8317806 Aarch64 10x+ slower at clearing IC callsites than x64 causes long code cache unloading times
- In Progress
-
JDK-8316670 Remove effectively unused nmethodBucket::_count
- Resolved
-
JDK-8327289 Remove unused PrintMethodFlushingStatistics option
- Resolved
-
JDK-8295920 remove nmethodBucket::_count
- Closed