-
Notifications
You must be signed in to change notification settings - Fork 915
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Truffle] Added a new GetRubyEncodingNode to have a fast path for con…
…verting jcodings encodings to Ruby encodings.
- Loading branch information
Showing
2 changed files
with
42 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,6 +71,41 @@ protected static boolean isAsciiCompatible(DynamicObject encoding) { | |
} | ||
} | ||
|
||
@NodeChild("encoding") | ||
public abstract static class GetRubyEncodingNode extends RubyNode { | ||
|
||
public static GetRubyEncodingNode create() { | ||
return EncodingNodesFactory.GetRubyEncodingNodeGen.create(null); | ||
} | ||
|
||
public abstract DynamicObject executeGetRubyEncoding(Encoding encoding); | ||
|
||
@Specialization(guards = "isSameEncoding(encoding, cachedRubyEncoding)", | ||
limit = "getCacheLimit()") | ||
protected DynamicObject getRubyEncodingCached(Encoding encoding, | ||
@Cached("getRubyEncodingUncached(encoding)") DynamicObject cachedRubyEncoding) { | ||
return cachedRubyEncoding; | ||
} | ||
|
||
@Specialization(contains = "getRubyEncodingCached") | ||
protected DynamicObject getRubyEncodingUncached(Encoding encoding) { | ||
if (encoding == null) { | ||
throw new UnsupportedOperationException("cannot convert null Java encoding to a Ruby encoding"); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
|
||
return getContext().getEncodingManager().getRubyEncoding(encoding); | ||
} | ||
|
||
protected boolean isSameEncoding(Encoding encoding, DynamicObject rubyEncoding) { | ||
return encoding == Layouts.ENCODING.getEncoding(rubyEncoding); | ||
} | ||
This comment has been minimized.
Sorry, something went wrong.
eregon
Member
|
||
|
||
protected int getCacheLimit() { | ||
return getContext().getOptions().ENCODING_LOADED_CLASSES_CACHE; | ||
} | ||
|
||
} | ||
|
||
@NodeChildren({ @NodeChild("first"), @NodeChild("second") }) | ||
public static abstract class NegotiateCompatibleEncodingNode extends RubyNode { | ||
|
||
|
@@ -300,10 +335,12 @@ protected int getCacheLimit() { | |
@CoreMethod(names = "compatible?", onSingleton = true, required = 2) | ||
public abstract static class CompatibleQueryNode extends CoreMethodArrayArgumentsNode { | ||
|
||
@Child private GetRubyEncodingNode getRubyEncodingNode; | ||
@Child private NegotiateCompatibleEncodingNode negotiateCompatibleEncodingNode; | ||
|
||
public CompatibleQueryNode(SourceIndexLength sourceSection) { | ||
super(sourceSection); | ||
getRubyEncodingNode = EncodingNodesFactory.GetRubyEncodingNodeGen.create(); | ||
negotiateCompatibleEncodingNode = NegotiateCompatibleEncodingNode.create(); | ||
} | ||
|
||
|
@@ -318,7 +355,7 @@ protected DynamicObject isCompatible(Object first, Object second, | |
return nil(); | ||
} | ||
|
||
return getContext().getEncodingManager().getRubyEncoding(negotiatedEncoding); | ||
return getRubyEncodingNode.executeGetRubyEncoding(negotiatedEncoding); | ||
} | ||
|
||
protected int getCacheLimit() { | ||
|
This should either have a BranchProfile or the method have a TruffleBoundary or become an
assert
, otherwise all the exception throwing code will compile (that's also the reason ArrayList.get() doesn't compile well with Truffle, it would need a profile for out-of-bounds).