[External] : Re: EG meeting, 2021-11-17

John Rose john.r.rose at oracle.com
Wed Nov 24 06:48:32 UTC 2021


On Nov 22, 2021, at 5:13 PM, Dan Smith <daniel.smith at oracle.com> wrote:
> 
>> On Nov 22, 2021, at 2:07 PM, Kevin Bourrillion <kevinb at google.com> wrote:
>> 
>>> On Mon, Nov 22, 2021 at 6:27 AM Dan Heidinga <heidinga at redhat.com> wrote:
>>> 
>>> I'll echo Brian's comment that I'd like to understand Kevin's use
>>> cases better to see if there's something we're missing in the design /
>>> a major use case that isn't being addressed that will cause useer
>>> confusion / pain.
>>> 
>> Sorry if I threw another wrench here!
>> 
>> What I'm raising is only the wish that users can reasonably default to B2-over-B1 unless their use case requires something on our list of "only B1 does this". And that list can be however long it needs to be, just hopefully no longer. That's probably how we were looking at it already.
> 
> Here's the current list, FYI (derived from JEP 401):
> 
> 	• Implicitly final class, cannot be extended.

JVMS requires ACC_FINAL on class.

> 	• All instance fields are implicitly final, so must be assigned exactly once by constructors or initializers, and cannot be assigned outside of a constructor or initializer.

JVMS requires ACC_FINAL on every instance field.  (Static fields OK.)

> 	• The class does not implement—directly or indirectly—IdentityObject. This implies that the superclass is either Object or a stateless abstract class.

JVMS requires a check for this.

> 	• No constructor makes a super constructor call. Instance creation will occur without executing any superclass initialization code.

JVMS rules for invokespecial <init> must exclude this.

> 	• No instance methods are declared synchronized.

JVMS forbits ACC_SYNC. on all instance methods.  (Static methods OK.)

> 	• (Possibly) The class does not implement Cloneable or declare a clone()method.
> 	• (Possibly) The class does not declare a finalize() method.

A conservative move is to forbid these things, in language and JVMS.
Minor precedent:  record has similar special cases (for component names).

> 	• (Possibly) The constructor does not make use of this except to set the fields in the constructor body, or perhaps after all fields are definitely assigned.

JVMS doesn’t care about this.

The private opcodes initialvalue and withfield work to set up ’this’
as the constructor executes.  It’s OK to sample the value at any time,
but maybe the language says, “don’t do that”.

I think there are use cases for private methods to work on partially
initialized stuff.  The theory is tricky.  OK to be conservative now
and more lenient later.

> 
> And elaborating on IdentityObject & stateless abstract classes:
> 
> An abstract class can be declared to implement either IdentityObject or ValueObject; or, if it declares a field, an instance initializer, a non-empty constructor, or a synchronized method, it implicitly implements IdentityObject (perhaps with a warning).

JVMS should enforce corresponding structural rules on loaded classfiles.
Neither a source class-or-interface nor a loaded classfile can ever
implement both IO and VO at the same time.

As a special feature in the JVM I want an explicit form for these
“empty constructors”.  We’ve discussed this; I’m not sure which form
is best, but I don’t want it to be a “not-really-empty” constructor which
has a super-call in it; that’s what seemingly “empty” constructor look
like today to the JVM.

The JVM should both allow and require an empty constructor if
and only if the abstract class implements VO.  (Alternative:
The JVM implicitly injects VO if it sees an empty constructor,
and if it sees VO it looks for an empty constructor.)

IIRC maybe our last consensus was to add an attribute to an
<init> method of signature ()V that says, “whatever you think
you see in this method, Mr. VM, please also feel free to skip it.”
That’s a more hacky way to specify an empty constructor than
would be my preference (which is an ACC_ABSTRACT <init>()V
or even a zero-length class attribute).  If a VO-only abstract
has an <init>()V method, that’s a smell, because it will never
be used!  OTOH, maybe just being a VO-0nly abstract class is
enough to tell the JVM that the constructor is empty, with
no further markings.  Anyway, there’s a little corner of the
design space to consider here.

> Otherwise, the abstract class extends neither interface and can be extended by both kinds of concrete classes.

Such a class is very handy.  It needs *both kinds of constructors*.

Are you thinking that just mentioning the special VO super is
enough to trigger inclusion of an empty constructor?  That’s
probably a good move.  Is this the *only* way to request an
empty constructor, or is there a way to make an explicit
empty constructor?  (I mean a really-empty one, not just
today’s seemingly-empty ones.  Even Object’s empty constructor
has an areturn instruction, so it’s not really empty.)

> (Such a "both kinds" abstract class has its ACC_PRIM_SUPER—name to be changed—flag set in the class file, along with an <init> method for identity classes.)

Yes, that makes sense.  So maybe a VO-capable abstract class
is always assumed to have an implicit empty constructor,
even if there is no other marking than the PRIM_SUPER?
I guess that’s OK for the JVM.  For the source language it
might be too magic.



More information about the valhalla-spec-observers mailing list