Comments on JDK-8198408 please ?

John Rose john.r.rose at oracle.com
Mon Feb 26 21:46:24 UTC 2018


On Feb 26, 2018, at 9:04 AM, Srikanth <srikanth.adayapalam at oracle.com> wrote:
> 
> 
> Frederic and I have been discussing the code sequence that javac should produce for certain
> more involved attempts to update value fields using withfield.
> 
> Basically for the test case in JDK-8198408, what should be the bytecode generated for
> 
> d.c.b.a.x = 11;
> 
> where x is an int field and a, b, c and d are value classes. I imagine 
> this would call for a.x to be updated via withfield to obtain a', b.a to be updated with a' using withfield to obtain b', 
> c.b to be updated with b' using withfield to obtain c' and d.c to be updated with c' using withfield 
> to obtain d' and for d' to be finally stored back into d - Is that correct ?? 

This is taking us away from the close coupling between value-based classes
and value types.  I'm pretty sure it's a bad road with no good destinations.

Notice that none of these expressions has a meaning which can be predicted
by referring to value-based object classes:

 a.x = 11;
 a.p.x = 11;
 …
 a.p.q.r.s.x = 11;

Not even the first has a meaning predicted from standard Java, since x
is a final field in a value-based class.  (The other p/q/r/… fields are final,
but the whole process stops immediately with x.)

Years ago, at the inception of the value types project, we considered a
number of alternative ways to give a meaning to all of these expressions.
They are all overly complex for the limited amount of expressiveness
we think they will purchase.

- disallow (the decision we made)
- turn single level assignment into withfield, disallow others
- allow multiple-level assignment to resolve to subfield descriptors
- generate nested dup;getfield;…;withfield sequences
- make field assignment a distinct API point

The basic problem is that we have to bend the meaning of a.x = 11 with
a value type, to include a change to the value of a.  No other Java construct
does this.  This is why it's a puzzle to wedge value field assignment into
the language.

Other languages have constructs like this.  Nested (flat) C structs behave
like this—and almost nobody uses this language feature.  Some languages
have elaborate property-definition mechanisms which can endow such
reference chains with assignable behavior (JS, Perl, VB, looking at you).
But we don't want to go there; at the very least we don't want to get on
a slippery slope that slides us into programmable properties.

> This calls for non-trivial changes to be made to javac - I don't think it is a blocker issue, a solution can be 
> found quickly, but it is a radical departure from how code generation in Javac works today. 

More fundamentally, even the single level assignment a.x = 11 is a
radical departure.  So it's no surprise that javac is unready for such things.

> (at the time of withfield emission for updating a.x with 11, the expression stack has been mostly drained and 
> has no trace of the complex sequence of operations that led up to that point. When a' is computed 
> by updating a.x with 11 using withfield, we reach a dead end - there is nothing in the expression stack to write 
> back to. When the updated field is an instance of field of a value instance that is a local variable, the problem 
> is lot simpler - all it calls for an astore which does not expect much from the expression stack as far as the destination 
> is concerned, the astore opcode fully specifies the destination)

Even if we support single-level field assignment (as twisted sugar for
withfield) we should *not* support multiple-level field assignment.

In fact, I'm doubting (again, after several years) the wisdom of allowing
even the single-level x.a = 11.  It seems to lead the user model into a
swamp.  And also contains a paradox, that a subexpression on the LHS
of an assignment gets modified, in addition to the whole LHS.

Dan Smith once very tentatively suggested defining a new compound
assignment operation to capture the subexpression changing behavior,
something vaguely like x += __Edit(a = 11).  There are lots of variations on
such syntaxes; they are easy to come up with.  And of course the
compound assignment always goes with a plain non-assignment
operator, which would be a very direct representation for withfield,
something like y=__Edit(x, a = 11) or y=__Edit(x.a, 11).

I think we want some sort of "reconstructor" mechanism like _Edit
for scoped-in-place modification of value types.  It will take a while
to work out the details of such a thing.

Meanwhile, to provide withfield encodings, the single-level a.x=11
is acceptable, given the understanding that *it will probably go away*
when we figure out a story that allows a more natural notation.

(By natural I mean not natural to existing Java but natural to the
semantic structure of value types.  Something like WITH in VB
or Modula-3, or something like Java constructor bodies,
sprinkled into other code as sub-blocks.)

We could also represent withfield directly with a temporary
extra operator:  __WithField(a.x, 11).  I think I'd prefer that,
because it's more obviously a temporary expedient to be
replaced later.  Would that be difficult to prototype in javac?

> Could the experts weigh in on the required sequence please - before we go down too far deep in implementing anyone presumed sequence ?

Thanks for asking.  See above; I think this represents significant
parts of Brian's thinking as well as my own.

— John


More information about the valhalla-dev mailing list