[foreign-memaccess] RFR 8235259: Java layout constants should use native endianness

John Rose john.r.rose at oracle.com
Wed Dec 4 02:49:45 UTC 2019


On Dec 3, 2019, at 2:03 PM, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> wrote:
> 
> Pushed.

+1

> One thing that occurred to me earlier today is that, if we wanted, instead of exposing JAVA_INT constants we could instead provide them in a more implicit way:
> 
> MemoryLayouts::layoutFor(Class<?>)
> 
> so:
> 
> JAVA_INT == layoutFor(int.class)
> JAVA_FLOAT == layoutFor(float.class)

That seems very nice to me!  About as concise, and more strongly
linked to the Java-ness of the types (despite the shouting “JAVA”
of the other alternative). 

> 
> ...
> 
> The upside of this approach is that it scales beyond primitive - e.g.
> 
> layoutFor(int.class) == MemoryLayout.ofSequence(layoutFor(int.class))

Did you mean int[].class?  In that case there’s the puzzle of depending on int[]::length.

> 
> [and, when Valhalla is ready, it will even scale to support inline classes that are "inline all the way down”]

Yes, that is very very cool.

> Another advantage is that we don't have constants whose interpretation depends on what ByteOrder::nativeOrder does (which seems problematic with respect to make these things foldable at compile-time).
> 
> The flip side is that these things are 'less constants' - and probably less scrutable by the JIT.

Well, there will always be a distinction between “really constant” constants and
“bound at runtime and then constant” constants.  The guys that depend on
the native ordering are in the latter class, while the WORA ones are in the
former.  A naming convention “JAVA_INT” vs. “BITS_32_BE” can carry that
distinction (via a learned connotation).  Another more decisive way to carry
the distinction is “javaInt()” vs “BITS_32_BE”, but that swings to the other
extreme, since then you can’t easily see that “javaInt()” is really a constant
(of the second kind).

As long as we have opened this can of worms, here’s another serving:

class MemoryLayouts {
   static class BE { … INT32, INT64, … }
   static class LE { … INT32, INT64, … }
   … JAVA_INT, JAVA_LONG …
}

Given this:

import static MemoryLayouts.*;

then code can refer to JAVA_INT, BE.INT, and LE.INT with reasonable clarity.
Relentlessly LE or relentlessly BE code can do this:

import static …MemoryLayouts.LE.*;
or this:
import static …MemoryLayouts.BE.*;

That’s what I was thinking when I mentioned static imports.

I *also* like layoutFor(Class), and wouldn’t mind if it were named just
layout(Class), a la the static-importable MethodType.methodType.

— John

"Nobody but a lay-out man knows what a lay-out man's feelings is.” — D. Sayers, Murder Must Advertise

> Thoughts?
> 
> Maurizio
> 
> On 03/12/2019 19:12, Maurizio Cimadamore wrote:
>> 
>> On 03/12/2019 18:49, John Rose wrote:
>>> Probably an import static
>>> idiom is sufficient
>> 
>> This is where we're currently at.
>> 
>> MemoryLayouts has various constants inside. It has WORA constants (such as BITS_64_BE) as well as internal layouts (such as JAVA_INT - these will be moved, eventually, to the corresponding wrapper classes).
>> 
>> The realization is that if we just provide WORA, it is then very hard to work with Java arrays - which is a very common case for the API (e.g. think about moving data from on-heap to off-heap and back - e.g. to talk to a native library).
>> 
>> It's up to the user to decide which constants he/she wants to use. Each set of constant has a very different audience in mind - and there's no silver bullet.
>> 
>> Maurizio
>> 



More information about the panama-dev mailing list