Replying to both this and the previous email in one:

> I guess I prefer C and D over A and B because of the reflection magic problem,
> and also because of Dan H’s issue (IIUC) about “where do we look for the
> metadata, if not in somebody’s constant pool?”

+1 I prefer C or D as well for similar reasons.

> Since D and C have about equal practical effect, and D is both simpler to
> specify and less ceremony, I prefer D best of all.
>
> I agree that ACC_VALUE is useful to prevent “action at a distance”.
>
> There is the converse problem that comes from the redundancy:
> What happens if the class directly implements or inherits ValueObject
> and ACC_VALUE is not set?  I guess that is an error also.

That's the unfortunate part of having two ways to say things and why I
really liked Brian's suggestion to only have the interface.  The VM
can infer the bit from the presence of the interface, especially if we
went with option C as the interface would always be directly present
in the value classfiles.  It's a little different than the normal path
of "as long as it's in the hierarchy" but it does mean there's only 1
piece of info.

> I hit send too soon:  That’s probably true for concrete classes.
> For abstracts, ACC_VALUE must not be set (yes?) and ValueObject
> “just flows” along with all the other super types, with no particular
> notice.  It all comes together when ACC_VALUE appears, and that
> must be on a final, concrete class.

That's a reasonable restriction if we keep the bit - ACC_VALUE is only
for concrete classes and must be met by either a direct or inherited
VO interface.

> I keep wondering what ACC_VALUE “should mean” for an abstract.
> Maybe it “should mean” that the abstract is thereby also forced to
> implement VO, so that all subtypes will be VO’s.

Isn't that the role of the VO interface though?  I think it makes more
sense to keep ACC_VALUE for final concrete classes.

>
> The slightly different meaning of ACC_PERMITS_VALUE is “hold
> off on injecting IdentityObject at this point”.  Because the type
> might allow subtypes that implement VO (whether abstract or
> concrete).  At this point it also allows IdentityObject to be
> introduced in subtypes.  Mmm… It could also have been
> spelled ACC_NOT_NECESSARILY_IDENTITY.

Or ACC_UNDECIDED.  If we see bucket 2 classes becoming popular enough
that the ACC_PERMITS_VALUE is a common flag on abstract classes, we
may want to pick a name that indicates "both allowed".  It's our
current code base's bias towards identity that makes us want to spell
it "PERMITS_VALUE" when, as John says, flipping the meaning is equally
valid.

>
> As we said in the meeting, it seems to need magic injection of
> IdObj, even if we can require non-magic explicit presence of VO.
> Dan H., will the metadata pointer of IdObj be a problem to access,
> if it is magically injected?

I'm not concerned about the metadata pointer - injecting an extra
interface is doable and required for legacy identity classes.  My
worry is consistency flowing through the system - primarily with
determining whether an interface is injected or not.  At least in our
implementation, the easiest way to inject the interface is to add it
when converting the .class file into our internal forms (ROM & RAM
class).  Once injected, it looks like any other interface.

When converting back from our internal form to a classfile for the
JVMTI RetransformClasses agents, I need to either filter the interface
out if we injected it or not if it was already there.  JVMTI's
GetImplementedInterfaces call has a similar issue with being
consistent - and that's really the same issue as reflection.

There's a lot of small places that can easily become inconsistent -
and therefore a lot of places that need to be checked - to hide
injected interfaces.  The easiest solution to that is to avoid
injecting interfaces in cases where javac can do it for us so the VM
has a consistent view.

None of this is impossible - or even that hard - but it's really easy
to get wrong and only discover after it's been in the wild for a
while.  When the bug reports come in, we'll have to decide which set
of users to break - those who wanted it returned like a normal
interface or those who expected it to be hidden.

My vote is for javac to inject the VO interface as before we ship is
the only time we can by design avoid a long tail of (minor) bugs.

--Dan

Reply via email to