Details
-
Improvement
-
Status: Resolved
-
Medium
-
Resolution: Done
-
None
-
None
Description
mdsal-binding-dom codec uses volatile fields in a number of places to implement thread-safe lazily-populated cache:
- CodecDataObject.cachedHashcode (double-checked locking)
- DataContainerCodecContext.eventStreamSerializer (concurrently-loaded cache)
- DataContainerCodecPrototype.instance (double-checked locking)
Accessing these fields causes synchronization actions and thus is subject to global synchronization order (https://docs.oracle.com/javase/specs/jls/se11/html/jls-17.html#jls-17.4.4) . This is strictly not necessary, as the objects being held by the field are immutable (#1), stateless (#2) or effectively-immutable (#3, with a documented quirk).
Of these, #3 is by far the most interesting, as it is accessed each time the corresponding CodecDataObject's property is filled – forcing these fills to occur in program order. Each such property is effectively immutable, hence this constraint of execution is not really needed.
Java 9+ allows us to improve the situation here by loosening synchronization to acquire/release on the field. This retains the basic semantics (fill-once) while allowing the runtime to better reorder accesses.
Attachments
| # | Subject | Branch | Project | Status | CR | V |
|---|---|---|---|---|---|---|
| 85994,3 | Use VarHandle for CodecDataObject hashCode cache | master | mdsal | Status: MERGED | +2 | +1 |
| 85995,3 | Switch streamer instantiation to VarHandles | master | mdsal | Status: MERGED | +2 | +1 |
| 85996,3 | Switch DataContainerCodecPrototype to VarHandles | master | mdsal | Status: MERGED | +2 | +1 |