On Sun, 18 Aug 2024 23:04:33 GMT, Shaojin Wen <d...@openjdk.org> wrote:
>> Right, which is why we need to balance these microbenchmark speed-ups >> against any added static footprint and other factors. Going through fewer >> but less specialized methods can reduce runtime footprint and lead to >> quicker warmup, for example. Also, @liach pointed out elsewhere the we might >> be able to avoid many of these `ofDescriptor` calls with optimizations >> elsewhere, so perhaps let's not go overboard here and re-measure with those >> optimizations in place as it might make this work less impactful. >> >> On a related note: Running micros with `-Xint` and `-XX:TieredStopAtLevel=1` >> can help indicate whether some optimization will be helpful during startup >> or not. Often things align well, but sometimes optimizations that help peak >> performance make interpreted performance worse, and vice versa. >> >> If we're optimizing for startup the best is obviously to check on some >> startup benchmark of choice. A recent example (on Linux): `perf stat -r 50 >> java -jar benchmarks.jar org.openjdk.bench.java.lang.StringConcatStartup` or >> simply `make test TEST=micro:StringConcatStartup` >> >> FWIW I use this technique all the time to diagnose what we're doing during >> startup: >> https://cl4es.github.io/2018/11/23/Investigating-Startup-Using-Bytestacks.html >> - it has helped me find numerous candidates for startup optimization. Main >> reason I'm insisting on adding a main method to startup-centric JMH >> benchmarks. > > All calls to ofDescriptor during the startup process come from here, which > cannot be avoided in a simple way. > > > at > java.base/jdk.internal.constant.MethodTypeDescImpl.ofDescriptor(MethodTypeDescImpl.java:142) > at > java.base/java.lang.constant.MethodTypeDesc.ofDescriptor(MethodTypeDesc.java:60) > at > java.base/jdk.internal.classfile.impl.DirectMethodBuilder.methodTypeSymbol(DirectMethodBuilder.java:88) > at > java.base/jdk.internal.classfile.impl.TerminalCodeBuilder.setupTopLocal(TerminalCodeBuilder.java:36) > at > java.base/jdk.internal.classfile.impl.DirectCodeBuilder.<init>(DirectCodeBuilder.java:133) > at > java.base/jdk.internal.classfile.impl.DirectCodeBuilder.build(DirectCodeBuilder.java:106) > at > java.base/jdk.internal.classfile.impl.DirectMethodBuilder.withCode(DirectMethodBuilder.java:123) > at > java.base/jdk.internal.classfile.impl.DirectMethodBuilder.withCode(DirectMethodBuilder.java:130) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator$5.accept(InvokerBytecodeGenerator.java:589) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator$5.accept(InvokerBytecodeGenerator.java:567) > at > java.base/jdk.internal.classfile.impl.DirectMethodBuilder.run(DirectMethodBuilder.java:144) > at > java.base/jdk.internal.classfile.impl.DirectClassBuilder.withMethod(DirectClassBuilder.java:106) > at > java.base/java.lang.classfile.ClassBuilder.withMethod(ClassBuilder.java:260) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator.methodSetup(InvokerBytecodeGenerator.java:292) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator.addMethod(InvokerBytecodeGenerator.java:567) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator$4.accept(InvokerBytecodeGenerator.java:558) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator$4.accept(InvokerBytecodeGenerator.java:555) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator$2.accept(InvokerBytecodeGenerator.java:282) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator$2.accept(InvokerBytecodeGenerator.java:276) > at > java.base/jdk.internal.classfile.impl.ClassFileImpl.build(ClassFileImpl.java:113) > at java.base/java.lang.classfile.ClassFile.build(ClassFile.java:332) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator.classFileSetup(InvokerBytecodeGenerator.java:276) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator.generateCustomizedCodeBytes(InvokerBytecodeGenerator.java:555) > at > java.base/java.lang.invoke.InvokerBytecodeGenerator.generateCustomizedCode(InvokerBytecodeGenerator.java:533) > at java.base/java.lang.i... Hmm, based on your stacktrace I think you are running the exploded image in `build/<arch>/jdk` instead of from a final image, e.g. the one that `make jdk-image` produces in `build/<arch>/images/jdk` - the former will do a lot more stuff during startup, while the latter applies numerous link-time optimizations to reduce lambda and method handle spinning on startup. While speeding up the exploded image is a nice bonus, the runtime images should be the focus of startup optimization work. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/20611#discussion_r1721090415