A value in an object field cannot be constant-folded even when the field is marked 'final' and the enclosing object itself can be determined at compile time. This is because 'final' fields are not enforced by the JVM.
The long term fix for this is to properly optimize the common case of any field which is set in an object constructor and then never changed, not even by reflection or JNI.
This is a performance issue for various system data structures, which is patched for specific classes like method handle combinators and strings. We need general-purpose logic, since the number of performance-affecting final fields is trending upward.
The fix for the previous bugJDK-6912065 includes an experimental JVM flag -XX:+TrustFinalNonStaticFields for performance experiments. But that is not a general fix, because it does not check for store-to-final events caused by reflection, JNI, Unsafe, deserialization, etc.
I think the hard part is convincing ourselves that we have found all the places where the surprising store-to-final could occur. The straightforward part is putting a little interlock in each of those places to discard code blocs (n-methods) that rely on the field suffering the store.
We would create a new JIT dependency for registering which code blobs speculate against store-to-final. It can be made nicely granular, by indexing on the class containing the final, rather than having a global "panic button". We also need a record of which finals had been "spoiled" in this way; this can be a bit on the containing class.
Deserialization of objects with finals might create false positives; it is moderately likely that this is worth special-casing. For example, the final field java.util.Arrays.ArrayList.a is both deserialized and performance-affecting.
The long term fix for this is to properly optimize the common case of any field which is set in an object constructor and then never changed, not even by reflection or JNI.
This is a performance issue for various system data structures, which is patched for specific classes like method handle combinators and strings. We need general-purpose logic, since the number of performance-affecting final fields is trending upward.
The fix for the previous bug
I think the hard part is convincing ourselves that we have found all the places where the surprising store-to-final could occur. The straightforward part is putting a little interlock in each of those places to discard code blocs (n-methods) that rely on the field suffering the store.
We would create a new JIT dependency for registering which code blobs speculate against store-to-final. It can be made nicely granular, by indexing on the class containing the final, rather than having a global "panic button". We also need a record of which finals had been "spoiled" in this way; this can be a bit on the containing class.
Deserialization of objects with finals might create false positives; it is moderately likely that this is worth special-casing. For example, the final field java.util.Arrays.ArrayList.a is both deserialized and performance-affecting.
- relates to
-
JDK-8140483 Atomic*FieldUpdaters final fields should be trusted
-
- Resolved
-
-
JDK-6912065 final fields in objects need to support inlining optimizations for JSR 292
-
- Resolved
-
-
JDK-8233873 final field values should be trusted as constant
-
- Open
-
-
JDK-8334754 C2: Optimize accesses to provably final instance fields
-
- Open
-
-
JDK-8087218 Constant fold loads from final instance fields in VM anonymous classes
-
- Resolved
-
-
JDK-8132243 Optimize Final Field Loads In Generated Code
-
- Draft
-
(1 relates to)