3333import java .lang .ref .WeakReference ;
3434import java .util .Arrays ;
3535import java .util .Collections ;
36+ import java .util .function .Supplier ;
3637import java .util .List ;
38+ import java .util .Map ;
3739import java .util .NoSuchElementException ;
3840import java .util .Objects ;
3941import java .util .Optional ;
4244import java .util .concurrent .ConcurrentMap ;
4345import java .util .stream .Stream ;
4446
45- import jdk .internal .access .SharedSecrets ;
47+ import jdk .internal .util .ReferencedKeySet ;
48+ import jdk .internal .util .ReferenceKey ;
4649import jdk .internal .vm .annotation .Stable ;
4750import sun .invoke .util .BytecodeDescriptor ;
4851import sun .invoke .util .VerifyType ;
@@ -227,7 +230,13 @@ private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num
227230 return new IndexOutOfBoundsException (num .toString ());
228231 }
229232
230- static final ConcurrentWeakInternSet <MethodType > internTable = new ConcurrentWeakInternSet <>();
233+ static final ReferencedKeySet <MethodType > internTable =
234+ ReferencedKeySet .create (false , true , new Supplier <>() {
235+ @ Override
236+ public Map <ReferenceKey <MethodType >, ReferenceKey <MethodType >> get () {
237+ return new ConcurrentHashMap <>(512 );
238+ }
239+ });
231240
232241 static final Class <?>[] NO_PTYPES = {};
233242
@@ -405,7 +414,7 @@ private static MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean tr
405414 mt = new MethodType (rtype , ptypes );
406415 }
407416 mt .form = MethodTypeForm .findForm (mt );
408- return internTable .add (mt );
417+ return internTable .intern (mt );
409418 }
410419 private static final @ Stable MethodType [] objectOnlyTypes = new MethodType [20 ];
411420
@@ -883,10 +892,6 @@ public Class<?>[] parameterArray() {
883892 * @param x object to compare
884893 * @see Object#equals(Object)
885894 */
886- // This implementation may also return true if x is a WeakEntry containing
887- // a method type that is equal to this. This is an internal implementation
888- // detail to allow for faster method type lookups.
889- // See ConcurrentWeakInternSet.WeakEntry#equals(Object)
890895 @ Override
891896 public boolean equals (Object x ) {
892897 if (this == x ) {
@@ -895,10 +900,6 @@ public boolean equals(Object x) {
895900 if (x instanceof MethodType mt ) {
896901 return equals (mt );
897902 }
898- if (x instanceof ConcurrentWeakInternSet .WeakEntry <?> e
899- && e .get () instanceof MethodType mt ) {
900- return equals (mt );
901- }
902903 return false ;
903904 }
904905
@@ -1390,112 +1391,4 @@ private Object readResolve() {
13901391 wrapAlt = null ;
13911392 return mt ;
13921393 }
1393-
1394- /**
1395- * Simple implementation of weak concurrent intern set.
1396- *
1397- * @param <T> interned type
1398- */
1399- private static class ConcurrentWeakInternSet <T > {
1400-
1401- private final ConcurrentMap <WeakEntry <T >, WeakEntry <T >> map ;
1402- private final ReferenceQueue <T > stale ;
1403-
1404- public ConcurrentWeakInternSet () {
1405- this .map = new ConcurrentHashMap <>(512 );
1406- this .stale = SharedSecrets .getJavaLangRefAccess ().newNativeReferenceQueue ();
1407- }
1408-
1409- /**
1410- * Get the existing interned element.
1411- * This method returns null if no element is interned.
1412- *
1413- * @param elem element to look up
1414- * @return the interned element
1415- */
1416- public T get (T elem ) {
1417- if (elem == null ) throw new NullPointerException ();
1418- expungeStaleElements ();
1419-
1420- WeakEntry <T > value = map .get (elem );
1421- if (value != null ) {
1422- T res = value .get ();
1423- if (res != null ) {
1424- return res ;
1425- }
1426- }
1427- return null ;
1428- }
1429-
1430- /**
1431- * Interns the element.
1432- * Always returns non-null element, matching the one in the intern set.
1433- * Under the race against another add(), it can return <i>different</i>
1434- * element, if another thread beats us to interning it.
1435- *
1436- * @param elem element to add
1437- * @return element that was actually added
1438- */
1439- public T add (T elem ) {
1440- if (elem == null ) throw new NullPointerException ();
1441-
1442- // Playing double race here, and so spinloop is required.
1443- // First race is with two concurrent updaters.
1444- // Second race is with GC purging weak ref under our feet.
1445- // Hopefully, we almost always end up with a single pass.
1446- T interned ;
1447- WeakEntry <T > e = new WeakEntry <>(elem , stale );
1448- do {
1449- expungeStaleElements ();
1450- WeakEntry <T > exist = map .putIfAbsent (e , e );
1451- interned = (exist == null ) ? elem : exist .get ();
1452- } while (interned == null );
1453- return interned ;
1454- }
1455-
1456- private void expungeStaleElements () {
1457- Reference <? extends T > reference ;
1458- while ((reference = stale .poll ()) != null ) {
1459- map .remove (reference );
1460- }
1461- }
1462-
1463- private static class WeakEntry <T > extends WeakReference <T > {
1464-
1465- public final int hashcode ;
1466-
1467- public WeakEntry (T key , ReferenceQueue <T > queue ) {
1468- super (key , queue );
1469- hashcode = key .hashCode ();
1470- }
1471-
1472- /**
1473- * This implementation returns {@code true} if {@code obj} is another
1474- * {@code WeakEntry} whose referent is equal to this referent, or
1475- * if {@code obj} is equal to the referent of this. This allows
1476- * lookups to be made without wrapping in a {@code WeakEntry}.
1477- *
1478- * @param obj the object to compare
1479- * @return true if {@code obj} is equal to this or the referent of this
1480- * @see MethodType#equals(Object)
1481- * @see Object#equals(Object)
1482- */
1483- @ Override
1484- public boolean equals (Object obj ) {
1485- Object mine = get ();
1486- if (obj instanceof WeakEntry <?> we ) {
1487- Object that = we .get ();
1488- return (that == null || mine == null ) ? (this == obj ) : mine .equals (that );
1489- }
1490- return (mine == null ) ? (obj == null ) : mine .equals (obj );
1491- }
1492-
1493- @ Override
1494- public int hashCode () {
1495- return hashcode ;
1496- }
1497-
1498- }
1499- }
1500-
15011394}
0 commit comments