RFR: 8340812: LambdaForm customization via MethodHandle::updateForm is not thread safe
David Holmes
dholmes at openjdk.org
Sun Sep 29 23:55:41 UTC 2024
On Sun, 29 Sep 2024 22:39:28 GMT, Chen Liang <liach at 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
More information about the core-libs-dev
mailing list