8218700: infinite loop in HotSpotJVMCIMetaAccessContext.fromClass after OutOfMemoryError

Reviewed-by: never, kvn
This commit is contained in:
Dean Long 2019-04-25 13:35:34 -07:00
parent 72f082e925
commit a854955d3e
2 changed files with 32 additions and 18 deletions

View File

@ -383,7 +383,25 @@ assert factories != null : "sanity";
/**
* 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;
@ -485,27 +503,25 @@ assert factories != null : "sanity";
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();
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.
*/
resolvedJavaType.remove(javaClass);
}
WeakReferenceHolder<HotSpotResolvedJavaType> ref = resolvedJavaType.get(javaClass);
HotSpotResolvedJavaType javaType = ref.get();
if (javaType == null) {
/*
* If the referent has become null, create a new value and
* update cached weak reference.
*/
javaType = createClass(javaClass);
ref.set(javaType);
}
return javaType;
}

View File

@ -210,8 +210,6 @@ serviceability/tmtools/jstat/GcTest02.java 81
serviceability/tmtools/jstat/GcCapacityTest.java 8196611 generic-all
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorMultiArrayTest.java 8196611 generic-all
vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock02/TestDescription.java 8218700 generic-all
vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java 8218701 generic-all
vmTestbase/nsk/jdb/clear/clear003/clear003.java 8218701 generic-all