< prev index next >

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

Print this page

 14  *  version 2 for more details (a copy is included in the LICENSE file that
 15  *  accompanied this code).
 16  *
 17  *  You should have received a copy of the GNU General Public License version
 18  *  2 along with this work; if not, write to the Free Software Foundation,
 19  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  *   Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  *  or visit www.oracle.com if you need additional information or have any
 23  *  questions.
 24  *
 25  */
 26 package jdk.internal.foreign.abi.x64.sysv;
 27 
 28 import jdk.incubator.foreign.CSupport;
 29 import jdk.incubator.foreign.GroupLayout;
 30 import jdk.incubator.foreign.MemoryAddress;
 31 import jdk.incubator.foreign.MemoryHandles;
 32 import jdk.incubator.foreign.MemoryLayout;
 33 import jdk.incubator.foreign.MemorySegment;
 34 import jdk.internal.foreign.AbstractMemorySegmentImpl;
 35 import jdk.internal.foreign.NativeMemorySegmentImpl;
 36 import jdk.internal.foreign.Utils;
 37 import jdk.internal.foreign.abi.SharedUtils;

 38 
 39 import java.lang.invoke.VarHandle;
 40 import java.lang.ref.Cleaner;
 41 import java.nio.ByteOrder;
 42 import java.util.ArrayList;
 43 import java.util.List;
 44 
 45 import static jdk.incubator.foreign.CSupport.SysV;
 46 import static jdk.incubator.foreign.CSupport.VaList;
 47 import static jdk.incubator.foreign.MemoryLayout.PathElement.groupElement;
 48 import static jdk.internal.foreign.abi.SharedUtils.SimpleVaArg;
 49 import static jdk.internal.foreign.abi.SharedUtils.checkCompatibleType;
 50 import static jdk.internal.foreign.abi.SharedUtils.vhPrimitiveOrAddress;
 51 
 52 // See https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf "3.5.7 Variable Argument Lists"
 53 public class SysVVaList implements VaList {


 54     static final Class<?> CARRIER = MemoryAddress.class;
 55 
 56 //    struct typedef __va_list_tag __va_list_tag {
 57 //        unsigned int               gp_offset;            /*     0     4 */
 58 //        unsigned int               fp_offset;            /*     4     4 */
 59 //        void *                     overflow_arg_area;    /*     8     8 */
 60 //        void *                     reg_save_area;        /*    16     8 */
 61 //
 62 //        /* size: 24, cachelines: 1, members: 4 */
 63 //        /* last cacheline: 24 bytes */
 64 //    };
 65     static final GroupLayout LAYOUT = MemoryLayout.ofStruct(
 66         SysV.C_INT.withName("gp_offset"),
 67         SysV.C_INT.withName("fp_offset"),
 68         SysV.C_POINTER.withName("overflow_arg_area"),
 69         SysV.C_POINTER.withName("reg_save_area")
 70     ).withName("__va_list_tag");
 71 
 72     private static final MemoryLayout GP_REG = MemoryLayout.ofValueBits(64, ByteOrder.nativeOrder());
 73     private static final MemoryLayout FP_REG = MemoryLayout.ofValueBits(128, ByteOrder.nativeOrder());

111     private static final VarHandle VH_gp_offset = LAYOUT.varHandle(int.class, groupElement("gp_offset"));
112     private static final VarHandle VH_overflow_arg_area
113         = MemoryHandles.asAddressVarHandle(LAYOUT.varHandle(long.class, groupElement("overflow_arg_area")));
114     private static final VarHandle VH_reg_save_area
115         = MemoryHandles.asAddressVarHandle(LAYOUT.varHandle(long.class, groupElement("reg_save_area")));
116 
117     private static final Cleaner cleaner = Cleaner.create();
118     private static final CSupport.VaList EMPTY = new SharedUtils.EmptyVaList(emptyListAddress());
119 
120     private final MemorySegment segment;
121     private final List<MemorySegment> slices = new ArrayList<>();
122     private final MemorySegment regSaveArea;
123 
124     SysVVaList(MemorySegment segment) {
125         this.segment = segment;
126         regSaveArea = regSaveArea();
127         slices.add(regSaveArea);
128     }
129 
130     private static MemoryAddress emptyListAddress() {
131         MemorySegment ms = MemorySegment.allocateNative(LAYOUT);


132         cleaner.register(SysVVaList.class, ms::close);
133         MemoryAddress base = ms.baseAddress();
134         VH_gp_offset.set(base, MAX_GP_OFFSET);
135         VH_fp_offset.set(base, MAX_FP_OFFSET);
136         VH_overflow_arg_area.set(base, MemoryAddress.NULL);
137         VH_reg_save_area.set(base, MemoryAddress.NULL);
138         MemorySegment unconfined = NativeMemorySegmentImpl.makeNativeSegmentUnchecked(
139                 base, ms.byteSize(), null, null, null).withAccessModes(0);
140         return unconfined.baseAddress();
141     }
142 
143     public static CSupport.VaList empty() {
144         return EMPTY;
145     }
146 
147     private int currentGPOffset() {
148         return (int) VH_gp_offset.get(segment.baseAddress());
149     }
150 
151     private void currentGPOffset(int i) {

 14  *  version 2 for more details (a copy is included in the LICENSE file that
 15  *  accompanied this code).
 16  *
 17  *  You should have received a copy of the GNU General Public License version
 18  *  2 along with this work; if not, write to the Free Software Foundation,
 19  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  *   Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  *  or visit www.oracle.com if you need additional information or have any
 23  *  questions.
 24  *
 25  */
 26 package jdk.internal.foreign.abi.x64.sysv;
 27 
 28 import jdk.incubator.foreign.CSupport;
 29 import jdk.incubator.foreign.GroupLayout;
 30 import jdk.incubator.foreign.MemoryAddress;
 31 import jdk.incubator.foreign.MemoryHandles;
 32 import jdk.incubator.foreign.MemoryLayout;
 33 import jdk.incubator.foreign.MemorySegment;

 34 import jdk.internal.foreign.NativeMemorySegmentImpl;
 35 import jdk.internal.foreign.Utils;
 36 import jdk.internal.foreign.abi.SharedUtils;
 37 import jdk.internal.misc.Unsafe;
 38 
 39 import java.lang.invoke.VarHandle;
 40 import java.lang.ref.Cleaner;
 41 import java.nio.ByteOrder;
 42 import java.util.ArrayList;
 43 import java.util.List;
 44 
 45 import static jdk.incubator.foreign.CSupport.SysV;
 46 import static jdk.incubator.foreign.CSupport.VaList;
 47 import static jdk.incubator.foreign.MemoryLayout.PathElement.groupElement;
 48 import static jdk.internal.foreign.abi.SharedUtils.SimpleVaArg;
 49 import static jdk.internal.foreign.abi.SharedUtils.checkCompatibleType;
 50 import static jdk.internal.foreign.abi.SharedUtils.vhPrimitiveOrAddress;
 51 
 52 // See https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf "3.5.7 Variable Argument Lists"
 53 public class SysVVaList implements VaList {
 54     private static final Unsafe U = Unsafe.getUnsafe();
 55 
 56     static final Class<?> CARRIER = MemoryAddress.class;
 57 
 58 //    struct typedef __va_list_tag __va_list_tag {
 59 //        unsigned int               gp_offset;            /*     0     4 */
 60 //        unsigned int               fp_offset;            /*     4     4 */
 61 //        void *                     overflow_arg_area;    /*     8     8 */
 62 //        void *                     reg_save_area;        /*    16     8 */
 63 //
 64 //        /* size: 24, cachelines: 1, members: 4 */
 65 //        /* last cacheline: 24 bytes */
 66 //    };
 67     static final GroupLayout LAYOUT = MemoryLayout.ofStruct(
 68         SysV.C_INT.withName("gp_offset"),
 69         SysV.C_INT.withName("fp_offset"),
 70         SysV.C_POINTER.withName("overflow_arg_area"),
 71         SysV.C_POINTER.withName("reg_save_area")
 72     ).withName("__va_list_tag");
 73 
 74     private static final MemoryLayout GP_REG = MemoryLayout.ofValueBits(64, ByteOrder.nativeOrder());
 75     private static final MemoryLayout FP_REG = MemoryLayout.ofValueBits(128, ByteOrder.nativeOrder());

113     private static final VarHandle VH_gp_offset = LAYOUT.varHandle(int.class, groupElement("gp_offset"));
114     private static final VarHandle VH_overflow_arg_area
115         = MemoryHandles.asAddressVarHandle(LAYOUT.varHandle(long.class, groupElement("overflow_arg_area")));
116     private static final VarHandle VH_reg_save_area
117         = MemoryHandles.asAddressVarHandle(LAYOUT.varHandle(long.class, groupElement("reg_save_area")));
118 
119     private static final Cleaner cleaner = Cleaner.create();
120     private static final CSupport.VaList EMPTY = new SharedUtils.EmptyVaList(emptyListAddress());
121 
122     private final MemorySegment segment;
123     private final List<MemorySegment> slices = new ArrayList<>();
124     private final MemorySegment regSaveArea;
125 
126     SysVVaList(MemorySegment segment) {
127         this.segment = segment;
128         regSaveArea = regSaveArea();
129         slices.add(regSaveArea);
130     }
131 
132     private static MemoryAddress emptyListAddress() {
133         long ptr = U.allocateMemory(LAYOUT.byteSize());
134         MemorySegment ms = NativeMemorySegmentImpl.makeNativeSegmentUnchecked(
135                 MemoryAddress.ofLong(ptr), LAYOUT.byteSize(), null, () -> U.freeMemory(ptr), null);
136         cleaner.register(SysVVaList.class, ms::close);
137         MemoryAddress base = ms.baseAddress();
138         VH_gp_offset.set(base, MAX_GP_OFFSET);
139         VH_fp_offset.set(base, MAX_FP_OFFSET);
140         VH_overflow_arg_area.set(base, MemoryAddress.NULL);
141         VH_reg_save_area.set(base, MemoryAddress.NULL);
142         MemorySegment unconfined = NativeMemorySegmentImpl.makeNativeSegmentUnchecked(
143                 base, ms.byteSize(), null, null, null).withAccessModes(0);
144         return unconfined.baseAddress();
145     }
146 
147     public static CSupport.VaList empty() {
148         return EMPTY;
149     }
150 
151     private int currentGPOffset() {
152         return (int) VH_gp_offset.get(segment.baseAddress());
153     }
154 
155     private void currentGPOffset(int i) {
< prev index next >