< prev index next > src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/sysv/SysVVaList.java
Print this page
import jdk.incubator.foreign.GroupLayout;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.MemoryHandles;
import jdk.incubator.foreign.MemoryLayout;
import jdk.incubator.foreign.MemorySegment;
+ import jdk.internal.foreign.AbstractMemorySegmentImpl;
+ import jdk.internal.foreign.NativeMemorySegmentImpl;
import jdk.internal.foreign.Utils;
import jdk.internal.foreign.abi.SharedUtils;
import java.lang.invoke.VarHandle;
+ import java.lang.ref.Cleaner;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import static jdk.incubator.foreign.CSupport.SysV;
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 Cleaner cleaner = Cleaner.create();
+ private static final CSupport.VaList EMPTY = new SharedUtils.EmptyVaList(emptyListAddress());
+
private final MemorySegment segment;
private final List<MemorySegment> slices = new ArrayList<>();
private final MemorySegment regSaveArea;
SysVVaList(MemorySegment segment) {
this.segment = segment;
regSaveArea = regSaveArea();
slices.add(regSaveArea);
}
+ private static MemoryAddress emptyListAddress() {
+ MemorySegment ms = MemorySegment.allocateNative(LAYOUT);
+ cleaner.register(SysVVaList.class, ms::close);
+ MemoryAddress base = ms.baseAddress();
+ 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);
+ MemorySegment unconfined = NativeMemorySegmentImpl.makeNativeSegmentUnchecked(
+ base, ms.byteSize(), null, null, null).withAccessModes(0);
+ return unconfined.baseAddress();
+ }
+
+ public static CSupport.VaList empty() {
+ return EMPTY;
+ }
+
private int currentGPOffset() {
return (int) VH_gp_offset.get(segment.baseAddress());
}
private void currentGPOffset(int i) {
public static VaList ofAddress(MemoryAddress ma) {
return new SysVVaList(MemorySegment.ofNativeRestricted(ma, LAYOUT.byteSize(), Thread.currentThread(), null, null));
}
- MemorySegment getSegment() {
- return segment;
- }
-
@Override
public boolean isAlive() {
return segment.isAlive();
}
}
}
return this;
}
- public SysVVaList build() {
+ private boolean isEmpty() {
+ return currentGPOffset == 0 && currentFPOffset == FP_OFFSET && stackArgs.isEmpty();
+ }
+
+ public VaList build() {
+ if (isEmpty()) {
+ return EMPTY;
+ }
+
MemorySegment vaListSegment = MemorySegment.allocateNative(LAYOUT.byteSize());
SysVVaList res = new SysVVaList(vaListSegment);
MemoryAddress stackArgsPtr = MemoryAddress.NULL;
if (!stackArgs.isEmpty()) {
long stackArgsSize = stackArgs.stream().reduce(0L, (acc, e) -> acc + e.layout.byteSize(), Long::sum);
< prev index next >