Skip to content

Commit bc49b8b

Browse files
committed
Cache the Symbol of the method name in dispatch nodes only when needed
1 parent 15bc037 commit bc49b8b

File tree

5 files changed

+21
-14
lines changed

5 files changed

+21
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ Compatibility:
7676
* Implemented `Enumerator::Chain`, `Enumerator#+`, and `Enumerable#chain` (#1859, #1858).
7777
* Implemented `Thread#backtrace_locations` and `Exception#backtrace_locations` (#1556).
7878
* Implemented `rb_module_new`, `rb_define_class_id`, `rb_define_module_id`, (#1876, @chrisseaton).
79+
* Cache the `Symbol` of method names in call nodes only when needed (#1872).
7980

8081
Performance:
8182

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public Object executeDispatch(
108108
public String toString() {
109109
return StringUtils.format(
110110
"CachedBoxedDispatchNode(:%s, %x, %s)",
111-
getCachedNameAsSymbol().toString(),
111+
getCachedName().toString(),
112112
expectedShape.hashCode(),
113113
method == null ? "null" : method.toString());
114114
}

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

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
public abstract class CachedDispatchNode extends DispatchNode {
3131

3232
private final Object cachedName;
33-
private final DynamicObject cachedNameAsSymbol;
3433

3534
@Child protected DispatchNode next;
3635
@Child private RopeNodes.BytesEqualNode ropeEqualsNode;
@@ -48,15 +47,8 @@ public CachedDispatchNode(
4847
(RubyGuards.isRubyString(cachedName));
4948
this.cachedName = cachedName;
5049

51-
if (RubyGuards.isRubySymbol(cachedName)) {
52-
cachedNameAsSymbol = (DynamicObject) cachedName;
53-
} else if (RubyGuards.isRubyString(cachedName)) {
54-
cachedNameAsSymbol = context.getSymbolTable().getSymbol(StringOperations.rope((DynamicObject) cachedName));
50+
if (RubyGuards.isRubyString(cachedName)) {
5551
ropeEqualsNode = RopeNodes.BytesEqualNode.create();
56-
} else if (cachedName instanceof String) {
57-
cachedNameAsSymbol = context.getSymbolTable().getSymbol((String) cachedName);
58-
} else {
59-
throw new UnsupportedOperationException();
6052
}
6153

6254
this.next = next;
@@ -97,8 +89,8 @@ protected final boolean guardName(Object methodName) {
9789
}
9890
}
9991

100-
protected DynamicObject getCachedNameAsSymbol() {
101-
return cachedNameAsSymbol;
92+
public Object getCachedName() {
93+
return cachedName;
10294
}
10395

10496
protected abstract void reassessSplittingInliningStrategy();

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import org.truffleruby.RubyContext;
1313
import org.truffleruby.core.array.ArrayUtils;
1414
import org.truffleruby.core.module.MethodLookupResult;
15+
import org.truffleruby.core.string.StringOperations;
16+
import org.truffleruby.language.RubyGuards;
1517
import org.truffleruby.language.methods.InternalMethod;
1618
import org.truffleruby.language.objects.MetaClassNode;
1719

@@ -34,6 +36,8 @@ public class CachedMethodMissingDispatchNode extends CachedDispatchNode {
3436
@Child private MetaClassNode metaClassNode;
3537
@Child private DirectCallNode callNode;
3638

39+
private final DynamicObject cachedNameAsSymbol;
40+
3741
public CachedMethodMissingDispatchNode(
3842
RubyContext context,
3943
Object cachedName,
@@ -50,6 +54,16 @@ public CachedMethodMissingDispatchNode(
5054
this.methodMissing = methodMissingLookup.getMethod();
5155
this.metaClassNode = MetaClassNode.create();
5256
this.callNode = Truffle.getRuntime().createDirectCallNode(methodMissing.getCallTarget());
57+
58+
if (RubyGuards.isRubySymbol(cachedName)) {
59+
cachedNameAsSymbol = (DynamicObject) cachedName;
60+
} else if (RubyGuards.isRubyString(cachedName)) {
61+
cachedNameAsSymbol = context.getSymbolTable().getSymbol(StringOperations.rope((DynamicObject) cachedName));
62+
} else if (cachedName instanceof String) {
63+
cachedNameAsSymbol = context.getSymbolTable().getSymbol((String) cachedName);
64+
} else {
65+
throw new UnsupportedOperationException();
66+
}
5367
}
5468

5569
@Override
@@ -114,7 +128,7 @@ public Object executeDispatch(
114128
switch (getDispatchAction()) {
115129
case CALL_METHOD:
116130
// When calling #method_missing we need to prepend the symbol
117-
final Object[] modifiedArgumentsObjects = ArrayUtils.unshift(argumentsObjects, getCachedNameAsSymbol());
131+
final Object[] modifiedArgumentsObjects = ArrayUtils.unshift(argumentsObjects, cachedNameAsSymbol);
118132

119133
return call(callNode, frame, methodMissing, receiverObject, blockObject, modifiedArgumentsObjects);
120134

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public Object executeDispatch(
107107
public String toString() {
108108
return StringUtils.format(
109109
"CachedBoxedDispatchNode(:%s, %s@%x, %s)",
110-
getCachedNameAsSymbol().toString(),
110+
getCachedName().toString(),
111111
expectedReceiver,
112112
expectedReceiver.hashCode(),
113113
method == null ? "null" : method.toString());

0 commit comments

Comments
 (0)