Skip to content

Commit

Permalink
[Truffle] Use a StringAppendPrimitiveNode directly in InterpolatedStr…
Browse files Browse the repository at this point in the history
…ingNode.

This cuts out some overhead of routing method calls when run in the interpreter.
nirvdrum committed Jan 28, 2016

Unverified

This user has not yet uploaded their public signing key.
1 parent d518253 commit a447e47
Showing 1 changed file with 8 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyGuards;
@@ -22,6 +23,8 @@
import org.jruby.truffle.nodes.objects.IsTaintedNodeGen;
import org.jruby.truffle.nodes.objects.TaintNode;
import org.jruby.truffle.nodes.objects.TaintNodeGen;
import org.jruby.truffle.nodes.rubinius.StringPrimitiveNodes;
import org.jruby.truffle.nodes.rubinius.StringPrimitiveNodesFactory;
import org.jruby.truffle.runtime.RubyContext;

/**
@@ -31,7 +34,7 @@ public final class InterpolatedStringNode extends RubyNode {

@Children private final ToSNode[] children;

@Child private CallDispatchHeadNode appendNode;
@Child private StringPrimitiveNodes.StringAppendPrimitiveNode appendNode;
@Child private CallDispatchHeadNode dupNode;
@Child private IsTaintedNode isTaintedNode;
@Child private TaintNode taintNode;
@@ -41,7 +44,7 @@ public final class InterpolatedStringNode extends RubyNode {
public InterpolatedStringNode(RubyContext context, SourceSection sourceSection, ToSNode[] children) {
super(context, sourceSection);
this.children = children;
appendNode = DispatchHeadNodeFactory.createMethodCall(context);
appendNode = StringPrimitiveNodesFactory.StringAppendPrimitiveNodeFactory.create(context, sourceSection, new RubyNode[] {});
dupNode = DispatchHeadNodeFactory.createMethodCall(context);
isTaintedNode = IsTaintedNodeGen.create(context, sourceSection, null);
taintNode = TaintNodeGen.create(context, sourceSection, null);
@@ -72,16 +75,16 @@ public Object execute(VirtualFrame frame) {
private Object concat(VirtualFrame frame, Object[] strings) {

This comment has been minimized.

Copy link
@eregon

eregon Feb 1, 2016

Member

This should be @ExplodeLoop

This comment has been minimized.

Copy link
@nirvdrum

nirvdrum Feb 1, 2016

Author Contributor

Isn't it a concern that the String parts can be arbitrarily wrong?

This comment has been minimized.

Copy link
@eregon

eregon Feb 2, 2016

Member

long?
The number of strings is the number of children is the number of #{} in the syntax so that's fairly bounded, right?

// TODO(CS): there is a lot of copying going on here - and I think this is sometimes inner loop stuff

Object builder = null;
DynamicObject builder = null;

// TODO (nirvdrum 11-Jan-16) Rewrite to avoid massively unbalanced trees.
for (Object string : strings) {
assert RubyGuards.isRubyString(string);

if (builder == null) {
builder = dupNode.call(frame, string, "dup", null);
builder = (DynamicObject) dupNode.call(frame, string, "dup", null);
} else {
builder = appendNode.call(frame, builder, "append", null, string);
builder = appendNode.executeStringAppend(frame, builder, (DynamicObject) string);
}
}

0 comments on commit a447e47

Please sign in to comment.