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());
Loading

0 comments on commit cdf659e

Please sign in to comment.