<div dir="ltr"><div dir="ltr">In my experiments, IIRC two or three times I had a bug caused by passing a byte quantity where a bit quantity was expected. This is something I have observed many times in programming security APIs, where sometimes key sizes are expressed in bytes, sometimes in bits. Types are always int and the compiler never complains. I welcome this change.<div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Em ter., 16 de mai. de 2023 às 11:22, Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com">maurizio.cimadamore@oracle.com</a>> escreveu:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
as we're going through the FFM API with a finer comb, we were reminded <br>
again of an asymmetry between memory segments and memory layouts. Memory <br>
segments are expressed as "bag of bytes". All their sizes and offsets <br>
are expressed in number of bytes, which obviously makes sense given that <br>
(a) memory addressing is byte-oriented and (b) ByteBuffer API also works <br>
that way (so changing it would make transition from BB a lot more painful).<br>
<br>
On the other hand, memory layouts are expressed in bits. The historical <br>
reasons for this can be found in John's great LDL document [1]. <br>
Essentially, the layout language proposed in the LDL document was <br>
originally intended to model both memory **and** registers. That said, <br>
the memory layout API is firmly in the territory of modelling memory <br>
structure/dereference, so it seems that ship has sailed already. If we <br>
want to talk about sub-byte structure, we could still do so, in the <br>
future, by adding a dedicated API for "register layouts" (e.g. so that a <br>
JAVA_INT could be associated with a sub-byte layout which indicates how <br>
the 32 bits are partitioned and used).<br>
<br>
While this asymmetry can rarely be observed in practice, it is <br>
bothersome for a number of reasons:<br>
<br>
* Factories accepting layouts (e.g. <br>
SegmentAllocator::allocate(MemoryLayout)) cannot be expressed as simple <br>
sugar for factories expressed in byte size/alignment (e.g. <br>
SegmentAllocator::allocate(long, long)). That is, there is always some <br>
segments that can be allocated in one factory which can't be allocated <br>
in the other.<br>
<br>
* Var handles generated using the memory layout API have different <br>
constraints from those generated directly from MethodHandles. The latter <br>
just accepts a byte offset (in sync with what memory segments do), while <br>
the former perform all internal computation, as well as range checking, <br>
in bits - which again leads to asymmetries.<br>
<br>
We would like to rectify this asymmetry now (possibly in Java 21). <br>
Here's a draft PR that does just that:<br>
<br>
<a href="https://github.com/openjdk/jdk/pull/14013" rel="noreferrer" target="_blank">https://github.com/openjdk/jdk/pull/14013</a><br>
<br>
While tedious, in reality there's not much that leaks outside the API <br>
and tests because:<br>
<br>
* Clients access value layouts using one of the ready-made constants <br>
(e.g. ValueLayout.JAVA_INT or, ValueLayout.JAVA_INT_UNALIGNED for <br>
unaligned access)<br>
* I suspect clients are only using methods such as <br>
MemoryLayout::byteSize() and MemoryLayout::byteAlignment() already<br>
<br>
There is however, some compatibility surface as well:<br>
<br>
* The factory for padding layouts will need to take a byte size, not a <br>
bit one (but note that we already required the bit size to be multiple <br>
of 8, so no real change). This is by far the most annoying, because <br>
existing code will "not get the memo", and, if unchanged, will end up <br>
creating padding layouts that are too big.<br>
* Instead of using MemoryLayout::withBitAlignment, clients will need to <br>
use MemoryLayout::withByteAlignment. Since this will result in a <br>
compilation error (and since the method name says "byte" and not "bit"), <br>
I believe that, while annoying, this poses far less issues.<br>
<br>
Of course code that works against jextract bindings won't need any <br>
updates, but bindings will need to be re-generated to have paddings and <br>
alignments expressed in bits, not bytes.<br>
<br>
I believe that, on the whole, these changes are rather sensible - having <br>
segments and layouts using different "currencies" seems like a recipe <br>
for future trouble. Of course if there are some objections, we'd like to <br>
hear from you.<br>
<br>
Thanks<br>
Maurizio<br>
<br>
[1] - <a href="https://cr.openjdk.org/~jrose/panama/minimal-ldl.html" rel="noreferrer" target="_blank">https://cr.openjdk.org/~jrose/panama/minimal-ldl.html</a><br>
<br>
</blockquote></div><br clear="all"><div><br></div><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div>Pedro Lamarão</div></div></div></div>