-
-
Notifications
You must be signed in to change notification settings - Fork 925
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
Truffle ropes #3605
Truffle ropes #3605
Conversation
I should note that all feedback is appreciated. But please be open to the answer "I didn't get to that yet." |
tagged_example "'abc' == 'abc'", true # seems to fail sometimes | ||
example "x = 'abc'; x == x", true | ||
example "x = 'abc'; x == x.dup", true |
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.
This is where the optimisation magic starts! This dup has been completely eliminated by the PE.
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.
How does it work? The rope is only shallow-copied? Then ropes are purely immutable?
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.
Yes, so dup
allocates a tiny new wrapper around the same rope node and then the ==
is just a reference comparison in the fast path, which of course all PEs really well.
Looks good to merge to me. |
for (Object string : strings) { | ||
assert RubyGuards.isRubyString(string); | ||
|
||
if (builder == null) { | ||
builder = dupNode.call(frame, string, "dup", null); | ||
} else { | ||
builder = concatNode.call(frame, builder, "concat", null, string); | ||
builder = appendNode.call(frame, builder, "append", null, string); |
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.
What is append
?
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.
A Rubinius method/primitive. It does much of the same without some of the extra checking that concat
needs to perform.
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.
But this means it's a public Ruby method. If it's not needed as such, it could be just a normal node.
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.
Rubinius calls this method. We had it shimmed previously (
jruby/truffle/src/main/ruby/core/shims.rb
Lines 68 to 72 in 18866ad
class String | |
def append(other) | |
self << other | |
end | |
end |
bootstrap/string.rb
. This was necessary because I moved a lot of String#concat
out to Rubinus, which uses String#append
to implement the method. Our old shim would have been cyclical.
I could indeed just call the method rather than go through the full dispatch here. I've been avoiding that generally in case we need to run through taint or frozen checks.
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 would go for the having an AppendNode and using executeStringAppend
here, it's much lighter weight.
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'm going to defer this until after the merge. It's no worse off than what we had before and this PR is already getting rather long.
int getCodeRange(DynamicObject object); | ||
void setCodeRange(DynamicObject object, int codeRange); | ||
Rope getRope(DynamicObject object); | ||
void setRope(DynamicObject object, Rope byteList); |
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.
Rope rope
here
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.
Good catch. Thanks.
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'll grep for similar issues.
5244909
to
fbebcc4
Compare
} | ||
} | ||
|
||
@CompilerDirectives.TruffleBoundary |
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.
Didn't we make a convention to use just @TruffleBoundary
?
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.
Probably. I'll fix them. It's just how IntelliJ autocompletes.
👍 nice work |
All Strings are now backed by ropes.
…difies the string being iterated.
…the source string by the iterator.
…n String#setbyte.
Doing a critical operation like this purely in Ruby caused performance regressions that we need to investigate.
…ead of CR_7BIT. While there shouldn't be a difference, it can lead Strings down wrong optimization paths. For now we'll match what MRI and JRuby do to make things simpler.
This should help cases where a byte buffer is pre-allocated using String#* (such as with StringIO). Also, rope links probably cost more than just making a flat array in this case.
8671dea
to
018855f
Compare
This is the initial work in changing the storage strategy for Strings in JRuby+Truffle from ByteList to Rope. There was a fair bit of rote translation work here. I haven't spend any appreciable amount of time on optimizing anything yet. And Symbols are still backed by ByteList.
I tried to make the code work well for both JRuby backends. For simplicity I did pull in some Truffle annotations, but it should be easy to divorce the two.
@chrisseaton @pitr-ch @eregon Please review at your leisure.
@enebo @headius @lopex This work may be of interest to you.