Skip to content
Permalink
Browse files
Remove Meth{Add,odHandle,odLookupInstr}. Saves a couple of MB on Rail…
…s console
  • Loading branch information
enebo committed Dec 18, 2014
1 parent bf0ebab commit d56d246d95bd6338b394fcf2c7ccbc0f204dbc9c
Showing with 165 additions and 474 deletions.
  1. +19 −19 core/src/main/java/org/jruby/ir/IRBuilder.java
  2. +0 −3 core/src/main/java/org/jruby/ir/IRVisitor.java
  3. +1 −2 core/src/main/java/org/jruby/ir/Operation.java
  4. +70 −10 core/src/main/java/org/jruby/ir/dataflow/analyses/UnboxableOpsAnalysisNode.java
  5. +4 −6 core/src/main/java/org/jruby/ir/instructions/AttrAssignInstr.java
  6. +19 −23 core/src/main/java/org/jruby/ir/instructions/CallBase.java
  7. +12 −15 core/src/main/java/org/jruby/ir/instructions/CallInstr.java
  8. +5 −6 core/src/main/java/org/jruby/ir/instructions/ClassSuperInstr.java
  9. +1 −2 core/src/main/java/org/jruby/ir/instructions/ConstMissingInstr.java
  10. +5 −7 core/src/main/java/org/jruby/ir/instructions/InstanceSuperInstr.java
  11. +0 −76 core/src/main/java/org/jruby/ir/instructions/MethodLookupInstr.java
  12. +5 −7 core/src/main/java/org/jruby/ir/instructions/NoResultCallInstr.java
  13. +4 −5 core/src/main/java/org/jruby/ir/instructions/PushFrameInstr.java
  14. +3 −2 core/src/main/java/org/jruby/ir/instructions/UnresolvedSuperInstr.java
  15. +1 −1 core/src/main/java/org/jruby/ir/instructions/specialized/OneArgOperandAttrAssignInstr.java
  16. +0 −113 core/src/main/java/org/jruby/ir/operands/MethAddr.java
  17. +0 −120 core/src/main/java/org/jruby/ir/operands/MethodHandle.java
  18. +0 −2 core/src/main/java/org/jruby/ir/operands/OperandType.java
  19. +1 −2 core/src/main/java/org/jruby/ir/passes/AddCallProtocolInstructions.java
  20. +5 −6 core/src/main/java/org/jruby/ir/persistence/InstrDecoderMap.java
  21. +2 −7 core/src/main/java/org/jruby/ir/persistence/InstrEncoderMap.java
  22. +0 −4 core/src/main/java/org/jruby/ir/persistence/OperandDecoderMap.java
  23. +0 −10 core/src/main/java/org/jruby/ir/persistence/OperandEncoderMap.java
  24. +8 −26 core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
@@ -830,7 +830,7 @@ private Operand buildAttrAssign(final AttrAssignNode attrAssignNode, IRScope s)
List<Operand> args = new ArrayList<>();
Node argsNode = attrAssignNode.getArgsNode();
Operand lastArg = (argsNode == null) ? manager.getNil() : buildCallArgs(args, argsNode, s);
addInstr(s, new AttrAssignInstr(obj, new MethAddr(attrAssignNode.getName()), args.toArray(new Operand[args.size()])));
addInstr(s, new AttrAssignInstr(obj, attrAssignNode.getName(), args.toArray(new Operand[args.size()])));
return lastArg;
}

@@ -839,7 +839,7 @@ public Operand buildAttrAssignAssignment(Node node, IRScope s, Operand value) {
Operand obj = build(attrAssignNode.getReceiverNode(), s);
List<Operand> args = setupCallArgs(attrAssignNode.getArgsNode(), s);
args.add(value);
addInstr(s, new AttrAssignInstr(obj, new MethAddr(attrAssignNode.getName()), args.toArray(new Operand[args.size()])));
addInstr(s, new AttrAssignInstr(obj, attrAssignNode.getName(), args.toArray(new Operand[args.size()])));
return value;
}

@@ -987,7 +987,7 @@ public Operand buildCall(CallNode callNode, IRScope s) {
List<Operand> args = setupCallArgs(callArgsNode, s);
Operand block = setupCallClosure(callNode.getIterNode(), s);
Variable callResult = s.createTemporaryVariable();
CallInstr callInstr = CallInstr.create(callResult, new MethAddr(callNode.getName()), receiver, args.toArray(new Operand[args.size()]), block);
CallInstr callInstr = CallInstr.create(callResult, callNode.getName(), receiver, args.toArray(new Operand[args.size()]), block);

// This is to support the ugly Proc.new with no block, which must see caller's frame
if (
@@ -2204,7 +2204,7 @@ public Operand buildFCall(FCallNode fcallNode, IRScope s) {
List<Operand> args = setupCallArgs(callArgsNode, s);
Operand block = setupCallClosure(fcallNode.getIterNode(), s);
Variable callResult = s.createTemporaryVariable();
CallInstr callInstr = CallInstr.create(CallType.FUNCTIONAL, callResult, new MethAddr(fcallNode.getName()), s.getSelf(), args.toArray(new Operand[args.size()]), block);
CallInstr callInstr = CallInstr.create(CallType.FUNCTIONAL, callResult, fcallNode.getName(), s.getSelf(), args.toArray(new Operand[args.size()]), block);
receiveBreakException(s, block, callInstr);
return callResult;
}
@@ -2321,7 +2321,7 @@ public Operand buildFor(ForNode forNode, IRScope s) {
Variable result = s.createTemporaryVariable();
Operand receiver = build(forNode.getIterNode(), s);
Operand forBlock = buildForIter(forNode, s);
CallInstr callInstr = new CallInstr(CallType.NORMAL, result, new MethAddr("each"), receiver, NO_ARGS, forBlock);
CallInstr callInstr = new CallInstr(CallType.NORMAL, result, "each", receiver, NO_ARGS, forBlock);
receiveBreakException(s, forBlock, callInstr);

return result;
@@ -2711,7 +2711,7 @@ public Operand buildOpAsgn(OpAsgnNode opAsgnNode, IRScope s) {

// get attr
Operand v1 = build(opAsgnNode.getReceiverNode(), s);
addInstr(s, CallInstr.create(readerValue, new MethAddr(opAsgnNode.getVariableName()), v1, NO_ARGS, null));
addInstr(s, CallInstr.create(readerValue, opAsgnNode.getVariableName(), v1, NO_ARGS, null));

// Ex: e.val ||= n
// e.val &&= n
@@ -2722,7 +2722,7 @@ public Operand buildOpAsgn(OpAsgnNode opAsgnNode, IRScope s) {

// compute value and set it
Operand v2 = build(opAsgnNode.getValueNode(), s);
addInstr(s, CallInstr.create(writerValue, new MethAddr(opAsgnNode.getVariableNameAsgn()), v1, new Operand[] {v2}, null));
addInstr(s, CallInstr.create(writerValue, opAsgnNode.getVariableNameAsgn(), v1, new Operand[] {v2}, null));
// It is readerValue = v2.
// readerValue = writerValue is incorrect because the assignment method
// might return something else other than the value being set!
@@ -2736,10 +2736,10 @@ public Operand buildOpAsgn(OpAsgnNode opAsgnNode, IRScope s) {
// call operator
Operand v2 = build(opAsgnNode.getValueNode(), s);
Variable setValue = s.createTemporaryVariable();
addInstr(s, CallInstr.create(setValue, new MethAddr(opAsgnNode.getOperatorName()), readerValue, new Operand[]{v2}, null));
addInstr(s, CallInstr.create(setValue, opAsgnNode.getOperatorName(), readerValue, new Operand[]{v2}, null));

// set attr
addInstr(s, CallInstr.create(writerValue, new MethAddr(opAsgnNode.getVariableNameAsgn()), v1, new Operand[] {setValue}, null));
addInstr(s, CallInstr.create(writerValue, opAsgnNode.getVariableNameAsgn(), v1, new Operand[] {setValue}, null));
// Returning writerValue is incorrect becuase the assignment method
// might return something else other than the value being set!
return setValue;
@@ -2823,11 +2823,11 @@ public Operand buildOpElementAsgnWithOr(OpElementAsgnNode opElementAsgnNode, IRS
Label l = s.getNewLabel();
Variable elt = s.createTemporaryVariable();
List<Operand> argList = setupCallArgs(opElementAsgnNode.getArgsNode(), s);
addInstr(s, CallInstr.create(elt, new MethAddr("[]"), array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, CallInstr.create(elt, "[]", array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, BEQInstr.create(elt, manager.getTrue(), l));
Operand value = build(opElementAsgnNode.getValueNode(), s);
argList.add(value);
addInstr(s, CallInstr.create(elt, new MethAddr("[]="), array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, CallInstr.create(elt, "[]=", array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, new CopyInstr(elt, value));
addInstr(s, new LabelInstr(l));
return elt;
@@ -2839,11 +2839,11 @@ public Operand buildOpElementAsgnWithAnd(OpElementAsgnNode opElementAsgnNode, IR
Label l = s.getNewLabel();
Variable elt = s.createTemporaryVariable();
List<Operand> argList = setupCallArgs(opElementAsgnNode.getArgsNode(), s);
addInstr(s, CallInstr.create(elt, new MethAddr("[]"), array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, CallInstr.create(elt, "[]", array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, BEQInstr.create(elt, manager.getFalse(), l));
Operand value = build(opElementAsgnNode.getValueNode(), s);
argList.add(value);
addInstr(s, CallInstr.create(elt, new MethAddr("[]="), array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, CallInstr.create(elt, "[]=", array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, new CopyInstr(elt, value));
addInstr(s, new LabelInstr(l));
return elt;
@@ -2860,15 +2860,15 @@ public Operand buildOpElementAsgnWithMethod(OpElementAsgnNode opElementAsgnNode,
Operand array = build(opElementAsgnNode.getReceiverNode(), s);
List<Operand> argList = setupCallArgs(opElementAsgnNode.getArgsNode(), s);
Variable elt = s.createTemporaryVariable();
addInstr(s, CallInstr.create(elt, new MethAddr("[]"), array, argList.toArray(new Operand[argList.size()]), null)); // elt = a[args]
addInstr(s, CallInstr.create(elt, "[]", array, argList.toArray(new Operand[argList.size()]), null)); // elt = a[args]
Operand value = build(opElementAsgnNode.getValueNode(), s); // Load 'value'
String operation = opElementAsgnNode.getOperatorName();
addInstr(s, CallInstr.create(elt, new MethAddr(operation), elt, new Operand[] { value }, null)); // elt = elt.OPERATION(value)
addInstr(s, CallInstr.create(elt, operation, elt, new Operand[] { value }, null)); // elt = elt.OPERATION(value)
// SSS: do not load the call result into 'elt' to eliminate the RAW dependency on the call
// We already know what the result is going be .. we are just storing it back into the array
Variable tmp = s.createTemporaryVariable();
argList.add(elt);
addInstr(s, CallInstr.create(tmp, new MethAddr("[]="), array, argList.toArray(new Operand[argList.size()]), null)); // a[args] = elt
addInstr(s, CallInstr.create(tmp, "[]=", array, argList.toArray(new Operand[argList.size()]), null)); // a[args] = elt
return elt;
}

@@ -3264,9 +3264,9 @@ private Operand buildSuperInstr(IRScope s, Operand block, Operand[] args) {
if ((s instanceof IRMethod) && (s.getLexicalParent() instanceof IRClassBody)) {
IRMethod m = (IRMethod)s;
if (m.isInstanceMethod) {
superInstr = new InstanceSuperInstr(ret, s.getCurrentModuleVariable(), new MethAddr(s.getName()), args, block);
superInstr = new InstanceSuperInstr(ret, s.getCurrentModuleVariable(), s.getName(), args, block);
} else {
superInstr = new ClassSuperInstr(ret, s.getCurrentModuleVariable(), new MethAddr(s.getName()), args, block);
superInstr = new ClassSuperInstr(ret, s.getCurrentModuleVariable(), s.getName(), args, block);
}
} else {
// We dont always know the method name we are going to be invoking if the super occurs in a closure.
@@ -3378,7 +3378,7 @@ public Operand buildVAlias(VAliasNode valiasNode, IRScope s) {

public Operand buildVCall(VCallNode node, IRScope s) {
Variable callResult = s.createTemporaryVariable();
Instr callInstr = CallInstr.create(CallType.VARIABLE, callResult, new MethAddr(node.getName()), s.getSelf(), NO_ARGS, null);
Instr callInstr = CallInstr.create(CallType.VARIABLE, callResult, node.getName(), s.getSelf(), NO_ARGS, null);
addInstr(s, callInstr);
return callResult;
}
@@ -71,7 +71,6 @@ private void error(Object object) {
public void Match2Instr(Match2Instr match2instr) { error(match2instr); }
public void Match3Instr(Match3Instr match3instr) { error(match3instr); }
public void MatchInstr(MatchInstr matchinstr) { error(matchinstr); }
public void MethodLookupInstr(MethodLookupInstr methodlookupinstr) { error(methodlookupinstr); }
public void ModuleVersionGuardInstr(ModuleVersionGuardInstr moduleversionguardinstr) { error(moduleversionguardinstr); }
public void NonlocalReturnInstr(NonlocalReturnInstr nonlocalreturninstr) { error(nonlocalreturninstr); }
public void NopInstr(NopInstr nopinstr) { error(nopinstr); }
@@ -153,8 +152,6 @@ private void error(Object object) {
public void IRException(IRException irexception) { error(irexception); }
public void Label(Label label) { error(label); }
public void LocalVariable(LocalVariable localvariable) { error(localvariable); }
public void MethAddr(MethAddr methaddr) { error(methaddr); }
public void MethodHandle(MethodHandle methodhandle) { error(methodhandle); }
public void Nil(Nil nil) { error(nil); }
public void NthRef(NthRef nthref) { error(nthref); }
public void ObjectClass(ObjectClass objectclass) { error(objectclass); }
@@ -204,8 +204,7 @@ public enum Operation {
PUSH_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
PUSH_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
POP_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
POP_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
METHOD_LOOKUP(0); /* for splitting calls into method-lookup and call -- unused **/
POP_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect);

public final OpClass opClass;
private int flags;
@@ -242,10 +242,10 @@ public void applyTransferFunction(Instr i) {
// Process calls specially -- these are what we want to optimize!
if (i instanceof CallBase && o == null) {
CallBase c = (CallBase)i;
MethAddr m = c.getMethodAddr();
String m = c.getName();
Operand r = c.getReceiver();
Operand[] args = c.getCallArgs();
if (dst != null && args.length == 1 && m.resemblesALUOp()) {
if (dst != null && args.length == 1 && resemblesALUOp(m)) {
Operand a = args[0];
Class receiverType = getOperandType(tmpState, r);
Class argType = getOperandType(tmpState, a);
@@ -255,7 +255,7 @@ public void applyTransferFunction(Instr i) {
{
dirtied = true;

Class dstType = m.getUnboxedResultType(Float.class);
Class dstType = getUnboxedResultType(Float.class, m);
setOperandType(tmpState, dst, dstType);
tmpState.unboxedVars.put(dst, dstType);

@@ -272,7 +272,7 @@ public void applyTransferFunction(Instr i) {
{
dirtied = true;

Class dstType = m.getUnboxedResultType(Fixnum.class);
Class dstType = getUnboxedResultType(Fixnum.class, m);
setOperandType(tmpState, dst, dstType);
tmpState.unboxedVars.put(dst, dstType);

@@ -641,21 +641,21 @@ public void unbox(Map<Variable, TemporaryLocalVariable> unboxMap) {
Operand o = ((ClosureAcceptingInstr)i).getClosureArg();
if (i instanceof CallBase && o == null) {
CallBase c = (CallBase)i;
MethAddr m = c.getMethodAddr();
String m = c.getName();
Operand r = c.getReceiver();
Operand[] args = c.getCallArgs();
if (dst != null && args.length == 1 && m.resemblesALUOp()) {
if (dst != null && args.length == 1 && resemblesALUOp(m)) {
Operand a = args[0];
Class receiverType = getOperandType(tmpState, r);
Class argType = getOperandType(tmpState, a);
// Optimistically assume that call is an ALU op
Operation unboxedOp;
if ((receiverType == Float.class || (receiverType == Fixnum.class && argType == Float.class)) &&
(unboxedOp = m.getUnboxedOp(Float.class)) != null)
(unboxedOp = getUnboxedOp(Float.class, m)) != null)
{
dirtied = true;

Class dstType = m.getUnboxedResultType(Float.class);
Class dstType = getUnboxedResultType(Float.class, m);
setOperandType(tmpState, dst, dstType);
tmpState.unboxedVars.put(dst, dstType);

@@ -664,11 +664,11 @@ public void unbox(Map<Variable, TemporaryLocalVariable> unboxMap) {
a = unboxOperand(tmpState, Float.class, unboxMap, a, newInstrs);
newInstrs.add(new AluInstr(unboxedOp, unboxedDst, r, a));
} else if ((receiverType == Float.class || (receiverType == Fixnum.class && argType == Fixnum.class)) &&
(unboxedOp = m.getUnboxedOp(Fixnum.class)) != null)
(unboxedOp = getUnboxedOp(Fixnum.class, m)) != null)
{
dirtied = true;

Class dstType = m.getUnboxedResultType(Fixnum.class);
Class dstType = getUnboxedResultType(Fixnum.class, m);
setOperandType(tmpState, dst, dstType);
tmpState.unboxedVars.put(dst, dstType);

@@ -755,6 +755,66 @@ public void unbox(Map<Variable, TemporaryLocalVariable> unboxMap) {
basicBlock.replaceInstrs(newInstrs);
}

private boolean resemblesALUOp(String name) {
return name.equals("+") || name.equals("-") || name.equals("*") || name.equals("/") ||
name.equals("|") || name.equals("&") || name.equals(">>") || name.equals("<<") ||
name.equals(">") || name.equals("<") || name.equals("==") || name.equals("!=");
}

private Class getUnboxedResultType(Class operandType, String name) {
if (name.length() == 1) {
switch (name.charAt(0)) {
case '+' :
case '-' :
case '*' :
case '/' : return operandType == Float.class ? Float.class : operandType == Fixnum.class ? Fixnum.class : null;
case '>' :
case '<' : return operandType == Float.class || operandType == Fixnum.class ? UnboxedBoolean.class : null;
}
}
return null;
}

public Operation getUnboxedOp(Class unboxedType, String name) {
if (unboxedType == Float.class) {
if (name.length() == 1) {
switch (name.charAt(0)) {
case '+' : return Operation.FADD;
case '-' : return Operation.FSUB;
case '*' : return Operation.FMUL;
case '/' : return Operation.FDIV;
case '>' : return Operation.FGT;
case '<' : return Operation.FLT;
}
} else if (name.length() == 2) {
if (name.equals("==")) return Operation.FEQ;
} else if (name.equals("===")) {
return Operation.FEQ;
}
} else if (unboxedType == Fixnum.class) {
if (name.length() == 1) {
switch (name.charAt(0)) {
case '+' : return Operation.IADD;
case '-' : return Operation.ISUB;
case '*' : return Operation.IMUL;
case '/' : return Operation.IDIV;
case '>' : return Operation.IGT;
case '<' : return Operation.ILT;
case '|' : return Operation.IOR;
case '&' : return Operation.IAND;
case '^' : return Operation.IXOR;
}
} else if (name.length() == 2) {
if (name.equals(">>")) return Operation.ISHR;
if (name.equals("<<")) return Operation.ISHL;
if (name.equals("==")) return Operation.IEQ;
} else if (name.equals("===")) {
return Operation.IEQ;
}
}
return null;
}

@Override
public String toString() {
return "";

0 comments on commit d56d246

Please sign in to comment.