1 /*
  2  *  Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  3  *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  *  This code is free software; you can redistribute it and/or modify it
  6  *  under the terms of the GNU General Public License version 2 only, as
  7  *  published by the Free Software Foundation.  Oracle designates this
  8  *  particular file as subject to the "Classpath" exception as provided
  9  *  by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  *  This code is distributed in the hope that it will be useful, but WITHOUT
 12  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 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 
 27 package jdk.incubator.foreign;
 28 
 29 import jdk.internal.misc.Unsafe;
 30 
 31 import java.nio.ByteOrder;
 32 
 33 /**
 34  * This class defines useful layout constants. Some of the constants defined in this class are explicit in both
 35  * size and byte order (see {@link #BITS_64_BE}), and can therefore be used to explicitly and unambiguously specify the
 36  * contents of a memory segment. Other constants make implicit byte order assumptions (see
 37  * {@link #JAVA_INT}); as such, these constants make it easy to work with other serialization-centric APIs,
 38  * such as {@link java.nio.ByteBuffer}.
 39  */
 40 public final class MemoryLayouts {
 41 
 42     private MemoryLayouts() {
 43         //just the one, please
 44     }
 45 
 46     /**
 47      * A value layout constant with size of one byte, and byte order set to {@link ByteOrder#LITTLE_ENDIAN}.
 48      */
 49     public static final ValueLayout BITS_8_LE = MemoryLayout.valueLayout(8, ByteOrder.LITTLE_ENDIAN);
 50 
 51     /**
 52      * A value layout constant with size of two bytes, and byte order set to {@link ByteOrder#LITTLE_ENDIAN}.
 53      */
 54     public static final ValueLayout BITS_16_LE = MemoryLayout.valueLayout(16, ByteOrder.LITTLE_ENDIAN);
 55 
 56     /**
 57      * A value layout constant with size of four bytes, and byte order set to {@link ByteOrder#LITTLE_ENDIAN}.
 58      */
 59     public static final ValueLayout BITS_32_LE = MemoryLayout.valueLayout(32, ByteOrder.LITTLE_ENDIAN);
 60 
 61     /**
 62      * A value layout constant with size of eight bytes, and byte order set to {@link ByteOrder#LITTLE_ENDIAN}.
 63      */
 64     public static final ValueLayout BITS_64_LE = MemoryLayout.valueLayout(64, ByteOrder.LITTLE_ENDIAN);
 65 
 66     /**
 67      * A value layout constant with size of one byte, and byte order set to {@link ByteOrder#BIG_ENDIAN}.
 68      */
 69     public static final ValueLayout BITS_8_BE = MemoryLayout.valueLayout(8, ByteOrder.BIG_ENDIAN);
 70 
 71     /**
 72      * A value layout constant with size of two bytes, and byte order set to {@link ByteOrder#BIG_ENDIAN}.
 73      */
 74     public static final ValueLayout BITS_16_BE = MemoryLayout.valueLayout(16, ByteOrder.BIG_ENDIAN);
 75 
 76     /**
 77      * A value layout constant with size of four bytes, and byte order set to {@link ByteOrder#BIG_ENDIAN}.
 78      */
 79     public static final ValueLayout BITS_32_BE = MemoryLayout.valueLayout(32, ByteOrder.BIG_ENDIAN);
 80 
 81     /**
 82      * A value layout constant with size of eight bytes, and byte order set to {@link ByteOrder#BIG_ENDIAN}.
 83      */
 84     public static final ValueLayout BITS_64_BE = MemoryLayout.valueLayout(64, ByteOrder.BIG_ENDIAN);
 85 
 86     /**
 87      * A padding layout constant with size of one byte.
 88      */
 89     public static final MemoryLayout PAD_8 = MemoryLayout.paddingLayout(8);
 90 
 91     /**
 92      * A padding layout constant with size of two bytes.
 93      */
 94     public static final MemoryLayout PAD_16 = MemoryLayout.paddingLayout(16);
 95 
 96     /**
 97      * A padding layout constant with size of four bytes.
 98      */
 99     public static final MemoryLayout PAD_32 = MemoryLayout.paddingLayout(32);
100 
101     /**
102      * A padding layout constant with size of eight bytes.
103      */
104     public static final MemoryLayout PAD_64 = MemoryLayout.paddingLayout(64);
105 
106     /**
107      * A value layout constant whose size is the same as that of a machine address (e.g. {@code size_t}), and byte order set to {@link ByteOrder#nativeOrder()}.
108      */
109     public static final ValueLayout ADDRESS = MemoryLayout.valueLayout(Unsafe.ADDRESS_SIZE * 8, ByteOrder.nativeOrder());
110 
111     /**
112      * A value layout constant whose size is the same as that of a Java {@code byte}, and byte order set to {@link ByteOrder#nativeOrder()}.
113      */
114     public static final ValueLayout JAVA_BYTE = MemoryLayout.valueLayout(8, ByteOrder.nativeOrder());
115 
116     /**
117      * A value layout constant whose size is the same as that of a Java {@code char}, and byte order set to {@link ByteOrder#nativeOrder()}.
118      */
119     public static final ValueLayout JAVA_CHAR = MemoryLayout.valueLayout(16, ByteOrder.nativeOrder());
120 
121     /**
122      * A value layout constant whose size is the same as that of a Java {@code short}, and byte order set to {@link ByteOrder#nativeOrder()}.
123      */
124     public static final ValueLayout JAVA_SHORT = MemoryLayout.valueLayout(16, ByteOrder.nativeOrder());
125 
126     /**
127      * A value layout constant whose size is the same as that of a Java {@code int}, and byte order set to {@link ByteOrder#nativeOrder()}.
128      */
129     public static final ValueLayout JAVA_INT = MemoryLayout.valueLayout(32, ByteOrder.nativeOrder());
130 
131     /**
132      * A value layout constant whose size is the same as that of a Java {@code long}, and byte order set to {@link ByteOrder#nativeOrder()}.
133      * The alignment of this layout (see {@link MemoryLayout#byteAlignment()} is platform-dependent, so that the following
134      * invariant holds:
135      * <blockquote><pre>{@code
136     MemoryLayouts.JAVA_LONG.byteAlignment() == MemoryLayouts.ADDRESS.byteSize();
137      * }</pre></blockquote>
138      */
139     public static final ValueLayout JAVA_LONG = MemoryLayout.valueLayout(64, ByteOrder.nativeOrder())
140             .withBitAlignment(ADDRESS.bitSize());
141 
142     /**
143      * A value layout constant whose size is the same as that of a Java {@code float}, and byte order set to {@link ByteOrder#nativeOrder()}.
144      */
145     public static final ValueLayout JAVA_FLOAT = MemoryLayout.valueLayout(32, ByteOrder.nativeOrder());
146 
147     /**
148      * A value layout constant whose size is the same as that of a Java {@code double}, and byte order set to {@link ByteOrder#nativeOrder()}.
149      * The alignment of this layout (see {@link MemoryLayout#byteAlignment()} is platform-dependent, so that the following
150      * invariant holds:
151      * <blockquote><pre>{@code
152     MemoryLayouts.JAVA_DOUBLE.byteAlignment() == MemoryLayouts.ADDRESS.byteSize();
153      * }</pre></blockquote>
154      */
155     public static final ValueLayout JAVA_DOUBLE = MemoryLayout.valueLayout(64, ByteOrder.nativeOrder())
156             .withBitAlignment(ADDRESS.bitSize());
157 }