Skip to content

Commit 05f7f0a

Browse files
author
Tom Rodriguez
committed
8321288: [JVMCI] HotSpotJVMCIRuntime doesn't clean up WeakReferences in resolvedJavaTypes
Reviewed-by: dnsimon, kvn
1 parent 6311dab commit 05f7f0a

File tree

1 file changed

+48
-5
lines changed

1 file changed

+48
-5
lines changed

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

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.lang.invoke.CallSite;
3636
import java.lang.invoke.ConstantCallSite;
3737
import java.lang.invoke.MethodHandle;
38+
import java.lang.ref.ReferenceQueue;
3839
import java.lang.ref.WeakReference;
3940
import java.lang.reflect.Executable;
4041
import java.lang.reflect.Field;
@@ -499,7 +500,32 @@ T get() {
499500
}
500501
}
501502

502-
@NativeImageReinitialize private HashMap<Long, WeakReference<ResolvedJavaType>> resolvedJavaTypes;
503+
504+
/**
505+
* A weak reference that also tracks the key used to insert the value into {@link #resolvedJavaTypes} so that
506+
* it can be removed when the referent is cleared.
507+
*/
508+
static class KlassWeakReference extends WeakReference<HotSpotResolvedObjectTypeImpl> {
509+
510+
private final Long klassPointer;
511+
512+
public KlassWeakReference(Long klassPointer, HotSpotResolvedObjectTypeImpl referent, ReferenceQueue<HotSpotResolvedObjectTypeImpl> q) {
513+
super(referent, q);
514+
this.klassPointer = klassPointer;
515+
}
516+
}
517+
518+
/**
519+
* A mapping from the {@code Klass*} to the corresponding {@link HotSpotResolvedObjectTypeImpl}. The value is
520+
* held weakly through a {@link KlassWeakReference} so that unused types can be unloaded when the compiler no longer needs them.
521+
*/
522+
@NativeImageReinitialize private HashMap<Long, KlassWeakReference> resolvedJavaTypes;
523+
524+
/**
525+
* A {@link ReferenceQueue} to track when {@link KlassWeakReference}s have been freed so that the corresponding
526+
* entry in {@link #resolvedJavaTypes} can be cleared.
527+
*/
528+
@NativeImageReinitialize private ReferenceQueue<HotSpotResolvedObjectTypeImpl> resolvedJavaTypesQueue;
503529

504530
/**
505531
* Stores the value set by {@link #excludeFromJVMCICompilation(Module...)} so that it can be
@@ -662,24 +688,41 @@ HotSpotResolvedJavaType fromClass(Class<?> javaClass) {
662688
return fromClass0(javaClass);
663689
}
664690

665-
synchronized HotSpotResolvedObjectTypeImpl fromMetaspace(long klassPointer) {
691+
synchronized HotSpotResolvedObjectTypeImpl fromMetaspace(Long klassPointer) {
666692
if (resolvedJavaTypes == null) {
667693
resolvedJavaTypes = new HashMap<>();
694+
resolvedJavaTypesQueue = new ReferenceQueue<>();
668695
}
669696
assert klassPointer != 0;
670-
WeakReference<ResolvedJavaType> klassReference = resolvedJavaTypes.get(klassPointer);
697+
KlassWeakReference klassReference = resolvedJavaTypes.get(klassPointer);
671698
HotSpotResolvedObjectTypeImpl javaType = null;
672699
if (klassReference != null) {
673-
javaType = (HotSpotResolvedObjectTypeImpl) klassReference.get();
700+
javaType = klassReference.get();
674701
}
675702
if (javaType == null) {
676703
String name = compilerToVm.getSignatureName(klassPointer);
677704
javaType = new HotSpotResolvedObjectTypeImpl(klassPointer, name);
678-
resolvedJavaTypes.put(klassPointer, new WeakReference<>(javaType));
705+
resolvedJavaTypes.put(klassPointer, new KlassWeakReference(klassPointer, javaType, resolvedJavaTypesQueue));
679706
}
707+
expungeStaleKlassEntries();
680708
return javaType;
681709
}
682710

711+
712+
/**
713+
* Clean up WeakReferences whose referents have been cleared. This should be called from a synchronized context.
714+
*/
715+
private void expungeStaleKlassEntries() {
716+
KlassWeakReference current = (KlassWeakReference) resolvedJavaTypesQueue.poll();
717+
while (current != null) {
718+
// Make sure the entry is still mapped to the weak reference
719+
if (resolvedJavaTypes.get(current.klassPointer) == current) {
720+
resolvedJavaTypes.remove(current.klassPointer);
721+
}
722+
current = (KlassWeakReference) resolvedJavaTypesQueue.poll();
723+
}
724+
}
725+
683726
private JVMCIBackend registerBackend(JVMCIBackend backend) {
684727
Class<? extends Architecture> arch = backend.getCodeCache().getTarget().arch.getClass();
685728
JVMCIBackend oldValue = backends.put(arch, backend);

0 commit comments

Comments
 (0)