<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>