On Sun, 29 Sep 2024 22:39:28 GMT, Chen Liang <li...@openjdk.org> wrote:
>> src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 1882: >> >>> 1880: assert (newForm.customized == null || >>> newForm.customized == this); >>> 1881: newForm.prepare(); // as in MethodHandle.<init> >>> 1882: UNSAFE.putReferenceRelease(this, FORM_OFFSET, >>> newForm); // properly publish newForm >> >> A full-fence is a one-sided global synchronization action. A "release" store >> is one side of a two-sided synchronization action: where is the >> "load-acquire" that this pairs with? > > The `form` field is a final field; thus, all reads to that field is a > load-acquire. This load-load barrier is critical to ensure observing the > correct, non-null `vmentry` field value if the updated form is observed. > > Note that JIT compilation may constant-fold the preexisting form and ignore > the updated form. This is still behaviorally identical, but usually the new > form is more suitable for constant folding if JIT compilation can pick it up. That's not exactly how final fields are specified. It is hard to see here exactly what fields/objects are involved in this case. The final field semantics only provide load-acquire-like semantics if you dereference the final field after the freeze action in the constructor. And our use of Unsafe here means we are stepping outside any JLS guarantees anyway. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/21160#discussion_r1780208741