New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use StringConcatFactory
for string concatenation on JDK 9+
#9556
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've unit tested this and it seems to work well. I'd like to know if there is a chance this could be merged before I put more effort into testing and benchmarking though.
src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
Outdated
Show resolved
Hide resolved
b591154
to
00369f8
Compare
-YstringConcat
to support indy string concatStringConcatFactory
for string concatenation on JDK 9+
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I'll add some tests today. Still interested in feedback for whether we want this to be configurable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change LGTM. How do we test it (not only once, but continuously)? We could switch our JDK 16 nightly build on travis to use -target:11
everywhere.
This would be the first feature in the compiler where -target
actually has an effect (besides the classfile version).
I'm wondering if we can make this more dynamic so that StringConcatFactory
is used when available at runtime. Would that be possible by writing a custom indy bootstrap method? Maybe it would be simpler to rewrite our own StringConcatFactory
and ship that in the Scala library.
I think licensing wouldn't allow us to use or look at the implementation in the JDK (@sjrd has experience with this question).
Yeah, as soon as you look at the OpenJDK source code or even its tests, you're out. You can't contribute anything remotely similar to the feature you looked at in a Scala project. That's because OpenJDK is GPL and Scala is Apache. The only things you can do are to look at the JavaDocs and the specs, and experiment with the behavior on an OpenJDK build (avoid OracleJDK builds, because they have a clause against reverse engineering, and I don't want a lawyer to tell me that poking at the behavior constitutes reverse engineering). |
If we were to ever make a release of Scala 2 not building on JDK 8 it would target at least JDK 11, so I would be happy with that change. Making the compiler emit a fancy indy bootstrap method based on the runtime availability of |
Sorry for dropping the ball on this PR. I'm back and I'll add some tests that basically just test the different code paths (eg. spilling slots, strings that involve some of the magical tags). Those tests will only be actually useful if/when some CI uses
Whenever possible, I think we should prefer to use
Agreed! Even in this case though, I would expect an indy call to such a custom BM to only be emitted for |
ec7b7d0
to
e6eea41
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a test. It just tests string concatenation in general though, so on -target:8
it'll use the old StringBuilder
and on -target:9+
it'll use indy. I manually checked that both work (but not through partest
, since I can't get the stack configuration to work).
Thanks @lrytz for the help working around the stack overflow in the test! Do we need more tests, or is this enough? If everyone is satisfied, I'll squash the history. |
ping @lrytz (but if you've got too much else to do and you want to hand this over to me, that would be fine) |
JEP 280, released in JDK 9, proposes a new way to compile string concatenation using `invokedynamic` and `StringConcatFactory`. This new approach generates less bytecode, doesn't have to incur the overhead of `StringBuilder` allocations, and allows users to pick swap the concatenation technique at runtime. This changes the codegen when the target is at least Java 9 to leverage `invokedynamic` and `StringConcatFactory`. On Java 8, the old `StringBuilder` approach is still used.
48f11cb
to
b7dc31f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, squashed!
JEP 280, released in JDK 9, proposes a new way to compile string concatenation using
invokedynamic
andStringConcatFactory
. This new approach generates less bytecode, doesn't incur the overhead ofStringBuilder
allocations, and allows users to pick swap the concatenation technique at runtime.This changes the codegen when the target is at least Java 9 to leverage
invokedynamic
andStringConcatFactory
. On Java 8, the oldStringBuilder
approach is still used.