< prev index next >

src/java.base/share/classes/jdk/internal/misc/Unsafe.java

Print this page




1401     public final boolean weakCompareAndSwapIntAcquire(Object o, long offset,
1402                                                              int expected,
1403                                                              int x) {
1404         return compareAndSwapInt(o, offset, expected, x);
1405     }
1406 
1407     @HotSpotIntrinsicCandidate
1408     public final boolean weakCompareAndSwapIntRelease(Object o, long offset,
1409                                                              int expected,
1410                                                              int x) {
1411         return compareAndSwapInt(o, offset, expected, x);
1412     }
1413 
1414     @HotSpotIntrinsicCandidate
1415     public final boolean weakCompareAndSwapIntVolatile(Object o, long offset,
1416                                                              int expected,
1417                                                              int x) {
1418         return compareAndSwapInt(o, offset, expected, x);
1419     }
1420 























































































































































































































































































1421     /**
1422      * Atomically updates Java variable to {@code x} if it is currently
1423      * holding {@code expected}.
1424      *
1425      * <p>This operation has memory semantics of a {@code volatile} read
1426      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
1427      *
1428      * @return {@code true} if successful
1429      */
1430     @HotSpotIntrinsicCandidate
1431     public final native boolean compareAndSwapLong(Object o, long offset,
1432                                                    long expected,
1433                                                    long x);
1434 
1435     @HotSpotIntrinsicCandidate
1436     public final native long compareAndExchangeLongVolatile(Object o, long offset,
1437                                                             long expected,
1438                                                             long x);
1439 
1440     @HotSpotIntrinsicCandidate


1841 
1842     // The following contain CAS-based Java implementations used on
1843     // platforms not supporting native instructions
1844 
1845     /**
1846      * Atomically adds the given value to the current value of a field
1847      * or array element within the given object {@code o}
1848      * at the given {@code offset}.
1849      *
1850      * @param o object/array to update the field/element in
1851      * @param offset field/element offset
1852      * @param delta the value to add
1853      * @return the previous value
1854      * @since 1.8
1855      */
1856     @HotSpotIntrinsicCandidate
1857     public final int getAndAddInt(Object o, long offset, int delta) {
1858         int v;
1859         do {
1860             v = getIntVolatile(o, offset);
1861         } while (!compareAndSwapInt(o, offset, v, v + delta));
1862         return v;
1863     }
1864 
1865     /**
1866      * Atomically adds the given value to the current value of a field
1867      * or array element within the given object {@code o}
1868      * at the given {@code offset}.
1869      *
1870      * @param o object/array to update the field/element in
1871      * @param offset field/element offset
1872      * @param delta the value to add
1873      * @return the previous value
1874      * @since 1.8
1875      */
1876     @HotSpotIntrinsicCandidate
1877     public final long getAndAddLong(Object o, long offset, long delta) {
1878         long v;
1879         do {
1880             v = getLongVolatile(o, offset);
1881         } while (!compareAndSwapLong(o, offset, v, v + delta));
1882         return v;
1883     }
1884 






















1885     /**
1886      * Atomically exchanges the given value with the current value of
1887      * a field or array element within the given object {@code o}
1888      * at the given {@code offset}.
1889      *
1890      * @param o object/array to update the field/element in
1891      * @param offset field/element offset
1892      * @param newValue new value
1893      * @return the previous value
1894      * @since 1.8
1895      */
1896     @HotSpotIntrinsicCandidate
1897     public final int getAndSetInt(Object o, long offset, int newValue) {
1898         int v;
1899         do {
1900             v = getIntVolatile(o, offset);
1901         } while (!compareAndSwapInt(o, offset, v, newValue));
1902         return v;
1903     }
1904 
1905     /**
1906      * Atomically exchanges the given value with the current value of
1907      * a field or array element within the given object {@code o}
1908      * at the given {@code offset}.
1909      *
1910      * @param o object/array to update the field/element in
1911      * @param offset field/element offset
1912      * @param newValue new value
1913      * @return the previous value
1914      * @since 1.8
1915      */
1916     @HotSpotIntrinsicCandidate
1917     public final long getAndSetLong(Object o, long offset, long newValue) {
1918         long v;
1919         do {
1920             v = getLongVolatile(o, offset);
1921         } while (!compareAndSwapLong(o, offset, v, newValue));
1922         return v;
1923     }
1924 
1925     /**
1926      * Atomically exchanges the given reference value with the current
1927      * reference value of a field or array element within the given
1928      * object {@code o} at the given {@code offset}.
1929      *
1930      * @param o object/array to update the field/element in
1931      * @param offset field/element offset
1932      * @param newValue new value
1933      * @return the previous value
1934      * @since 1.8
1935      */
1936     @HotSpotIntrinsicCandidate
1937     public final Object getAndSetObject(Object o, long offset, Object newValue) {
1938         Object v;
1939         do {
1940             v = getObjectVolatile(o, offset);
1941         } while (!compareAndSwapObject(o, offset, v, newValue));






















1942         return v;
1943     }
1944 



1945 
1946     /**
1947      * Ensures that loads before the fence will not be reordered with loads and
1948      * stores after the fence; a "LoadLoad plus LoadStore barrier".
1949      *
1950      * Corresponds to C11 atomic_thread_fence(memory_order_acquire)
1951      * (an "acquire fence").
1952      *
1953      * A pure LoadLoad fence is not provided, since the addition of LoadStore
1954      * is almost always desired, and most current hardware instructions that
1955      * provide a LoadLoad barrier also provide a LoadStore barrier for free.
1956      * @since 1.8
1957      */
1958     @HotSpotIntrinsicCandidate
1959     public native void loadFence();
1960 
1961     /**
1962      * Ensures that loads and stores before the fence will not be reordered with
1963      * stores after the fence; a "StoreStore plus LoadStore barrier".
1964      *




1401     public final boolean weakCompareAndSwapIntAcquire(Object o, long offset,
1402                                                              int expected,
1403                                                              int x) {
1404         return compareAndSwapInt(o, offset, expected, x);
1405     }
1406 
1407     @HotSpotIntrinsicCandidate
1408     public final boolean weakCompareAndSwapIntRelease(Object o, long offset,
1409                                                              int expected,
1410                                                              int x) {
1411         return compareAndSwapInt(o, offset, expected, x);
1412     }
1413 
1414     @HotSpotIntrinsicCandidate
1415     public final boolean weakCompareAndSwapIntVolatile(Object o, long offset,
1416                                                              int expected,
1417                                                              int x) {
1418         return compareAndSwapInt(o, offset, expected, x);
1419     }
1420 
1421     @HotSpotIntrinsicCandidate
1422     public final byte compareAndExchangeByteVolatile(Object o, long offset,
1423                                                      byte expected,
1424                                                      byte x) {
1425         long wordOffset = offset & ~3;
1426         int shift = (int) (offset & 3) << 3;
1427         if (BE) {
1428             shift = 24 - shift;
1429         }
1430         int mask           = 0xFF << shift;
1431         int maskedExpected = (expected & 0xFF) << shift;
1432         int maskedX        = (x & 0xFF) << shift;
1433         int fullWord;
1434         do {
1435             fullWord = getIntVolatile(o, wordOffset);
1436             if ((fullWord & mask) != maskedExpected)
1437                 return (byte) ((fullWord & mask) >> shift);
1438         } while (!weakCompareAndSwapIntVolatile(o, wordOffset,
1439                                                 fullWord, (fullWord & ~mask) | maskedX));
1440         return expected;
1441     }
1442 
1443     @HotSpotIntrinsicCandidate
1444     public final boolean compareAndSwapByte(Object o, long offset,
1445                                             byte expected,
1446                                             byte x) {
1447         return compareAndExchangeByteVolatile(o, offset, expected, x) == expected;
1448     }
1449 
1450     @HotSpotIntrinsicCandidate
1451     public final boolean weakCompareAndSwapByteVolatile(Object o, long offset,
1452                                                         byte expected,
1453                                                         byte x) {
1454         return compareAndSwapByte(o, offset, expected, x);
1455     }
1456 
1457     @HotSpotIntrinsicCandidate
1458     public final boolean weakCompareAndSwapByteAcquire(Object o, long offset,
1459                                                        byte expected,
1460                                                        byte x) {
1461         return weakCompareAndSwapByteVolatile(o, offset, expected, x);
1462     }
1463 
1464     @HotSpotIntrinsicCandidate
1465     public final boolean weakCompareAndSwapByteRelease(Object o, long offset,
1466                                                        byte expected,
1467                                                        byte x) {
1468         return weakCompareAndSwapByteVolatile(o, offset, expected, x);
1469     }
1470 
1471     @HotSpotIntrinsicCandidate
1472     public final boolean weakCompareAndSwapByte(Object o, long offset,
1473                                                         byte expected,
1474                                                         byte x) {
1475         return weakCompareAndSwapByteVolatile(o, offset, expected, x);
1476     }
1477 
1478     @HotSpotIntrinsicCandidate
1479     public final byte compareAndExchangeByteAcquire(Object o, long offset,
1480                                                     byte expected,
1481                                                     byte x) {
1482         return compareAndExchangeByteVolatile(o, offset, expected, x);
1483     }
1484 
1485     @HotSpotIntrinsicCandidate
1486     public final byte compareAndExchangeByteRelease(Object o, long offset,
1487                                                     byte expected,
1488                                                     byte x) {
1489         return compareAndExchangeByteVolatile(o, offset, expected, x);
1490     }
1491 
1492     @HotSpotIntrinsicCandidate
1493     public final short compareAndExchangeShortVolatile(Object o, long offset,
1494                                              short expected,
1495                                              short x) {
1496         if ((offset & 3) == 3) {
1497             throw new IllegalArgumentException("Update spans the word, not supported");
1498         }
1499         long wordOffset = offset & ~3;
1500         int shift = (int) (offset & 3) << 3;
1501         if (BE) {
1502             shift = 16 - shift;
1503         }
1504         int mask           = 0xFFFF << shift;
1505         int maskedExpected = (expected & 0xFFFF) << shift;
1506         int maskedX        = (x & 0xFFFF) << shift;
1507         int fullWord;
1508         do {
1509             fullWord = getIntVolatile(o, wordOffset);
1510             if ((fullWord & mask) != maskedExpected) {
1511                 return (short) ((fullWord & mask) >> shift);
1512             }
1513         } while (!weakCompareAndSwapIntVolatile(o, wordOffset,
1514                                                 fullWord, (fullWord & ~mask) | maskedX));
1515         return expected;
1516     }
1517 
1518     @HotSpotIntrinsicCandidate
1519     public final boolean compareAndSwapShort(Object o, long offset,
1520                                              short expected,
1521                                              short x) {
1522         return compareAndExchangeShortVolatile(o, offset, expected, x) == expected;
1523     }
1524 
1525     @HotSpotIntrinsicCandidate
1526     public final boolean weakCompareAndSwapShortVolatile(Object o, long offset,
1527                                                          short expected,
1528                                                          short x) {
1529         return compareAndSwapShort(o, offset, expected, x);
1530     }
1531 
1532     @HotSpotIntrinsicCandidate
1533     public final boolean weakCompareAndSwapShortAcquire(Object o, long offset,
1534                                                         short expected,
1535                                                         short x) {
1536         return weakCompareAndSwapShortVolatile(o, offset, expected, x);
1537     }
1538 
1539     @HotSpotIntrinsicCandidate
1540     public final boolean weakCompareAndSwapShortRelease(Object o, long offset,
1541                                                         short expected,
1542                                                         short x) {
1543         return weakCompareAndSwapShortVolatile(o, offset, expected, x);
1544     }
1545 
1546     @HotSpotIntrinsicCandidate
1547     public final boolean weakCompareAndSwapShort(Object o, long offset,
1548                                                  short expected,
1549                                                  short x) {
1550         return weakCompareAndSwapShortVolatile(o, offset, expected, x);
1551     }
1552 
1553 
1554     @HotSpotIntrinsicCandidate
1555     public final short compareAndExchangeShortAcquire(Object o, long offset,
1556                                                      short expected,
1557                                                      short x) {
1558         return compareAndExchangeShortVolatile(o, offset, expected, x);
1559     }
1560 
1561     @HotSpotIntrinsicCandidate
1562     public final short compareAndExchangeShortRelease(Object o, long offset,
1563                                                     short expected,
1564                                                     short x) {
1565         return compareAndExchangeShortVolatile(o, offset, expected, x);
1566     }
1567 
1568     @ForceInline
1569     private char s2c(short s) {
1570         return (char) s;
1571     }
1572 
1573     @ForceInline
1574     private short c2s(char s) {
1575         return (short) s;
1576     }
1577 
1578     @ForceInline
1579     public final boolean compareAndSwapChar(Object o, long offset,
1580                                             char expected,
1581                                             char x) {
1582         return compareAndSwapShort(o, offset, c2s(expected), c2s(x));
1583     }
1584 
1585     @ForceInline
1586     public final char compareAndExchangeCharVolatile(Object o, long offset,
1587                                             char expected,
1588                                             char x) {
1589         return s2c(compareAndExchangeShortVolatile(o, offset, c2s(expected), c2s(x)));
1590     }
1591 
1592     @ForceInline
1593     public final char compareAndExchangeCharAcquire(Object o, long offset,
1594                                             char expected,
1595                                             char x) {
1596         return s2c(compareAndExchangeShortAcquire(o, offset, c2s(expected), c2s(x)));
1597     }
1598 
1599     @ForceInline
1600     public final char compareAndExchangeCharRelease(Object o, long offset,
1601                                             char expected,
1602                                             char x) {
1603         return s2c(compareAndExchangeShortRelease(o, offset, c2s(expected), c2s(x)));
1604     }
1605 
1606     @ForceInline
1607     public final boolean weakCompareAndSwapCharVolatile(Object o, long offset,
1608                                             char expected,
1609                                             char x) {
1610         return weakCompareAndSwapShortVolatile(o, offset, c2s(expected), c2s(x));
1611     }
1612 
1613     @ForceInline
1614     public final boolean weakCompareAndSwapCharAcquire(Object o, long offset,
1615                                             char expected,
1616                                             char x) {
1617         return weakCompareAndSwapShortAcquire(o, offset, c2s(expected), c2s(x));
1618     }
1619 
1620     @ForceInline
1621     public final boolean weakCompareAndSwapCharRelease(Object o, long offset,
1622                                             char expected,
1623                                             char x) {
1624         return weakCompareAndSwapShortRelease(o, offset, c2s(expected), c2s(x));
1625     }
1626 
1627     @ForceInline
1628     public final boolean weakCompareAndSwapChar(Object o, long offset,
1629                                             char expected,
1630                                             char x) {
1631         return weakCompareAndSwapShort(o, offset, c2s(expected), c2s(x));
1632     }
1633 
1634     @ForceInline
1635     private boolean byte2bool(byte b) {
1636         return b > 0;
1637     }
1638 
1639     @ForceInline
1640     private byte bool2byte(boolean b) {
1641         return b ? (byte)1 : (byte)0;
1642     }
1643 
1644     @ForceInline
1645     public final boolean compareAndSwapBoolean(Object o, long offset,
1646                                                boolean expected,
1647                                                boolean x) {
1648         return compareAndSwapByte(o, offset, bool2byte(expected), bool2byte(x));
1649     }
1650 
1651     @ForceInline
1652     public final boolean compareAndExchangeBooleanVolatile(Object o, long offset,
1653                                                         boolean expected,
1654                                                         boolean x) {
1655         return byte2bool(compareAndExchangeByteVolatile(o, offset, bool2byte(expected), bool2byte(x)));
1656     }
1657 
1658     @ForceInline
1659     public final boolean compareAndExchangeBooleanAcquire(Object o, long offset,
1660                                                     boolean expected,
1661                                                     boolean x) {
1662         return byte2bool(compareAndExchangeByteAcquire(o, offset, bool2byte(expected), bool2byte(x)));
1663     }
1664 
1665     @ForceInline
1666     public final boolean compareAndExchangeBooleanRelease(Object o, long offset,
1667                                                        boolean expected,
1668                                                        boolean x) {
1669         return byte2bool(compareAndExchangeByteRelease(o, offset, bool2byte(expected), bool2byte(x)));
1670     }
1671 
1672     @ForceInline
1673     public final boolean weakCompareAndSwapBooleanVolatile(Object o, long offset,
1674                                                            boolean expected,
1675                                                            boolean x) {
1676         return weakCompareAndSwapByteVolatile(o, offset, bool2byte(expected), bool2byte(x));
1677     }
1678 
1679     @ForceInline
1680     public final boolean weakCompareAndSwapBooleanAcquire(Object o, long offset,
1681                                                           boolean expected,
1682                                                           boolean x) {
1683         return weakCompareAndSwapByteAcquire(o, offset, bool2byte(expected), bool2byte(x));
1684     }
1685 
1686     @ForceInline
1687     public final boolean weakCompareAndSwapBooleanRelease(Object o, long offset,
1688                                                           boolean expected,
1689                                                           boolean x) {
1690         return weakCompareAndSwapByteRelease(o, offset, bool2byte(expected), bool2byte(x));
1691     }
1692 
1693     @ForceInline
1694     public final boolean weakCompareAndSwapBoolean(Object o, long offset,
1695                                                    boolean expected,
1696                                                    boolean x) {
1697         return weakCompareAndSwapByte(o, offset, bool2byte(expected), bool2byte(x));
1698     }
1699 
1700     /**
1701      * Atomically updates Java variable to {@code x} if it is currently
1702      * holding {@code expected}.
1703      *
1704      * <p>This operation has memory semantics of a {@code volatile} read
1705      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
1706      *
1707      * @return {@code true} if successful
1708      */
1709     @HotSpotIntrinsicCandidate
1710     public final native boolean compareAndSwapLong(Object o, long offset,
1711                                                    long expected,
1712                                                    long x);
1713 
1714     @HotSpotIntrinsicCandidate
1715     public final native long compareAndExchangeLongVolatile(Object o, long offset,
1716                                                             long expected,
1717                                                             long x);
1718 
1719     @HotSpotIntrinsicCandidate


2120 
2121     // The following contain CAS-based Java implementations used on
2122     // platforms not supporting native instructions
2123 
2124     /**
2125      * Atomically adds the given value to the current value of a field
2126      * or array element within the given object {@code o}
2127      * at the given {@code offset}.
2128      *
2129      * @param o object/array to update the field/element in
2130      * @param offset field/element offset
2131      * @param delta the value to add
2132      * @return the previous value
2133      * @since 1.8
2134      */
2135     @HotSpotIntrinsicCandidate
2136     public final int getAndAddInt(Object o, long offset, int delta) {
2137         int v;
2138         do {
2139             v = getIntVolatile(o, offset);
2140         } while (!weakCompareAndSwapIntVolatile(o, offset, v, v + delta));
2141         return v;
2142     }
2143 
2144     /**
2145      * Atomically adds the given value to the current value of a field
2146      * or array element within the given object {@code o}
2147      * at the given {@code offset}.
2148      *
2149      * @param o object/array to update the field/element in
2150      * @param offset field/element offset
2151      * @param delta the value to add
2152      * @return the previous value
2153      * @since 1.8
2154      */
2155     @HotSpotIntrinsicCandidate
2156     public final long getAndAddLong(Object o, long offset, long delta) {
2157         long v;
2158         do {
2159             v = getLongVolatile(o, offset);
2160         } while (!weakCompareAndSwapLongVolatile(o, offset, v, v + delta));
2161         return v;
2162     }
2163 
2164     @HotSpotIntrinsicCandidate
2165     public final byte getAndAddByte(Object o, long offset, byte delta) {
2166         byte v;
2167         do {
2168             v = getByteVolatile(o, offset);
2169         } while (!weakCompareAndSwapByteVolatile(o, offset, v, (byte) (v + delta)));
2170         return v;
2171     }
2172 
2173     @HotSpotIntrinsicCandidate
2174     public final short getAndAddShort(Object o, long offset, short delta) {
2175         short v;
2176         do {
2177             v = getShortVolatile(o, offset);
2178         } while (!weakCompareAndSwapShortVolatile(o, offset, v, (short) (v + delta)));
2179         return v;
2180     }
2181 
2182     public final char getAndAddChar(Object o, long offset, char delta) {
2183         return (char) getAndAddShort(o, offset, (short) delta);
2184     }
2185 
2186     /**
2187      * Atomically exchanges the given value with the current value of
2188      * a field or array element within the given object {@code o}
2189      * at the given {@code offset}.
2190      *
2191      * @param o object/array to update the field/element in
2192      * @param offset field/element offset
2193      * @param newValue new value
2194      * @return the previous value
2195      * @since 1.8
2196      */
2197     @HotSpotIntrinsicCandidate
2198     public final int getAndSetInt(Object o, long offset, int newValue) {
2199         int v;
2200         do {
2201             v = getIntVolatile(o, offset);
2202         } while (!weakCompareAndSwapIntVolatile(o, offset, v, newValue));
2203         return v;
2204     }
2205 
2206     /**
2207      * Atomically exchanges the given value with the current value of
2208      * a field or array element within the given object {@code o}
2209      * at the given {@code offset}.
2210      *
2211      * @param o object/array to update the field/element in
2212      * @param offset field/element offset
2213      * @param newValue new value
2214      * @return the previous value
2215      * @since 1.8
2216      */
2217     @HotSpotIntrinsicCandidate
2218     public final long getAndSetLong(Object o, long offset, long newValue) {
2219         long v;
2220         do {
2221             v = getLongVolatile(o, offset);
2222         } while (!weakCompareAndSwapLongVolatile(o, offset, v, newValue));
2223         return v;
2224     }
2225 
2226     /**
2227      * Atomically exchanges the given reference value with the current
2228      * reference value of a field or array element within the given
2229      * object {@code o} at the given {@code offset}.
2230      *
2231      * @param o object/array to update the field/element in
2232      * @param offset field/element offset
2233      * @param newValue new value
2234      * @return the previous value
2235      * @since 1.8
2236      */
2237     @HotSpotIntrinsicCandidate
2238     public final Object getAndSetObject(Object o, long offset, Object newValue) {
2239         Object v;
2240         do {
2241             v = getObjectVolatile(o, offset);
2242         } while (!weakCompareAndSwapObjectVolatile(o, offset, v, newValue));
2243         return v;
2244     }
2245 
2246     @HotSpotIntrinsicCandidate
2247     public final byte getAndSetByte(Object o, long offset, byte newValue) {
2248         byte v;
2249         do {
2250             v = getByteVolatile(o, offset);
2251         } while (!weakCompareAndSwapByteVolatile(o, offset, v, newValue));
2252         return v;
2253     }
2254 
2255     public final boolean getAndSetBoolean(Object o, long offset, boolean newValue) {
2256         return byte2bool(getAndSetByte(o, offset, bool2byte(newValue)));
2257     }
2258 
2259     @HotSpotIntrinsicCandidate
2260     public final short getAndSetShort(Object o, long offset, short newValue) {
2261         short v;
2262         do {
2263             v = getShortVolatile(o, offset);
2264         } while (!weakCompareAndSwapShortVolatile(o, offset, v, newValue));
2265         return v;
2266     }
2267 
2268     public final char getAndSetChar(Object o, long offset, char newValue) {
2269         return s2c(getAndSetShort(o, offset, c2s(newValue)));
2270     }
2271 
2272     /**
2273      * Ensures that loads before the fence will not be reordered with loads and
2274      * stores after the fence; a "LoadLoad plus LoadStore barrier".
2275      *
2276      * Corresponds to C11 atomic_thread_fence(memory_order_acquire)
2277      * (an "acquire fence").
2278      *
2279      * A pure LoadLoad fence is not provided, since the addition of LoadStore
2280      * is almost always desired, and most current hardware instructions that
2281      * provide a LoadLoad barrier also provide a LoadStore barrier for free.
2282      * @since 1.8
2283      */
2284     @HotSpotIntrinsicCandidate
2285     public native void loadFence();
2286 
2287     /**
2288      * Ensures that loads and stores before the fence will not be reordered with
2289      * stores after the fence; a "StoreStore plus LoadStore barrier".
2290      *


< prev index next >