Introducing PaddingLayout – Foreign (Function) Memory API

0 Comments

148. Introducing PaddingLayout

Data types are typically characterized by several properties: size, alignment, stride, padding, and order of bytes.Padding layout (java.lang.foreign.PaddingLayout) allows us to specify the padding. In other words, PaddingLayout allows us to add at certain offsets some extra space that is usually ignored by the applications but is needed to align the member layouts of a memory segment.For instance, let’s consider the following two memory segments (the left-hand side is a memory segment without padding, while the right-hand side is a memory segment with two paddings of 4 bytes each).

Figure 7.15 – Memory segments with (right hand side)/without (left hand side) padding

In code lines, the padding-free memory segment can be shaped as follows:

StructLayout npStruct = MemoryLayout.structLayout(              
  ValueLayout.JAVA_INT.withName(“x”),            
  ValueLayout.JAVA_INT.withName(“y”)
);

Since the size of JAVA_INT is 4 bytes, we can set x and y as follows:

VarHandle xpHandle = wpStruct.varHandle(
  PathElement.groupElement(“x”));
VarHandle ypHandle = wpStruct.varHandle(
  PathElement.groupElement(“y”));
try (Arena arena = Arena.openConfined()) {
          
  MemorySegment segment = arena.allocate(npStruct);
  xnHandle.set(segment, 23); // offset 0
  ynHandle.set(segment, 54); // offset 4
}

This code writes the value 23 at offset 0, and 54 at offset 4. No surprises, right?Next, let’s code a memory segment with padding. For this, we call MemoryLayout.paddingLayout(long size) as in the following snippet (since we have two interleaved padding of 4 bytes, we have to interleave two calls of paddingLayout()):

StructLayout wpStruct = MemoryLayout.structLayout(
  MemoryLayout.paddingLayout(32),     // 32 bits, so 4 bytes
  ValueLayout.JAVA_INT.withName(“x”),
  MemoryLayout.paddingLayout(32),     // 32 bits, so 4 bytes
  ValueLayout.JAVA_INT.withName(“y”)
);

Notice that the size of padding is given in bits, not in bytes. Next, we write the two int values (23 and 54) again:

VarHandle xpHandle = wpStruct.varHandle(
  PathElement.groupElement(“x”));
        VarHandle ypHandle = wpStruct.varHandle(
  PathElement.groupElement(“y”));
try (Arena arena = Arena.openConfined()) {
         
  MemorySegment segment = arena.allocate(wpStruct);
  xpHandle.set(segment, 23); // offset 4
  ypHandle.set(segment, 54); // offset 12
}

This time, the padding zones are skipped, and 23 is written to offset 4, while 54 is written to offset 12. Reading x and y should be done from offset 4, respectively offset 12. From 0 to 3, and from 8-11 we have extra space added via paddigLayout() that is ignored by the application. Attempting to read an int from these zones results in values of 0 (default values).These examples have nicely and smoothly introduced the padding notion but they are not quite useful. Remember that we said earlier that padding is useful for aligning the members of a memory segment. In order to understand this, let’s briefly hook a few more players.


Leave a Reply

Your email address will not be published. Required fields are marked *