From b2639e1d6246a7e1aab1d9d15add7979adf40766 Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Fri, 17 Mar 2023 11:47:11 +0000 Subject: [PATCH] 8304164: jdk/classfile/CorpusTest.java still fails after JDK-8303910 Reviewed-by: jpai --- .../internal/classfile/impl/ClassHierarchyImpl.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java index fb697e1df059d..6f2bd440349ca 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java @@ -110,6 +110,10 @@ public boolean isAssignableFrom(ClassDesc thisClass, ClassDesc fromClass) { public static final class CachedClassHierarchyResolver implements ClassHierarchyResolver { + //this instance should never appear in the cache nor leak out + private static final ClassHierarchyResolver.ClassHierarchyInfo NOPE = + new ClassHierarchyResolver.ClassHierarchyInfo(null, false, null); + private final Function streamProvider; private final Map resolvedCache; @@ -124,9 +128,11 @@ public CachedClassHierarchyResolver(Function classStream // empty ClInfo is stored in case of an exception to avoid repeated scanning failures @Override public ClassHierarchyResolver.ClassHierarchyInfo getClassInfo(ClassDesc classDesc) { - var res = resolvedCache.get(classDesc); - //additional test for null value is important to avoid repeated resolution attempts - if (res == null && !resolvedCache.containsKey(classDesc)) { + //using NOPE to distinguish between null value and non-existent record in the cache + //this code is on JDK bootstrap critical path, so cannot use lambdas here + var res = resolvedCache.getOrDefault(classDesc, NOPE); + if (res == NOPE) { + res = null; var ci = streamProvider.apply(classDesc); if (ci != null) { try (var in = new DataInputStream(new BufferedInputStream(ci))) {