< prev index next >

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java

Print this page
rev 54697 : [mq]: 8218700

@@ -382,11 +382,29 @@
     @NativeImageReinitialize private volatile boolean creatingCompiler;
 
     /**
      * Cache for speeding up {@link #fromClass(Class)}.
      */
-    @NativeImageReinitialize private volatile ClassValue<WeakReference<HotSpotResolvedJavaType>> resolvedJavaType;
+    @NativeImageReinitialize private volatile ClassValue<WeakReferenceHolder<HotSpotResolvedJavaType>> resolvedJavaType;
+
+    /**
+     * To avoid calling ClassValue.remove to refresh the weak reference, which
+     * under certain circumstances can lead to an infinite loop, we use a
+     * permanent holder with a mutable field that we refresh.
+     */
+    private static class WeakReferenceHolder<T> {
+        private volatile WeakReference<T> ref;
+        WeakReferenceHolder(T value) {
+            set(value);
+        }
+        void set(T value) {
+            ref = new WeakReference<T>(value);
+        }
+        T get() {
+            return ref.get();
+        }
+    };
 
     @NativeImageReinitialize private HashMap<Long, WeakReference<ResolvedJavaType>> resolvedJavaTypes;
 
     /**
      * Stores the value set by {@link #excludeFromJVMCICompilation(Module...)} so that it can

@@ -484,31 +502,29 @@
 
     private HotSpotResolvedJavaType fromClass0(Class<?> javaClass) {
         if (resolvedJavaType == null) {
             synchronized (this) {
                 if (resolvedJavaType == null) {
-                    resolvedJavaType = new ClassValue<WeakReference<HotSpotResolvedJavaType>>() {
+                    resolvedJavaType = new ClassValue<WeakReferenceHolder<HotSpotResolvedJavaType>>() {
                         @Override
-                        protected WeakReference<HotSpotResolvedJavaType> computeValue(Class<?> type) {
-                            return new WeakReference<>(createClass(type));
+                        protected WeakReferenceHolder<HotSpotResolvedJavaType> computeValue(Class<?> type) {
+                            return new WeakReferenceHolder<>(createClass(type));
                         }
                     };
                 }
             }
         }
-        HotSpotResolvedJavaType javaType = null;
-        while (javaType == null) {
-            WeakReference<HotSpotResolvedJavaType> type = resolvedJavaType.get(javaClass);
-            javaType = type.get();
+
+        WeakReferenceHolder<HotSpotResolvedJavaType> ref = resolvedJavaType.get(javaClass);
+        HotSpotResolvedJavaType javaType = ref.get();
             if (javaType == null) {
                 /*
-                 * If the referent has become null, clear out the current value and let computeValue
-                 * above create a new value. Reload the value in a loop because in theory the
-                 * WeakReference referent can be reclaimed at any point.
+             * If the referent has become null, create a new value and
+             * update cached weak reference.
                  */
-                resolvedJavaType.remove(javaClass);
-            }
+            javaType = createClass(javaClass);
+            ref.set(javaType);
         }
         return javaType;
     }
 
     /**
< prev index next >