Array fields in value objects
Brian Goetz
brian.goetz at oracle.com
Tue May 20 14:24:19 UTC 2025
I think this is pushing on the short end of the lever; it’s a heroic, narrow, brittle (expensive!) optimization for a narrow outcome. I have a hard time believing we would ever run out of opportunities to invest in higher-leverage activities.
This is, at root, a layout specialization problem, similar to specializing instantiated generic types such as Pair<int,int>; investing in that seems likely to be higher-leverage for the imaginable future.
On May 20, 2025, at 12:28 AM, John Bossons <jbossons at gmail.com<mailto:jbossons at gmail.com>> wrote:
Looking for a way to avoid complicating the VM, suppose I rewrite the PostCodeCA class as follows:
value class PostCodeCA {
byte b0;
...
byte b5;
PostCodeCA(String s) {
byte[] asciiBytes = s.getBytes("US-ASCII");
if (asciiBytes.length != 6) throw exception;
// other validation code here
b0 = asciiBytes[0];
etc.
}
// equals, hashCode etc. based on b0 ... b5
}
This works and can be flattened, but is rather ugly and laborious. So maybe I'm asking the question the wrong way. Maybe what I should be asking for is a subsequent JEP that (using record as a model) gets the compiler to generate detailed code such as the above from a specification like
fixedSmallArray PostCodeCA { byte[6] asciiBytes } // immutable array thanks to encapsulation
Is this a workable idea? (Again, for the future, after value objects are delivered.) The key thought is that the compiler ought to be able to do this without requiring any more modification of the VM than was required for records.
It's immutable arrays through the back door.
On Mon, May 19, 2025 at 5:07 PM Brian Goetz <brian.goetz at oracle.com<mailto:brian.goetz at oracle.com>> wrote:
Except that object layout time is way too early for the JVM to figure out that “no one could possibly write to this.” The JVM makes layout decisions on the basis of what is evident in the class file — ACC bits on fields, field descriptors, attributes on fields.
If you recall, the descriptor type system is quite limited: carriers for the primitive types (I, J, F, D, etc), carrier for OOPs (Ljava/lang/String), and arrays of one of these types (e.g., [I, [[LString;, etc.). We would have to cram both finality _of elements_ and array size into one of the above channels, and at this point we’re describing a different virtual machine.
> On May 19, 2025, at 4:23 PM, John Bossons <jbossons at gmail.com<mailto:jbossons at gmail.com>> wrote:
>
> That's why I encapsulated the char[6] array in the PostCodeCA class. The immutability is a consequence of the array field being private and final, so that part should be easy to handle. I don't know how it could easily be accomplished other than through encapsulation.
>
> With respect to fixing the size, could that be handled by providing an additional term to the field declaration (e.g. "fixed", as in "fixed char[6] codeValue", or even by just "char[6]" without the"fixed")? That would mean the JVM only needs a single tag to know that the field is special and therefore possible to flatten.
>
> The compiler would need to verify that the field initialization is correct, but could this not be done by requiring
> consistency between the field specification and the array constructor size parameter -- or for strings requiring use of a new toCharArray(int size) method? All the compiler needs to do is to check that the constructor/method parameter matches the field specification. Even if this were only done for primitives it would be very useful. Could a limited circumscribed version of this not be done as a "small" lift?
>
> John
--
Phone: (416) 450-3584 (cell)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-dev/attachments/20250520/4550ad0a/attachment.htm>
More information about the valhalla-dev
mailing list