On Fri, 21 Nov 2025 16:54:48 GMT, Trevor Bond <[email protected]> wrote:
> Enhance `ResourceParsingClassHierarchyResolver.getClassInfo` to use
> `ClassReaderImpl` to improve performance. Previously this method inflated and
> stored all UTF-8 entries in the constant pool and later accessed the array of
> strings to try finding the name of the superclass. `ClassReaderImpl` instead
> stores constant pool offsets and later lazily reads/inflates UTF8 entries as
> needed.
>
> I’ve ran all tier 1 tests and tests within `test/jdk/jdk/classfile` on the
> latest version of this change, and they all pass.
>
> I ran some informal performance testing to see if these changes led to any
> improvement. I created a .class file with several thousand unique strings in
> a String array to deliberately enlarge the number of UTF-8 entries in the
> constant pool. I then benchmarked the performance of running a process nearly
> identical to `ClassHierarchyInfoTest.testClassLoaderParsingResolver` on this
> custom class over 200 runs using JMH. The results are as follows.
>
> | Version | Avg Time (ns/op) | Δ vs Before |
> |--------|------------------:|-------------|
> | **Before** | 1,483,671.539 ± 3,477.744 | — |
> | **After** | 1,380,064.517 ± 3,482.434 | ≈ 7.0% faster |
Looks good in principle. Even though people wonder about the buffering policy,
I think it is negligible considering that we have caching mechanism. And the
constant pool is flexible sized, so "only read the classfile header" might be
an optimisitic assumption.
Also, the key to this patch is not performance - it is about the
maintainability from a consistent way to parse class files, so in the future,
we don't need to update this site any more if we have new constant pool entry
type or other format expansions.
src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java
line 171:
> 169: if (ci == null) return null;
> 170: try (ci) {
> 171: ClassReader reader = new
> ClassReaderImpl(ci.readAllBytes(), (ClassFileImpl) ClassFile.of());
Suggestion:
var reader = new ClassReaderImpl(ci.readAllBytes(),
ClassFileImpl.DEFAULT_CONTEXT);
And you can remove the 3 imports you have added.
-------------
Marked as reviewed by liach (Reviewer).
PR Review: https://git.openjdk.org/jdk/pull/28458#pullrequestreview-3503212041
PR Comment: https://git.openjdk.org/jdk/pull/28458#issuecomment-3573741129
PR Review Comment: https://git.openjdk.org/jdk/pull/28458#discussion_r2558503313