The last miles

John Rose john.r.rose at oracle.com
Thu Jul 13 20:55:42 UTC 2023


P.S. If the original designers of Java bytecode had allowed <init> to allocate its own object, and return it, we’d be having a different discussion.  I wish it had been like that.  I think it is a false economy to have “new X(…)” and “super(…)” call the same method symbol; that is the root of many evils.

On 13 Jul 2023, at 13:52, John Rose wrote:

> On 13 Jul 2023, at 7:24, Brian Goetz wrote:
>
>> This is a good thought; we split the initialization protocol and its a fair question to ask whether we can go back to a lump.
>>
>> In this case, I suspect John is about to say “Please let’s not give the verifier any more jobs to do.”
>
> It is that, and even worse.  If you work the details, you’ll quickly run into the fact that the <init> protocol (for Java constructors) builds an object but does not return the new object, it takes the new object from the caller in a tabula rasa (blank) state, and pokes values into it.  Worse, the new object is supplied (by a new opcode) from an untrusted (even hostile) client.  That means that the verifier needs complex rules (>10% of the total complexity) to track these untrusted-but-trusted blank objects and make sure they are handed to <init> before being used.  That’s bad.  We have a steady bug stream from this very delicate machinery.  Maybe it’s done after a quarter century but I wouldn’t bet the farm on that.
>
> Worse still, for values, there is no architecturally defined state, for values, which corresponds to the “tabula rasa” state of the receiver of an <init> call.  We know something of that state; it is called a “larval object”, but the Valhalla JVMS does not define or rely on it.  The proposed “unification” would require us to somehow simulate larval objects in terms of today’s blank identity objects, and define how the larval-to-adult state transition works, or it would have to build new verifier rules for larval objects (mutable while <init> runs, then pure values after that).  Either option seems much worse than what we have chosen to do so far.
>
> What we have chosen to do so far is have a functionally clean model for value objects that does not require mutability, either temporary (larval-only) or permanent (I shudder at that thought). This functionally clean model uses withfield instead of getfield, and aconst_init instead of the “new” opcode.  I think that is a great trade, because it lets us off the hook from defining mutability into values, at any stage of their lifetimes.
>
> Yes, serialization smuggles larval mutability back in, but that’s a private matter of optimization, between the VM and JDK.  I really don’t want to see that in the JVMS, because it would be just as hairy and complex and bug-prone as today’s new/<init> dance.  Yes, we should use the old mechanisms when we can, and we do!  But the new/<init> dance is, IMO, hopelessly entangled with a presupposition of object identity, and also hopelessly buggy; so I don’t think it can help us, and I wouldn’t touch to extend it even if I thought it might help.
>
> How’s that?  :-)


More information about the valhalla-spec-observers mailing list