Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 9d63e45017b6
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 3b426d6f4049
Choose a head ref
  • 2 commits
  • 2 files changed
  • 2 contributors

Commits on Apr 21, 2016

  1. Copy the full SHA
    1691865 View commit details

Commits on Apr 22, 2016

  1. Merge pull request #3815 from pitr-ch/snippet

    [Truffle] accept expression and parameter names in SnippetNode#execute
    Petr Chalupa committed Apr 22, 2016
    Copy the full SHA
    3b426d6 View commit details
Showing with 52 additions and 34 deletions.
  1. +7 −6 truffle/src/main/java/org/jruby/truffle/core/array/ArrayNodes.java
  2. +45 −28 truffle/src/main/java/org/jruby/truffle/language/SnippetNode.java
Original file line number Diff line number Diff line change
@@ -3173,17 +3173,18 @@ public DynamicObject sortVeryShortObject(VirtualFrame frame, DynamicObject array
return createArray(getContext(), store, size);
}

public static final String SNIPPET = "sorted = dup; Rubinius.privately { sorted.isort_block!(0, right, block) }; sorted";
public static final String RIGHT = "right";
public static final String BLOCK = "block";

@Specialization(guards = { "!isNullArray(array)" })
public Object sortUsingRubinius(
VirtualFrame frame,
DynamicObject array,
DynamicObject block,
@Cached("new(SNIPPET, RIGHT, BLOCK)") SnippetNode snippet) {
return snippet.execute(frame, getSize(array), block);
@Cached("new()") SnippetNode snippet) {

return snippet.execute(
frame,
"sorted = dup; Rubinius.privately { sorted.isort_block!(0, right, block) }; sorted",
"right", getSize(array),
"block", block);
}

@Specialization(guards = { "!isNullArray(array)", "!isSmall(array)" })
73 changes: 45 additions & 28 deletions truffle/src/main/java/org/jruby/truffle/language/SnippetNode.java
Original file line number Diff line number Diff line change
@@ -27,36 +27,37 @@

public class SnippetNode extends RubyBaseNode {

private final String expression;
private final String[] parameters;

@CompilationFinal private String expression;
@CompilationFinal private String[] parameters;
@CompilationFinal private FrameDescriptor frameDescriptor;
@CompilationFinal private FrameSlot[] parameterFrameSlots;

@Child private DirectCallNode directCallNode;

public SnippetNode(String expression, String a, String b) {
this(expression, new String[]{a, b});
}

public SnippetNode(String expression, String... parameters) {
this.expression = expression;
this.parameters = parameters;
public SnippetNode() {
}

@ExplodeLoop
public Object execute(VirtualFrame frame, Object... arguments) {
public Object execute(VirtualFrame frame, String expression, Object... arguments) {
if (directCallNode == null) {
CompilerDirectives.transferToInterpreter();

this.expression = expression;
assert arguments.length % 2 == 0;
parameters = new String[arguments.length / 2];
for (int n = 0; n < parameters.length; n++) {
parameters[n] = (String) arguments[2 * n];
}

frameDescriptor = new FrameDescriptor(nil());
parameterFrameSlots = new FrameSlot[parameters.length];

for (int n = 0; n < parameters.length; n++) {
parameterFrameSlots[n] = frameDescriptor.findOrAddFrameSlot(parameters[n]);
}

final Source source = Source.fromText(StringOperations.createByteList(expression), "(snippet)");
final Source source = Source.fromText(
StringOperations.createByteList(this.expression),
"(snippet)");

final RubyRootNode rootNode = getContext().getCodeLoader().parse(
source,
@@ -67,15 +68,24 @@ public Object execute(VirtualFrame frame, Object... arguments) {
true,
this);

directCallNode = insert(Truffle.getRuntime().createDirectCallNode(Truffle.getRuntime().createCallTarget(rootNode)));
directCallNode = insert(Truffle.getRuntime().createDirectCallNode(
Truffle.getRuntime().createCallTarget(rootNode)));

if (directCallNode.isInlinable()) {
directCallNode.forceInlining();
}
}

final Object[] parentFrameArguments = RubyArguments.pack(
null,
if (arguments.length != parameters.length * 2) {
CompilerDirectives.transferToInterpreter();
throw new UnsupportedOperationException(
"number of arguments doesn't match number of parameters");
}

ensureConstantExpressionParameters(expression, arguments);

final Object[] callArguments = RubyArguments.pack(
parentFrame(frame, arguments),
null,
RubyArguments.getMethod(frame),
DeclarationContext.INSTANCE_EVAL,
@@ -84,21 +94,21 @@ public Object execute(VirtualFrame frame, Object... arguments) {
null,
new Object[]{});

final MaterializedFrame parentFrame = Truffle.getRuntime().createMaterializedFrame(
parentFrameArguments,
frameDescriptor);

if (arguments.length != parameterFrameSlots.length) {
CompilerDirectives.transferToInterpreter();
throw new UnsupportedOperationException("number of arguments doesn't match number of parameters");
}
return directCallNode.call(frame, callArguments);
}

@ExplodeLoop
private void ensureConstantExpressionParameters(String expression, Object[] arguments) {
assert this.expression == expression;
for (int n = 0; n < parameters.length; n++) {
parentFrame.setObject(parameterFrameSlots[n], arguments[n]);
assert parameters[n] == arguments[2 * n];
}
}

final Object[] callArguments = RubyArguments.pack(
parentFrame,
@ExplodeLoop
private MaterializedFrame parentFrame(VirtualFrame frame, Object[] arguments) {
final Object[] parentFrameArguments = RubyArguments.pack(
null,
null,
RubyArguments.getMethod(frame),
DeclarationContext.INSTANCE_EVAL,
@@ -107,7 +117,14 @@ public Object execute(VirtualFrame frame, Object... arguments) {
null,
new Object[]{});

return directCallNode.call(frame, callArguments);
final MaterializedFrame parentFrame = Truffle.getRuntime().createMaterializedFrame(
parentFrameArguments,
frameDescriptor);

for (int n = 0; n < parameters.length; n++) {
parentFrame.setObject(parameterFrameSlots[n], arguments[2 * n + 1]);
}
return parentFrame;
}

}