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 } |