Locking on primitive boxes
Brian Goetz
brian.goetz at oracle.com
Wed Feb 19 19:12:30 UTC 2020
I received the following reply, which is worth reading into the record:
> Brian,
>
> Let me add my 5 cents here. My fear is that actually removing (making
> private) constructors of primitive wrappers will break a lot of code
> legacy code out there. In fact, even today we use those constructors
> to work around limitations in HotSpot's escape analysis and allocation
> elimination. E.g. if you conditionally return the result of
> `Integer.valueOf(x)` from a method, then the allocation inside of the
> valueOf cannot be eliminated by HotSpot (that allocation is
> conditional itself and that is too much for HotSpot to see through),
> but if, on the other hand, you conditionally return the result of `new
> Integer(x)`, then HotSpot consistently eliminates this allocation.
>
> Sincerely,
> Roman Elizarov
It is notable that you bring up escape analysis here. The hiding of the
concrete constructors is something we are undertaking _precisely so we
can migrate these wrappers to inline classes_; making them inline
classes greatly improves the compiler's ability to eliminate
allocations. So I think this concern becomes "your grand plan, which
has as a benefit greatly improved escape analysis, will interfere with
my workarounds to get better escape analysis."
That said, it will take some time for existing uses to migrate away from
these constructors -- all the more reason to deprecate them for removal
earlier.
On 2/19/2020 11:45 AM, Brian Goetz wrote:
> One of the main impediments to migrating the primitive wrappers to be
> the reference projection of an inline class is locking -- there may be
> code out there that locks on instances of primitive wrappers. Let's
> look at how we might wean users off, and what the compatibility
> constraints really are.
>
> First, note that all the wrappers have had static `valueOf()`
> factories, and the corresponding constructors have been deprecated
> since Java 9. It would be reasonable to deprecate these for removal
> at any time. (These would not actually be removed, but instead made
> private.)
>
> Having removed the public constructors, now the only way to get your
> hands on an Integer is through some mechanism like `valueOf()`. I
> claim now that:
>
> Under such a scheme, any code outside of java.lang that
> synchronizes on a wrapper is
> inherently broken
>
> That is, it is synchronizing on an object whose locking protocol you
> are not party to, which is not guaranteed non-aliased, and which may
> in fact be permanently locked by some other thread. Therefore, it is
> a forseeable outcome for such a sync attempt to block forever.
>
> This was the intent behind https://openjdk.java.net/jeps/169, though
> it wasn't obvious from the title -- the ability to mark certain
> objects as permanently locked.
>
> So, concrete proposal:
>
> - Move forward with the deprecation-for-removal of the constructors;
>
> - Add hortatory notes in the spec for `valueOf()` that locking on
> objects whose provenance you do not control is a risky business, and
> may well never complete;
>
> - Poison instances of primitive wrappers by marking their headers at
> creation with a bit pattern that will send locking through the slow
> path, where it can see that these are poisoned objects and cause lock
> attempts to never complete (or throw)
>
> - Provide a JDK-scoped option to turn off the above behavior
> (-Xx:AllowStupidBrokenLockingOnPrimitiveWrappers)
>
> I don't see anything stopping us from doing any of these immediately.
>
>
>
More information about the valhalla-spec-observers
mailing list