1 /*
2 * Copyright (c) 2000, 2025, 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
169 * The first two parameters are interpreted exactly as with
170 * {@link #getInt(Object, long)} to refer to a specific
171 * Java variable (field or array element). The given value
172 * is stored into that variable.
173 * <p>
174 * The variable must be of the same type as the method
175 * parameter {@code x}.
176 *
177 * @param o Java heap object in which the variable resides, if any, else
178 * null
179 * @param offset indication of where the variable resides in a Java heap
180 * object, if any, else a memory address locating the variable
181 * statically
182 * @param x the value to store into the indicated Java variable
183 * @throws RuntimeException No defined exceptions are thrown, not even
184 * {@link NullPointerException}
185 */
186 @IntrinsicCandidate
187 public native void putInt(Object o, long offset, int x);
188
189 /**
190 * Fetches a reference value from a given Java variable.
191 * @see #getInt(Object, long)
192 */
193 @IntrinsicCandidate
194 public native Object getReference(Object o, long offset);
195
196 /**
197 * Stores a reference value into a given Java variable.
198 * <p>
199 * Unless the reference {@code x} being stored is either null
200 * or matches the field type, the results are undefined.
201 * If the reference {@code o} is non-null, card marks or
202 * other store barriers for that object (if the VM requires them)
203 * are updated.
204 * @see #putInt(Object, long, int)
205 */
206 @IntrinsicCandidate
207 public native void putReference(Object o, long offset, Object x);
208
209 /** @see #getInt(Object, long) */
210 @IntrinsicCandidate
211 public native boolean getBoolean(Object o, long offset);
212
213 /** @see #putInt(Object, long, int) */
214 @IntrinsicCandidate
215 public native void putBoolean(Object o, long offset, boolean x);
216
217 /** @see #getInt(Object, long) */
218 @IntrinsicCandidate
219 public native byte getByte(Object o, long offset);
220
221 /** @see #putInt(Object, long, int) */
222 @IntrinsicCandidate
223 public native void putByte(Object o, long offset, byte x);
224
225 /** @see #getInt(Object, long) */
226 @IntrinsicCandidate
227 public native short getShort(Object o, long offset);
228
1178 }
1179
1180 /**
1181 * Ensures the given class has been initialized (see JVMS-5.5 for details).
1182 * This is often needed in conjunction with obtaining the static field base
1183 * of a class.
1184 *
1185 * The call returns when either class {@code c} is fully initialized or
1186 * class {@code c} is being initialized and the call is performed from
1187 * the initializing thread. In the latter case a subsequent call to
1188 * {@link #shouldBeInitialized} will return {@code true}.
1189 */
1190 public void ensureClassInitialized(Class<?> c) {
1191 if (c == null) {
1192 throw new NullPointerException();
1193 }
1194
1195 ensureClassInitialized0(c);
1196 }
1197
1198 /**
1199 * Reports the offset of the first element in the storage allocation of a
1200 * given array class. If {@link #arrayIndexScale} returns a non-zero value
1201 * for the same class, you may use that scale factor, together with this
1202 * base offset, to form new offsets to access elements of arrays of the
1203 * given class.
1204 * <p>
1205 * The return value is in the range of a {@code int}. The return type is
1206 * {@code long} to emphasize that long arithmetic should always be used
1207 * for offset calculations to avoid overflows.
1208 *
1209 * @see #getInt(Object, long)
1210 * @see #putInt(Object, long, int)
1211 */
1212 public long arrayBaseOffset(Class<?> arrayClass) {
1213 if (arrayClass == null) {
1214 throw new NullPointerException();
1215 }
1216
1217 return arrayBaseOffset0(arrayClass);
1218 }
1219
1220
1221 /** The value of {@code arrayBaseOffset(boolean[].class)} */
1222 public static final long ARRAY_BOOLEAN_BASE_OFFSET
1223 = theUnsafe.arrayBaseOffset(boolean[].class);
1224
1225 /** The value of {@code arrayBaseOffset(byte[].class)} */
1226 public static final long ARRAY_BYTE_BASE_OFFSET
1227 = theUnsafe.arrayBaseOffset(byte[].class);
1228
1229 /** The value of {@code arrayBaseOffset(short[].class)} */
1230 public static final long ARRAY_SHORT_BASE_OFFSET
1231 = theUnsafe.arrayBaseOffset(short[].class);
1232
1233 /** The value of {@code arrayBaseOffset(char[].class)} */
1234 public static final long ARRAY_CHAR_BASE_OFFSET
1235 = theUnsafe.arrayBaseOffset(char[].class);
1236
1237 /** The value of {@code arrayBaseOffset(int[].class)} */
1238 public static final long ARRAY_INT_BASE_OFFSET
1239 = theUnsafe.arrayBaseOffset(int[].class);
1246 public static final long ARRAY_FLOAT_BASE_OFFSET
1247 = theUnsafe.arrayBaseOffset(float[].class);
1248
1249 /** The value of {@code arrayBaseOffset(double[].class)} */
1250 public static final long ARRAY_DOUBLE_BASE_OFFSET
1251 = theUnsafe.arrayBaseOffset(double[].class);
1252
1253 /** The value of {@code arrayBaseOffset(Object[].class)} */
1254 public static final long ARRAY_OBJECT_BASE_OFFSET
1255 = theUnsafe.arrayBaseOffset(Object[].class);
1256
1257 /**
1258 * Reports the scale factor for addressing elements in the storage
1259 * allocation of a given array class. However, arrays of "narrow" types
1260 * will generally not work properly with accessors like {@link
1261 * #getByte(Object, long)}, so the scale factor for such classes is reported
1262 * as zero.
1263 * <p>
1264 * The computation of the actual memory offset should always use {@code
1265 * long} arithmetic to avoid overflows.
1266 *
1267 * @see #arrayBaseOffset
1268 * @see #getInt(Object, long)
1269 * @see #putInt(Object, long, int)
1270 */
1271 public int arrayIndexScale(Class<?> arrayClass) {
1272 if (arrayClass == null) {
1273 throw new NullPointerException();
1274 }
1275
1276 return arrayIndexScale0(arrayClass);
1277 }
1278
1279
1280 /** The value of {@code arrayIndexScale(boolean[].class)} */
1281 public static final int ARRAY_BOOLEAN_INDEX_SCALE
1282 = theUnsafe.arrayIndexScale(boolean[].class);
1283
1284 /** The value of {@code arrayIndexScale(byte[].class)} */
1285 public static final int ARRAY_BYTE_INDEX_SCALE
1286 = theUnsafe.arrayIndexScale(byte[].class);
1287
1288 /** The value of {@code arrayIndexScale(short[].class)} */
1289 public static final int ARRAY_SHORT_INDEX_SCALE
1290 = theUnsafe.arrayIndexScale(short[].class);
1291
1292 /** The value of {@code arrayIndexScale(char[].class)} */
1293 public static final int ARRAY_CHAR_INDEX_SCALE
1294 = theUnsafe.arrayIndexScale(char[].class);
1295
1296 /** The value of {@code arrayIndexScale(int[].class)} */
1297 public static final int ARRAY_INT_INDEX_SCALE
1298 = theUnsafe.arrayIndexScale(int[].class);
1437 return null;
1438 }
1439
1440 /** Throws the exception without telling the verifier. */
1441 public native void throwException(Throwable ee);
1442
1443 /**
1444 * Atomically updates Java variable to {@code x} if it is currently
1445 * holding {@code expected}.
1446 *
1447 * <p>This operation has memory semantics of a {@code volatile} read
1448 * and write. Corresponds to C11 atomic_compare_exchange_strong.
1449 *
1450 * @return {@code true} if successful
1451 */
1452 @IntrinsicCandidate
1453 public final native boolean compareAndSetReference(Object o, long offset,
1454 Object expected,
1455 Object x);
1456
1457 @IntrinsicCandidate
1458 public final native Object compareAndExchangeReference(Object o, long offset,
1459 Object expected,
1460 Object x);
1461
1462 @IntrinsicCandidate
1463 public final Object compareAndExchangeReferenceAcquire(Object o, long offset,
1464 Object expected,
1465 Object x) {
1466 return compareAndExchangeReference(o, offset, expected, x);
1467 }
1468
1469 @IntrinsicCandidate
1470 public final Object compareAndExchangeReferenceRelease(Object o, long offset,
1471 Object expected,
1472 Object x) {
1473 return compareAndExchangeReference(o, offset, expected, x);
1474 }
1475
1476 @IntrinsicCandidate
1477 public final boolean weakCompareAndSetReferencePlain(Object o, long offset,
1478 Object expected,
1479 Object x) {
1480 return compareAndSetReference(o, offset, expected, x);
1481 }
1482
1483 @IntrinsicCandidate
1484 public final boolean weakCompareAndSetReferenceAcquire(Object o, long offset,
1485 Object expected,
1486 Object x) {
1487 return compareAndSetReference(o, offset, expected, x);
1488 }
1489
1490 @IntrinsicCandidate
1491 public final boolean weakCompareAndSetReferenceRelease(Object o, long offset,
1492 Object expected,
1493 Object x) {
1494 return compareAndSetReference(o, offset, expected, x);
1495 }
1496
1497 @IntrinsicCandidate
1498 public final boolean weakCompareAndSetReference(Object o, long offset,
1499 Object expected,
1500 Object x) {
1501 return compareAndSetReference(o, offset, expected, x);
1502 }
1503
1504 /**
1505 * Atomically updates Java variable to {@code x} if it is currently
1506 * holding {@code expected}.
1507 *
1508 * <p>This operation has memory semantics of a {@code volatile} read
1509 * and write. Corresponds to C11 atomic_compare_exchange_strong.
1510 *
1511 * @return {@code true} if successful
1512 */
1513 @IntrinsicCandidate
1514 public final native boolean compareAndSetInt(Object o, long offset,
1515 int expected,
1516 int x);
1517
1518 @IntrinsicCandidate
1519 public final native int compareAndExchangeInt(Object o, long offset,
1520 int expected,
1521 int x);
1522
1523 @IntrinsicCandidate
2099 public final boolean weakCompareAndSetLongRelease(Object o, long offset,
2100 long expected,
2101 long x) {
2102 return compareAndSetLong(o, offset, expected, x);
2103 }
2104
2105 @IntrinsicCandidate
2106 public final boolean weakCompareAndSetLong(Object o, long offset,
2107 long expected,
2108 long x) {
2109 return compareAndSetLong(o, offset, expected, x);
2110 }
2111
2112 /**
2113 * Fetches a reference value from a given Java variable, with volatile
2114 * load semantics. Otherwise identical to {@link #getReference(Object, long)}
2115 */
2116 @IntrinsicCandidate
2117 public native Object getReferenceVolatile(Object o, long offset);
2118
2119 /**
2120 * Stores a reference value into a given Java variable, with
2121 * volatile store semantics. Otherwise identical to {@link #putReference(Object, long, Object)}
2122 */
2123 @IntrinsicCandidate
2124 public native void putReferenceVolatile(Object o, long offset, Object x);
2125
2126 /** Volatile version of {@link #getInt(Object, long)} */
2127 @IntrinsicCandidate
2128 public native int getIntVolatile(Object o, long offset);
2129
2130 /** Volatile version of {@link #putInt(Object, long, int)} */
2131 @IntrinsicCandidate
2132 public native void putIntVolatile(Object o, long offset, int x);
2133
2134 /** Volatile version of {@link #getBoolean(Object, long)} */
2135 @IntrinsicCandidate
2136 public native boolean getBooleanVolatile(Object o, long offset);
2137
2138 /** Volatile version of {@link #putBoolean(Object, long, boolean)} */
2139 @IntrinsicCandidate
2140 public native void putBooleanVolatile(Object o, long offset, boolean x);
2141
2142 /** Volatile version of {@link #getByte(Object, long)} */
2143 @IntrinsicCandidate
2144 public native byte getByteVolatile(Object o, long offset);
2145
2178 /** Volatile version of {@link #putFloat(Object, long, float)} */
2179 @IntrinsicCandidate
2180 public native void putFloatVolatile(Object o, long offset, float x);
2181
2182 /** Volatile version of {@link #getDouble(Object, long)} */
2183 @IntrinsicCandidate
2184 public native double getDoubleVolatile(Object o, long offset);
2185
2186 /** Volatile version of {@link #putDouble(Object, long, double)} */
2187 @IntrinsicCandidate
2188 public native void putDoubleVolatile(Object o, long offset, double x);
2189
2190
2191
2192 /** Acquire version of {@link #getReferenceVolatile(Object, long)} */
2193 @IntrinsicCandidate
2194 public final Object getReferenceAcquire(Object o, long offset) {
2195 return getReferenceVolatile(o, offset);
2196 }
2197
2198 /** Acquire version of {@link #getBooleanVolatile(Object, long)} */
2199 @IntrinsicCandidate
2200 public final boolean getBooleanAcquire(Object o, long offset) {
2201 return getBooleanVolatile(o, offset);
2202 }
2203
2204 /** Acquire version of {@link #getByteVolatile(Object, long)} */
2205 @IntrinsicCandidate
2206 public final byte getByteAcquire(Object o, long offset) {
2207 return getByteVolatile(o, offset);
2208 }
2209
2210 /** Acquire version of {@link #getShortVolatile(Object, long)} */
2211 @IntrinsicCandidate
2212 public final short getShortAcquire(Object o, long offset) {
2213 return getShortVolatile(o, offset);
2214 }
2215
2216 /** Acquire version of {@link #getCharVolatile(Object, long)} */
2217 @IntrinsicCandidate
2242 public final double getDoubleAcquire(Object o, long offset) {
2243 return getDoubleVolatile(o, offset);
2244 }
2245
2246 /*
2247 * Versions of {@link #putReferenceVolatile(Object, long, Object)}
2248 * that do not guarantee immediate visibility of the store to
2249 * other threads. This method is generally only useful if the
2250 * underlying field is a Java volatile (or if an array cell, one
2251 * that is otherwise only accessed using volatile accesses).
2252 *
2253 * Corresponds to C11 atomic_store_explicit(..., memory_order_release).
2254 */
2255
2256 /** Release version of {@link #putReferenceVolatile(Object, long, Object)} */
2257 @IntrinsicCandidate
2258 public final void putReferenceRelease(Object o, long offset, Object x) {
2259 putReferenceVolatile(o, offset, x);
2260 }
2261
2262 /** Release version of {@link #putBooleanVolatile(Object, long, boolean)} */
2263 @IntrinsicCandidate
2264 public final void putBooleanRelease(Object o, long offset, boolean x) {
2265 putBooleanVolatile(o, offset, x);
2266 }
2267
2268 /** Release version of {@link #putByteVolatile(Object, long, byte)} */
2269 @IntrinsicCandidate
2270 public final void putByteRelease(Object o, long offset, byte x) {
2271 putByteVolatile(o, offset, x);
2272 }
2273
2274 /** Release version of {@link #putShortVolatile(Object, long, short)} */
2275 @IntrinsicCandidate
2276 public final void putShortRelease(Object o, long offset, short x) {
2277 putShortVolatile(o, offset, x);
2278 }
2279
2280 /** Release version of {@link #putCharVolatile(Object, long, char)} */
2281 @IntrinsicCandidate
2298 /** Release version of {@link #putLongVolatile(Object, long, long)} */
2299 @IntrinsicCandidate
2300 public final void putLongRelease(Object o, long offset, long x) {
2301 putLongVolatile(o, offset, x);
2302 }
2303
2304 /** Release version of {@link #putDoubleVolatile(Object, long, double)} */
2305 @IntrinsicCandidate
2306 public final void putDoubleRelease(Object o, long offset, double x) {
2307 putDoubleVolatile(o, offset, x);
2308 }
2309
2310 // ------------------------------ Opaque --------------------------------------
2311
2312 /** Opaque version of {@link #getReferenceVolatile(Object, long)} */
2313 @IntrinsicCandidate
2314 public final Object getReferenceOpaque(Object o, long offset) {
2315 return getReferenceVolatile(o, offset);
2316 }
2317
2318 /** Opaque version of {@link #getBooleanVolatile(Object, long)} */
2319 @IntrinsicCandidate
2320 public final boolean getBooleanOpaque(Object o, long offset) {
2321 return getBooleanVolatile(o, offset);
2322 }
2323
2324 /** Opaque version of {@link #getByteVolatile(Object, long)} */
2325 @IntrinsicCandidate
2326 public final byte getByteOpaque(Object o, long offset) {
2327 return getByteVolatile(o, offset);
2328 }
2329
2330 /** Opaque version of {@link #getShortVolatile(Object, long)} */
2331 @IntrinsicCandidate
2332 public final short getShortOpaque(Object o, long offset) {
2333 return getShortVolatile(o, offset);
2334 }
2335
2336 /** Opaque version of {@link #getCharVolatile(Object, long)} */
2337 @IntrinsicCandidate
2352 }
2353
2354 /** Opaque version of {@link #getLongVolatile(Object, long)} */
2355 @IntrinsicCandidate
2356 public final long getLongOpaque(Object o, long offset) {
2357 return getLongVolatile(o, offset);
2358 }
2359
2360 /** Opaque version of {@link #getDoubleVolatile(Object, long)} */
2361 @IntrinsicCandidate
2362 public final double getDoubleOpaque(Object o, long offset) {
2363 return getDoubleVolatile(o, offset);
2364 }
2365
2366 /** Opaque version of {@link #putReferenceVolatile(Object, long, Object)} */
2367 @IntrinsicCandidate
2368 public final void putReferenceOpaque(Object o, long offset, Object x) {
2369 putReferenceVolatile(o, offset, x);
2370 }
2371
2372 /** Opaque version of {@link #putBooleanVolatile(Object, long, boolean)} */
2373 @IntrinsicCandidate
2374 public final void putBooleanOpaque(Object o, long offset, boolean x) {
2375 putBooleanVolatile(o, offset, x);
2376 }
2377
2378 /** Opaque version of {@link #putByteVolatile(Object, long, byte)} */
2379 @IntrinsicCandidate
2380 public final void putByteOpaque(Object o, long offset, byte x) {
2381 putByteVolatile(o, offset, x);
2382 }
2383
2384 /** Opaque version of {@link #putShortVolatile(Object, long, short)} */
2385 @IntrinsicCandidate
2386 public final void putShortOpaque(Object o, long offset, short x) {
2387 putShortVolatile(o, offset, x);
2388 }
2389
2390 /** Opaque version of {@link #putCharVolatile(Object, long, char)} */
2391 @IntrinsicCandidate
2400 }
2401
2402 /** Opaque version of {@link #putFloatVolatile(Object, long, float)} */
2403 @IntrinsicCandidate
2404 public final void putFloatOpaque(Object o, long offset, float x) {
2405 putFloatVolatile(o, offset, x);
2406 }
2407
2408 /** Opaque version of {@link #putLongVolatile(Object, long, long)} */
2409 @IntrinsicCandidate
2410 public final void putLongOpaque(Object o, long offset, long x) {
2411 putLongVolatile(o, offset, x);
2412 }
2413
2414 /** Opaque version of {@link #putDoubleVolatile(Object, long, double)} */
2415 @IntrinsicCandidate
2416 public final void putDoubleOpaque(Object o, long offset, double x) {
2417 putDoubleVolatile(o, offset, x);
2418 }
2419
2420 /**
2421 * Unblocks the given thread blocked on {@code park}, or, if it is
2422 * not blocked, causes the subsequent call to {@code park} not to
2423 * block. Note: this operation is "unsafe" solely because the
2424 * caller must somehow ensure that the thread has not been
2425 * destroyed. Nothing special is usually required to ensure this
2426 * when called from Java (in which there will ordinarily be a live
2427 * reference to the thread) but this is not nearly-automatically
2428 * so when calling from native code.
2429 *
2430 * @param thread the thread to unpark.
2431 */
2432 @IntrinsicCandidate
2433 public native void unpark(Object thread);
2434
2435 /**
2436 * Blocks current thread, returning when a balancing
2437 * {@code unpark} occurs, or a balancing {@code unpark} has
2438 * already occurred, or the thread is interrupted, or, if not
2439 * absolute and time is not zero, the given time nanoseconds have
2786 /**
2787 * Atomically exchanges the given reference value with the current
2788 * reference value of a field or array element within the given
2789 * object {@code o} at the given {@code offset}.
2790 *
2791 * @param o object/array to update the field/element in
2792 * @param offset field/element offset
2793 * @param newValue new value
2794 * @return the previous value
2795 * @since 1.8
2796 */
2797 @IntrinsicCandidate
2798 public final Object getAndSetReference(Object o, long offset, Object newValue) {
2799 Object v;
2800 do {
2801 v = getReferenceVolatile(o, offset);
2802 } while (!weakCompareAndSetReference(o, offset, v, newValue));
2803 return v;
2804 }
2805
2806 @ForceInline
2807 public final Object getAndSetReferenceRelease(Object o, long offset, Object newValue) {
2808 Object v;
2809 do {
2810 v = getReference(o, offset);
2811 } while (!weakCompareAndSetReferenceRelease(o, offset, v, newValue));
2812 return v;
2813 }
2814
2815 @ForceInline
2816 public final Object getAndSetReferenceAcquire(Object o, long offset, Object newValue) {
2817 Object v;
2818 do {
2819 v = getReferenceAcquire(o, offset);
2820 } while (!weakCompareAndSetReferenceAcquire(o, offset, v, newValue));
2821 return v;
2822 }
2823
2824 @IntrinsicCandidate
2825 public final byte getAndSetByte(Object o, long offset, byte newValue) {
2826 byte v;
2827 do {
2828 v = getByteVolatile(o, offset);
2829 } while (!weakCompareAndSetByte(o, offset, v, newValue));
2830 return v;
2831 }
2832
2833 @ForceInline
2834 public final byte getAndSetByteRelease(Object o, long offset, byte newValue) {
2835 byte v;
2836 do {
2837 v = getByte(o, offset);
2838 } while (!weakCompareAndSetByteRelease(o, offset, v, newValue));
2839 return v;
2840 }
2841
2842 @ForceInline
2843 public final byte getAndSetByteAcquire(Object o, long offset, byte newValue) {
3859 private static short convEndian(boolean big, short n) { return big == BIG_ENDIAN ? n : Short.reverseBytes(n) ; }
3860 private static int convEndian(boolean big, int n) { return big == BIG_ENDIAN ? n : Integer.reverseBytes(n) ; }
3861 private static long convEndian(boolean big, long n) { return big == BIG_ENDIAN ? n : Long.reverseBytes(n) ; }
3862
3863
3864
3865 private native long allocateMemory0(long bytes);
3866 private native long reallocateMemory0(long address, long bytes);
3867 private native void freeMemory0(long address);
3868 @IntrinsicCandidate
3869 private native void setMemory0(Object o, long offset, long bytes, byte value);
3870 @IntrinsicCandidate
3871 private native void copyMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
3872 private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize);
3873 private native long objectFieldOffset0(Field f); // throws IAE
3874 private native long knownObjectFieldOffset0(Class<?> c, String name); // error code: -1 not found, -2 static
3875 private native long staticFieldOffset0(Field f); // throws IAE
3876 private native Object staticFieldBase0(Field f); // throws IAE
3877 private native boolean shouldBeInitialized0(Class<?> c);
3878 private native void ensureClassInitialized0(Class<?> c);
3879 private native int arrayBaseOffset0(Class<?> arrayClass); // public version returns long to promote correct arithmetic
3880 private native int arrayIndexScale0(Class<?> arrayClass);
3881 private native int getLoadAverage0(double[] loadavg, int nelems);
3882
3883
3884 /**
3885 * Invokes the given direct byte buffer's cleaner, if any.
3886 *
3887 * @param directBuffer a direct byte buffer
3888 * @throws NullPointerException if {@code directBuffer} is null
3889 * @throws IllegalArgumentException if {@code directBuffer} is non-direct,
3890 * or is a {@link java.nio.Buffer#slice slice}, or is a
3891 * {@link java.nio.Buffer#duplicate duplicate}
3892 */
3893 public void invokeCleaner(java.nio.ByteBuffer directBuffer) {
3894 if (!directBuffer.isDirect())
3895 throw new IllegalArgumentException("buffer is non-direct");
3896
3897 DirectBuffer db = (DirectBuffer) directBuffer;
3898 if (db.attachment() != null)
3899 throw new IllegalArgumentException("duplicate or slice");
3900
3901 Cleaner cleaner = db.cleaner();
|
1 /*
2 * Copyright (c) 2000, 2026, 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
169 * The first two parameters are interpreted exactly as with
170 * {@link #getInt(Object, long)} to refer to a specific
171 * Java variable (field or array element). The given value
172 * is stored into that variable.
173 * <p>
174 * The variable must be of the same type as the method
175 * parameter {@code x}.
176 *
177 * @param o Java heap object in which the variable resides, if any, else
178 * null
179 * @param offset indication of where the variable resides in a Java heap
180 * object, if any, else a memory address locating the variable
181 * statically
182 * @param x the value to store into the indicated Java variable
183 * @throws RuntimeException No defined exceptions are thrown, not even
184 * {@link NullPointerException}
185 */
186 @IntrinsicCandidate
187 public native void putInt(Object o, long offset, int x);
188
189
190 /**
191 * Returns true if the given field is flattened.
192 */
193 public boolean isFlatField(Field f) {
194 if (f == null) {
195 throw new NullPointerException();
196 }
197 return isFlatField0(f);
198 }
199
200 private native boolean isFlatField0(Object o);
201
202 /* Returns true if the given field has a null marker
203 * <p>
204 * Nullable flat fields are stored in a flattened representation
205 * and have an associated null marker to indicate if the the field value is
206 * null or the one stored with the flat representation
207 */
208
209 public boolean hasNullMarker(Field f) {
210 if (f == null) {
211 throw new NullPointerException();
212 }
213 return hasNullMarker0(f);
214 }
215
216 private native boolean hasNullMarker0(Object o);
217
218 /* Returns the offset of the null marker of the field,
219 * or -1 if the field doesn't have a null marker
220 */
221
222 public int nullMarkerOffset(Field f) {
223 if (f == null) {
224 throw new NullPointerException();
225 }
226 return nullMarkerOffset0(f);
227 }
228
229 private native int nullMarkerOffset0(Object o);
230
231 public static final int NON_FLAT_LAYOUT = 0;
232
233 /* Reports the kind of layout used for an element in the storage
234 * allocation of the given array. Do not expect to perform any logic
235 * or layout control with this value, it is just an opaque token
236 * used for performance reasons.
237 *
238 * A layout of 0 indicates this array is not flat.
239 */
240 public int arrayLayout(Object[] array) {
241 if (array == null) {
242 throw new NullPointerException();
243 }
244 return arrayLayout0(array);
245 }
246
247 @IntrinsicCandidate
248 private native int arrayLayout0(Object[] array);
249
250
251 /* Reports the kind of layout used for a given field in the storage
252 * allocation of its class. Do not expect to perform any logic
253 * or layout control with this value, it is just an opaque token
254 * used for performance reasons.
255 *
256 * A layout of 0 indicates this field is not flat.
257 */
258 public int fieldLayout(Field f) {
259 if (f == null) {
260 throw new NullPointerException();
261 }
262 return fieldLayout0(f);
263 }
264
265 private native int fieldLayout0(Object o);
266
267 public native Object[] newSpecialArray(Class<?> componentType,
268 int length, int layoutKind);
269
270 /**
271 * Fetches a reference value from a given Java variable.
272 * This method can return a reference to either an object or value
273 * or a null reference.
274 *
275 * @see #getInt(Object, long)
276 */
277 @IntrinsicCandidate
278 public native Object getReference(Object o, long offset);
279
280 /**
281 * Stores a reference value into a given Java variable.
282 * This method can store a reference to either an object or value
283 * or a null reference.
284 * <p>
285 * Unless the reference {@code x} being stored is either null
286 * or matches the field type, the results are undefined.
287 * If the reference {@code o} is non-null, card marks or
288 * other store barriers for that object (if the VM requires them)
289 * are updated.
290 * @see #putInt(Object, long, int)
291 */
292 @IntrinsicCandidate
293 public native void putReference(Object o, long offset, Object x);
294
295 /**
296 * Fetches a value of type {@code <V>} from a given Java variable.
297 * More specifically, fetches a field or array element within the given
298 * {@code o} object at the given offset, or (if {@code o} is null)
299 * from the memory address whose numerical value is the given offset.
300 *
301 * @apiNote
302 * The returned object is newly allocated into the heap, because flat
303 * values lack object headers and thus can't be used as objects directly.
304 *
305 * @param o Java heap object in which the variable resides, if any, else
306 * null
307 * @param offset indication of where the variable resides in a Java heap
308 * object, if any, else a memory address locating the variable
309 * statically
310 * @param layoutKind opaque value used by the VM to know the layout
311 * the field or array element. This value must be retrieved with
312 * {@link #fieldLayout} or {@link #arrayLayout}.
313 * @param valueType value type
314 * @param <V> the type of a value
315 * @return the value fetched from the indicated Java variable
316 * @throws RuntimeException No defined exceptions are thrown, not even
317 * {@link NullPointerException}
318 */
319 @IntrinsicCandidate
320 public native <V> V getFlatValue(Object o, long offset, int layoutKind, Class<?> valueType);
321
322 /**
323 * Stores the given value into a given Java variable.
324 *
325 * Unless the reference {@code o} being stored is either null
326 * or matches the field type, the results are undefined.
327 *
328 * @param o Java heap object in which the variable resides, if any, else
329 * null
330 * @param offset indication of where the variable resides in a Java heap
331 * object, if any, else a memory address locating the variable
332 * statically
333 * @param layoutKind opaque value used by the VM to know the layout
334 * the field or array element. This value must be retrieved with
335 * {@link #fieldLayout} or {@link #arrayLayout}.
336 * @param valueType value type
337 * @param v the value to store into the indicated Java variable
338 * @param <V> the type of a value
339 * @throws RuntimeException No defined exceptions are thrown, not even
340 * {@link NullPointerException}
341 */
342 @IntrinsicCandidate
343 public native <V> void putFlatValue(Object o, long offset, int layoutKind, Class<?> valueType, V v);
344
345 /**
346 * Returns the header size of the given value type.
347 *
348 * @param valueType value type
349 * @return the header size of the value type
350 */
351 public native <V> long valueHeaderSize(Class<V> valueType);
352
353 /** @see #getInt(Object, long) */
354 @IntrinsicCandidate
355 public native boolean getBoolean(Object o, long offset);
356
357 /** @see #putInt(Object, long, int) */
358 @IntrinsicCandidate
359 public native void putBoolean(Object o, long offset, boolean x);
360
361 /** @see #getInt(Object, long) */
362 @IntrinsicCandidate
363 public native byte getByte(Object o, long offset);
364
365 /** @see #putInt(Object, long, int) */
366 @IntrinsicCandidate
367 public native void putByte(Object o, long offset, byte x);
368
369 /** @see #getInt(Object, long) */
370 @IntrinsicCandidate
371 public native short getShort(Object o, long offset);
372
1322 }
1323
1324 /**
1325 * Ensures the given class has been initialized (see JVMS-5.5 for details).
1326 * This is often needed in conjunction with obtaining the static field base
1327 * of a class.
1328 *
1329 * The call returns when either class {@code c} is fully initialized or
1330 * class {@code c} is being initialized and the call is performed from
1331 * the initializing thread. In the latter case a subsequent call to
1332 * {@link #shouldBeInitialized} will return {@code true}.
1333 */
1334 public void ensureClassInitialized(Class<?> c) {
1335 if (c == null) {
1336 throw new NullPointerException();
1337 }
1338
1339 ensureClassInitialized0(c);
1340 }
1341
1342 /**
1343 * The reading or writing of strict static fields may require
1344 * special processing. Notify the VM that such an event is about
1345 * to happen. The VM may respond by throwing an exception, in the
1346 * case of a read of an uninitialized field. If the VM allows the
1347 * method to return normally, no further calls are needed, with
1348 * the same arguments.
1349 */
1350 public void notifyStrictStaticAccess(Class<?> c, long staticFieldOffset, boolean writing) {
1351 if (c == null) {
1352 throw new NullPointerException();
1353 }
1354 notifyStrictStaticAccess0(c, staticFieldOffset, writing);
1355 }
1356
1357 /**
1358 * Reports the offset of the first element in the storage allocation of a
1359 * given array class. If {@link #arrayIndexScale} returns a non-zero value
1360 * for the same class, you may use that scale factor, together with this
1361 * base offset, to form new offsets to access elements of arrays of the
1362 * given class.
1363 * <p>
1364 * The return value is in the range of a {@code int}. The return type is
1365 * {@code long} to emphasize that long arithmetic should always be used
1366 * for offset calculations to avoid overflows.
1367 * <p>
1368 * This method doesn't support arrays with an element type that is
1369 * a value class, because this type of array can have multiple layouts.
1370 * For these arrays, {@code arrayInstanceBaseOffset(Object[] array)}
1371 * must be used instead.
1372 *
1373 * @see #getInt(Object, long)
1374 * @see #putInt(Object, long, int)
1375 */
1376 public long arrayBaseOffset(Class<?> arrayClass) {
1377 if (arrayClass == null) {
1378 throw new NullPointerException();
1379 }
1380
1381 return arrayBaseOffset0(arrayClass);
1382 }
1383
1384 public long arrayInstanceBaseOffset(Object[] array) {
1385 if (array == null) {
1386 throw new NullPointerException();
1387 }
1388
1389 return arrayInstanceBaseOffset0(array);
1390 }
1391
1392 /** The value of {@code arrayBaseOffset(boolean[].class)} */
1393 public static final long ARRAY_BOOLEAN_BASE_OFFSET
1394 = theUnsafe.arrayBaseOffset(boolean[].class);
1395
1396 /** The value of {@code arrayBaseOffset(byte[].class)} */
1397 public static final long ARRAY_BYTE_BASE_OFFSET
1398 = theUnsafe.arrayBaseOffset(byte[].class);
1399
1400 /** The value of {@code arrayBaseOffset(short[].class)} */
1401 public static final long ARRAY_SHORT_BASE_OFFSET
1402 = theUnsafe.arrayBaseOffset(short[].class);
1403
1404 /** The value of {@code arrayBaseOffset(char[].class)} */
1405 public static final long ARRAY_CHAR_BASE_OFFSET
1406 = theUnsafe.arrayBaseOffset(char[].class);
1407
1408 /** The value of {@code arrayBaseOffset(int[].class)} */
1409 public static final long ARRAY_INT_BASE_OFFSET
1410 = theUnsafe.arrayBaseOffset(int[].class);
1417 public static final long ARRAY_FLOAT_BASE_OFFSET
1418 = theUnsafe.arrayBaseOffset(float[].class);
1419
1420 /** The value of {@code arrayBaseOffset(double[].class)} */
1421 public static final long ARRAY_DOUBLE_BASE_OFFSET
1422 = theUnsafe.arrayBaseOffset(double[].class);
1423
1424 /** The value of {@code arrayBaseOffset(Object[].class)} */
1425 public static final long ARRAY_OBJECT_BASE_OFFSET
1426 = theUnsafe.arrayBaseOffset(Object[].class);
1427
1428 /**
1429 * Reports the scale factor for addressing elements in the storage
1430 * allocation of a given array class. However, arrays of "narrow" types
1431 * will generally not work properly with accessors like {@link
1432 * #getByte(Object, long)}, so the scale factor for such classes is reported
1433 * as zero.
1434 * <p>
1435 * The computation of the actual memory offset should always use {@code
1436 * long} arithmetic to avoid overflows.
1437 * <p>
1438 * This method doesn't support arrays with an element type that is
1439 * a value class, because this type of array can have multiple layouts.
1440 * For these arrays, {@code arrayInstanceIndexScale(Object[] array)}
1441 * must be used instead.
1442 *
1443 * @see #arrayBaseOffset
1444 * @see #getInt(Object, long)
1445 * @see #putInt(Object, long, int)
1446 */
1447 public int arrayIndexScale(Class<?> arrayClass) {
1448 if (arrayClass == null) {
1449 throw new NullPointerException();
1450 }
1451
1452 return arrayIndexScale0(arrayClass);
1453 }
1454
1455 public int arrayInstanceIndexScale(Object[] array) {
1456 if (array == null) {
1457 throw new NullPointerException();
1458 }
1459
1460 return arrayInstanceIndexScale0(array);
1461 }
1462
1463 public int[] getFieldMap(Class<? extends Object> c) {
1464 if (c == null) {
1465 throw new NullPointerException();
1466 }
1467 return getFieldMap0(c);
1468 }
1469
1470 /**
1471 * Return the size of the object in the heap.
1472 * @param o an object
1473 * @return the objects's size
1474 * @since Valhalla
1475 */
1476 public long getObjectSize(Object o) {
1477 if (o == null)
1478 throw new NullPointerException();
1479 return getObjectSize0(o);
1480 }
1481
1482 /** The value of {@code arrayIndexScale(boolean[].class)} */
1483 public static final int ARRAY_BOOLEAN_INDEX_SCALE
1484 = theUnsafe.arrayIndexScale(boolean[].class);
1485
1486 /** The value of {@code arrayIndexScale(byte[].class)} */
1487 public static final int ARRAY_BYTE_INDEX_SCALE
1488 = theUnsafe.arrayIndexScale(byte[].class);
1489
1490 /** The value of {@code arrayIndexScale(short[].class)} */
1491 public static final int ARRAY_SHORT_INDEX_SCALE
1492 = theUnsafe.arrayIndexScale(short[].class);
1493
1494 /** The value of {@code arrayIndexScale(char[].class)} */
1495 public static final int ARRAY_CHAR_INDEX_SCALE
1496 = theUnsafe.arrayIndexScale(char[].class);
1497
1498 /** The value of {@code arrayIndexScale(int[].class)} */
1499 public static final int ARRAY_INT_INDEX_SCALE
1500 = theUnsafe.arrayIndexScale(int[].class);
1639 return null;
1640 }
1641
1642 /** Throws the exception without telling the verifier. */
1643 public native void throwException(Throwable ee);
1644
1645 /**
1646 * Atomically updates Java variable to {@code x} if it is currently
1647 * holding {@code expected}.
1648 *
1649 * <p>This operation has memory semantics of a {@code volatile} read
1650 * and write. Corresponds to C11 atomic_compare_exchange_strong.
1651 *
1652 * @return {@code true} if successful
1653 */
1654 @IntrinsicCandidate
1655 public final native boolean compareAndSetReference(Object o, long offset,
1656 Object expected,
1657 Object x);
1658
1659 private final boolean isValueObject(Object o) {
1660 return o != null && o.getClass().isValue();
1661 }
1662
1663 /*
1664 * For value type, CAS should do substitutability test as opposed
1665 * to two pointers comparison.
1666 */
1667 @ForceInline
1668 public final <V> boolean compareAndSetReference(Object o, long offset,
1669 Class<?> type,
1670 V expected,
1671 V x) {
1672 if (type.isValue() || isValueObject(expected)) {
1673 while (true) {
1674 Object witness = getReferenceVolatile(o, offset);
1675 if (witness != expected) {
1676 return false;
1677 }
1678 if (compareAndSetReference(o, offset, witness, x)) {
1679 return true;
1680 }
1681 }
1682 } else {
1683 return compareAndSetReference(o, offset, expected, x);
1684 }
1685 }
1686
1687 @ForceInline
1688 public final <V> boolean compareAndSetFlatValue(Object o, long offset,
1689 int layout,
1690 Class<?> valueType,
1691 V expected,
1692 V x) {
1693 Object[] array = newSpecialArray(valueType, 2, layout);
1694 return compareAndSetFlatValueAsBytes(array, o, offset, layout, valueType, expected, x);
1695 }
1696
1697 @IntrinsicCandidate
1698 public final native Object compareAndExchangeReference(Object o, long offset,
1699 Object expected,
1700 Object x);
1701
1702 @ForceInline
1703 public final <V> Object compareAndExchangeReference(Object o, long offset,
1704 Class<?> valueType,
1705 V expected,
1706 V x) {
1707 if (valueType.isValue() || isValueObject(expected)) {
1708 while (true) {
1709 Object witness = getReferenceVolatile(o, offset);
1710 if (witness != expected) {
1711 return witness;
1712 }
1713 if (compareAndSetReference(o, offset, witness, x)) {
1714 return witness;
1715 }
1716 }
1717 } else {
1718 return compareAndExchangeReference(o, offset, expected, x);
1719 }
1720 }
1721
1722 @ForceInline
1723 public final <V> Object compareAndExchangeFlatValue(Object o, long offset,
1724 int layout,
1725 Class<?> valueType,
1726 V expected,
1727 V x) {
1728 Object[] array = newSpecialArray(valueType, 2, layout);
1729 compareAndSetFlatValueAsBytes(array, o, offset, layout, valueType, expected, x);
1730 return array[0];
1731 }
1732
1733 @IntrinsicCandidate
1734 public final Object compareAndExchangeReferenceAcquire(Object o, long offset,
1735 Object expected,
1736 Object x) {
1737 return compareAndExchangeReference(o, offset, expected, x);
1738 }
1739
1740 public final <V> Object compareAndExchangeReferenceAcquire(Object o, long offset,
1741 Class<?> valueType,
1742 V expected,
1743 V x) {
1744 return compareAndExchangeReference(o, offset, valueType, expected, x);
1745 }
1746
1747 @ForceInline
1748 public final <V> Object compareAndExchangeFlatValueAcquire(Object o, long offset,
1749 int layout,
1750 Class<?> valueType,
1751 V expected,
1752 V x) {
1753 return compareAndExchangeFlatValue(o, offset, layout, valueType, expected, x);
1754 }
1755
1756 @IntrinsicCandidate
1757 public final Object compareAndExchangeReferenceRelease(Object o, long offset,
1758 Object expected,
1759 Object x) {
1760 return compareAndExchangeReference(o, offset, expected, x);
1761 }
1762
1763 public final <V> Object compareAndExchangeReferenceRelease(Object o, long offset,
1764 Class<?> valueType,
1765 V expected,
1766 V x) {
1767 return compareAndExchangeReference(o, offset, valueType, expected, x);
1768 }
1769
1770 @ForceInline
1771 public final <V> Object compareAndExchangeFlatValueRelease(Object o, long offset,
1772 int layout,
1773 Class<?> valueType,
1774 V expected,
1775 V x) {
1776 return compareAndExchangeFlatValue(o, offset, layout, valueType, expected, x);
1777 }
1778
1779 @IntrinsicCandidate
1780 public final boolean weakCompareAndSetReferencePlain(Object o, long offset,
1781 Object expected,
1782 Object x) {
1783 return compareAndSetReference(o, offset, expected, x);
1784 }
1785
1786 public final <V> boolean weakCompareAndSetReferencePlain(Object o, long offset,
1787 Class<?> valueType,
1788 V expected,
1789 V x) {
1790 if (valueType.isValue() || isValueObject(expected)) {
1791 return compareAndSetReference(o, offset, valueType, expected, x);
1792 } else {
1793 return weakCompareAndSetReferencePlain(o, offset, expected, x);
1794 }
1795 }
1796
1797 @ForceInline
1798 public final <V> boolean weakCompareAndSetFlatValuePlain(Object o, long offset,
1799 int layout,
1800 Class<?> valueType,
1801 V expected,
1802 V x) {
1803 return compareAndSetFlatValue(o, offset, layout, valueType, expected, x);
1804 }
1805
1806 @IntrinsicCandidate
1807 public final boolean weakCompareAndSetReferenceAcquire(Object o, long offset,
1808 Object expected,
1809 Object x) {
1810 return compareAndSetReference(o, offset, expected, x);
1811 }
1812
1813 public final <V> boolean weakCompareAndSetReferenceAcquire(Object o, long offset,
1814 Class<?> valueType,
1815 V expected,
1816 V x) {
1817 if (valueType.isValue() || isValueObject(expected)) {
1818 return compareAndSetReference(o, offset, valueType, expected, x);
1819 } else {
1820 return weakCompareAndSetReferencePlain(o, offset, expected, x);
1821 }
1822 }
1823
1824 @ForceInline
1825 public final <V> boolean weakCompareAndSetFlatValueAcquire(Object o, long offset,
1826 int layout,
1827 Class<?> valueType,
1828 V expected,
1829 V x) {
1830 return compareAndSetFlatValue(o, offset, layout, valueType, expected, x);
1831 }
1832
1833 @IntrinsicCandidate
1834 public final boolean weakCompareAndSetReferenceRelease(Object o, long offset,
1835 Object expected,
1836 Object x) {
1837 return compareAndSetReference(o, offset, expected, x);
1838 }
1839
1840 public final <V> boolean weakCompareAndSetReferenceRelease(Object o, long offset,
1841 Class<?> valueType,
1842 V expected,
1843 V x) {
1844 if (valueType.isValue() || isValueObject(expected)) {
1845 return compareAndSetReference(o, offset, valueType, expected, x);
1846 } else {
1847 return weakCompareAndSetReferencePlain(o, offset, expected, x);
1848 }
1849 }
1850
1851 @ForceInline
1852 public final <V> boolean weakCompareAndSetFlatValueRelease(Object o, long offset,
1853 int layout,
1854 Class<?> valueType,
1855 V expected,
1856 V x) {
1857 return compareAndSetFlatValue(o, offset, layout, valueType, expected, x);
1858 }
1859
1860 @IntrinsicCandidate
1861 public final boolean weakCompareAndSetReference(Object o, long offset,
1862 Object expected,
1863 Object x) {
1864 return compareAndSetReference(o, offset, expected, x);
1865 }
1866
1867 public final <V> boolean weakCompareAndSetReference(Object o, long offset,
1868 Class<?> valueType,
1869 V expected,
1870 V x) {
1871 if (valueType.isValue() || isValueObject(expected)) {
1872 return compareAndSetReference(o, offset, valueType, expected, x);
1873 } else {
1874 return weakCompareAndSetReferencePlain(o, offset, expected, x);
1875 }
1876 }
1877
1878 @ForceInline
1879 public final <V> boolean weakCompareAndSetFlatValue(Object o, long offset,
1880 int layout,
1881 Class<?> valueType,
1882 V expected,
1883 V x) {
1884 return compareAndSetFlatValue(o, offset, layout, valueType, expected, x);
1885 }
1886
1887 /**
1888 * Atomically updates Java variable to {@code x} if it is currently
1889 * holding {@code expected}.
1890 *
1891 * <p>This operation has memory semantics of a {@code volatile} read
1892 * and write. Corresponds to C11 atomic_compare_exchange_strong.
1893 *
1894 * @return {@code true} if successful
1895 */
1896 @IntrinsicCandidate
1897 public final native boolean compareAndSetInt(Object o, long offset,
1898 int expected,
1899 int x);
1900
1901 @IntrinsicCandidate
1902 public final native int compareAndExchangeInt(Object o, long offset,
1903 int expected,
1904 int x);
1905
1906 @IntrinsicCandidate
2482 public final boolean weakCompareAndSetLongRelease(Object o, long offset,
2483 long expected,
2484 long x) {
2485 return compareAndSetLong(o, offset, expected, x);
2486 }
2487
2488 @IntrinsicCandidate
2489 public final boolean weakCompareAndSetLong(Object o, long offset,
2490 long expected,
2491 long x) {
2492 return compareAndSetLong(o, offset, expected, x);
2493 }
2494
2495 /**
2496 * Fetches a reference value from a given Java variable, with volatile
2497 * load semantics. Otherwise identical to {@link #getReference(Object, long)}
2498 */
2499 @IntrinsicCandidate
2500 public native Object getReferenceVolatile(Object o, long offset);
2501
2502 @ForceInline
2503 public final <V> Object getFlatValueVolatile(Object o, long offset, int layout, Class<?> valueType) {
2504 // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
2505 Object res = getFlatValue(o, offset, layout, valueType);
2506 fullFence();
2507 return res;
2508 }
2509
2510 /**
2511 * Stores a reference value into a given Java variable, with
2512 * volatile store semantics. Otherwise identical to {@link #putReference(Object, long, Object)}
2513 */
2514 @IntrinsicCandidate
2515 public native void putReferenceVolatile(Object o, long offset, Object x);
2516
2517 @ForceInline
2518 public final <V> void putFlatValueVolatile(Object o, long offset, int layout, Class<?> valueType, V x) {
2519 // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
2520 putFlatValueRelease(o, offset, layout, valueType, x);
2521 fullFence();
2522 }
2523
2524 /** Volatile version of {@link #getInt(Object, long)} */
2525 @IntrinsicCandidate
2526 public native int getIntVolatile(Object o, long offset);
2527
2528 /** Volatile version of {@link #putInt(Object, long, int)} */
2529 @IntrinsicCandidate
2530 public native void putIntVolatile(Object o, long offset, int x);
2531
2532 /** Volatile version of {@link #getBoolean(Object, long)} */
2533 @IntrinsicCandidate
2534 public native boolean getBooleanVolatile(Object o, long offset);
2535
2536 /** Volatile version of {@link #putBoolean(Object, long, boolean)} */
2537 @IntrinsicCandidate
2538 public native void putBooleanVolatile(Object o, long offset, boolean x);
2539
2540 /** Volatile version of {@link #getByte(Object, long)} */
2541 @IntrinsicCandidate
2542 public native byte getByteVolatile(Object o, long offset);
2543
2576 /** Volatile version of {@link #putFloat(Object, long, float)} */
2577 @IntrinsicCandidate
2578 public native void putFloatVolatile(Object o, long offset, float x);
2579
2580 /** Volatile version of {@link #getDouble(Object, long)} */
2581 @IntrinsicCandidate
2582 public native double getDoubleVolatile(Object o, long offset);
2583
2584 /** Volatile version of {@link #putDouble(Object, long, double)} */
2585 @IntrinsicCandidate
2586 public native void putDoubleVolatile(Object o, long offset, double x);
2587
2588
2589
2590 /** Acquire version of {@link #getReferenceVolatile(Object, long)} */
2591 @IntrinsicCandidate
2592 public final Object getReferenceAcquire(Object o, long offset) {
2593 return getReferenceVolatile(o, offset);
2594 }
2595
2596 @ForceInline
2597 public final <V> Object getFlatValueAcquire(Object o, long offset, int layout, Class<?> valueType) {
2598 // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
2599 Object res = getFlatValue(o, offset, layout, valueType);
2600 loadFence();
2601 return res;
2602 }
2603
2604 /** Acquire version of {@link #getBooleanVolatile(Object, long)} */
2605 @IntrinsicCandidate
2606 public final boolean getBooleanAcquire(Object o, long offset) {
2607 return getBooleanVolatile(o, offset);
2608 }
2609
2610 /** Acquire version of {@link #getByteVolatile(Object, long)} */
2611 @IntrinsicCandidate
2612 public final byte getByteAcquire(Object o, long offset) {
2613 return getByteVolatile(o, offset);
2614 }
2615
2616 /** Acquire version of {@link #getShortVolatile(Object, long)} */
2617 @IntrinsicCandidate
2618 public final short getShortAcquire(Object o, long offset) {
2619 return getShortVolatile(o, offset);
2620 }
2621
2622 /** Acquire version of {@link #getCharVolatile(Object, long)} */
2623 @IntrinsicCandidate
2648 public final double getDoubleAcquire(Object o, long offset) {
2649 return getDoubleVolatile(o, offset);
2650 }
2651
2652 /*
2653 * Versions of {@link #putReferenceVolatile(Object, long, Object)}
2654 * that do not guarantee immediate visibility of the store to
2655 * other threads. This method is generally only useful if the
2656 * underlying field is a Java volatile (or if an array cell, one
2657 * that is otherwise only accessed using volatile accesses).
2658 *
2659 * Corresponds to C11 atomic_store_explicit(..., memory_order_release).
2660 */
2661
2662 /** Release version of {@link #putReferenceVolatile(Object, long, Object)} */
2663 @IntrinsicCandidate
2664 public final void putReferenceRelease(Object o, long offset, Object x) {
2665 putReferenceVolatile(o, offset, x);
2666 }
2667
2668 @ForceInline
2669 public final <V> void putFlatValueRelease(Object o, long offset, int layout, Class<?> valueType, V x) {
2670 // we translate using fences (see: https://gee.cs.oswego.edu/dl/html/j9mm.html)
2671 storeFence();
2672 putFlatValue(o, offset, layout, valueType, x);
2673 }
2674
2675 /** Release version of {@link #putBooleanVolatile(Object, long, boolean)} */
2676 @IntrinsicCandidate
2677 public final void putBooleanRelease(Object o, long offset, boolean x) {
2678 putBooleanVolatile(o, offset, x);
2679 }
2680
2681 /** Release version of {@link #putByteVolatile(Object, long, byte)} */
2682 @IntrinsicCandidate
2683 public final void putByteRelease(Object o, long offset, byte x) {
2684 putByteVolatile(o, offset, x);
2685 }
2686
2687 /** Release version of {@link #putShortVolatile(Object, long, short)} */
2688 @IntrinsicCandidate
2689 public final void putShortRelease(Object o, long offset, short x) {
2690 putShortVolatile(o, offset, x);
2691 }
2692
2693 /** Release version of {@link #putCharVolatile(Object, long, char)} */
2694 @IntrinsicCandidate
2711 /** Release version of {@link #putLongVolatile(Object, long, long)} */
2712 @IntrinsicCandidate
2713 public final void putLongRelease(Object o, long offset, long x) {
2714 putLongVolatile(o, offset, x);
2715 }
2716
2717 /** Release version of {@link #putDoubleVolatile(Object, long, double)} */
2718 @IntrinsicCandidate
2719 public final void putDoubleRelease(Object o, long offset, double x) {
2720 putDoubleVolatile(o, offset, x);
2721 }
2722
2723 // ------------------------------ Opaque --------------------------------------
2724
2725 /** Opaque version of {@link #getReferenceVolatile(Object, long)} */
2726 @IntrinsicCandidate
2727 public final Object getReferenceOpaque(Object o, long offset) {
2728 return getReferenceVolatile(o, offset);
2729 }
2730
2731 @ForceInline
2732 public final <V> Object getFlatValueOpaque(Object o, long offset, int layout, Class<?> valueType) {
2733 // this is stronger than opaque semantics
2734 return getFlatValueAcquire(o, offset, layout, valueType);
2735 }
2736
2737 /** Opaque version of {@link #getBooleanVolatile(Object, long)} */
2738 @IntrinsicCandidate
2739 public final boolean getBooleanOpaque(Object o, long offset) {
2740 return getBooleanVolatile(o, offset);
2741 }
2742
2743 /** Opaque version of {@link #getByteVolatile(Object, long)} */
2744 @IntrinsicCandidate
2745 public final byte getByteOpaque(Object o, long offset) {
2746 return getByteVolatile(o, offset);
2747 }
2748
2749 /** Opaque version of {@link #getShortVolatile(Object, long)} */
2750 @IntrinsicCandidate
2751 public final short getShortOpaque(Object o, long offset) {
2752 return getShortVolatile(o, offset);
2753 }
2754
2755 /** Opaque version of {@link #getCharVolatile(Object, long)} */
2756 @IntrinsicCandidate
2771 }
2772
2773 /** Opaque version of {@link #getLongVolatile(Object, long)} */
2774 @IntrinsicCandidate
2775 public final long getLongOpaque(Object o, long offset) {
2776 return getLongVolatile(o, offset);
2777 }
2778
2779 /** Opaque version of {@link #getDoubleVolatile(Object, long)} */
2780 @IntrinsicCandidate
2781 public final double getDoubleOpaque(Object o, long offset) {
2782 return getDoubleVolatile(o, offset);
2783 }
2784
2785 /** Opaque version of {@link #putReferenceVolatile(Object, long, Object)} */
2786 @IntrinsicCandidate
2787 public final void putReferenceOpaque(Object o, long offset, Object x) {
2788 putReferenceVolatile(o, offset, x);
2789 }
2790
2791 @ForceInline
2792 public final <V> void putFlatValueOpaque(Object o, long offset, int layout, Class<?> valueType, V x) {
2793 // this is stronger than opaque semantics
2794 putFlatValueRelease(o, offset, layout, valueType, x);
2795 }
2796
2797 /** Opaque version of {@link #putBooleanVolatile(Object, long, boolean)} */
2798 @IntrinsicCandidate
2799 public final void putBooleanOpaque(Object o, long offset, boolean x) {
2800 putBooleanVolatile(o, offset, x);
2801 }
2802
2803 /** Opaque version of {@link #putByteVolatile(Object, long, byte)} */
2804 @IntrinsicCandidate
2805 public final void putByteOpaque(Object o, long offset, byte x) {
2806 putByteVolatile(o, offset, x);
2807 }
2808
2809 /** Opaque version of {@link #putShortVolatile(Object, long, short)} */
2810 @IntrinsicCandidate
2811 public final void putShortOpaque(Object o, long offset, short x) {
2812 putShortVolatile(o, offset, x);
2813 }
2814
2815 /** Opaque version of {@link #putCharVolatile(Object, long, char)} */
2816 @IntrinsicCandidate
2825 }
2826
2827 /** Opaque version of {@link #putFloatVolatile(Object, long, float)} */
2828 @IntrinsicCandidate
2829 public final void putFloatOpaque(Object o, long offset, float x) {
2830 putFloatVolatile(o, offset, x);
2831 }
2832
2833 /** Opaque version of {@link #putLongVolatile(Object, long, long)} */
2834 @IntrinsicCandidate
2835 public final void putLongOpaque(Object o, long offset, long x) {
2836 putLongVolatile(o, offset, x);
2837 }
2838
2839 /** Opaque version of {@link #putDoubleVolatile(Object, long, double)} */
2840 @IntrinsicCandidate
2841 public final void putDoubleOpaque(Object o, long offset, double x) {
2842 putDoubleVolatile(o, offset, x);
2843 }
2844
2845 @ForceInline
2846 private boolean compareAndSetFlatValueAsBytes(Object[] array, Object o, long offset, int layout, Class<?> valueType, Object expected, Object x) {
2847 // We can convert between a value object and a binary value (of suitable size) using array elements.
2848 // This only works if the payload contains no oops (see VarHandles::isAtomicFlat).
2849 // Thus, we can implement the CAS with a plain numeric CAS.
2850
2851 // array[0]: witness (put as binary, get as object), at base
2852 // array[1]: x (put as object, get as binary), at base + scale
2853 // When witness == expected, the witness binary may be different from the expected binary.
2854 // This happens when compiler does not zero unused positions in the witness.
2855 // So we must obtain the witness binary and use it as expected binary for the numeric CAS.
2856 long base = arrayInstanceBaseOffset(array);
2857 int scale = arrayInstanceIndexScale(array);
2858 putFlatValue(array, base + scale, layout, valueType, x); // put x as object
2859 switch (scale) {
2860 case 1: {
2861 do {
2862 byte witnessByte = getByteVolatile(o, offset);
2863 putByte(array, base, witnessByte); // put witness as binary
2864 Object witness = getFlatValue(array, base, layout, valueType); // get witness as object
2865 if (witness != expected) {
2866 return false;
2867 }
2868 byte xByte = getByte(array, base + scale); // get x as binary
2869 if (compareAndSetByte(o, offset, witnessByte, xByte)) {
2870 return true;
2871 }
2872 } while (true);
2873 }
2874 case 2: {
2875 do {
2876 short witnessShort = getShortVolatile(o, offset);
2877 putShort(array, base, witnessShort); // put witness as binary
2878 Object witness = getFlatValue(array, base, layout, valueType); // get witness as object
2879 if (witness != expected) {
2880 return false;
2881 }
2882 short xShort = getShort(array, base + scale); // get x as binary
2883 if (compareAndSetShort(o, offset, witnessShort, xShort)) {
2884 return true;
2885 }
2886 } while (true);
2887 }
2888 case 4: {
2889 do {
2890 int witnessInt = getIntVolatile(o, offset);
2891 putInt(array, base, witnessInt); // put witness as binary
2892 Object witness = getFlatValue(array, base, layout, valueType); // get witness as object
2893 if (witness != expected) {
2894 return false;
2895 }
2896 int xInt = getInt(array, base + scale); // get x as binary
2897 if (compareAndSetInt(o, offset, witnessInt, xInt)) {
2898 return true;
2899 }
2900 } while (true);
2901 }
2902 case 8: {
2903 do {
2904 long witnessLong = getLongVolatile(o, offset);
2905 putLong(array, base, witnessLong); // put witness as binary
2906 Object witness = getFlatValue(array, base, layout, valueType);
2907 if (witness != expected) {
2908 return false;
2909 }
2910 long xLong = getLong(array, base + scale); // get x as binary
2911 if (compareAndSetLong(o, offset, witnessLong, xLong)) {
2912 return true;
2913 }
2914 } while (true);
2915 }
2916 default: {
2917 throw new UnsupportedOperationException();
2918 }
2919 }
2920 }
2921
2922 /**
2923 * Unblocks the given thread blocked on {@code park}, or, if it is
2924 * not blocked, causes the subsequent call to {@code park} not to
2925 * block. Note: this operation is "unsafe" solely because the
2926 * caller must somehow ensure that the thread has not been
2927 * destroyed. Nothing special is usually required to ensure this
2928 * when called from Java (in which there will ordinarily be a live
2929 * reference to the thread) but this is not nearly-automatically
2930 * so when calling from native code.
2931 *
2932 * @param thread the thread to unpark.
2933 */
2934 @IntrinsicCandidate
2935 public native void unpark(Object thread);
2936
2937 /**
2938 * Blocks current thread, returning when a balancing
2939 * {@code unpark} occurs, or a balancing {@code unpark} has
2940 * already occurred, or the thread is interrupted, or, if not
2941 * absolute and time is not zero, the given time nanoseconds have
3288 /**
3289 * Atomically exchanges the given reference value with the current
3290 * reference value of a field or array element within the given
3291 * object {@code o} at the given {@code offset}.
3292 *
3293 * @param o object/array to update the field/element in
3294 * @param offset field/element offset
3295 * @param newValue new value
3296 * @return the previous value
3297 * @since 1.8
3298 */
3299 @IntrinsicCandidate
3300 public final Object getAndSetReference(Object o, long offset, Object newValue) {
3301 Object v;
3302 do {
3303 v = getReferenceVolatile(o, offset);
3304 } while (!weakCompareAndSetReference(o, offset, v, newValue));
3305 return v;
3306 }
3307
3308 @ForceInline
3309 public final Object getAndSetReference(Object o, long offset, Class<?> valueType, Object newValue) {
3310 Object v;
3311 do {
3312 v = getReferenceVolatile(o, offset);
3313 } while (!compareAndSetReference(o, offset, valueType, v, newValue));
3314 return v;
3315 }
3316
3317 @ForceInline
3318 public Object getAndSetFlatValue(Object o, long offset, int layoutKind, Class<?> valueType, Object newValue) {
3319 Object v;
3320 do {
3321 v = getFlatValueVolatile(o, offset, layoutKind, valueType);
3322 } while (!compareAndSetFlatValue(o, offset, layoutKind, valueType, v, newValue));
3323 return v;
3324 }
3325
3326 @ForceInline
3327 public final Object getAndSetReferenceRelease(Object o, long offset, Object newValue) {
3328 Object v;
3329 do {
3330 v = getReference(o, offset);
3331 } while (!weakCompareAndSetReferenceRelease(o, offset, v, newValue));
3332 return v;
3333 }
3334
3335 @ForceInline
3336 public final Object getAndSetReferenceRelease(Object o, long offset, Class<?> valueType, Object newValue) {
3337 return getAndSetReference(o, offset, valueType, newValue);
3338 }
3339
3340 @ForceInline
3341 public Object getAndSetFlatValueRelease(Object o, long offset, int layoutKind, Class<?> valueType, Object x) {
3342 return getAndSetFlatValue(o, offset, layoutKind, valueType, x);
3343 }
3344
3345 @ForceInline
3346 public final Object getAndSetReferenceAcquire(Object o, long offset, Object newValue) {
3347 Object v;
3348 do {
3349 v = getReferenceAcquire(o, offset);
3350 } while (!weakCompareAndSetReferenceAcquire(o, offset, v, newValue));
3351 return v;
3352 }
3353
3354 @ForceInline
3355 public final Object getAndSetReferenceAcquire(Object o, long offset, Class<?> valueType, Object newValue) {
3356 return getAndSetReference(o, offset, valueType, newValue);
3357 }
3358
3359 @ForceInline
3360 public Object getAndSetFlatValueAcquire(Object o, long offset, int layoutKind, Class<?> valueType, Object x) {
3361 return getAndSetFlatValue(o, offset, layoutKind, valueType, x);
3362 }
3363
3364 @IntrinsicCandidate
3365 public final byte getAndSetByte(Object o, long offset, byte newValue) {
3366 byte v;
3367 do {
3368 v = getByteVolatile(o, offset);
3369 } while (!weakCompareAndSetByte(o, offset, v, newValue));
3370 return v;
3371 }
3372
3373 @ForceInline
3374 public final byte getAndSetByteRelease(Object o, long offset, byte newValue) {
3375 byte v;
3376 do {
3377 v = getByte(o, offset);
3378 } while (!weakCompareAndSetByteRelease(o, offset, v, newValue));
3379 return v;
3380 }
3381
3382 @ForceInline
3383 public final byte getAndSetByteAcquire(Object o, long offset, byte newValue) {
4399 private static short convEndian(boolean big, short n) { return big == BIG_ENDIAN ? n : Short.reverseBytes(n) ; }
4400 private static int convEndian(boolean big, int n) { return big == BIG_ENDIAN ? n : Integer.reverseBytes(n) ; }
4401 private static long convEndian(boolean big, long n) { return big == BIG_ENDIAN ? n : Long.reverseBytes(n) ; }
4402
4403
4404
4405 private native long allocateMemory0(long bytes);
4406 private native long reallocateMemory0(long address, long bytes);
4407 private native void freeMemory0(long address);
4408 @IntrinsicCandidate
4409 private native void setMemory0(Object o, long offset, long bytes, byte value);
4410 @IntrinsicCandidate
4411 private native void copyMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
4412 private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize);
4413 private native long objectFieldOffset0(Field f); // throws IAE
4414 private native long knownObjectFieldOffset0(Class<?> c, String name); // error code: -1 not found, -2 static
4415 private native long staticFieldOffset0(Field f); // throws IAE
4416 private native Object staticFieldBase0(Field f); // throws IAE
4417 private native boolean shouldBeInitialized0(Class<?> c);
4418 private native void ensureClassInitialized0(Class<?> c);
4419 private native void notifyStrictStaticAccess0(Class<?> c, long staticFieldOffset, boolean writing);
4420 private native int arrayBaseOffset0(Class<?> arrayClass); // public version returns long to promote correct arithmetic
4421 @IntrinsicCandidate
4422 private native int arrayInstanceBaseOffset0(Object[] array);
4423 private native int arrayIndexScale0(Class<?> arrayClass);
4424 @IntrinsicCandidate
4425 private native int arrayInstanceIndexScale0(Object[] array);
4426 private native long getObjectSize0(Object o);
4427 private native int getLoadAverage0(double[] loadavg, int nelems);
4428 @IntrinsicCandidate
4429 private native int[] getFieldMap0(Class <?> c);
4430
4431
4432 /**
4433 * Invokes the given direct byte buffer's cleaner, if any.
4434 *
4435 * @param directBuffer a direct byte buffer
4436 * @throws NullPointerException if {@code directBuffer} is null
4437 * @throws IllegalArgumentException if {@code directBuffer} is non-direct,
4438 * or is a {@link java.nio.Buffer#slice slice}, or is a
4439 * {@link java.nio.Buffer#duplicate duplicate}
4440 */
4441 public void invokeCleaner(java.nio.ByteBuffer directBuffer) {
4442 if (!directBuffer.isDirect())
4443 throw new IllegalArgumentException("buffer is non-direct");
4444
4445 DirectBuffer db = (DirectBuffer) directBuffer;
4446 if (db.attachment() != null)
4447 throw new IllegalArgumentException("duplicate or slice");
4448
4449 Cleaner cleaner = db.cleaner();
|