More detail than I had intended on Layout description language
Tobi Ajila
atobia at ca.ibm.com
Wed Dec 17 15:26:40 UTC 2014
> 2. We will add
> Unsafe.{be,le,native},{Load,Store,Cas}{Short,Int,Long,Float,Double}
> to enable efficient implementation of 1. These should compile to
intrinsics.
> The reason to do it this way is to ensure consistent translation of
little
> languages into bytecodes across platforms, whenever possible, and also
to
> minimize the offense given to the keepers of the Java/JDK faith by
confining
> the ugly to the official pile of ugly. No need for endian variants of
byte
> load/store.
This seems reasonable and portable bytecodes is probably the right design
goal. For the new Unsafe methods, let's ensure that the behaviour is well
specified.
Are the Float/Double versions necessary? So far the LD has been about
specifying bits, not the type information. How likely is it that Java's
float/double map correctly onto the native side's representation of
float/double? Wouldn't using "Float.floatToRawIntBits(float) /
intBitsToFloat(int)" and the Double equivalents make more sense?
> 4. I don't know the best way to express offsets. Uniformity suggests
that
> we express all offsets in terms of bits, and we would then do
container-math
> to extract the byte offset of the container (8, 16, 32, or 64-bit) and
the
> shift/mask of the field to extract.
> That is, an endianness, offset, field size, and alignment/container
size
> (ALERT: what about platforms that allow unaligned containers?) are
required
> to identify the bits for a field. Endianness tells us how to load the
> container, alignment/container size tells us both how large a thing to
> load and how to convert the bit offset into a byte offset + shift, and
the
> size tells us what mask to use.
Our first thought on containers was that it unnecessarily exposes
implementation details. We now see it as attempt to externalize the
underlying memory model.
> If you look at C bitfields, there is very
> much a model of ?load a box this big, then shift the data towards the low
order
> bits some distance, then mask/sign-smear the part we don?t care about?.
The container model increases the amount of memory reads when accessing
bit-fields. Reading a single bit field has the side effect of reading all
other fields in the container. This would affect the behaviour of systems
with memory mapped I/O that take certain actions when an address is read.
e.g. incrementing a counter every time an address is read.
We should also consider the performance impact of masking + shifting every
time we interact with a bit field. In the example below, do we need to mask
+ shift + OR + CaS every time we write to a field in that structure?
struct A {
int16_t val1 : 8;
int16_t val2 : 8;
}
">,16",
"val1, 0, 16, 8",
"val2, 8, 16, 8"
Will we have restrictions on container sizes? If someone specifies a 128
bit container in the LDL, how will it be dealt with on platforms that don't
have those container sizes? Do we want to go so far as to specify the
number, ordering, and atomicity of memory operations used to read a layout
field?
> Perhaps, per field:
> offset (in bits)
> container size (in bits)
> [field size (in bits) = container size]
> [container alignment (in bits) = container size]
> [endianness = structure default]
>
> Structure information would look like
> endianness (<,> -- see Python link for other options)
> container size (in bits)
> [container alignment (in bits) = container size]
Then there are some ambiguous cases. e.g.
">, 16",
"x, 0, 8, 8",
"y, 4, 8, 8", //where does this one start? it has offset of 4 but alignment
of 8
"z, 8, 8, 8"
What is the expected behaviour of this? or is it even legal? To be more
general, how do we handle fields that don't fit into their containers?
To summarize, we think:
1) The LD implementation should be able to derive container sizes from
field sizes and offsets
2) Container attributes create more opportunity for inconsistent layout
descriptors.
If we need to specify a memory model, then we propose the following
strawman rules:
1) Where a field is completely contained inside a container, and where the
container size is no larger than a platform-dependent limit, reads and
writes of the field will be atomic.
2) Reads and writes of a field may cause reads and writes of adjacent
fields in the same container.
3) Modifying the value of a field preserves the value of adjacent fields in
the same container. This rule does not apply to overlapping fields.
Doug Lea's input may be valuable for refining this.
Is this level of specification needed?
More information about the panama-spec-experts
mailing list