Migrating the primitive boxes to values

Remi Forax forax at univ-mlv.fr
Sat Jan 26 11:49:20 UTC 2019


For 5, the first idea is to forward the call to the constructor to the factory method, but detecting the new + dup + invokespecial may be hard especially in the interpreter.
The other solution is to redirect the call to new to create a larval value type and have the invokespecial call to fill the larval buffer, but it means that the larval API (at least part of it) has to be included in the VM spec even if only to restricted to wrapper types :(

Rémi

----- Mail original -----
> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: "valhalla-spec-experts" <valhalla-spec-experts at openjdk.java.net>
> Envoyé: Vendredi 25 Janvier 2019 19:12:51
> Objet: Migrating the primitive boxes to values

> Let's take this problem from the other direction.  What are the
> impediments to us migrating the existing java.lang.Integer classes and
> friends to being values?  I think its pretty clear that "all things
> being equal", this is a better choice than creating new pox classes, and
> dealing with the sharp edges that entails.  So, what's stopping us?
> It's the usual suspects:
> 
> 1.  Equality.  People do `==` on hopefully-interned Integer values.  We
> advise against it, but they do.  Having these always fail would surely
> break lots and lots of code.
> 
> 2.  System.identityHashCode.  People put `Integer` in object graphs that
> get serialized; serialization will put them through IdentityHashMap.
> 
> 3.  Nullability.  These types are surely nullable; I think there's no
> turning back from that.
> 
> 4.  Locking.  While it seems dumb, there is surely code out there that
> locks on Integer instances.
> 
> 5.  Constructor access.  There are existing constructors, which we
> deprecated in 9.  Existing binaries will invoke them with
> new/dup/invokespecial rather than the appropriate value instantiation.
> 
> 
> My "Finding the Spirit" proposal offered a cure for 1: turn `==` into a
> substitutibility test.  For wrappers, this behaves as if all instances
> were interned, rather than just the numbers from zero to some small
> value; the spec warns that the range depends on runtime parameters.
> Combined with deprecating and eventually removing the constructors, this
> seems like it is a move that is within the range of the spec, and only
> would affect code that is relying on accidental identity.  Could we get
> away with this?
> 
> My proposed cure for (2) is similar: make identityHashCode on values
> return the "built-in hashCode" -- that is, the state-based hashCode that
> is the default for values if you don't override hashCode.
> 
> Nullability is a migration concern, shared by other types migrating to
> value types, so this is something we likely have to address regardless.
> 
> Which brings us to ... locking.  The two choices are: assign locking on
> values a state-based semantics (which no one really wants to do), or ...
> let code that locks on Integer just break. Both are obviously squirmy
> options.
> 
> Which brings me to my real point: if we go the latter route, when a big
> legacy customer with a big legacy codebase has their code broken by
> this, what happens next?  I know its really easy to say that we'll tell
> them they were making a mistake for 22 years and their bad behavior
> finally caught up with them, but this answer is rarely well received in
> reality.
> 
> It seems that if we can get comfortable with `==` being substitutibility
> (which I still think is a kind of forced move), and with outlawing
> locking on the primitive boxes -- both potentially big-ticket choices --
> then we can rehabilitate the existing boxes.  Which would be a nice
> place to be.


More information about the valhalla-spec-observers mailing list