Skip to content

Commit ed38ea4

Browse files
committed
DefinedNode converted to DSL node so BooleanCastNode can be inlined
1 parent c67bf5f commit ed38ea4

File tree

1 file changed

+39
-22
lines changed

1 file changed

+39
-22
lines changed

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

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@
99
*/
1010
package org.truffleruby.language.dispatch;
1111

12+
import com.oracle.truffle.api.dsl.Cached;
13+
import com.oracle.truffle.api.dsl.Specialization;
1214
import com.oracle.truffle.api.profiles.CountingConditionProfile;
15+
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
16+
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
1317
import org.truffleruby.RubyContext;
1418
import org.truffleruby.RubyLanguage;
1519
import org.truffleruby.core.array.ArrayAppendOneNode;
1620
import org.truffleruby.core.array.AssignableNode;
1721
import org.truffleruby.core.array.RubyArray;
1822
import org.truffleruby.core.cast.BooleanCastNode;
19-
import org.truffleruby.core.cast.BooleanCastNodeGen;
2023
import org.truffleruby.core.inlined.LambdaToProcNode;
2124
import org.truffleruby.core.string.FrozenStrings;
2225
import org.truffleruby.core.symbol.RubySymbol;
@@ -37,8 +40,6 @@
3740
import com.oracle.truffle.api.CompilerDirectives;
3841
import com.oracle.truffle.api.frame.VirtualFrame;
3942
import com.oracle.truffle.api.nodes.ExplodeLoop;
40-
import com.oracle.truffle.api.profiles.BranchProfile;
41-
import com.oracle.truffle.api.profiles.ConditionProfile;
4243
import org.truffleruby.language.methods.LookupMethodOnSelfNode;
4344

4445
import java.util.Map;
@@ -230,10 +231,11 @@ private SplatToArgsNode createSplatToArgsNode() {
230231
public Object isDefined(VirtualFrame frame, RubyLanguage language, RubyContext context) {
231232
if (definedNode == null) {
232233
CompilerDirectives.transferToInterpreterAndInvalidate();
233-
definedNode = insert(new DefinedNode());
234+
definedNode = insert(
235+
RubyCallNodeFactory.DefinedNodeGen.create(methodName, receiver, arguments, dispatchConfig));
234236
}
235237

236-
return definedNode.isDefined(frame, context);
238+
return definedNode.execute(frame, context);
237239
}
238240

239241
public String getName() {
@@ -290,48 +292,65 @@ public RubyNode cloneUninitialized() {
290292
return copy.copyFlags(this);
291293
}
292294

293-
private class DefinedNode extends RubyBaseNode {
295+
abstract static class DefinedNode extends RubyBaseNode {
294296

295-
private final RubySymbol methodNameSymbol = getSymbol(methodName);
297+
private final RubySymbol methodNameSymbol;
298+
private final String methodName;
299+
private final DispatchConfiguration dispatchConfig;
296300

301+
@Child private RubyNode receiver;
302+
@Children private final RubyNode[] arguments;
297303
@Child private DispatchNode respondToMissing = DispatchNode.create(PRIVATE_RETURN_MISSING);
298-
@Child private BooleanCastNode respondToMissingCast = BooleanCastNodeGen.create(null);
299304

305+
public DefinedNode(
306+
String methodName,
307+
RubyNode receiver,
308+
RubyNode[] arguments,
309+
DispatchConfiguration dispatchConfig) {
310+
this.methodName = methodName;
311+
this.methodNameSymbol = getSymbol(methodName);
312+
this.receiver = receiver;
313+
this.arguments = arguments;
314+
this.dispatchConfig = dispatchConfig;
300315

301-
@Child private LookupMethodOnSelfNode lookupMethodNode = LookupMethodOnSelfNode.create();
316+
}
302317

303-
private final ConditionProfile receiverDefinedProfile = ConditionProfile.create();
304-
private final BranchProfile argumentNotDefinedProfile = BranchProfile.create();
305-
private final BranchProfile allArgumentsDefinedProfile = BranchProfile.create();
306-
private final BranchProfile receiverExceptionProfile = BranchProfile.create();
307-
private final ConditionProfile methodNotFoundProfile = ConditionProfile.create();
318+
public abstract Object execute(VirtualFrame frame, RubyContext context);
308319

320+
@Specialization
309321
@ExplodeLoop
310-
public Object isDefined(VirtualFrame frame, RubyContext context) {
311-
if (receiverDefinedProfile.profile(receiver.isDefined(frame, getLanguage(), context) == nil)) {
322+
protected Object isDefined(VirtualFrame frame, RubyContext context,
323+
@Cached LookupMethodOnSelfNode lookupMethodNode,
324+
@Cached BooleanCastNode respondToMissingCast,
325+
@Cached InlinedConditionProfile receiverDefinedProfile,
326+
@Cached InlinedBranchProfile allArgumentsDefinedProfile,
327+
@Cached InlinedBranchProfile receiverExceptionProfile,
328+
@Cached InlinedConditionProfile methodNotFoundProfile,
329+
@Cached InlinedBranchProfile argumentNotDefinedProfile) {
330+
if (receiverDefinedProfile.profile(this, receiver.isDefined(frame, getLanguage(), context) == nil)) {
312331
return nil;
313332
}
314333

315334
for (RubyNode argument : arguments) {
316335
if (argument.isDefined(frame, getLanguage(), context) == nil) {
317-
argumentNotDefinedProfile.enter();
336+
argumentNotDefinedProfile.enter(this);
318337
return nil;
319338
}
320339
}
321340

322-
allArgumentsDefinedProfile.enter();
341+
allArgumentsDefinedProfile.enter(this);
323342

324343
final Object receiverObject;
325344
try {
326345
receiverObject = receiver.execute(frame);
327346
} catch (RaiseException e) {
328-
receiverExceptionProfile.enter();
347+
receiverExceptionProfile.enter(this);
329348
return nil;
330349
}
331350

332351
final InternalMethod method = lookupMethodNode.execute(frame, receiverObject, methodName, dispatchConfig);
333352

334-
if (methodNotFoundProfile.profile(method == null)) {
353+
if (methodNotFoundProfile.profile(this, method == null)) {
335354
final Object r = respondToMissing.call(receiverObject, "respond_to_missing?", methodNameSymbol, false);
336355

337356
if (r != DispatchNode.MISSING && !respondToMissingCast.execute(r)) {
@@ -341,7 +360,5 @@ public Object isDefined(VirtualFrame frame, RubyContext context) {
341360

342361
return FrozenStrings.METHOD;
343362
}
344-
345363
}
346-
347364
}

0 commit comments

Comments
 (0)