A return barrier is a patched return PC word that vectors to some kind of fixup code and then eventually returns to the actual caller (the un-patched return PC word). There are several variations on this theme in HotSpot, and more seem to be in our future. For better maintainability and robustness, there should be just one (or as few as possible) such mechanisms.
A patched return PC can only be patched to one value. This means that if there are two extra events in modules A, B that need to happen on return, then we need to avoid a situation where A is patched and then B overwrites the patch of A, causing the event for A to be lost. We avoid this by having A know about B, and/or B know about A. So if B "sees" A's return PC patch, B takes on the burden of executing A's fixup logic. This pattern can be continued for B, C, D, etc., but the couplings between the modules are excessive.
Also, a stack walker may need to recognize all possible return patches. This adds more cross-module couplings. It's probably harder to maintain and more prone to bugs than a single integrated mechanism X which handles all requests for A, B, etc.
This enhancement calls for such a mechanism X.
Possible current uses of X:
- deoptimize caller on return
- execute JVMTI action on return
Possible future uses of X:
- thaw Loom continuation frame on return
- free frame-local resources on return (Loom? tail-call argument storage?)
- remove doPrivileged protection domain marker?
- release frame-local resource reservation (spare heap for OOM processing)?
- perform some other VM-managed cleanup
- emit JFR event or increment external performance counter (after dynamic registration of interest)
- concurrent thread stack scanning (ZGC)
A patched return PC can only be patched to one value. This means that if there are two extra events in modules A, B that need to happen on return, then we need to avoid a situation where A is patched and then B overwrites the patch of A, causing the event for A to be lost. We avoid this by having A know about B, and/or B know about A. So if B "sees" A's return PC patch, B takes on the burden of executing A's fixup logic. This pattern can be continued for B, C, D, etc., but the couplings between the modules are excessive.
Also, a stack walker may need to recognize all possible return patches. This adds more cross-module couplings. It's probably harder to maintain and more prone to bugs than a single integrated mechanism X which handles all requests for A, B, etc.
This enhancement calls for such a mechanism X.
Possible current uses of X:
- deoptimize caller on return
- execute JVMTI action on return
Possible future uses of X:
- thaw Loom continuation frame on return
- free frame-local resources on return (Loom? tail-call argument storage?)
- remove doPrivileged protection domain marker?
- release frame-local resource reservation (spare heap for OOM processing)?
- perform some other VM-managed cleanup
- emit JFR event or increment external performance counter (after dynamic registration of interest)
- concurrent thread stack scanning (ZGC)
- relates to
-
JDK-8214584 stackwalk returns null for scalar-replaced value
- Open