jdk/src/java.base/share/classes/sun/misc/Unsafe.java
changeset 33656 ef901bc43f7a
parent 31671 362e0c0acece
child 34882 ce2a8ec851c1
child 35253 ed92ce9fac46
equal deleted inserted replaced
33655:5b575aff8fa0 33656:ef901bc43f7a
  1034      */
  1034      */
  1035     private static void throwIllegalAccessError() {
  1035     private static void throwIllegalAccessError() {
  1036         throw new IllegalAccessError();
  1036         throw new IllegalAccessError();
  1037     }
  1037     }
  1038 
  1038 
  1039     /**
       
  1040      * @return Returns true if the native byte ordering of this
       
  1041      * platform is big-endian, false if it is little-endian.
       
  1042      */
       
  1043     public final boolean isBigEndian() { return BE; }
       
  1044 
       
  1045     /**
       
  1046      * @return Returns true if this platform is capable of performing
       
  1047      * accesses at addresses which are not aligned for the type of the
       
  1048      * primitive type being accessed, false otherwise.
       
  1049      */
       
  1050     public final boolean unalignedAccess() { return unalignedAccess; }
       
  1051 
       
  1052     /**
       
  1053      * Fetches a value at some byte offset into a given Java object.
       
  1054      * More specifically, fetches a value within the given object
       
  1055      * <code>o</code> at the given offset, or (if <code>o</code> is
       
  1056      * null) from the memory address whose numerical value is the
       
  1057      * given offset.  <p>
       
  1058      *
       
  1059      * The specification of this method is the same as {@link
       
  1060      * #getLong(Object, long)} except that the offset does not need to
       
  1061      * have been obtained from {@link #objectFieldOffset} on the
       
  1062      * {@link java.lang.reflect.Field} of some Java field.  The value
       
  1063      * in memory is raw data, and need not correspond to any Java
       
  1064      * variable.  Unless <code>o</code> is null, the value accessed
       
  1065      * must be entirely within the allocated object.  The endianness
       
  1066      * of the value in memory is the endianness of the native platform.
       
  1067      *
       
  1068      * <p> The read will be atomic with respect to the largest power
       
  1069      * of two that divides the GCD of the offset and the storage size.
       
  1070      * For example, getLongUnaligned will make atomic reads of 2-, 4-,
       
  1071      * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
       
  1072      * respectively.  There are no other guarantees of atomicity.
       
  1073      * <p>
       
  1074      * 8-byte atomicity is only guaranteed on platforms on which
       
  1075      * support atomic accesses to longs.
       
  1076      *
       
  1077      * @param o Java heap object in which the value resides, if any, else
       
  1078      *        null
       
  1079      * @param offset The offset in bytes from the start of the object
       
  1080      * @return the value fetched from the indicated object
       
  1081      * @throws RuntimeException No defined exceptions are thrown, not even
       
  1082      *         {@link NullPointerException}
       
  1083      * @since 1.9
       
  1084      */
       
  1085     @HotSpotIntrinsicCandidate
       
  1086     public final long getLongUnaligned(Object o, long offset) {
       
  1087         if ((offset & 7) == 0) {
       
  1088             return getLong(o, offset);
       
  1089         } else if ((offset & 3) == 0) {
       
  1090             return makeLong(getInt(o, offset),
       
  1091                             getInt(o, offset + 4));
       
  1092         } else if ((offset & 1) == 0) {
       
  1093             return makeLong(getShort(o, offset),
       
  1094                             getShort(o, offset + 2),
       
  1095                             getShort(o, offset + 4),
       
  1096                             getShort(o, offset + 6));
       
  1097         } else {
       
  1098             return makeLong(getByte(o, offset),
       
  1099                             getByte(o, offset + 1),
       
  1100                             getByte(o, offset + 2),
       
  1101                             getByte(o, offset + 3),
       
  1102                             getByte(o, offset + 4),
       
  1103                             getByte(o, offset + 5),
       
  1104                             getByte(o, offset + 6),
       
  1105                             getByte(o, offset + 7));
       
  1106         }
       
  1107     }
       
  1108     /**
       
  1109      * As {@link #getLongUnaligned(Object, long)} but with an
       
  1110      * additional argument which specifies the endianness of the value
       
  1111      * as stored in memory.
       
  1112      *
       
  1113      * @param o Java heap object in which the variable resides
       
  1114      * @param offset The offset in bytes from the start of the object
       
  1115      * @param bigEndian The endianness of the value
       
  1116      * @return the value fetched from the indicated object
       
  1117      * @since 1.9
       
  1118      */
       
  1119     public final long getLongUnaligned(Object o, long offset, boolean bigEndian) {
       
  1120         return convEndian(bigEndian, getLongUnaligned(o, offset));
       
  1121     }
       
  1122 
       
  1123     /** @see #getLongUnaligned(Object, long) */
       
  1124     @HotSpotIntrinsicCandidate
       
  1125     public final int getIntUnaligned(Object o, long offset) {
       
  1126         if ((offset & 3) == 0) {
       
  1127             return getInt(o, offset);
       
  1128         } else if ((offset & 1) == 0) {
       
  1129             return makeInt(getShort(o, offset),
       
  1130                            getShort(o, offset + 2));
       
  1131         } else {
       
  1132             return makeInt(getByte(o, offset),
       
  1133                            getByte(o, offset + 1),
       
  1134                            getByte(o, offset + 2),
       
  1135                            getByte(o, offset + 3));
       
  1136         }
       
  1137     }
       
  1138     /** @see #getLongUnaligned(Object, long, boolean) */
       
  1139     public final int getIntUnaligned(Object o, long offset, boolean bigEndian) {
       
  1140         return convEndian(bigEndian, getIntUnaligned(o, offset));
       
  1141     }
       
  1142 
       
  1143     /** @see #getLongUnaligned(Object, long) */
       
  1144     @HotSpotIntrinsicCandidate
       
  1145     public final short getShortUnaligned(Object o, long offset) {
       
  1146         if ((offset & 1) == 0) {
       
  1147             return getShort(o, offset);
       
  1148         } else {
       
  1149             return makeShort(getByte(o, offset),
       
  1150                              getByte(o, offset + 1));
       
  1151         }
       
  1152     }
       
  1153     /** @see #getLongUnaligned(Object, long, boolean) */
       
  1154     public final short getShortUnaligned(Object o, long offset, boolean bigEndian) {
       
  1155         return convEndian(bigEndian, getShortUnaligned(o, offset));
       
  1156     }
       
  1157 
       
  1158     /** @see #getLongUnaligned(Object, long) */
       
  1159     @HotSpotIntrinsicCandidate
       
  1160     public final char getCharUnaligned(Object o, long offset) {
       
  1161         return (char)getShortUnaligned(o, offset);
       
  1162     }
       
  1163 
       
  1164     /** @see #getLongUnaligned(Object, long, boolean) */
       
  1165     public final char getCharUnaligned(Object o, long offset, boolean bigEndian) {
       
  1166         return convEndian(bigEndian, getCharUnaligned(o, offset));
       
  1167     }
       
  1168 
       
  1169     /**
       
  1170      * Stores a value at some byte offset into a given Java object.
       
  1171      * <p>
       
  1172      * The specification of this method is the same as {@link
       
  1173      * #getLong(Object, long)} except that the offset does not need to
       
  1174      * have been obtained from {@link #objectFieldOffset} on the
       
  1175      * {@link java.lang.reflect.Field} of some Java field.  The value
       
  1176      * in memory is raw data, and need not correspond to any Java
       
  1177      * variable.  The endianness of the value in memory is the
       
  1178      * endianness of the native platform.
       
  1179      * <p>
       
  1180      * The write will be atomic with respect to the largest power of
       
  1181      * two that divides the GCD of the offset and the storage size.
       
  1182      * For example, putLongUnaligned will make atomic writes of 2-, 4-,
       
  1183      * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
       
  1184      * respectively.  There are no other guarantees of atomicity.
       
  1185      * <p>
       
  1186      * 8-byte atomicity is only guaranteed on platforms on which
       
  1187      * support atomic accesses to longs.
       
  1188      *
       
  1189      * @param o Java heap object in which the value resides, if any, else
       
  1190      *        null
       
  1191      * @param offset The offset in bytes from the start of the object
       
  1192      * @param x the value to store
       
  1193      * @throws RuntimeException No defined exceptions are thrown, not even
       
  1194      *         {@link NullPointerException}
       
  1195      * @since 1.9
       
  1196      */
       
  1197     @HotSpotIntrinsicCandidate
       
  1198     public final void putLongUnaligned(Object o, long offset, long x) {
       
  1199         if ((offset & 7) == 0) {
       
  1200             putLong(o, offset, x);
       
  1201         } else if ((offset & 3) == 0) {
       
  1202             putLongParts(o, offset,
       
  1203                          (int)(x >> 0),
       
  1204                          (int)(x >>> 32));
       
  1205         } else if ((offset & 1) == 0) {
       
  1206             putLongParts(o, offset,
       
  1207                          (short)(x >>> 0),
       
  1208                          (short)(x >>> 16),
       
  1209                          (short)(x >>> 32),
       
  1210                          (short)(x >>> 48));
       
  1211         } else {
       
  1212             putLongParts(o, offset,
       
  1213                          (byte)(x >>> 0),
       
  1214                          (byte)(x >>> 8),
       
  1215                          (byte)(x >>> 16),
       
  1216                          (byte)(x >>> 24),
       
  1217                          (byte)(x >>> 32),
       
  1218                          (byte)(x >>> 40),
       
  1219                          (byte)(x >>> 48),
       
  1220                          (byte)(x >>> 56));
       
  1221         }
       
  1222     }
       
  1223 
       
  1224     /**
       
  1225      * As {@link #putLongUnaligned(Object, long, long)} but with an additional
       
  1226      * argument which specifies the endianness of the value as stored in memory.
       
  1227      * @param o Java heap object in which the value resides
       
  1228      * @param offset The offset in bytes from the start of the object
       
  1229      * @param x the value to store
       
  1230      * @param bigEndian The endianness of the value
       
  1231      * @throws RuntimeException No defined exceptions are thrown, not even
       
  1232      *         {@link NullPointerException}
       
  1233      * @since 1.9
       
  1234      */
       
  1235     public final void putLongUnaligned(Object o, long offset, long x, boolean bigEndian) {
       
  1236         putLongUnaligned(o, offset, convEndian(bigEndian, x));
       
  1237     }
       
  1238 
       
  1239     /** @see #putLongUnaligned(Object, long, long) */
       
  1240     @HotSpotIntrinsicCandidate
       
  1241     public final void putIntUnaligned(Object o, long offset, int x) {
       
  1242         if ((offset & 3) == 0) {
       
  1243             putInt(o, offset, x);
       
  1244         } else if ((offset & 1) == 0) {
       
  1245             putIntParts(o, offset,
       
  1246                         (short)(x >> 0),
       
  1247                         (short)(x >>> 16));
       
  1248         } else {
       
  1249             putIntParts(o, offset,
       
  1250                         (byte)(x >>> 0),
       
  1251                         (byte)(x >>> 8),
       
  1252                         (byte)(x >>> 16),
       
  1253                         (byte)(x >>> 24));
       
  1254         }
       
  1255     }
       
  1256     /** @see #putLongUnaligned(Object, long, long, boolean) */
       
  1257     public final void putIntUnaligned(Object o, long offset, int x, boolean bigEndian) {
       
  1258         putIntUnaligned(o, offset, convEndian(bigEndian, x));
       
  1259     }
       
  1260 
       
  1261     /** @see #putLongUnaligned(Object, long, long) */
       
  1262     @HotSpotIntrinsicCandidate
       
  1263     public final void putShortUnaligned(Object o, long offset, short x) {
       
  1264         if ((offset & 1) == 0) {
       
  1265             putShort(o, offset, x);
       
  1266         } else {
       
  1267             putShortParts(o, offset,
       
  1268                           (byte)(x >>> 0),
       
  1269                           (byte)(x >>> 8));
       
  1270         }
       
  1271     }
       
  1272     /** @see #putLongUnaligned(Object, long, long, boolean) */
       
  1273     public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
       
  1274         putShortUnaligned(o, offset, convEndian(bigEndian, x));
       
  1275     }
       
  1276 
       
  1277     /** @see #putLongUnaligned(Object, long, long) */
       
  1278     @HotSpotIntrinsicCandidate
       
  1279     public final void putCharUnaligned(Object o, long offset, char x) {
       
  1280         putShortUnaligned(o, offset, (short)x);
       
  1281     }
       
  1282     /** @see #putLongUnaligned(Object, long, long, boolean) */
       
  1283     public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
       
  1284         putCharUnaligned(o, offset, convEndian(bigEndian, x));
       
  1285     }
       
  1286 
       
  1287     // JVM interface methods
  1039     // JVM interface methods
  1288     private native boolean unalignedAccess0();
  1040     private native boolean unalignedAccess0();
  1289     private native boolean isBigEndian0();
  1041     private native boolean isBigEndian0();
  1290 
  1042 
  1291     // BE is true iff the native endianness of this platform is big.
       
  1292     private static final boolean BE = theUnsafe.isBigEndian0();
       
  1293 
       
  1294     // unalignedAccess is true iff this platform can perform unaligned accesses.
       
  1295     private static final boolean unalignedAccess = theUnsafe.unalignedAccess0();
       
  1296 
       
  1297     private static int pickPos(int top, int pos) { return BE ? top - pos : pos; }
       
  1298 
       
  1299     // These methods construct integers from bytes.  The byte ordering
       
  1300     // is the native endianness of this platform.
       
  1301     private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
       
  1302         return ((toUnsignedLong(i0) << pickPos(56, 0))
       
  1303               | (toUnsignedLong(i1) << pickPos(56, 8))
       
  1304               | (toUnsignedLong(i2) << pickPos(56, 16))
       
  1305               | (toUnsignedLong(i3) << pickPos(56, 24))
       
  1306               | (toUnsignedLong(i4) << pickPos(56, 32))
       
  1307               | (toUnsignedLong(i5) << pickPos(56, 40))
       
  1308               | (toUnsignedLong(i6) << pickPos(56, 48))
       
  1309               | (toUnsignedLong(i7) << pickPos(56, 56)));
       
  1310     }
       
  1311     private static long makeLong(short i0, short i1, short i2, short i3) {
       
  1312         return ((toUnsignedLong(i0) << pickPos(48, 0))
       
  1313               | (toUnsignedLong(i1) << pickPos(48, 16))
       
  1314               | (toUnsignedLong(i2) << pickPos(48, 32))
       
  1315               | (toUnsignedLong(i3) << pickPos(48, 48)));
       
  1316     }
       
  1317     private static long makeLong(int i0, int i1) {
       
  1318         return (toUnsignedLong(i0) << pickPos(32, 0))
       
  1319              | (toUnsignedLong(i1) << pickPos(32, 32));
       
  1320     }
       
  1321     private static int makeInt(short i0, short i1) {
       
  1322         return (toUnsignedInt(i0) << pickPos(16, 0))
       
  1323              | (toUnsignedInt(i1) << pickPos(16, 16));
       
  1324     }
       
  1325     private static int makeInt(byte i0, byte i1, byte i2, byte i3) {
       
  1326         return ((toUnsignedInt(i0) << pickPos(24, 0))
       
  1327               | (toUnsignedInt(i1) << pickPos(24, 8))
       
  1328               | (toUnsignedInt(i2) << pickPos(24, 16))
       
  1329               | (toUnsignedInt(i3) << pickPos(24, 24)));
       
  1330     }
       
  1331     private static short makeShort(byte i0, byte i1) {
       
  1332         return (short)((toUnsignedInt(i0) << pickPos(8, 0))
       
  1333                      | (toUnsignedInt(i1) << pickPos(8, 8)));
       
  1334     }
       
  1335 
       
  1336     private static byte  pick(byte  le, byte  be) { return BE ? be : le; }
       
  1337     private static short pick(short le, short be) { return BE ? be : le; }
       
  1338     private static int   pick(int   le, int   be) { return BE ? be : le; }
       
  1339 
       
  1340     // These methods write integers to memory from smaller parts
       
  1341     // provided by their caller.  The ordering in which these parts
       
  1342     // are written is the native endianness of this platform.
       
  1343     private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
       
  1344         putByte(o, offset + 0, pick(i0, i7));
       
  1345         putByte(o, offset + 1, pick(i1, i6));
       
  1346         putByte(o, offset + 2, pick(i2, i5));
       
  1347         putByte(o, offset + 3, pick(i3, i4));
       
  1348         putByte(o, offset + 4, pick(i4, i3));
       
  1349         putByte(o, offset + 5, pick(i5, i2));
       
  1350         putByte(o, offset + 6, pick(i6, i1));
       
  1351         putByte(o, offset + 7, pick(i7, i0));
       
  1352     }
       
  1353     private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) {
       
  1354         putShort(o, offset + 0, pick(i0, i3));
       
  1355         putShort(o, offset + 2, pick(i1, i2));
       
  1356         putShort(o, offset + 4, pick(i2, i1));
       
  1357         putShort(o, offset + 6, pick(i3, i0));
       
  1358     }
       
  1359     private void putLongParts(Object o, long offset, int i0, int i1) {
       
  1360         putInt(o, offset + 0, pick(i0, i1));
       
  1361         putInt(o, offset + 4, pick(i1, i0));
       
  1362     }
       
  1363     private void putIntParts(Object o, long offset, short i0, short i1) {
       
  1364         putShort(o, offset + 0, pick(i0, i1));
       
  1365         putShort(o, offset + 2, pick(i1, i0));
       
  1366     }
       
  1367     private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
       
  1368         putByte(o, offset + 0, pick(i0, i3));
       
  1369         putByte(o, offset + 1, pick(i1, i2));
       
  1370         putByte(o, offset + 2, pick(i2, i1));
       
  1371         putByte(o, offset + 3, pick(i3, i0));
       
  1372     }
       
  1373     private void putShortParts(Object o, long offset, byte i0, byte i1) {
       
  1374         putByte(o, offset + 0, pick(i0, i1));
       
  1375         putByte(o, offset + 1, pick(i1, i0));
       
  1376     }
       
  1377 
       
  1378     // Zero-extend an integer
       
  1379     private static int toUnsignedInt(byte n)    { return n & 0xff; }
       
  1380     private static int toUnsignedInt(short n)   { return n & 0xffff; }
       
  1381     private static long toUnsignedLong(byte n)  { return n & 0xffl; }
       
  1382     private static long toUnsignedLong(short n) { return n & 0xffffl; }
       
  1383     private static long toUnsignedLong(int n)   { return n & 0xffffffffl; }
       
  1384 
       
  1385     // Maybe byte-reverse an integer
       
  1386     private static char convEndian(boolean big, char n)   { return big == BE ? n : Character.reverseBytes(n); }
       
  1387     private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n)    ; }
       
  1388     private static int convEndian(boolean big, int n)     { return big == BE ? n : Integer.reverseBytes(n)  ; }
       
  1389     private static long convEndian(boolean big, long n)   { return big == BE ? n : Long.reverseBytes(n)     ; }
       
  1390 }
  1043 }