< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/sysv/SysVVaList.java

Print this page
@@ -24,31 +24,30 @@
   *
   */
  package jdk.internal.foreign.abi.x64.sysv;
  
  import jdk.incubator.foreign.*;
+ import jdk.internal.foreign.ResourceScopeImpl;
+ import jdk.internal.foreign.Scoped;
  import jdk.internal.foreign.Utils;
  import jdk.internal.foreign.abi.SharedUtils;
  import jdk.internal.misc.Unsafe;
  
  import java.lang.invoke.VarHandle;
  import java.lang.ref.Cleaner;
- import java.nio.ByteOrder;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Objects;
  
  import static jdk.internal.foreign.PlatformLayouts.SysV;
- import static jdk.incubator.foreign.CLinker.VaList;
+ 
  import static jdk.incubator.foreign.MemoryLayout.PathElement.groupElement;
  import static jdk.internal.foreign.abi.SharedUtils.SimpleVaArg;
  import static jdk.internal.foreign.abi.SharedUtils.THROWING_ALLOCATOR;
- import static jdk.internal.foreign.abi.SharedUtils.checkCompatibleType;
- import static jdk.internal.foreign.abi.SharedUtils.vhPrimitiveOrAddress;
  
  // See https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf "3.5.7 Variable Argument Lists"
- public non-sealed class SysVVaList implements VaList {
+ public non-sealed class SysVVaList implements VaList, Scoped {
      private static final Unsafe U = Unsafe.getUnsafe();
  
      static final Class<?> CARRIER = MemoryAddress.class;
  
  //    struct typedef __va_list_tag __va_list_tag {

@@ -65,12 +64,12 @@
          SysV.C_INT.withName("fp_offset"),
          SysV.C_POINTER.withName("overflow_arg_area"),
          SysV.C_POINTER.withName("reg_save_area")
      ).withName("__va_list_tag");
  
-     private static final MemoryLayout GP_REG = MemoryLayout.valueLayout(64, ByteOrder.nativeOrder());
-     private static final MemoryLayout FP_REG = MemoryLayout.valueLayout(128, ByteOrder.nativeOrder());
+     private static final MemoryLayout GP_REG = MemoryLayout.paddingLayout(64).withBitAlignment(64);
+     private static final MemoryLayout FP_REG = MemoryLayout.paddingLayout(128).withBitAlignment(128);
  
      private static final GroupLayout LAYOUT_REG_SAVE_AREA = MemoryLayout.structLayout(
          GP_REG.withName("%rdi"),
          GP_REG.withName("%rsi"),
          GP_REG.withName("%rdx"),

@@ -103,18 +102,15 @@
      private static final int FP_SLOT_SIZE = (int) FP_REG.byteSize();
  
      private static final int MAX_GP_OFFSET = (int) FP_OFFSET; // 6 regs used
      private static final int MAX_FP_OFFSET = (int) LAYOUT_REG_SAVE_AREA.byteSize(); // 8 16 byte regs
  
-     private static final VarHandle VH_fp_offset = LAYOUT.varHandle(int.class, groupElement("fp_offset"));
-     private static final VarHandle VH_gp_offset = LAYOUT.varHandle(int.class, groupElement("gp_offset"));
-     private static final VarHandle VH_overflow_arg_area
-         = MemoryHandles.asAddressVarHandle(LAYOUT.varHandle(long.class, groupElement("overflow_arg_area")));
-     private static final VarHandle VH_reg_save_area
-         = MemoryHandles.asAddressVarHandle(LAYOUT.varHandle(long.class, groupElement("reg_save_area")));
+     private static final VarHandle VH_fp_offset = LAYOUT.varHandle(groupElement("fp_offset"));
+     private static final VarHandle VH_gp_offset = LAYOUT.varHandle(groupElement("gp_offset"));
+     private static final VarHandle VH_overflow_arg_area = LAYOUT.varHandle(groupElement("overflow_arg_area"));
+     private static final VarHandle VH_reg_save_area = LAYOUT.varHandle(groupElement("reg_save_area"));
  
-     private static final Cleaner cleaner = Cleaner.create();
      private static final VaList EMPTY = new SharedUtils.EmptyVaList(emptyListAddress());
  
      private final MemorySegment segment;
      private final MemorySegment regSaveArea;
  

@@ -128,13 +124,14 @@
          return new SysVVaList(segment, regSaveArea);
      }
  
      private static MemoryAddress emptyListAddress() {
          long ptr = U.allocateMemory(LAYOUT.byteSize());
-         MemorySegment base = MemoryAddress.ofLong(ptr).asSegment(
-                 LAYOUT.byteSize(), () -> U.freeMemory(ptr), ResourceScope.newSharedScope());
-         cleaner.register(SysVVaList.class, () -> base.scope().close());
+         ResourceScope scope = ResourceScope.newImplicitScope();
+         scope.addCloseAction(() -> U.freeMemory(ptr));
+         MemorySegment base = MemorySegment.ofAddressNative(MemoryAddress.ofLong(ptr),
+                 LAYOUT.byteSize(), scope);
          VH_gp_offset.set(base, MAX_GP_OFFSET);
          VH_fp_offset.set(base, MAX_FP_OFFSET);
          VH_overflow_arg_area.set(base, MemoryAddress.NULL);
          VH_reg_save_area.set(base, MemoryAddress.NULL);
          return base.address();

@@ -171,11 +168,11 @@
      private MemorySegment regSaveArea() {
          return getRegSaveArea(segment);
      }
  
      private static MemorySegment getRegSaveArea(MemorySegment segment) {
-         return ((MemoryAddress)VH_reg_save_area.get(segment)).asSegment(
+         return MemorySegment.ofAddressNative(((MemoryAddress)VH_reg_save_area.get(segment)),
                  LAYOUT_REG_SAVE_AREA.byteSize(), segment.scope());
      }
  
      private void preAlignStack(MemoryLayout layout) {
          if (layout.byteAlignment() > 8) {

@@ -186,63 +183,57 @@
      private void postAlignStack(MemoryLayout layout) {
          stackPtr(Utils.alignUp(stackPtr().addOffset(layout.byteSize()), 8));
      }
  
      @Override
-     public int vargAsInt(MemoryLayout layout) {
+     public int nextVarg(ValueLayout.OfInt layout) {
          return (int) read(int.class, layout);
      }
  
      @Override
-     public long vargAsLong(MemoryLayout layout) {
+     public long nextVarg(ValueLayout.OfLong layout) {
          return (long) read(long.class, layout);
      }
  
      @Override
-     public double vargAsDouble(MemoryLayout layout) {
+     public double nextVarg(ValueLayout.OfDouble layout) {
          return (double) read(double.class, layout);
      }
  
      @Override
-     public MemoryAddress vargAsAddress(MemoryLayout layout) {
+     public MemoryAddress nextVarg(ValueLayout.OfAddress layout) {
          return (MemoryAddress) read(MemoryAddress.class, layout);
      }
  
      @Override
-     public MemorySegment vargAsSegment(MemoryLayout layout, SegmentAllocator allocator) {
+     public MemorySegment nextVarg(GroupLayout layout, SegmentAllocator allocator) {
          Objects.requireNonNull(allocator);
          return (MemorySegment) read(MemorySegment.class, layout, allocator);
      }
  
-     @Override
-     public MemorySegment vargAsSegment(MemoryLayout layout, ResourceScope scope) {
-         return vargAsSegment(layout, SegmentAllocator.ofScope(scope));
-     }
- 
      private Object read(Class<?> carrier, MemoryLayout layout) {
          return read(carrier, layout, THROWING_ALLOCATOR);
      }
  
      private Object read(Class<?> carrier, MemoryLayout layout, SegmentAllocator allocator) {
          Objects.requireNonNull(layout);
-         checkCompatibleType(carrier, layout, SysVx64Linker.ADDRESS_SIZE);
          TypeClass typeClass = TypeClass.classifyLayout(layout);
          if (isRegOverflow(currentGPOffset(), currentFPOffset(), typeClass)
                  || typeClass.inMemory()) {
              preAlignStack(layout);
              return switch (typeClass.kind()) {
                  case STRUCT -> {
-                     MemorySegment slice = stackPtr().asSegment(layout.byteSize(), scope());
+                     MemorySegment slice = MemorySegment.ofAddressNative(stackPtr(), layout.byteSize(), scope());
                      MemorySegment seg = allocator.allocate(layout);
                      seg.copyFrom(slice);
                      postAlignStack(layout);
                      yield seg;
                  }
                  case POINTER, INTEGER, FLOAT -> {
-                     VarHandle reader = vhPrimitiveOrAddress(carrier, layout);
+                     VarHandle reader = layout.varHandle();
                      try (ResourceScope localScope = ResourceScope.newConfinedScope()) {
-                         MemorySegment slice = stackPtr().asSegment(layout.byteSize(), localScope);
+                         MemorySegment slice = MemorySegment.ofAddressNative(stackPtr(), layout.byteSize(), localScope);
                          Object res = reader.get(slice);
                          postAlignStack(layout);
                          yield res;
                      }
                  }

@@ -254,30 +245,29 @@
                      int classIdx = 0;
                      long offset = 0;
                      while (offset < layout.byteSize()) {
                          final long copy = Math.min(layout.byteSize() - offset, 8);
                          boolean isSSE = typeClass.classes.get(classIdx++) == ArgumentClassImpl.SSE;
-                         MemorySegment slice = value.asSlice(offset, copy);
                          if (isSSE) {
-                             slice.copyFrom(regSaveArea.asSlice(currentFPOffset(), copy));
+                             MemorySegment.copy(regSaveArea, currentFPOffset(), value, offset, copy);
                              currentFPOffset(currentFPOffset() + FP_SLOT_SIZE);
                          } else {
-                             slice.copyFrom(regSaveArea.asSlice(currentGPOffset(), copy));
+                             MemorySegment.copy(regSaveArea, currentGPOffset(), value, offset, copy);
                              currentGPOffset(currentGPOffset() + GP_SLOT_SIZE);
                          }
                          offset += copy;
                      }
                      yield value;
                  }
                  case POINTER, INTEGER -> {
-                     VarHandle reader = SharedUtils.vhPrimitiveOrAddress(carrier, layout);
+                     VarHandle reader = layout.varHandle();
                      Object res = reader.get(regSaveArea.asSlice(currentGPOffset()));
                      currentGPOffset(currentGPOffset() + GP_SLOT_SIZE);
                      yield res;
                  }
                  case FLOAT -> {
-                     VarHandle reader = layout.varHandle(carrier);
+                     VarHandle reader = layout.varHandle();
                      Object res = reader.get(regSaveArea.asSlice(currentFPOffset()));
                      currentFPOffset(currentFPOffset() + FP_SLOT_SIZE);
                      yield res;
                  }
              };

@@ -285,10 +275,11 @@
      }
  
      @Override
      public void skip(MemoryLayout... layouts) {
          Objects.requireNonNull(layouts);
+         ((ResourceScopeImpl)segment.scope()).checkValidStateSlow();
          for (MemoryLayout layout : layouts) {
              Objects.requireNonNull(layout);
              TypeClass typeClass = TypeClass.classifyLayout(layout);
              if (isRegOverflow(currentGPOffset(), currentFPOffset(), typeClass)) {
                  preAlignStack(layout);

@@ -303,11 +294,11 @@
      static SysVVaList.Builder builder(ResourceScope scope) {
          return new SysVVaList.Builder(scope);
      }
  
      public static VaList ofAddress(MemoryAddress ma, ResourceScope scope) {
-         return readFromSegment(ma.asSegment(LAYOUT.byteSize(), scope));
+         return readFromSegment(MemorySegment.ofAddressNative(ma, LAYOUT.byteSize(), scope));
      }
  
      @Override
      public ResourceScope scope() {
          return segment.scope();

@@ -351,38 +342,37 @@
              this.scope = scope;
              this.reg_save_area = MemorySegment.allocateNative(LAYOUT_REG_SAVE_AREA, scope);
          }
  
          @Override
-         public Builder vargFromInt(ValueLayout layout, int value) {
+         public Builder addVarg(ValueLayout.OfInt layout, int value) {
              return arg(int.class, layout, value);
          }
  
          @Override
-         public Builder vargFromLong(ValueLayout layout, long value) {
+         public Builder addVarg(ValueLayout.OfLong layout, long value) {
              return arg(long.class, layout, value);
          }
  
          @Override
-         public Builder vargFromDouble(ValueLayout layout, double value) {
+         public Builder addVarg(ValueLayout.OfDouble layout, double value) {
              return arg(double.class, layout, value);
          }
  
          @Override
-         public Builder vargFromAddress(ValueLayout layout, Addressable value) {
+         public Builder addVarg(ValueLayout.OfAddress layout, Addressable value) {
              return arg(MemoryAddress.class, layout, value.address());
          }
  
          @Override
-         public Builder vargFromSegment(GroupLayout layout, MemorySegment value) {
+         public Builder addVarg(GroupLayout layout, MemorySegment value) {
              return arg(MemorySegment.class, layout, value);
          }
  
          private Builder arg(Class<?> carrier, MemoryLayout layout, Object value) {
              Objects.requireNonNull(layout);
              Objects.requireNonNull(value);
-             checkCompatibleType(carrier, layout, SysVx64Linker.ADDRESS_SIZE);
              TypeClass typeClass = TypeClass.classifyLayout(layout);
              if (isRegOverflow(currentGPOffset, currentFPOffset, typeClass)
                      || typeClass.inMemory()) {
                  // stack it!
                  stackArgs.add(new SimpleVaArg(carrier, layout, value));

@@ -393,28 +383,27 @@
                          int classIdx = 0;
                          long offset = 0;
                          while (offset < layout.byteSize()) {
                              final long copy = Math.min(layout.byteSize() - offset, 8);
                              boolean isSSE = typeClass.classes.get(classIdx++) == ArgumentClassImpl.SSE;
-                             MemorySegment slice = valueSegment.asSlice(offset, copy);
                              if (isSSE) {
-                                 reg_save_area.asSlice(currentFPOffset, copy).copyFrom(slice);
+                                 MemorySegment.copy(valueSegment, offset, reg_save_area, currentFPOffset, copy);
                                  currentFPOffset += FP_SLOT_SIZE;
                              } else {
-                                 reg_save_area.asSlice(currentGPOffset, copy).copyFrom(slice);
+                                 MemorySegment.copy(valueSegment, offset, reg_save_area, currentGPOffset, copy);
                                  currentGPOffset += GP_SLOT_SIZE;
                              }
                              offset += copy;
                          }
                      }
                      case POINTER, INTEGER -> {
-                         VarHandle writer = SharedUtils.vhPrimitiveOrAddress(carrier, layout);
+                         VarHandle writer = layout.varHandle();
                          writer.set(reg_save_area.asSlice(currentGPOffset), value);
                          currentGPOffset += GP_SLOT_SIZE;
                      }
                      case FLOAT -> {
-                         VarHandle writer = layout.varHandle(carrier);
+                         VarHandle writer = layout.varHandle();
                          writer.set(reg_save_area.asSlice(currentFPOffset), value);
                          currentFPOffset += FP_SLOT_SIZE;
                      }
                  }
              }

@@ -428,11 +417,11 @@
          public VaList build() {
              if (isEmpty()) {
                  return EMPTY;
              }
  
-             SegmentAllocator allocator = SegmentAllocator.arenaAllocator(scope);
+             SegmentAllocator allocator = SegmentAllocator.newNativeArena(scope);
              MemorySegment vaListSegment = allocator.allocate(LAYOUT);
              MemoryAddress stackArgsPtr = MemoryAddress.NULL;
              if (!stackArgs.isEmpty()) {
                  long stackArgsSize = stackArgs.stream().reduce(0L, (acc, e) -> acc + e.layout.byteSize(), Long::sum);
                  MemorySegment stackArgsSegment = allocator.allocate(stackArgsSize, 16);
< prev index next >