<div><div><span style="font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;float:none;display:inline!important;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)">Hi all,</span><div style="font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)"><br></div><div style="font-size:1rem;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)">I'm new to contributing to OpenJDK and have been working with Dan Smith as a mentor. I've been looking at JDK-8350938, which suggests refactoring ResourceParsingClassHierarchyResolver to avoid inflating all UTF8 constant pool entries by using ClassReaderImpl. ClassReaderImpl stores constant pool offsets and later lazily reads/inflates UTF8 entries as needed, so it seems to make sense to use here as a performance enhancement.</div><div style="font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)"><br></div><div style="font-size:1rem;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)">I have an initial prototype that removes manual parsing in getClassInfo() and instead constructs a ClassReaderImpl and uses its helper methods to return the needed class information.<br></div><div style="font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)"><br></div><div style="font-size:1rem;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)">One question before I try to move forward with contributing: </div><div style="font-size:1rem;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)">- ClassReaderImpl takes a ClassFile context. I used ClassFile.of() (a ClassFile context with default options). Is this the correct usage here, or should the resolver provide a more specific context?</div><div style="font-size:1rem;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)">I am also open to and would appreciate any other ideas or feedback on this implementation.</div><div style="font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)"><br></div><div style="font-size:1rem;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)">I’ve included the small patch below for reference. </div><div style="font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)"><br></div><div style="font-size:1rem;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)">Thanks for your help,</div><div style="font-size:1rem;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)">Trevor<br></div><div style="font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)"><br></div><div style="font-size:1rem;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:1px;text-decoration:none;background-color:rgba(0,0,0,0);border-color:rgb(49,49,49);color:rgb(49,49,49)">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<br>index 5be14f42baa..463845ce612 100644<br>--- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java<br>+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java<br>@@ -30,7 +30,10 @@<br> import java.io.IOException;<br> import java.io.InputStream;<br> import java.io.UncheckedIOException;<br>+import java.lang.classfile.ClassFile;<br> import java.lang.classfile.ClassHierarchyResolver;<br>+import java.lang.classfile.ClassReader;<br>+import java.lang.classfile.constantpool.ClassEntry;<br> import java.lang.constant.ClassDesc;<br> import java.util.Collection;<br> import java.util.HashMap;<br>@@ -164,31 +167,12 @@ public ResourceParsingClassHierarchyResolver(Function<ClassDesc, InputStream> cl<br>         public ClassHierarchyResolver.ClassHierarchyInfo getClassInfo(ClassDesc classDesc) {<br>             var ci = streamProvider.apply(classDesc);<br>             if (ci == null) return null;<br>-            try (var in = new DataInputStream(new BufferedInputStream(ci))) {<br>-                in.skipBytes(8);<br>-                int cpLength = in.readUnsignedShort();<br>-                String[] cpStrings = new String[cpLength];<br>-                int[] cpClasses = new int[cpLength];<br>-                for (int i = 1; i < cpLength; i++) {<br>-                    int tag;<br>-                    switch (tag = in.readUnsignedByte()) {<br>-                        case TAG_UTF8 -> cpStrings[i] = in.readUTF();<br>-                        case TAG_CLASS -> cpClasses[i] = in.readUnsignedShort();<br>-                        case TAG_STRING, TAG_METHOD_TYPE, TAG_MODULE, TAG_PACKAGE -> in.skipBytes(2);<br>-                        case TAG_METHOD_HANDLE -> in.skipBytes(3);<br>-                        case TAG_INTEGER, TAG_FLOAT, TAG_FIELDREF, TAG_METHODREF, TAG_INTERFACE_METHODREF,<br>-                             TAG_NAME_AND_TYPE, TAG_DYNAMIC, TAG_INVOKE_DYNAMIC -> in.skipBytes(4);<br>-                        case TAG_LONG, TAG_DOUBLE -> {<br>-                            in.skipBytes(8);<br>-                            i++;<br>-                        }<br>-                        default -> throw new IllegalStateException("Bad tag (" + tag + ") at index (" + i + ")");<br>-                    }<br>-                }<br>-                boolean isInterface = (in.readUnsignedShort() & ACC_INTERFACE) != 0;<br>-                in.skipBytes(2);<br>-                int superIndex = in.readUnsignedShort();<br>-                var superClass = superIndex > 0 ? ClassDesc.ofInternalName(cpStrings[cpClasses[superIndex]]) : null;<br>+            try (ci) {<br>+                ClassReader reader = new ClassReaderImpl(ci.readAllBytes(), (ClassFileImpl) ClassFile.of());<br>+                boolean isInterface = (reader.flags() & ACC_INTERFACE) != 0;<br>+                ClassDesc superClass = reader.superclassEntry()<br>+                        .map(ClassEntry::asSymbol)<br>+                        .orElse(null);<br>                 return new ClassHierarchyInfoImpl(superClass, isInterface);<br>             } catch (IOException ioe) {<br>                 throw new UncheckedIOException(ioe);</div></div>
</div>