Once I recklessly tried to optimize Class.resolveName()
relying on the results of
benchmark (available in the referenced PR) replicating the logic of the mentioned method. The idea of optimization was quite trivial and about replacing new StringBuilder().append()
with plain concatenation. It turned out that while the benchmark demonstrated significant improvement, the patched method itself regressed. As it was pointed out in comments of the PR
The JMH test may show better results as it is compiled to bytecode that uses special invokedynamic-based string concatenation with optimal MH based underlying strategy. The code in java.lang.Class can't be compiled to use this kind of concatenation because of bootstrapping issues and is therefore compiled to bytecode that uses StringBuilder directly (much like the existing code of the patched method).
Indeed, concatenation of Strings in java.base
is compiled into StringBuilder
-based bytecode unlike it is done for client code (there they utilize invokedynamic
together with StringConcatFactory
).
I've investigated those 'bootstrapping issues' but the only thing that I've found is about the order of class loading. If one runs java -Xlog:class init -version
it becomes clear that StringConcatFactory
is loaded far after j.l.Class
. At the same time there are lots of other classes referenced from j.l.Class
loaded after it either.
So my question is why javac
can use e. g. StringBuilder
within Class.resolveName()
, but not StringConcatFactory
? What is so special about that class?
Or maybe my speculation is wrong and the bootstrapping issue is not about StringConcatFactory
and invokedynamic
?
CodePudding user response:
"Bootstrapping issues" here is the problem of the chicken or the egg.
StringConcatFactory
relies on JSR 292 machinery, which in turn uses java.base
classes that use string concatenation. In order to resolve this cyclic dependency, concatenation is java.base
classes is compiled in an old-fashioned way that does not depend on StringConcatFactory
.