[foreign-memaccess+abi] RFR: 8303017: Passing by-value structs whose size is not power of 2 doesn't work on all platforms

Maurizio Cimadamore mcimadamore at openjdk.org
Thu Mar 2 12:06:36 UTC 2023


On Fri, 24 Feb 2023 21:08:50 GMT, Jorn Vernee <jvernee at openjdk.org> wrote:

> Fix passing of by-value structs whose size is not a power of 2.
> 
> The issue is that currently we try to do loads using a ValueLayout that is the size of the nearest power of two that can fit the struct (or part of it, if it is passed in multiple registers). For instance, for a struct of size 6, we try to load its value using `ValueLayout.OfLong`, which is size 8, and thus produce an out of bounds error. A similar issue applies to writes.
> 
> For the solution I've implemented in this patch, I've attached an explicit byte width to BufferLoads/Stores, which indicates the size of the value we want to load/store. The type that is produced by the binding is still the same. For example, loading a struct of size 6 is implemented as an `int` load and a `short` load, which are then combined into a `long`, instead of attempting to do a single `long` load (and failing). This allows us to avoid doing an out of bounds access.
> 
> I've added a new test that tests a bunch of structs with varying byte sizes being passed in registers and on the stack. Using a nested `char[]` to precisely tweak the byte size of each struct.

Marked as reviewed by mcimadamore (Committer).

src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java line 347:

> 345:     }
> 346: 
> 347:     public static int byteWidthOfPrimitive(Class<?> type) {

When we create memory access var handles, we use this to compute the byte size of a primitive (`VarHandles::memorySegmentViewHandle`):


Wrapper.forPrimitiveType(carrier).bitWidth() / 8


Perhaps we should put this into Utils and then reuse in both places?

test/jdk/java/foreign/arraystructs/TestArrayStructs.java line 74:

> 72:     // Test if structs of various different sizes, including non-powers of two, work correctly
> 73:     @Test(dataProvider = "arrayStructs")
> 74:     public void testArrayStruct(String functionName, FunctionDescriptor upcallDesc, int numPrefixArgs) throws Throwable {

Nice test!

-------------

PR: https://git.openjdk.org/panama-foreign/pull/806


More information about the panama-dev mailing list