Shaping C-like unions into memory segments – Foreign (Function) Memory API

Java Certification Exams and ProgrammingExams of Java, Java Exams, Tackling the slicing allocator Shaping C-like unions into memory segments – Foreign (Function) Memory API
0 Comments

147. Shaping C-like unions into memory segments

Let’s consider the C-like union from the following figure (the members of a C union share the same memory location (the member’s largest data type dictates the size of the memory location), so only one of the members has a value at any moment in time):

Figure 7.14 – A C-like union

In Figure 7.14, we have a C-like union named product to shape two members, price (double) and sku (int), while only one can have a value at any moment in time. We can shape a memory segment to fit this model as follows (arena is an instance of Arena):

MemorySegment segment = MemorySegment.allocateNative(
  ValueLayout.JAVA_DOUBLE.byteSize(),
  ValueLayout.JAVA_DOUBLE.byteAlignment(), arena.scope());

Because double needs 8 bytes and int needs only 4 bytes, we choose ValueLayout.JAVA_DOUBLE to shape the size of the memory segment. This way, the segment can accommodate a double and an int at the same offset.Next, we can set the price or the sku and use it accordingly:

segment.setAtIndex(ValueLayout.JAVA_DOUBLE, 0, 500.99);
segment.setAtIndex(ValueLayout.JAVA_INT, 0, 101000);

When we set the sku (int), the value of price (double) became a garbage value and vice versa. For more details, check out the bundled code. Next, let’s see an alternative to this implementation based on UnionLayout.

Introducing UnionLayout

A UnionLayout is a group layout. In this layout, the members (other memory layouts) are laid out at the same starting offset exactly as in a C union. This means that we can shape our C-like union by laying out the price (double) and the sku (int) members as follows:

UnionLayout union = MemoryLayout.unionLayout(
  ValueLayout.JAVA_DOUBLE.withName(“price”),
  ValueLayout.JAVA_INT.withName(“sku”));

Next, as we already know from Problem x, we need to define the proper layout paths via PathElement and get back the VarHandle. We need a VarHandle for price and one for sku. Notice in the following code how we point them out via their names:

// VarHandle[varType=double,
// coord=[interface java.lang.foreign.MemorySegment]]
VarHandle pHandle = union.varHandle(
  PathElement.groupElement(“price”));
// VarHandle[varType=double,
// coord=[interface java.lang.foreign.MemorySegment]]
VarHandle sHandle = union.varHandle(
  PathElement.groupElement(“sku”));

Finally, we can use these VarHandle to set price or sku:

try (Arena arena = Arena.openConfined()) {
  MemorySegment segment = arena.allocate(union);
  pHandle.set(segment, 500.99);
  sHandle.set(segment, 101000);
}

When we set the sku (int), the value of price (double) became a garbage value and vice versa.


Leave a Reply

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