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?  :-)

Reply via email to