src/java.base/share/classes/sun/misc/Unsafe.java

Print this page




1126 
1127     /**
1128      * Ensures that loads and stores before the fence will not be reordered
1129      * with loads and stores after the fence.  Implies the effects of both
1130      * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
1131      * barrier.
1132      *
1133      * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
1134      * @since 1.8
1135      */
1136     public native void fullFence();
1137 
1138     /**
1139      * Throws IllegalAccessError; for use by the VM.
1140      * @since 1.8
1141      */
1142     private static void throwIllegalAccessError() {
1143        throw new IllegalAccessError();
1144     }
1145 

























































































































































































































































































































1146 }


1126 
1127     /**
1128      * Ensures that loads and stores before the fence will not be reordered
1129      * with loads and stores after the fence.  Implies the effects of both
1130      * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
1131      * barrier.
1132      *
1133      * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
1134      * @since 1.8
1135      */
1136     public native void fullFence();
1137 
1138     /**
1139      * Throws IllegalAccessError; for use by the VM.
1140      * @since 1.8
1141      */
1142     private static void throwIllegalAccessError() {
1143        throw new IllegalAccessError();
1144     }
1145 
1146     public final static boolean LITTLE_ENDIAN = false;
1147     public final static boolean BIG_ENDIAN = true;
1148     
1149     public native boolean getByteOrder();
1150 
1151     public native boolean unalignedAccess();
1152 
1153     public long getLongUnaligned(Object o, long offset) {
1154         if ((offset & 7) == 0) {
1155             return getLong(o, offset);
1156         } else if ((offset & 3) == 0) {
1157             return mem.makeLong(getInt(o, offset),
1158                                 getInt(o, offset + 4));
1159         } else if ((offset & 1) == 0) {
1160             return mem.makeLong(getShort(o, offset),
1161                                 getShort(o, offset + 2),
1162                                 getShort(o, offset + 4),
1163                                 getShort(o, offset + 6));
1164         } else {
1165             return mem.makeLong(getByte(o, offset),
1166                                 getByte(o, offset + 1),
1167                                 getByte(o, offset + 2),
1168                                 getByte(o, offset + 3),
1169                                 getByte(o, offset + 4),
1170                                 getByte(o, offset + 5),
1171                                 getByte(o, offset + 6),
1172                                 getByte(o, offset + 7));
1173 }
1174     }
1175     public long getLongUnaligned(Object o, long offset, boolean bigEndian) {
1176         return mem.fromEndian(bigEndian, getLongUnaligned(o, offset));
1177     }
1178         
1179     public int getIntUnaligned(Object o, long offset) {
1180         if ((offset & 3) == 0) {
1181             return getInt(o, offset);
1182         } else if ((offset & 1) == 0) {
1183             return mem.makeInt(getShort(o, offset),
1184                                getShort(o, offset + 2));
1185         } else {
1186             return mem.makeInt(getByte(o, offset),
1187                                getByte(o, offset + 1),
1188                                getByte(o, offset + 2),
1189                                getByte(o, offset + 3));
1190         }
1191     }
1192     public int getIntUnaligned(Object o, long offset, boolean bigEndian) {
1193         return mem.fromEndian(bigEndian, getIntUnaligned(o, offset));
1194     }
1195     
1196     public short getShortUnaligned(Object o, long offset) {
1197         if ((offset & 1) == 0) {
1198             return getShort(o, offset);
1199         } else {
1200             return mem.makeShort(getByte(o, offset),
1201                                  getByte(o, offset + 1));
1202         }
1203     }
1204     public short getShortUnaligned(Object o, long offset, boolean bigEndian) {
1205         return mem.fromEndian(bigEndian, getShortUnaligned(o, offset));
1206     }
1207 
1208     public char getCharUnaligned(Object o, long offset) {
1209         return (char)getShortUnaligned(o, offset);
1210     }
1211     public char getCharUnaligned(Object o, long offset, boolean bigEndian) {
1212         return mem.fromEndian(bigEndian, getCharUnaligned(o, offset));
1213     }
1214 
1215     public void putLongUnaligned(Object o, long offset, long x) {
1216         if ((offset & 7) == 0) {
1217             putLong(o, offset, x);
1218         } else if ((offset & 3) == 0) {
1219             mem.putLongParts(this, o, offset,
1220                              (int)(x >> 0),
1221                              (int)(x >>> 32));
1222         } else if ((offset & 1) == 0) {
1223             mem.putLongParts(this, o, offset,
1224                              (short)(x >>> 0),
1225                              (short)(x >>> 16),
1226                              (short)(x >>> 32),
1227                              (short)(x >>> 48));
1228         } else {
1229             mem.putLongParts(this, o, offset, 
1230                              (byte)(x >>> 0),
1231                              (byte)(x >>> 8),
1232                              (byte)(x >>> 16),
1233                              (byte)(x >>> 24),
1234                              (byte)(x >>> 32),
1235                              (byte)(x >>> 40),
1236                              (byte)(x >>> 48),
1237                              (byte)(x >>> 56));
1238         }
1239     }
1240 
1241     public 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             mem.putIntParts(this, o, offset,
1246                             (short)(x >> 0),
1247                             (short)(x >>> 16));
1248         } else {
1249             mem.putIntParts(this, o, offset, 
1250                             (byte)(x >>> 0),
1251                             (byte)(x >>> 8),
1252                             (byte)(x >>> 16),
1253                             (byte)(x >>> 24));
1254         }
1255     }
1256 
1257     public void putShortUnaligned(Object o, long offset, short x) {
1258         if ((offset & 1) == 0) {
1259             putShort(o, offset, x);
1260         } else {
1261             mem.putShortParts(this, o, offset, 
1262                               (byte)(x >>> 0),
1263                               (byte)(x >>> 8));
1264         }
1265     }
1266 
1267     public void putCharUnaligned(Object o, long offset, char x) {
1268         putShortUnaligned(o, offset, (short)x);
1269     }
1270 
1271     private static final boolean byteOrder = theUnsafe.getByteOrder();
1272 
1273     private static final NativeAccess mem
1274         = (byteOrder == LITTLE_ENDIAN) ? new NativeLittleEndian() : new NativeBigEndian();
1275 
1276     private abstract static class NativeAccess {
1277         // Native-enianness-dependent scatter/gather methods for integer types
1278         abstract long makeLong(int i0, int i1);
1279         abstract long makeLong(short i0, short i1, short i2, short i3);
1280         abstract long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7);
1281         abstract int makeInt(short i0, short i1);
1282         abstract int makeInt(byte i0, byte i1, byte i2, byte i3);
1283         abstract short makeShort(byte i0, byte i1);
1284 
1285         abstract void putLongParts(Unsafe theUnsafe, Object o, long offset, int i0, int i1);
1286         abstract void putLongParts(Unsafe theUnsafe, Object o, long offset,
1287                                    short i0, short i1, short i2, short i3);
1288         abstract void putLongParts(Unsafe theUnsafe, Object o, long offset,
1289                                    byte i0, byte i1, byte i2, byte i3, byte i4,
1290                                    byte i5, byte i6, byte i7);
1291         abstract void putIntParts(Unsafe theUnsafe, Object o, long offset, short i0, short i1);
1292         abstract void putIntParts(Unsafe theUnsafe, Object o, long offset,
1293                                   byte i0, byte i1, byte i2, byte i3);
1294         abstract void putShortParts(Unsafe theUnsafe, Object o, long offset, byte i0, byte i1);
1295 
1296         // Byte-reverse an integer if necessary
1297         abstract char fromEndian(boolean big, char n);
1298         abstract short fromEndian(boolean big, short n);
1299         abstract int fromEndian(boolean big, int n);
1300         abstract long fromEndian(boolean big, long n);
1301 
1302         // Zero-extend an integer type
1303         final int toUnsignedInt(byte n) { return n & 0xff; }
1304         final int toUnsignedInt(short n) { return n & 0xffff; }
1305         final long toUnsignedLong(byte n) { return n & 0xffl; }
1306         final long toUnsignedLong(short n) { return n & 0xffffl; }
1307         final long toUnsignedLong(int n) { return n & 0xffffffffl; }
1308     }
1309 
1310     private static class NativeLittleEndian extends NativeAccess {
1311         long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
1312             return ((toUnsignedLong(i0) << 0)
1313                   | (toUnsignedLong(i1) << 8)
1314                   | (toUnsignedLong(i2) << 16)
1315                   | (toUnsignedLong(i3) << 24)
1316                   | (toUnsignedLong(i4) << 32)
1317                   | (toUnsignedLong(i5) << 40)
1318                   | (toUnsignedLong(i6) << 48)
1319                   | (toUnsignedLong(i7) << 56));
1320         }
1321         long makeLong(short i0, short i1, short i2, short i3) {
1322             return ((toUnsignedLong(i0) << 0)
1323                   | (toUnsignedLong(i1) << 16)
1324                   | (toUnsignedLong(i2) << 32)
1325                   | (toUnsignedLong(i3) << 48));
1326         }
1327         long makeLong(int i0, int i1) {
1328             return (toUnsignedLong(i0) << 0)
1329                  | (toUnsignedLong(i1) << 32);
1330         }
1331         int makeInt(short i0, short i1) {
1332             return (toUnsignedInt(i0) << 0)
1333                  | (toUnsignedInt(i1) << 16);
1334         }
1335         int makeInt(byte i0, byte i1, byte i2, byte i3) {
1336             return ((toUnsignedInt(i0) << 0)
1337                   | (toUnsignedInt(i1) << 8)
1338                   | (toUnsignedInt(i2) << 16)
1339                   | (toUnsignedInt(i3) << 24));
1340         }
1341         short makeShort(byte i0, byte i1) {
1342             return (short)((toUnsignedInt(i0) << 0)
1343                          | (toUnsignedInt(i1) << 8));
1344         }
1345         void putLongParts(Unsafe theUnsafe, Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
1346             theUnsafe.putByte(o, offset + 0, i0);
1347             theUnsafe.putByte(o, offset + 1, i1);
1348             theUnsafe.putByte(o, offset + 2, i2);
1349             theUnsafe.putByte(o, offset + 3, i3);
1350             theUnsafe.putByte(o, offset + 4, i4);
1351             theUnsafe.putByte(o, offset + 5, i5);
1352             theUnsafe.putByte(o, offset + 6, i6);
1353             theUnsafe.putByte(o, offset + 7, i7);
1354         }
1355         void putLongParts(Unsafe theUnsafe, Object o, long offset, short i0, short i1, short i2, short i3) {
1356             theUnsafe.putShort(o, offset + 0, i0);
1357             theUnsafe.putShort(o, offset + 2, i1);
1358             theUnsafe.putShort(o, offset + 4, i2);
1359             theUnsafe.putShort(o, offset + 6, i3);
1360         }
1361         void putLongParts(Unsafe theUnsafe, Object o, long offset, int i0, int i1) {
1362             theUnsafe.putInt(o, offset + 0, i0);
1363             theUnsafe.putInt(o, offset + 4, i1);
1364         }
1365         void putIntParts(Unsafe theUnsafe, Object o, long offset, short i0, short i1) {
1366             theUnsafe.putShort(o, offset + 0, i0);
1367             theUnsafe.putShort(o, offset + 2, i1);
1368         }
1369         void putIntParts(Unsafe theUnsafe, Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
1370             theUnsafe.putByte(o, offset + 0, i0);
1371             theUnsafe.putByte(o, offset + 1, i1);
1372             theUnsafe.putByte(o, offset + 2, i2);
1373             theUnsafe.putByte(o, offset + 3, i3);
1374         }
1375         void putShortParts(Unsafe theUnsafe, Object o, long offset, byte i0, byte i1) {
1376             theUnsafe.putByte(o, offset + 0, i0);
1377             theUnsafe.putByte(o, offset + 1, i1);
1378         }
1379         char fromEndian(boolean big, char n) { return big ? Character.reverseBytes(n) : n; }
1380         short fromEndian(boolean big, short n) { return big ? Short.reverseBytes(n) : n; }
1381         int fromEndian(boolean big, int n) { return big ? Integer.reverseBytes(n) : n; }
1382         long fromEndian(boolean big, long n) { return big ? Long.reverseBytes(n) : n; }
1383     }
1384 
1385     private static class NativeBigEndian extends NativeAccess {
1386         long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
1387             return ((toUnsignedLong(i0) << 56)
1388                   | (toUnsignedLong(i1) << 48)
1389                   | (toUnsignedLong(i2) << 40)
1390                   | (toUnsignedLong(i3) << 32)
1391                   | (toUnsignedLong(i4) << 24)
1392                   | (toUnsignedLong(i5) << 16)
1393                   | (toUnsignedLong(i6) << 8)
1394                   | (toUnsignedLong(i7) << 0));
1395         }
1396         long makeLong(short i0, short i1, short i2, short i3) {
1397             return ((toUnsignedLong(i0) << 48)
1398                   | (toUnsignedLong(i1) << 32)
1399                   | (toUnsignedLong(i2) << 16)
1400                   | (toUnsignedLong(i3) << 0));
1401         }
1402         long makeLong(int i0, int i1) {
1403             return (toUnsignedLong(i0) << 32)
1404                  | (toUnsignedLong(i1) << 0);
1405         }
1406         int makeInt(byte i0, byte i1, byte i2, byte i3) {
1407             return ((toUnsignedInt(i0) << 24)
1408                   | (toUnsignedInt(i1) << 16)
1409                   | (toUnsignedInt(i2) << 8)
1410                   | (toUnsignedInt(i3) << 0));
1411         }
1412         int makeInt(short i0, short i1) {
1413             return ((toUnsignedInt(i0) << 16)
1414                   | (toUnsignedInt(i1) << 0));
1415         }
1416         short makeShort(byte i0, byte i1) {
1417             return (short)((toUnsignedInt(i0) << 8)
1418                          | (toUnsignedInt(i1) << 0));
1419         }
1420         void putLongParts(Unsafe theUnsafe, Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
1421             theUnsafe.putByte(o, offset + 0, i7);
1422             theUnsafe.putByte(o, offset + 1, i6);
1423             theUnsafe.putByte(o, offset + 2, i5);
1424             theUnsafe.putByte(o, offset + 3, i4);
1425             theUnsafe.putByte(o, offset + 4, i3);
1426             theUnsafe.putByte(o, offset + 5, i2);
1427             theUnsafe.putByte(o, offset + 6, i1);
1428             theUnsafe.putByte(o, offset + 7, i0);
1429         }
1430         void putLongParts(Unsafe theUnsafe, Object o, long offset, short i0, short i1, short i2, short i3) {
1431             theUnsafe.putShort(o, offset + 0, i3);
1432             theUnsafe.putShort(o, offset + 2, i2);
1433             theUnsafe.putShort(o, offset + 4, i1);
1434             theUnsafe.putShort(o, offset + 6, i0);
1435         }
1436         void putLongParts(Unsafe theUnsafe, Object o, long offset, int i0, int i1) {
1437             theUnsafe.putInt(o, offset + 0, i1);
1438             theUnsafe.putInt(o, offset + 4, i0);
1439         }
1440         void putIntParts(Unsafe theUnsafe, Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
1441             theUnsafe.putByte(o, offset + 0, i3);
1442             theUnsafe.putByte(o, offset + 1, i2);
1443             theUnsafe.putByte(o, offset + 2, i1);
1444             theUnsafe.putByte(o, offset + 3, i0);
1445         }
1446         void putIntParts(Unsafe theUnsafe, Object o, long offset, short i0, short i1) {
1447             theUnsafe.putShort(o, offset + 0, i1);
1448             theUnsafe.putShort(o, offset + 2, i0);
1449         }
1450         void putShortParts(Unsafe theUnsafe, Object o, long offset, byte i0, byte i1) {
1451             theUnsafe.putByte(o, offset + 0, i1);
1452             theUnsafe.putByte(o, offset + 1, i0);
1453         }
1454         char fromEndian(boolean big, char n) { return big ? n : Character.reverseBytes(n); }
1455         short fromEndian(boolean big, short n) { return big ? n : Short.reverseBytes(n); }
1456         int fromEndian(boolean big, int n) { return big ? n : Integer.reverseBytes(n); }
1457         long fromEndian(boolean big, long n) { return big ? n : Long.reverseBytes(n); }
1458     }
1459 }