8251397: NPE on ClassValue.ClassValueMap.cacheArray
Add release fence to ClassValueMap constructor. * Release fence guarantees that cacheArray field will published with a non-null value. * Without this fix, CacheValueMap.cacheArray can sometimes be seen as null. Reviewed-by: shade, psandoz
This commit is contained in:
parent
cca3a26e43
commit
81e2cf82d9
@ -29,6 +29,8 @@ import java.util.WeakHashMap;
|
|||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import jdk.internal.misc.Unsafe;
|
||||||
|
|
||||||
import static java.lang.ClassValue.ClassValueMap.probeHomeLocation;
|
import static java.lang.ClassValue.ClassValueMap.probeHomeLocation;
|
||||||
import static java.lang.ClassValue.ClassValueMap.probeBackupLocations;
|
import static java.lang.ClassValue.ClassValueMap.probeBackupLocations;
|
||||||
|
|
||||||
@ -369,12 +371,22 @@ public abstract class ClassValue<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final Object CRITICAL_SECTION = new Object();
|
private static final Object CRITICAL_SECTION = new Object();
|
||||||
|
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||||
private static ClassValueMap initializeMap(Class<?> type) {
|
private static ClassValueMap initializeMap(Class<?> type) {
|
||||||
ClassValueMap map;
|
ClassValueMap map;
|
||||||
synchronized (CRITICAL_SECTION) { // private object to avoid deadlocks
|
synchronized (CRITICAL_SECTION) { // private object to avoid deadlocks
|
||||||
// happens about once per type
|
// happens about once per type
|
||||||
if ((map = type.classValueMap) == null)
|
if ((map = type.classValueMap) == null) {
|
||||||
type.classValueMap = map = new ClassValueMap();
|
map = new ClassValueMap();
|
||||||
|
// Place a Store fence after construction and before publishing to emulate
|
||||||
|
// ClassValueMap containing final fields. This ensures it can be
|
||||||
|
// published safely in the non-volatile field Class.classValueMap,
|
||||||
|
// since stores to the fields of ClassValueMap will not be reordered
|
||||||
|
// to occur after the store to the field type.classValueMap
|
||||||
|
UNSAFE.storeFence();
|
||||||
|
|
||||||
|
type.classValueMap = map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user