> On Dec 1, 2021, at 8:48 AM, Dan Heidinga <heidi...@redhat.com> wrote:
> 
>> class file representation & interpretation
>> 
>> A value class is declared in a class file using the ACC_VALUE modifier 
>> (0x0100). At class load time, the class is considered to implement the 
>> interface ValueObject; an error occurs if a value class is not final, has a 
>> non-final instance field, or implements—directly or 
>> indirectly—IdentityObject.
> 
> I'll reiterate my earlier pleas to have javac explicitly make them
> implement ValueObject.  The VM can then check that they have both the
> bit and the interface.

So we went down the path of "maybe there's no need for a flag at all" in 
today's meeting, and it might be worth more consideration, but I convinced 
myself that the ACC_VALUE flag serves a useful purpose for validation and 
clarifying intent that can't be reproduced by a "directly/indirectly extends 
ValueObject" test.

As you suggest, though, we could mandate that ACC_VALUE implies 'implements 
ValueObject'. Some reasons not to require this:

- 'implements ValueObject' may be redundant if an ancestor implements 
ValueObject; but leaving it off risks a separate compilation error (e.g., 
ancestor used to implement ValueObject, doesn't anymore). So I think the proper 
compilation strategy would be to always implement it directly, even 
redundantly. There's an opportunity for a subtle compiler bug.

- It's extra ceremony in the class file. <shrug>

- Inferring is consistent with what we do for at least some identity classes. 
Inferring everywhere is, in some ways, simpler.*

(*Tangent about the idea of inferring IdentityObject in old versions, but 
requiring IdentityObject in new versions: the trouble with gating off 
less-preferred behavior in old versions is that it's still there and still must 
be supported. JVMs end up with two strategies instead of one. A (great 
strategy+ok strategy) combination is arguably *worse* than just (ok strategy) 
everywhere.)

> It's a simpler model if the interface is
> always there for values as the VM won't have to track whether it was
> injected for a value class or explicitly declared.  Why does that
> matter?  For two reasons: JVMTI will need to be consistent in the
> classfile bytes it returns and not included the interface if it was
> injected (less tracking), and given earlier conversations about
> whether to "hide" the injected interface from Class::getInterfaces,
> always having it for values removes one more sharp edge.

The plan of record is to make no distinction between inferred and explicit 
superinterfaces in reflection. Is that not acceptable for JVMTI? If there's no 
need for a distinction, does that address your concern about inferred supers?

Reply via email to