On Tue, 2 Apr 2024 15:04:40 GMT, Per Minborg <pminb...@openjdk.org> wrote:
> This PR proposes to add an internal layout transformer that could be used to > transform MemoryLayout entities. For example, it would be possible to convert > a struct layout to use network order ((big-endian) instead of native byte > order (often little-endian). Another application is to remove naming > recursively for composite layouts when caching shapes etc. src/java.base/share/classes/jdk/internal/foreign/layout/LayoutTransformers.java line 46: > 44: * A JDK-internal utility class that provides useful layout > transformations. > 45: */ > 46: public final class LayoutTransformers { In my experience when thinking about this problem, I always found that writing a layout transformer as a method implemented by pattern matching is almost always a better choice. The problem with going down that path is that it's a little verbose in cases where no transform needs to occur. Let's consider the endianness case: MemoryLayout setEndianness(MemoryLayout layout, ByteOrder order) { return switch (layout) { case ValueLayout vl -> yield vl.order(order); case SequenceLayout sl -> yield MemoryLayout.sequenceLayout(sl.elementCount(), setEndianness(sl.elementLayout(), order); case StructLayout stl -> yield MemoryLayout.structLayout(stl.memberLayouts().stream().map(e -> setEndianness(e, order)); ... } The problem with this is that the arms where "nothing" happens need to draw a lot of attention, as they need to contain the code which recursively propagates the transform. But what if we had a single utility like this: MemoryLayout adaptContents(MemoryLayout, UnaryOperator<MemoryLayout>) Which takes care of applying a transform recursively on the _contents_ of a nested layout (e.g. sequence layout element, or the members of a group layout). Then the above becomes: MemoryLayout setEndianness(MemoryLayout layout, ByteOrder order) { return switch (layout) { case ValueLayout vl -> yield vl.order(order); default -> yield layout.adaptContents(e -> setEndianness(e, order)); } } Which is quite simple. And, the remove names transform can be even simpler: MemoryLayout removeNames(MemoryLayout layout) { return layout.adaptContents(this::removeNames).withoutName(); } ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/18582#discussion_r1567127736