Migrating the primitive boxes to values

John Rose john.r.rose at oracle.com
Mon Sep 30 23:49:46 UTC 2019

We’ve been round and round on this one in various discussions, and I think our
answer is probably documented somewhere, but here’s a quick summary:

1. We will never endow every value at creation with an object identity.  (And an object identity is that thing which connects side-effecting writers to readers of their side effects.  And monitor locking is a side effect.)

2. Nor will we allow a side-effecting channel that can somehow add an object identity to all occurrences of the “same value”.  That’s just sneaking in object identities again, to define “same” in a way that allows side effects between occurrences of the “same value”.  Try to imagine assigning an object identity to all occurrences of some number “42”, that somehow “were copied from the same source”.  It doesn’t work; 42 is 42, globally.  Same thing with values.

3. Therefore, if we were to go through the motions of locking an inline value by assigning it an object identity, we would need to make a context-free choice of which identity to use.

4. We could build a fresh box on every monitor-enter event.  The effect of that would be to have all such locks be uncontended.  That’s a no-op.  Making locking on values into a no-op is asking for bugs, so we won’t do that.  (Example code from today:  “synchronized ((Object) 999999999) { }”.)

5. We could try to track “the same value” through local code paths and somehow assign the same box.  This is asking for even worse bugs, since it’s anybody’s guess which occurrences of “the same” value will be assigned the same box.

6. We could rummage around the universe to see if anybody else has previously built a box for the *same value*, and use that box.  (Example code from today:  “synchronized ((Object) 9) { }”.)  That requires a large dictionary of all inline values ever (mis-)treated in this way, which is expensive.  (Weak links make it slightly less costly.) Supplying such a table encourages its use; it’s an expense we wish to take on only if absolutely necessary, not just because someone says “why don’t you…”.

7. The safest thing is to break a minor compatibility to save a major one.  We say, “You can’t lock on an int, nor can you lock on an inline value.”  The locking operations on Object become partial, throwing exceptions for some inputs.  Having Object as a top-type is tremendously valuable, even at the expense of making some operations (those that require an object *identity*) into partial throwing operations.  It’s the best trade-off that we know of (and we know a lot of them, intimately by now).


— John

On Sep 30, 2019, at 1:12 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> Received on the -comments list (some time ago).  
> -------- Forwarded Message --------
> Subject:	Migrating the primitive boxes to values
> Date:	Sat, 26 Jan 2019 00:07:53 -0800
> From:	Jack Ammo <jackammo77 at gmail.com> <mailto:jackammo77 at gmail.com>
> To:	valhalla-spec-comments at openjdk.java.net <mailto:valhalla-spec-comments at openjdk.java.net>
> From an outsider's perspective, i'd like to ask a perhaps naive question
> about the locking issue on values. Instead of just opting to break existing
> code as you seem to be worried about, why not just box the value before
> locking? Assuming that a boxing conversion to a full fledged Object is
> still kicking around as a fall back, this seems like the most familiar
> option to me as a developer: i can technically do the lock on an Integer
> but it is not advised and results are not guaranteed. I understand that
> everyone has worked hard to avoid the cost of boxing, but in this
> particular case it seems like a decent option that is the least difficult
> to wrap my mind around. Locking requires a full Object, so values (like an
> int) need to be boxed as such.

More information about the valhalla-spec-observers mailing list