JDK-8145371 ClassCastException thrown in LambdaFormEditor.getInCache
paul.sandoz at oracle.com
Tue Jan 9 22:42:17 UTC 2018
> On 9 Jan 2018, at 14:20, Martin Buchholz <martinrb at google.com> wrote:
> The memory model is already too hard to reason about, but here the VM can assume that the final fields will never be mutated - yet they are!
Because of reflection and Field/AccessibleObject.setAccessible the VM is conservative and does not in general assume final fields are really final. Because of that we miss out on some juicy optimisations. We have made some inroads into limiting the use of setAccessible. If we can deprecate and remove it we can make progress on generally applying "final means final” to all Java code (which also means tackling the case of deserialisation).
> With the special j.l.invoke guarantees, there should be no need for final fields to additionally have @Stable annotations, yet many do!
In j.l.invoke I only found one redundant @Stable annotated field on MethodType:
private final @Stable Class<?> rtype;
All the others are on non-final fields or array fields where the stable semantics are propagated to array elements.
> LambdaForm is a mutable class, so publishing it via a plain Unsafe write is a (tiny, hard to detect) data race. I would feel much more comfortable replacing the Unsafe put with a putVolatile and dropping the fence. Whenever the form field is read, perhaps it should be explicitly read via a volatile or acquire read for safety.
That would incur a cost. j.l.invoke contains code that has carefully arranged interactions with the runtime compilers, this is one of those cases.
More information about the core-libs-dev