Skip to content

Commit e9da5a6

Browse files
committed
Add fine-grained profile for splat calls
* To avoid the extra control flow if the last argument is never or always a Hash.
1 parent b4a36e1 commit e9da5a6

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

src/main/java/org/truffleruby/language/dispatch/LiteralCallNode.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public abstract class LiteralCallNode extends RubyContextSourceNode {
2727
@Child private CopyHashAndSetRuby2KeywordsNode copyHashAndSetRuby2KeywordsNode;
2828

2929
protected final boolean isSplatted;
30-
@CompilationFinal private boolean notRuby2KeywordsHashProfile, emptyKeywordsProfile, notEmptyKeywordsProfile;
30+
@CompilationFinal private boolean lastArgIsNotHashProfile, notRuby2KeywordsHashProfile, emptyKeywordsProfile,
31+
notEmptyKeywordsProfile;
3132

3233
protected LiteralCallNode(boolean isSplatted, ArgumentsDescriptor descriptor) {
3334
this.isSplatted = isSplatted;
@@ -42,7 +43,17 @@ protected ArgumentsDescriptor getArgumentsDescriptorAndCheckRuby2KeywordsHash(Ob
4243
if (userArgsCount > 0) {
4344
final Object lastArgument = ArrayUtils.getLast(args);
4445
assert lastArgument != null;
45-
if (isRuby2KeywordsHash(lastArgument)) { // both branches profiled
46+
47+
if (!(lastArgument instanceof RubyHash)) {
48+
if (!lastArgIsNotHashProfile) {
49+
CompilerDirectives.transferToInterpreterAndInvalidate();
50+
lastArgIsNotHashProfile = true;
51+
}
52+
53+
return descriptor;
54+
}
55+
56+
if (((RubyHash) lastArgument).ruby2_keywords) { // both branches profiled
4657
if (copyHashAndSetRuby2KeywordsNode == null) {
4758
CompilerDirectives.transferToInterpreterAndInvalidate();
4859
copyHashAndSetRuby2KeywordsNode = insert(CopyHashAndSetRuby2KeywordsNode.create());
@@ -63,12 +74,10 @@ protected ArgumentsDescriptor getArgumentsDescriptorAndCheckRuby2KeywordsHash(Ob
6374
return descriptor;
6475
}
6576

66-
private boolean isRuby2KeywordsHash(Object lastArgument) {
67-
return lastArgument instanceof RubyHash && ((RubyHash) lastArgument).ruby2_keywords;
68-
}
69-
7077
// NOTE: args is either frame args or user args
7178
protected boolean emptyKeywordArguments(Object[] args) {
79+
assert isSplatted || descriptor instanceof KeywordArgumentsDescriptor;
80+
7281
if (((RubyHash) ArrayUtils.getLast(args)).empty()) {
7382
if (!emptyKeywordsProfile) {
7483
CompilerDirectives.transferToInterpreterAndInvalidate();

0 commit comments

Comments
 (0)