[foreign-memaccess] RFR 8223978: Add alignment support to layouts

Jorn Vernee jbvernee at xs4all.nl
Thu May 16 10:57:27 UTC 2019


> I think you can still model that use case - essentially what you want
> is to just align everything to 8. (in fact that's what pragma pack(1)
> does).

Ah, yes of course! My mistake.

---

Btw, while testing this I also noticed that aligning e.g. a Group with 
alignTo() will return a Layout. I think we should use covariant return 
types here (and in the other Layout sub-types). Also, Address is missing 
on override for alignTo, so this will just return a Value.

Thanks,
Jorn

[1] : https://docs.microsoft.com/en-us/cpp/cpp/align-cpp?view=vs-2019

Maurizio Cimadamore schreef op 2019-05-16 12:25:
> On 15/05/2019 21:07, Jorn Vernee wrote:
>>> * you can align a layout using Layout::alignTo(long) - this sets the
>>> additional constraint (provided is power of two, non-negative, and
>>> >=8)
>> 
>> Why the power of two constraint? Shouldn't it just be a multiple of 8?
>> 
>> This seems to preclude some packed structs, e.g. with elements with 3 
>> byte alignment:
>> 
>>     #pragma pack(1)
>> 
>>     struct Foo {
>>         char x;
>>         short y; // 1 byte alignment
>>         int z; // 3 byte alignment
>>     }; // size = 7 bytes
>> 
>> In the layout API this is:
>> 
>>     Value vChar = Value.ofSignedInt(8);
>>     Value vShort = Value.ofSignedInt(16);
>>     Value vInt = Value.ofSignedInt(32);
>>     Group g = Group.struct(vChar, vShort.alignTo(8), 
>> vInt.alignTo(24));
>> 
>> But this throws an IAE because alignment of 24 is not allowed.
> 
> I think you can still model that use case - essentially what you want
> is to just align everything to 8. (in fact that's what pragma pack(1)
> does).
> 
> I don't think there's such a thing as 3-byte aligned memory access: if
> you want to read 4 bytes on a 3-byte aligned address, that's just
> unaligned read.
> 
> In other words, nothing new here - we're kind of following what the
> pragma pack allows you to do: the argument to pragma pack must also be
> a power of 2 (1, 2, 4, 8 ...), see here [1, 2] - the only difference
> in the Panama API is that everything has to be multiplied by 8,
> because alignment (as sizes) are expressed in bits, to have more room
> to add sub-byte alignment (bit-fields, etc.) later on.
> 
> So, back to your example:
> 
> Value vChar = Value.ofSignedInt(8);
> Value vShort = Value.ofSignedInt(16);
> Value vInt = Value.ofSignedInt(32);
> Group g = Group.struct(vChar.alignTo(8), vShort.alignTo(8), 
> vInt.alignTo(8));
> 
> Maurizio
> 
> [1] - 
> https://docs.microsoft.com/en-us/cpp/preprocessor/pack?view=vs-2019
> [2] -
> https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Structure_002dPacking-Pragmas.html
> 
> 
>> 
>> Jorn
>> 
>> Maurizio Cimadamore schreef op 2019-05-15 19:57:
>>> Hi,
>>> this patch adds support to the API to express alignment constraints 
>>> on
>>> layouts. Following the model John put forward in [1], I did the
>>> following:
>>> 
>>> * there's a way to compute the 'natural alignment' of a layout
>>> 
>>> * if no alignment is specified, alignment is the natural alignment
>>> 
>>> * you can align a layout using Layout::alignTo(long) - this sets the
>>> additional constraint (provided is power of two, non-negative, and
>>> >=8)
>>> 
>>> * When we obtain a VarHandle out of a Layout, at that point we are in
>>> the process of computing offsets; here we can catch e.g. if the 
>>> offset
>>> of a given path doesn't match the specified alignment - in this case
>>> we fail fast, even before memory is accessed; this occurs e.g. if the
>>> layout path offset is not a multiple of its alignment, or if the
>>> alignment of the nested element is stricter than the one of the
>>> enclosing element.
>>> 
>>> (in principle we could enforce these checks on layout creation, but
>>> given we have unresolved layouts in our radar, I think it's best to 
>>> do
>>> minimal checks on layout creation and let the check fully kick in on
>>> path creation).
>>> 
>>> * If VarHandle can be constructed, a dynamic check verifies that
>>> alignment of address passed to VH matches the layout requirements
>>> 
>>> * MemoryScope::allocate also honors the alignment requirements - this
>>> works by up-allocating memory (to make sure a pointer with desired
>>> alignment exists in the allocated area) and then adjusting it after
>>> the fact. For alignments < 16bytes, nothing is done given that 
>>> malloc,
>>> at least on x64 is guaranteed to respect that.
>>> 
>>> 
>>> I think this is powerful and yet relatively simple to understand,
>>> overall I quite like it.
>>> 
>>> Webrev:
>>> http://cr.openjdk.java.net/~mcimadamore/panama/8223978/
>>> 
>>> Maurizio


More information about the panama-dev mailing list