>> > For the moment I think this does probably carry over to >> > WithIdentity/WithoutIdentity or whatever they are called. The question I >> > think is still open (to me) is whether there really are active contractual >> > implications of being identityless or if it's equivalent to being >> > uncommitted; i.e. should a clear-cut identityless class still be able to >> > have an identityful subclass, or does that clearly break something. >> >> It breaks flattening. If an identityless class is flattened - and we >> want to preserve the option to do this for bucket 2 values that are <= >> 64 bits - then we can't assign a subclass instance to a slot (field / >> array element) declared to be the superclass's type as we may have to >> truncate the subclass to have it fit. > > > Right. I guess I was figuring that the mere fact of the idenityless class > being non-final would already destroy that? > > Supposing this justifies requiring `final` for these classes, then my > question evaporates. I wasn't sure though. Even losing flattening entirely > doesn't leave you worse off than B1.
The model, up till now, has required `final` on identityless classes, though this restriction was born out of bucket 3 requirements of flattening. Changing it for B2 to allow subclassing will have a lot of unpleasant knock-on effects: * Lose flattening (at least for non-final B2 classes) * Break the construction model: B2 & B3 classes are instantiated by an `invokestatic <new>()X;` bytecode sequence rather than the `new; dup; invokespecial <init>()V;` sequence of B1 classes. In the B2/B3 sequence, there's no call to super class constructors which means either not running the super class's `<new>` method or .... maybe, grimacing, call `super.<new>()X` and do a field-by-field copy of X in SubX's `<new>` method? It becomes really ugly really quick. * Scalarization: I think it would also impede scalarization / reconstitution of B2 classes as compiled code wouldn't know a priori the shape of a B2 class. By giving up identity, it becomes "free" for the JIT to split a B2/B3 class into individual fields and later reconstitute the value into a complete aggregate. Allowing subclassing of B2 classes would mean that JITTed code would have to profile the types its seen before scalarizing - turning a freebie into another potential performance pot hole. (ie: OSR+recompile for new types, limits on the profiled types, etc) And while these can be viewed as implementation concerns, they start to negate the benefits of having an identityless class in the first place. Let me turn the question around: What do we gain by allowing subclassing of B2 classes? --Dan