Skip to content

Commit

Permalink
Showing 45 changed files with 286 additions and 300 deletions.
13 changes: 9 additions & 4 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -378,7 +378,7 @@ private Operand buildOperand(Node node) throws NotCompilableException {
case ANDNODE: return buildAnd((AndNode) node);
case ARGSCATNODE: return buildArgsCat((ArgsCatNode) node);
case ARGSPUSHNODE: return buildArgsPush((ArgsPushNode) node);
case ARRAYNODE: return buildArray((ArrayNode) node);
case ARRAYNODE: return buildArray((ArrayNode) node, false);
case ATTRASSIGNNODE: return buildAttrAssign((AttrAssignNode) node);
case BACKREFNODE: return buildBackref((BackRefNode) node);
case BEGINNODE: return buildBegin((BeginNode) node);
@@ -813,15 +813,16 @@ public Operand buildAnd(final AndNode andNode) {
}
}

public Operand buildArray(ArrayNode node) {
public Operand buildArray(ArrayNode node, boolean operandOnly) {
Node[] nodes = node.children();
Operand[] elts = new Operand[nodes.length];
boolean containsAssignments = node.containsVariableAssignment();
for (int i = 0; i < nodes.length; i++) {
elts[i] = buildWithOrder(nodes[i], containsAssignments);
}

return copyAndReturnValue(new Array(elts));
Operand array = new Array(elts);
return operandOnly ? array : copyAndReturnValue(array);
}

public Operand buildArgsCat(final ArgsCatNode argsCatNode) {
@@ -3464,7 +3465,11 @@ public Operand buildYield(YieldNode node) {
}

Variable ret = createTemporaryVariable();
addInstr(new YieldInstr(ret, scope.getYieldClosureVariable(), build(argNode), unwrap));
if (argNode instanceof ArrayNode && unwrap) {
addInstr(new YieldInstr(ret, scope.getYieldClosureVariable(), buildArray((ArrayNode)argNode, true), unwrap));
} else {
addInstr(new YieldInstr(ret, scope.getYieldClosureVariable(), build(argNode), unwrap));
}
return ret;
}

2 changes: 0 additions & 2 deletions core/src/main/java/org/jruby/ir/IRClassBody.java
Original file line number Diff line number Diff line change
@@ -2,8 +2,6 @@

import org.jruby.parser.StaticScope;

/**
*/
public class IRClassBody extends IRModuleBody {
public IRClassBody(IRManager manager, IRScope lexicalParent, String name, int lineNumber, StaticScope scope) {
super(manager, lexicalParent, name, lineNumber, scope);
4 changes: 0 additions & 4 deletions core/src/main/java/org/jruby/ir/IRMethod.java
Original file line number Diff line number Diff line change
@@ -3,13 +3,9 @@
import org.jruby.ast.DefNode;
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.ir.operands.LocalVariable;
import org.jruby.ir.persistence.IRDumper;
import org.jruby.ir.representations.BasicBlock;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.ArgumentDescriptor;
import org.jruby.util.cli.Options;

import java.io.ByteArrayOutputStream;

public class IRMethod extends IRScope {
public final boolean isInstanceMethod;
5 changes: 0 additions & 5 deletions core/src/main/java/org/jruby/ir/IRScope.java
Original file line number Diff line number Diff line change
@@ -11,21 +11,16 @@
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.ir.operands.*;
import org.jruby.ir.operands.Float;
import org.jruby.ir.operands.Boolean;
import org.jruby.ir.passes.*;
import org.jruby.ir.persistence.IRDumper;
import org.jruby.ir.representations.BasicBlock;
import org.jruby.ir.representations.CFG;
import org.jruby.ir.transformations.inlining.CFGInliner;
import org.jruby.ir.transformations.inlining.SimpleCloneInfo;
import org.jruby.parser.StaticScope;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import org.jruby.util.cli.Options;
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;

12 changes: 10 additions & 2 deletions core/src/main/java/org/jruby/ir/instructions/YieldInstr.java
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
import org.jruby.ir.IRVisitor;
import org.jruby.ir.Interp;
import org.jruby.ir.Operation;
import org.jruby.ir.operands.Array;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.operands.UndefinedValue;
import org.jruby.ir.operands.Variable;
@@ -72,8 +73,15 @@ public Object interpret(ThreadContext context, StaticScope currScope, DynamicSco
if (getYieldArg() == UndefinedValue.UNDEFINED) {
return IRRuntimeHelpers.yieldSpecific(context, blk);
} else {
IRubyObject yieldVal = (IRubyObject) getYieldArg().retrieve(context, self, currScope, currDynScope, temp);
return IRRuntimeHelpers.yield(context, blk, yieldVal, unwrapArray);
Operand yieldOp = getYieldArg();
if (unwrapArray && yieldOp instanceof Array && ((Array)yieldOp).size() > 1) {
// Special case this path!
// Don't build a RubyArray.
return blk.yieldValues(context, ((Array)yieldOp).retrieveArrayElts(context, self, currScope, currDynScope, temp));
} else {
IRubyObject yieldVal = (IRubyObject) yieldOp.retrieve(context, self, currScope, currDynScope, temp);
return IRRuntimeHelpers.yield(context, blk, yieldVal, unwrapArray);
}
}
}

18 changes: 14 additions & 4 deletions core/src/main/java/org/jruby/ir/operands/Array.java
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@@ -17,7 +19,7 @@
// NOTE: This operand is only used in the initial stages of optimization.
// Further down the line, this array operand could get converted to calls
// that actually build a Ruby object
public class Array extends Operand {
public class Array extends Operand implements Iterable<Operand> {
private final Operand[] elts;

// SSS FIXME: Do we create a special-case for zero-length arrays?
@@ -107,15 +109,18 @@ public static Array decode(IRReaderDecoder d) {
return new Array(d.decodeOperandArray());
}

@Override
public Object retrieve(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) {
public IRubyObject[] retrieveArrayElts(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) {
IRubyObject[] elements = new IRubyObject[elts.length];

for (int i = 0; i < elements.length; i++) {
elements[i] = (IRubyObject) elts[i].retrieve(context, self, currScope, currDynScope, temp);
}
return elements;
}

return context.runtime.newArray(elements);
@Override
public Object retrieve(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) {
return context.runtime.newArray(retrieveArrayElts(context, self, currScope, currDynScope, temp));
}

@Override
@@ -126,4 +131,9 @@ public void visit(IRVisitor visitor) {
public Operand[] getElts() {
return elts;
}

@Override
public Iterator<Operand> iterator() {
return Arrays.asList(elts).iterator();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.jruby.ir.passes;

import org.jruby.ir.*;
import org.jruby.ir.dataflow.analyses.StoreLocalVarPlacementProblem;
import org.jruby.ir.instructions.*;
import org.jruby.runtime.Signature;
import org.jruby.ir.operands.ImmutableLiteral;
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.jruby.ir.passes;

import org.jruby.ir.IRClosure;
import org.jruby.ir.IRFlags;
import org.jruby.ir.IRScope;
import org.jruby.ir.dataflow.analyses.LoadLocalVarPlacementProblem;
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.jruby.ir.passes;

import org.jruby.ir.IRClosure;
import org.jruby.ir.IRScope;
import org.jruby.ir.dataflow.analyses.LiveVariablesProblem;

Original file line number Diff line number Diff line change
@@ -8,12 +8,10 @@
import java.util.Map;
import org.jruby.ir.IRScope;
import org.jruby.ir.instructions.*;
import org.jruby.ir.operands.ImmutableLiteral;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.operands.TemporaryVariable;
import org.jruby.ir.operands.Variable;


/**
* Takes multiple single def-use temporary variables and reduces them to share the same temp variable.
* This ends up reducing the amount of allocation and most likely helps hotspot warm up in some way quicker.
Original file line number Diff line number Diff line change
@@ -14,8 +14,6 @@
import org.jruby.internal.runtime.methods.InterpretedIRMethod;
import org.jruby.internal.runtime.methods.MixedModeIRMethod;
import org.jruby.internal.runtime.methods.UndefinedMethod;
import org.jruby.ir.IRFlags;
import org.jruby.ir.IRManager;
import org.jruby.ir.IRMetaClassBody;
import org.jruby.ir.IRScope;
import org.jruby.ir.IRScopeType;
@@ -1645,8 +1643,8 @@ public static IRubyObject[] prepareFixedBlockArgs(ThreadContext context, Block b
}

boolean isProcCall = context.getCurrentBlockType() == Block.Type.PROC;
org.jruby.runtime.Signature sig = block.getBody().getSignature();
if (block.type == Block.Type.LAMBDA) {
org.jruby.runtime.Signature sig = block.getBody().getSignature();
// We don't need to check for the 1 required arg case here
// since that goes down the prepareSingleBlockArgs route
if (!isProcCall && sig.arityValue() != 1) {
Original file line number Diff line number Diff line change
@@ -583,6 +583,13 @@ public org.objectweb.asm.Label newLabel() {
*/
public abstract void yieldSpecific();

/**
* Yield a number of flat arguments to a block.
*
* Stack required: context, block
*/
public abstract void yieldValues(int arity);

/**
* Prepare a block for a subsequent call.
*
10 changes: 7 additions & 3 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter6.java
Original file line number Diff line number Diff line change
@@ -818,13 +818,17 @@ public void setGlobalVariable(String name) {

@Override
public void yield(boolean unwrap) {
adapter.ldc(unwrap);
invokeIRHelper("yield", sig(IRubyObject.class, ThreadContext.class, Block.class, IRubyObject.class, boolean.class));
adapter.invokedynamic("yield", sig(JVM.OBJECT, params(ThreadContext.class, Block.class, JVM.OBJECT)), YieldSite.BOOTSTRAP, unwrap ? 1 : 0);
}

@Override
public void yieldSpecific() {
invokeIRHelper("yieldSpecific", sig(IRubyObject.class, ThreadContext.class, Block.class));
adapter.invokedynamic("yieldSpecific", sig(JVM.OBJECT, params(ThreadContext.class, Block.class)), YieldSite.BOOTSTRAP, 0);
}

@Override
public void yieldValues(int arity) {
adapter.invokedynamic("yieldValues", sig(JVM.OBJECT, params(ThreadContext.class, Block.class, JVM.OBJECT, arity)), YieldSite.BOOTSTRAP, 0);
}

@Override
10 changes: 0 additions & 10 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter7.java
Original file line number Diff line number Diff line change
@@ -303,16 +303,6 @@ public void checkpoint() {
Bootstrap.checkpointHandle());
}

@Override
public void yield(boolean unwrap) {
adapter.invokedynamic("yield", sig(JVM.OBJECT, params(ThreadContext.class, Block.class, JVM.OBJECT)), YieldSite.BOOTSTRAP, unwrap ? 1 : 0);
}

@Override
public void yieldSpecific() {
adapter.invokedynamic("yieldSpecific", sig(JVM.OBJECT, params(ThreadContext.class, Block.class)), YieldSite.BOOTSTRAP, 0);
}

@Override
public void prepareBlock(Handle handle, org.jruby.runtime.Signature signature, String className) {
Handle scopeHandle = new Handle(Opcodes.H_GETSTATIC, getClassData().clsName, handle.getName() + "_IRScope", ci(IRScope.class));
13 changes: 11 additions & 2 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
@@ -2017,8 +2017,17 @@ public void YieldInstr(YieldInstr yieldinstr) {
if (yieldinstr.getYieldArg() == UndefinedValue.UNDEFINED) {
jvmMethod().yieldSpecific();
} else {
visit(yieldinstr.getYieldArg());
jvmMethod().yield(yieldinstr.isUnwrapArray());
Operand yieldOp = yieldinstr.getYieldArg();
if (yieldinstr.isUnwrapArray() && yieldOp instanceof Array && ((Array) yieldOp).size() > 1) {
Array yieldValues = (Array) yieldOp;
for (Operand yieldValue : yieldValues) {
visit(yieldValue);
}
jvmMethod().yieldValues(yieldValues.size());
} else {
visit(yieldinstr.getYieldArg());
jvmMethod().yield(yieldinstr.isUnwrapArray());
}
}

jvmStoreLocal(yieldinstr.getResult());
104 changes: 69 additions & 35 deletions core/src/main/java/org/jruby/ir/targets/YieldSite.java
Original file line number Diff line number Diff line change
@@ -3,7 +3,9 @@
import com.headius.invokebinder.Binder;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.runtime.Block;
import org.jruby.runtime.BlockBody;
import org.jruby.runtime.CompiledIRBlockBody;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.objectweb.asm.Handle;
@@ -35,52 +37,84 @@ public YieldSite(MethodType type, boolean unwrap) {
public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, int unwrap) throws Throwable {
YieldSite site = new YieldSite(type, unwrap == 1 ? true : false);

MethodHandle handle = Binder.from(type)
.prepend(YieldSite.class, site)
.invokeVirtual(lookup, name);
MethodHandle handle;
switch (name) {
case "yield":
case "yieldSpecific":
handle = Binder.from(type)
.prepend(YieldSite.class, site)
.invokeVirtual(lookup, name);
break;
case "yieldValues":
handle = Binder.from(type)
.collect(2, IRubyObject[].class)
.prepend(YieldSite.class, site)
.invokeVirtual(lookup, name);
break;
default:
throw new RuntimeException("invalid yield type: " + name);
}

site.setTarget(handle);

return site;
}

public IRubyObject yield(ThreadContext context, Block block, IRubyObject arg) throws Throwable {
if (block.getBody() instanceof CompiledIRBlockBody) {
CompiledIRBlockBody compiledBody = (CompiledIRBlockBody) block.getBody();

MethodHandle target = unwrap ? compiledBody.getNormalYieldUnwrapHandle() : compiledBody.getNormalYieldHandle();
MethodHandle fallback = getTarget();
MethodHandle test = compiledBody.getTestBlockBody();

MethodHandle guard = MethodHandles.guardWithTest(test, target, fallback);

setTarget(guard);

return (IRubyObject)target.invokeExact(context, block, arg);
}

context.setCurrentBlockType(Block.Type.NORMAL);

// BlockBody body = block.getBody();
// MethodHandle target;
//
// if (block.getBody() instanceof CompiledIRBlockBody) {
// CompiledIRBlockBody compiledBody = (CompiledIRBlockBody) block.getBody();
//
// target = unwrap ? compiledBody.getNormalYieldUnwrapHandle() : compiledBody.getNormalYieldHandle();
// } else {
// target = Binder.from(type())
// .append(unwrap)
// .invokeStaticQuiet(MethodHandles.lookup(), IRRuntimeHelpers.class, "yield");
// }
//
// MethodHandle fallback = getTarget();
// MethodHandle test = body.getTestBlockBody();
//
// MethodHandle guard = MethodHandles.guardWithTest(test, target, fallback);
//
// setTarget(guard);
//
// return (IRubyObject)target.invokeExact(context, block, arg);

// Fully MH-based dispatch for these still seems slower than megamorphic path
return IRRuntimeHelpers.yield(context, block, arg, unwrap);
}

public IRubyObject yieldSpecific(ThreadContext context, Block block) throws Throwable {
if (block.getBody() instanceof CompiledIRBlockBody) {
CompiledIRBlockBody compiledBody = (CompiledIRBlockBody) block.getBody();

MethodHandle target = compiledBody.getNormalYieldSpecificHandle();
MethodHandle fallback = getTarget();
MethodHandle test = compiledBody.getTestBlockBody();

MethodHandle guard = MethodHandles.guardWithTest(test, target, fallback);

setTarget(guard);

return (IRubyObject)target.invokeExact(context, block);
}

context.setCurrentBlockType(Block.Type.NORMAL);

// BlockBody body = block.getBody();
// MethodHandle target;
//
// if (block.getBody() instanceof CompiledIRBlockBody) {
// CompiledIRBlockBody compiledBody = (CompiledIRBlockBody) block.getBody();
//
// target = compiledBody.getNormalYieldSpecificHandle();
// } else {
// target = Binder.from(type())
// .permute(0, 1)
// .invokeVirtualQuiet(MethodHandles.lookup(), "yieldSpecific");
// }
//
// MethodHandle fallback = getTarget();
// MethodHandle test = body.getTestBlockBody();
//
// MethodHandle guard = MethodHandles.guardWithTest(test, target, fallback);
//
// setTarget(guard);
//
// return (IRubyObject)target.invokeExact(context, block);

// Fully MH-based dispatch for these still seems slower than megamorphic path
return IRRuntimeHelpers.yieldSpecific(context, block);
}

public IRubyObject yieldValues(ThreadContext context, Block block, IRubyObject[] args) {
return block.yieldValues(context, args);
}
}
7 changes: 5 additions & 2 deletions core/src/main/java/org/jruby/runtime/Block.java
Original file line number Diff line number Diff line change
@@ -174,11 +174,14 @@ public IRubyObject yieldArray(ThreadContext context, IRubyObject value, IRubyObj
// SSS FIXME: Later on, we can move this code into IR insructions or
// introduce a specialized entry-point when we know that this block has
// explicit call protocol IR instructions.
IRubyObject[] args;
args = IRRuntimeHelpers.singleBlockArgToArray(value);
IRubyObject[] args = IRRuntimeHelpers.singleBlockArgToArray(value);
return body.yield(context, this, args, self);
}

public IRubyObject yieldValues(ThreadContext context, IRubyObject[] args) {
return body.yield(context, this, args, null);
}

public Block cloneBlock() {
Block newBlock = new Block(body, binding);

17 changes: 17 additions & 0 deletions core/src/main/java/org/jruby/runtime/BlockBody.java
Original file line number Diff line number Diff line change
@@ -33,13 +33,17 @@

package org.jruby.runtime;

import com.headius.invokebinder.Binder;
import org.jruby.EvalType;
import org.jruby.RubyArray;
import org.jruby.RubyProc;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.builtin.IRubyObject;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;

/**
* The executable body portion of a closure.
*/
@@ -48,6 +52,7 @@ public abstract class BlockBody {
public static final String[] EMPTY_PARAMETER_LIST = org.jruby.util.StringSupport.EMPTY_STRING_ARRAY;

protected final Signature signature;
protected volatile MethodHandle testBlockBody;

public BlockBody(Signature signature) {
this.signature = signature;
@@ -64,6 +69,18 @@ public boolean canCallDirect() {
return false;
}

public MethodHandle getTestBlockBody() {
if (testBlockBody != null) return testBlockBody;

return testBlockBody = Binder.from(boolean.class, ThreadContext.class, Block.class).drop(0).append(this).invoke(TEST_BLOCK_BODY);
}

private static final MethodHandle TEST_BLOCK_BODY = Binder.from(boolean.class, Block.class, BlockBody.class).invokeStaticQuiet(MethodHandles.lookup(), BlockBody.class, "testBlockBody");

public static boolean testBlockBody(Block block, BlockBody body) {
return block.getBody() == body;
}

protected IRubyObject callDirect(ThreadContext context, Block block, IRubyObject[] args, Block blockArg) {
throw new RuntimeException("callDirect not implemented in base class. We should never get here.");
}
52 changes: 34 additions & 18 deletions core/src/main/java/org/jruby/runtime/CompiledIRBlockBody.java
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
import com.headius.invokebinder.Binder;
import org.jruby.ir.IRScope;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.builtin.IRubyObject;

import java.lang.invoke.MethodHandle;
@@ -13,7 +14,8 @@ public class CompiledIRBlockBody extends IRBlockBody {
protected volatile MethodHandle normalYieldSpecificHandle;
protected volatile MethodHandle normalYieldHandle;
protected volatile MethodHandle normalYieldUnwrapHandle;
protected volatile MethodHandle testBlockBody;
protected volatile MethodHandle yieldTwoValuesHandle;
protected volatile MethodHandle yieldThreeValuesHandle;

public CompiledIRBlockBody(MethodHandle handle, IRScope closure, long encodedSignature) {
super(closure, Signature.decode(encodedSignature));
@@ -23,12 +25,6 @@ public CompiledIRBlockBody(MethodHandle handle, IRScope closure, long encodedSig
closure.getStaticScope().determineModule();
}

private static final MethodHandle TEST_BLOCK_BODY = Binder.from(boolean.class, Block.class, IRBlockBody.class).invokeStaticQuiet(MethodHandles.lookup(), CompiledIRBlockBody.class, "testBlockBody");

public static boolean testBlockBody(Block block, IRBlockBody body) {
return block.getBody() == body;
}

private static final MethodHandle FOLD_METHOD1 = Binder.from(String.class, ThreadContext.class, Block.class).invokeStaticQuiet(MethodHandles.lookup(), CompiledIRBlockBody.class, "foldMethod");
private static String foldMethod(ThreadContext context, Block block) {
return block.getBinding().getMethod();
@@ -78,10 +74,8 @@ public MethodHandle getNormalYieldSpecificHandle() {
.foldVoid(SET_NORMAL)
.fold(FOLD_METHOD1)
.fold(FOLD_TYPE1)
.append(getStaticScope())
.append(IRubyObject.class, null)
.append(IRubyObject[].class, null)
.append(Block.class, Block.NULL_BLOCK)
.append(new Class[] {StaticScope.class, IRubyObject.class, IRubyObject[].class, Block.class},
getStaticScope(), null, null, Block.NULL_BLOCK)
.permute(2, 3, 4, 5, 6, 7, 1, 0)
.invoke(handle);
}
@@ -94,8 +88,7 @@ public MethodHandle getNormalYieldHandle() {
.fold(FOLD_METHOD2)
.fold(FOLD_TYPE2)
.filter(4, WRAP_VALUE)
.insert(4, getStaticScope())
.insert(5, IRubyObject.class, null)
.insert(4, new Class[]{StaticScope.class, IRubyObject.class}, getStaticScope(), null)
.append(Block.class, Block.NULL_BLOCK)
.permute(2, 3, 4, 5, 6, 7, 1, 0)
.invoke(handle);
@@ -109,17 +102,40 @@ public MethodHandle getNormalYieldUnwrapHandle() {
.fold(FOLD_METHOD2)
.fold(FOLD_TYPE2)
.filter(4, VALUE_TO_ARRAY)
.insert(4, getStaticScope())
.insert(5, IRubyObject.class, null)
.insert(4, new Class[] {StaticScope.class, IRubyObject.class}, getStaticScope(), null)
.append(Block.class, Block.NULL_BLOCK)
.permute(2, 3, 4, 5, 6, 7, 1, 0)
.invoke(handle);
}

public MethodHandle getTestBlockBody() {
if (testBlockBody != null) return testBlockBody;
public MethodHandle getYieldTwoValuesHandle() {
if (yieldTwoValuesHandle != null) return yieldTwoValuesHandle;

return testBlockBody = Binder.from(boolean.class, ThreadContext.class, Block.class).drop(0).append(this).invoke(TEST_BLOCK_BODY);
return yieldTwoValuesHandle = Binder.from(IRubyObject.class, ThreadContext.class, Block.class, IRubyObject.class, IRubyObject.class)
.foldVoid(SET_NORMAL)
.fold(FOLD_METHOD1)
.fold(FOLD_TYPE1)
.collect(5, IRubyObject[].class)
.insert(5, new Class[] {StaticScope.class, IRubyObject.class},
getStaticScope(), null)
.append(new Class[] {Block.class}, Block.NULL_BLOCK)
.permute(2, 3, 4, 5, 6, 7, 1, 0)
.invoke(handle);
}

public MethodHandle getYieldThreeValuesHandle() {
if (yieldThreeValuesHandle != null) return yieldThreeValuesHandle;

return yieldThreeValuesHandle = Binder.from(IRubyObject.class, ThreadContext.class, Block.class, IRubyObject.class, IRubyObject.class, IRubyObject.class)
.foldVoid(SET_NORMAL)
.fold(FOLD_METHOD1)
.fold(FOLD_TYPE1)
.collect(5, IRubyObject[].class)
.insert(5, new Class[] {StaticScope.class, IRubyObject.class},
getStaticScope(), null)
.append(new Class[] {Block.class}, Block.NULL_BLOCK)
.permute(2, 3, 4, 5, 6, 7, 1, 0)
.invoke(handle);
}

@Override
5 changes: 5 additions & 0 deletions test/truffle/integration/backtraces/pack.backtrace
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/pack.rb:13:in `to_str'
/pack.rb:18:in `pack'
/pack.rb:18:in `block in <main>'
/backtraces.rb:17:in `check'
/pack.rb:17:in `<main>'
19 changes: 19 additions & 0 deletions test/truffle/integration/backtraces/pack.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
# Eclipse Public License version 1.0
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

require_relative 'backtraces'

class Test
def to_str
raise 'message'
end
end

check('pack.backtrace') do
[Test.new].pack('a')
end
35 changes: 0 additions & 35 deletions truffle/src/main/java/org/jruby/truffle/PolyglotEngineMain.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -20,12 +20,13 @@
import org.jruby.truffle.core.format.runtime.PackResult;
import org.jruby.truffle.RubyLanguage;
import org.jruby.truffle.core.rope.CodeRange;
import org.jruby.truffle.language.InternalRootNode;
import org.jruby.util.StringSupport;

/**
* The node at the root of a pack expression.
*/
public class PackRootNode extends RootNode {
public class PackRootNode extends RootNode implements InternalRootNode {

private final String description;
private final PackEncoding encoding;
Original file line number Diff line number Diff line change
@@ -21,8 +21,9 @@
import org.jruby.truffle.RubyLanguage;
import org.jruby.truffle.core.array.ArrayUtils;
import org.jruby.truffle.core.rope.CodeRange;
import org.jruby.truffle.language.InternalRootNode;

public class UnpackRootNode extends RootNode {
public class UnpackRootNode extends RootNode implements InternalRootNode {

private final String description;
private final PackEncoding encoding;
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.util.ArgumentDescriptorUtils;
import org.jruby.truffle.language.arguments.ArgumentDescriptorUtils;

@CoreClass(name = "Method")
public abstract class MethodNodes {
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@
import org.jruby.truffle.language.objects.MetaClassNodeGen;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.util.ArgumentDescriptorUtils;
import org.jruby.truffle.language.arguments.ArgumentDescriptorUtils;

@CoreClass(name = "UnboundMethod")
public abstract class UnboundMethodNodes {
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.methods.SharedMethodInfo;
import org.jruby.truffle.util.ArgumentDescriptorUtils;
import org.jruby.truffle.language.arguments.ArgumentDescriptorUtils;

@CoreClass(name = "Proc")
public abstract class ProcNodes {
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.util;
package org.jruby.truffle.core.queue;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
@@ -24,15 +24,6 @@ public static MethodHandle getPrivateGetter(Class<?> klass, String fieldName) {
}
}

public static MethodHandle getPrivateSetter(final Class<?> klass, final String fieldName) {
final Field field = getPrivateField(klass, fieldName);
try {
return MethodHandles.lookup().unreflectSetter(field);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}

private static Field getPrivateField(final Class<?> klass, final String fieldName) {
try {
final Field field = klass.getDeclaredField(fieldName);
Original file line number Diff line number Diff line change
@@ -27,7 +27,6 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.core.thread.ThreadManager.BlockingAction;
import org.jruby.truffle.util.MethodHandleUtils;

import java.lang.invoke.MethodHandle;
import java.util.concurrent.BlockingQueue;
Original file line number Diff line number Diff line change
@@ -24,7 +24,6 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.core.thread.ThreadManager.BlockingAction;
import org.jruby.truffle.util.MethodHandleUtils;

import java.lang.invoke.MethodHandle;
import java.util.concurrent.ArrayBlockingQueue;
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
import org.jruby.truffle.language.backtrace.Backtrace;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.language.SafepointAction;
import org.jruby.util.func.Function2;

import static org.jruby.RubyThread.*;

@@ -45,9 +45,9 @@ public DynamicObject raise(DynamicObject thread, final DynamicObject exception)
public static void raiseInThread(final RubyContext context, DynamicObject rubyThread, final DynamicObject exception, Node currentNode) {
final Thread javaThread = Layouts.FIBER.getThread((Layouts.THREAD.getFiberManager(rubyThread).getCurrentFiber()));

context.getSafepointManager().pauseThreadAndExecuteLater(javaThread, currentNode, new SafepointAction() {
context.getSafepointManager().pauseThreadAndExecuteLater(javaThread, currentNode, new Function2<Void, DynamicObject, Node>() {
@Override
public void run(DynamicObject currentThread, Node currentNode) {
public Void apply(DynamicObject currentThread, Node currentNode) {
if (Layouts.EXCEPTION.getBacktrace(exception) == null) {
Backtrace backtrace = RubyCallStack.getBacktrace(context, currentNode);
Layouts.EXCEPTION.setBacktrace(exception, backtrace);
Original file line number Diff line number Diff line change
@@ -21,8 +21,8 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.backtrace.BacktraceFormatter;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.SafepointAction;
import org.jruby.truffle.language.SafepointManager;
import org.jruby.util.func.Function2;

import java.util.Collections;
import java.util.Set;
@@ -236,12 +236,13 @@ public Object[] getThreadList() {
private void killOtherThreads() {
while (true) {
try {
context.getSafepointManager().pauseAllThreadsAndExecute(null, false, new SafepointAction() {
context.getSafepointManager().pauseAllThreadsAndExecute(null, false, new Function2<Void, DynamicObject, Node>() {
@Override
public synchronized void run(DynamicObject thread, Node currentNode) {
public synchronized Void apply(DynamicObject thread, Node currentNode) {
if (thread != rootThread && Thread.currentThread() == Layouts.THREAD.getThread(thread)) {
ThreadNodes.shutdown(context, thread, currentNode);
}
return null;
}
});
break; // Successfully executed the safepoint and sent the exceptions.
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.control.ReturnException;
import org.jruby.truffle.language.control.ThreadExitException;
import org.jruby.truffle.language.SafepointAction;
import org.jruby.util.func.Function2;

import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
@@ -181,11 +181,12 @@ public DynamicObject backtrace(DynamicObject rubyThread) {

final DynamicObject[] result = new DynamicObject[1];

getContext().getSafepointManager().pauseThreadAndExecute(thread, this, new SafepointAction() {
getContext().getSafepointManager().pauseThreadAndExecute(thread, this, new Function2<Void, DynamicObject, Node>() {
@Override
public void run(DynamicObject thread, Node currentNode) {
public Void apply(DynamicObject thread, Node currentNode) {
final Backtrace backtrace = RubyCallStack.getBacktrace(getContext(), currentNode);
result[0] = ExceptionNodes.backtraceAsRubyStringArray(getContext(), null, backtrace);
return null;
}
});

@@ -224,10 +225,11 @@ public DynamicObject kill(final DynamicObject rubyThread) {
return rubyThread;
}

getContext().getSafepointManager().pauseThreadAndExecuteLater(toKill, this, new SafepointAction() {
getContext().getSafepointManager().pauseThreadAndExecuteLater(toKill, this, new Function2<Void, DynamicObject, Node>() {
@Override
public void run(DynamicObject currentThread, Node currentNode) {
public Void apply(DynamicObject currentThread, Node currentNode) {
shutdown(getContext(), currentThread, currentNode);
return null;
}
});

Original file line number Diff line number Diff line change
@@ -18,8 +18,8 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.util.Function;
import org.jruby.util.IdUtil;
import org.jruby.util.func.Function1;

import java.util.HashMap;
import java.util.Map;
@@ -328,7 +328,7 @@ public static Map<String, Object> getAllClassVariables(DynamicObject module) {

final Map<String, Object> classVariables = new HashMap<>();

classVariableLookup(module, new Function<DynamicObject, Object>() {
classVariableLookup(module, new Function1<Object, DynamicObject>() {
@Override
public Object apply(DynamicObject module) {
classVariables.putAll(Layouts.MODULE.getFields(module).getClassVariables());
@@ -343,7 +343,7 @@ public Object apply(DynamicObject module) {
public static Object lookupClassVariable(DynamicObject module, final String name) {
assert RubyGuards.isRubyModule(module);

return classVariableLookup(module, new Function<DynamicObject, Object>() {
return classVariableLookup(module, new Function1<Object, DynamicObject>() {
@Override
public Object apply(DynamicObject module) {
return Layouts.MODULE.getFields(module).getClassVariables().get(name);
@@ -355,7 +355,7 @@ public Object apply(DynamicObject module) {
public static void setClassVariable(final RubyContext context, DynamicObject module, final String name, final Object value, final Node currentNode) {
assert RubyGuards.isRubyModule(module);

DynamicObject found = classVariableLookup(module, new Function<DynamicObject, DynamicObject>() {
DynamicObject found = classVariableLookup(module, new Function1<DynamicObject, DynamicObject>() {
@Override
public DynamicObject apply(DynamicObject module) {
if (Layouts.MODULE.getFields(module).getClassVariables().containsKey(name)) {
@@ -373,7 +373,7 @@ public DynamicObject apply(DynamicObject module) {
}
}

private static <R> R classVariableLookup(DynamicObject module, Function<DynamicObject, R> action) {
private static <R> R classVariableLookup(DynamicObject module, Function1<R, DynamicObject> action) {
CompilerAsserts.neverPartOfCompilation();

// Look in the current module

This file was deleted.

Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@
import org.jruby.truffle.core.InterruptMode;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.Layouts;
import org.jruby.util.func.Function2;

import java.util.Collections;
import java.util.Set;
@@ -38,7 +39,7 @@ public class SafepointManager {
private final ReentrantLock lock = new ReentrantLock();

private final Phaser phaser = new Phaser();
private volatile SafepointAction action;
private volatile Function2<Void,DynamicObject,Node> action;
private volatile boolean deferred;

public SafepointManager(RubyContext context) {
@@ -93,16 +94,16 @@ private void assumptionInvalidated(Node currentNode, boolean fromBlockingCall) {
return; // interrupt me later
}

SafepointAction deferredAction = step(currentNode, false);
Function2<Void,DynamicObject,Node> deferredAction = step(currentNode, false);

// We're now running again normally and can run deferred actions
if (deferredAction != null) {
deferredAction.run(thread, currentNode);
deferredAction.apply(thread, currentNode);
}
}

@TruffleBoundary
private SafepointAction step(Node currentNode, boolean isDrivingThread) {
private Function2<Void,DynamicObject,Node> step(Node currentNode, boolean isDrivingThread) {
final DynamicObject thread = context.getThreadManager().getCurrentThread();

// wait other threads to reach their safepoint
@@ -116,11 +117,11 @@ private SafepointAction step(Node currentNode, boolean isDrivingThread) {
phaser.arriveAndAwaitAdvance();

// Read these while in the safepoint.
SafepointAction deferredAction = deferred ? action : null;
Function2<Void,DynamicObject,Node> deferredAction = deferred ? action : null;

try {
if (!deferred && thread != null && Layouts.THREAD.getStatus(thread) != Status.ABORTING) {
action.run(thread, currentNode);
action.apply(thread, currentNode);
}
} finally {
// wait other threads to finish their action
@@ -139,7 +140,7 @@ private void interruptOtherThreads() {
}
}

private void pauseAllThreadsAndExecute(Node currentNode, boolean isRubyThread, SafepointAction action, boolean deferred) {
private void pauseAllThreadsAndExecute(Node currentNode, boolean isRubyThread, Function2<Void,DynamicObject,Node> action, boolean deferred) {
this.action = action;
this.deferred = deferred;

@@ -156,7 +157,7 @@ private void pauseAllThreadsAndExecute(Node currentNode, boolean isRubyThread, S
// Variants for all threads

@TruffleBoundary
public void pauseAllThreadsAndExecute(Node currentNode, boolean deferred, SafepointAction action) {
public void pauseAllThreadsAndExecute(Node currentNode, boolean deferred, Function2<Void,DynamicObject,Node> action) {
if (lock.isHeldByCurrentThread()) {
throw new IllegalStateException("Re-entered SafepointManager");
}
@@ -174,12 +175,12 @@ public void pauseAllThreadsAndExecute(Node currentNode, boolean deferred, Safepo

// Run deferred actions after leaving the SafepointManager lock.
if (deferred) {
action.run(context.getThreadManager().getCurrentThread(), currentNode);
action.apply(context.getThreadManager().getCurrentThread(), currentNode);
}
}

@TruffleBoundary
public void pauseAllThreadsAndExecuteFromNonRubyThread(boolean deferred, SafepointAction action) {
public void pauseAllThreadsAndExecuteFromNonRubyThread(boolean deferred, Function2<Void,DynamicObject,Node> action) {
if (lock.isHeldByCurrentThread()) {
throw new IllegalStateException("Re-entered SafepointManager");
}
@@ -203,49 +204,52 @@ public void pauseAllThreadsAndExecuteFromNonRubyThread(boolean deferred, Safepoi
// Variants for a single thread

@TruffleBoundary
public void pauseThreadAndExecute(final Thread thread, Node currentNode, final SafepointAction action) {
public void pauseThreadAndExecute(final Thread thread, Node currentNode, final Function2<Void,DynamicObject,Node> action) {
if (Thread.currentThread() == thread) {
// fast path if we are already the right thread
DynamicObject rubyThread = context.getThreadManager().getCurrentThread();
action.run(rubyThread, currentNode);
action.apply(rubyThread, currentNode);
} else {
pauseAllThreadsAndExecute(currentNode, false, new SafepointAction() {
pauseAllThreadsAndExecute(currentNode, false, new Function2<Void, DynamicObject, Node>() {
@Override
public void run(DynamicObject rubyThread, Node currentNode) {
public Void apply(DynamicObject rubyThread, Node currentNode) {
if (Thread.currentThread() == thread) {
action.run(rubyThread, currentNode);
action.apply(rubyThread, currentNode);
}
return null;
}
});
}
}

@TruffleBoundary
public void pauseThreadAndExecuteLater(final Thread thread, Node currentNode, final SafepointAction action) {
public void pauseThreadAndExecuteLater(final Thread thread, Node currentNode, final Function2<Void,DynamicObject,Node> action) {
if (Thread.currentThread() == thread) {
// fast path if we are already the right thread
DynamicObject rubyThread = context.getThreadManager().getCurrentThread();
action.run(rubyThread, currentNode);
action.apply(rubyThread, currentNode);
} else {
pauseAllThreadsAndExecute(currentNode, true, new SafepointAction() {
pauseAllThreadsAndExecute(currentNode, true, new Function2<Void, DynamicObject, Node>() {
@Override
public void run(DynamicObject rubyThread, Node currentNode) {
public Void apply(DynamicObject rubyThread, Node currentNode) {
if (Thread.currentThread() == thread) {
action.run(rubyThread, currentNode);
action.apply(rubyThread, currentNode);
}
return null;
}
});
}
}

@TruffleBoundary
public void pauseThreadAndExecuteLaterFromNonRubyThread(final Thread thread, final SafepointAction action) {
pauseAllThreadsAndExecuteFromNonRubyThread(true, new SafepointAction() {
public void pauseThreadAndExecuteLaterFromNonRubyThread(final Thread thread, final Function2<Void,DynamicObject,Node> action) {
pauseAllThreadsAndExecuteFromNonRubyThread(true, new Function2<Void, DynamicObject, Node>() {
@Override
public void run(DynamicObject rubyThread, Node currentNode) {
public Void apply(DynamicObject rubyThread, Node currentNode) {
if (Thread.currentThread() == thread) {
action.run(rubyThread, currentNode);
action.apply(rubyThread, currentNode);
}
return null;
}
});
}
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
*
* Contains code modified from JRuby's org.jruby.runtime.Helpers and org.jruby.runtime.ArgumentType.
*/
package org.jruby.truffle.util;
package org.jruby.truffle.language.arguments;

import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.runtime.ArgumentDescriptor;
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.hash.Entry;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.language.SafepointAction;
import org.jruby.util.func.Function2;

import java.util.*;

@@ -33,10 +33,10 @@ public static Set<DynamicObject> stopAndGetAllObjects(

final Thread stoppingThread = Thread.currentThread();

context.getSafepointManager().pauseAllThreadsAndExecute(currentNode, false, new SafepointAction() {
context.getSafepointManager().pauseAllThreadsAndExecute(currentNode, false, new Function2<Void, DynamicObject, Node>() {

@Override
public void run(DynamicObject thread, Node currentNode) {
public Void apply(DynamicObject thread, Node currentNode) {
synchronized (visited) {
final Deque<DynamicObject> stack = new ArrayDeque<>();

@@ -66,6 +66,8 @@ public Object visitFrame(FrameInstance frameInstance) {
stack.addAll(ObjectGraph.getAdjacentObjects(object));
}
}

return null;
}
}
});
@@ -78,14 +80,16 @@ public static Set<DynamicObject> stopAndGetRootObjects(Node currentNode, final R

final Thread stoppingThread = Thread.currentThread();

context.getSafepointManager().pauseAllThreadsAndExecute(currentNode, false, new SafepointAction() {
context.getSafepointManager().pauseAllThreadsAndExecute(currentNode, false, new Function2<Void, DynamicObject, Node>() {
@Override
public void run(DynamicObject thread, Node currentNode) {
public Void apply(DynamicObject thread, Node currentNode) {
objects.add(thread);

if (Thread.currentThread() == stoppingThread) {
visitContextRoots(context, objects);
}

return null;
}
});

Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@
import org.jruby.truffle.core.proc.ProcNodes;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.language.SafepointAction;
import org.jruby.util.func.Function2;

public class ProcSignalHandler implements SignalHandler {

@@ -32,10 +32,11 @@ public ProcSignalHandler(RubyContext context, DynamicObject proc) {
@Override
public void handle(Signal signal) {
Thread mainThread = Layouts.FIBER.getThread((Layouts.THREAD.getFiberManager(context.getThreadManager().getRootThread()).getCurrentFiber()));
context.getSafepointManager().pauseThreadAndExecuteLaterFromNonRubyThread(mainThread, new SafepointAction() {
context.getSafepointManager().pauseThreadAndExecuteLaterFromNonRubyThread(mainThread, new Function2<Void, DynamicObject, Node>() {
@Override
public void run(DynamicObject thread, Node currentNode) {
public Void apply(DynamicObject thread, Node currentNode) {
ProcNodes.rootCall(proc);
return null;
}
});
}
Original file line number Diff line number Diff line change
@@ -18,10 +18,10 @@
import com.sun.net.httpserver.HttpServer;
import org.jruby.truffle.language.RubyCallStack;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.language.SafepointAction;
import org.jruby.truffle.language.backtrace.Backtrace;
import org.jruby.truffle.language.backtrace.BacktraceFormatter;
import org.jruby.truffle.core.Layouts;
import org.jruby.util.func.Function2;

import java.io.IOException;
import java.io.OutputStream;
@@ -62,10 +62,10 @@ public void handle(HttpExchange httpExchange) {
try {
final StringBuilder builder = new StringBuilder();

context.getSafepointManager().pauseAllThreadsAndExecuteFromNonRubyThread(false, new SafepointAction() {
context.getSafepointManager().pauseAllThreadsAndExecuteFromNonRubyThread(false, new Function2<Void, DynamicObject, Node>() {

@Override
public void run(DynamicObject thread, Node currentNode) {
public Void apply(DynamicObject thread, Node currentNode) {
try {
Backtrace backtrace = RubyCallStack.getBacktrace(context, null);

@@ -84,6 +84,8 @@ public void run(DynamicObject thread, Node currentNode) {
} catch (Throwable e) {
e.printStackTrace();
}

return null;
}

});
@@ -112,11 +114,12 @@ public void run(DynamicObject thread, Node currentNode) {
public void handle(HttpExchange httpExchange) {
try {
Thread mainThread = Layouts.FIBER.getThread((Layouts.THREAD.getFiberManager(context.getThreadManager().getRootThread()).getCurrentFiber()));
context.getSafepointManager().pauseThreadAndExecuteLaterFromNonRubyThread(mainThread, new SafepointAction() {
context.getSafepointManager().pauseThreadAndExecuteLaterFromNonRubyThread(mainThread, new Function2<Void, DynamicObject, Node>() {
@Override
public void run(DynamicObject thread, final Node currentNode) {
public Void apply(DynamicObject thread, final Node currentNode) {
new SimpleShell(context).run(Truffle.getRuntime().getCurrentFrame()
.getFrame(FrameInstance.FrameAccess.MATERIALIZE, true).materialize(), currentNode);
return null;
}
});

Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.util;
package org.jruby.truffle.tools.callgraph;

import java.util.IdentityHashMap;
import java.util.Map;
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.language.methods.SharedMethodInfo;
import org.jruby.truffle.util.IdProvider;

import java.io.PrintStream;

16 changes: 0 additions & 16 deletions truffle/src/main/java/org/jruby/truffle/util/Consumer.java

This file was deleted.

42 changes: 0 additions & 42 deletions truffle/src/main/java/org/jruby/truffle/util/FileUtils.java

This file was deleted.

16 changes: 0 additions & 16 deletions truffle/src/main/java/org/jruby/truffle/util/Function.java

This file was deleted.

0 comments on commit cdf659e

Please sign in to comment.