Mercurial > hg > truffle
changeset 21567:f41409c6ff26
Do not rely on single/double slot information from the Kind of the value in a local variable or expression stack entry. With word type rewriting during parsing, long values can be single slot values when they are rewritten from Object values.
line wrap: on
line diff
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/ForeignCallPlugin.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/ForeignCallPlugin.java Thu May 28 17:00:59 2015 -0700 @@ -43,7 +43,7 @@ public boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode[] args) { ForeignCallNode foreignCall = new ForeignCallNode(foreignCalls, descriptor, args); foreignCall.setBci(b.bci()); - b.addPush(foreignCall); + b.addPush(targetMethod.getSignature().getReturnKind(), foreignCall); return true; } }
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java Thu May 28 17:00:59 2015 -0700 @@ -48,8 +48,8 @@ public interface GraphBuilderContext { /** - * Raw operation for adding a node to the graph when neither {@link #add}, - * {@link #addPush(ValueNode)} nor {@link #addPush(Kind, ValueNode)} can be used. + * Raw operation for adding a node to the graph when neither {@link #add} nor + * {@link #addPush(Kind, ValueNode)} can be used. * * @return either the node added or an equivalent node */ @@ -102,26 +102,13 @@ * is a {@link StateSplit} with a null {@linkplain StateSplit#stateAfter() frame state}, the * frame state is initialized. * - * @param value the value to add to the graph and push to the stack. The {@code value.getKind()} - * kind is used when type checking this operation. - * @return a node equivalent to {@code value} in the graph - */ - default <T extends ValueNode> T addPush(T value) { - return addPush(value.getKind().getStackKind(), value); - } - - /** - * Adds a node with a non-void kind to the graph, pushes it to the stack. If the returned node - * is a {@link StateSplit} with a null {@linkplain StateSplit#stateAfter() frame state}, the - * frame state is initialized. - * * @param kind the kind to use when type checking this operation * @param value the value to add to the graph and push to the stack * @return a node equivalent to {@code value} in the graph */ default <T extends ValueNode> T addPush(Kind kind, T value) { T equivalentValue = value.graph() != null ? value : append(value); - push(kind.getStackKind(), equivalentValue); + push(kind, equivalentValue); if (equivalentValue instanceof StateSplit) { StateSplit stateSplit = (StateSplit) equivalentValue; if (stateSplit.stateAfter() == null && stateSplit.hasSideEffect()) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Thu May 28 17:00:59 2015 -0700 @@ -168,7 +168,7 @@ Registration r = new Registration(plugins, Reflection.class); r.register0("getCallerClass", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { - b.addPush(new ReflectionGetCallerClassNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnType())); + b.addPush(Kind.Object, new ReflectionGetCallerClassNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnType())); return true; } @@ -184,7 +184,7 @@ r.register0("nanoTime", new ForeignCallPlugin(foreignCalls, JAVA_TIME_NANOS)); r.register1("identityHashCode", Object.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) { - b.addPush(new IdentityHashCodeNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnType(), object)); + b.addPush(Kind.Int, new IdentityHashCodeNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnType(), object)); return true; }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Thu May 28 17:00:59 2015 -0700 @@ -69,7 +69,6 @@ public void processHotSpotWordOperation(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, HotSpotOperation operation) { Kind returnKind = method.getSignature().getReturnKind(); - Kind returnStackKind = returnKind.getStackKind(); switch (operation.opcode()) { case POINTER_EQ: case POINTER_NE: @@ -84,7 +83,7 @@ PointerEqualsNode comparison = b.add(new PointerEqualsNode(left, right)); ValueNode eqValue = b.add(forBoolean(opcode == POINTER_EQ)); ValueNode neValue = b.add(forBoolean(opcode == POINTER_NE)); - b.addPush(returnStackKind, new ConditionalNode(comparison, eqValue, neValue)); + b.addPush(returnKind, new ConditionalNode(comparison, eqValue, neValue)); break; case IS_NULL: @@ -93,22 +92,22 @@ assert pointer.stamp() instanceof MetaspacePointerStamp; IsNullNode isNull = b.add(new IsNullNode(pointer)); - b.addPush(returnStackKind, new ConditionalNode(isNull, b.add(forBoolean(true)), b.add(forBoolean(false)))); + b.addPush(returnKind, new ConditionalNode(isNull, b.add(forBoolean(true)), b.add(forBoolean(false)))); break; case FROM_POINTER: assert args.length == 1; - b.addPush(returnStackKind, new PointerCastNode(StampFactory.forKind(wordKind), args[0])); + b.addPush(returnKind, new PointerCastNode(StampFactory.forKind(wordKind), args[0])); break; case TO_KLASS_POINTER: assert args.length == 1; - b.addPush(returnStackKind, new PointerCastNode(KlassPointerStamp.klass(), args[0])); + b.addPush(returnKind, new PointerCastNode(KlassPointerStamp.klass(), args[0])); break; case TO_METHOD_POINTER: assert args.length == 1; - b.addPush(returnStackKind, new PointerCastNode(MethodPointerStamp.method(), args[0])); + b.addPush(returnKind, new PointerCastNode(MethodPointerStamp.method(), args[0])); break; case READ_KLASS_POINTER: @@ -126,7 +125,7 @@ * explicit zero check on its base address. */ read.setGuard(AbstractBeginNode.prevBegin(read)); - b.push(returnStackKind, read); + b.push(returnKind, read); break; default:
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Thu May 28 17:00:59 2015 -0700 @@ -22,16 +22,10 @@ */ package com.oracle.graal.java; -import com.oracle.jvmci.code.BailoutException; -import com.oracle.jvmci.code.BytecodeFrame; -import com.oracle.jvmci.code.BytecodePosition; -import com.oracle.jvmci.meta.ResolvedJavaType; -import com.oracle.jvmci.meta.Signature; -import com.oracle.jvmci.meta.ResolvedJavaMethod; -import com.oracle.jvmci.meta.Kind; -import com.oracle.jvmci.meta.JavaType; +import static com.oracle.graal.bytecode.Bytecodes.*; import static com.oracle.graal.graph.iterators.NodePredicates.*; import static com.oracle.graal.java.GraphBuilderPhase.Options.*; +import static com.oracle.jvmci.common.JVMCIError.*; import java.util.*; @@ -45,25 +39,26 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.util.*; -import com.oracle.jvmci.common.*; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.debug.*; +import com.oracle.jvmci.meta.*; public final class FrameStateBuilder implements SideEffectsState { - static final ValueNode[] EMPTY_ARRAY = new ValueNode[0]; - static final MonitorIdNode[] EMPTY_MONITOR_ARRAY = new MonitorIdNode[0]; + private static final ValueNode[] EMPTY_ARRAY = new ValueNode[0]; + private static final MonitorIdNode[] EMPTY_MONITOR_ARRAY = new MonitorIdNode[0]; - protected final BytecodeParser parser; - protected final ResolvedJavaMethod method; - protected int stackSize; + private final BytecodeParser parser; + private final ResolvedJavaMethod method; + private int stackSize; protected final ValueNode[] locals; protected final ValueNode[] stack; - protected ValueNode[] lockedObjects; + private ValueNode[] lockedObjects; /** * @see BytecodeFrame#rethrowException */ - protected boolean rethrowException; + private boolean rethrowException; private MonitorIdNode[] monitorIds; private final StructuredGraph graph; @@ -73,7 +68,7 @@ * The closest {@link StateSplit#hasSideEffect() side-effect} predecessors. There will be more * than one when the current block contains no side-effects but merging predecessor blocks do. */ - protected List<StateSplit> sideEffects; + private List<StateSplit> sideEffects; /** * Creates a new frame state builder for the given method and the given target graph. @@ -185,6 +180,10 @@ return length == 0 ? EMPTY_ARRAY : new ValueNode[length]; } + public ResolvedJavaMethod getMethod() { + return method; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -214,29 +213,30 @@ } // Skip intrinsic frames - return create(bci, parser.getNonIntrinsicAncestor(), false, (ValueNode[]) null); + return create(bci, parser.getNonIntrinsicAncestor(), false, null, null); } /** * @param pushedValues if non-null, values to {@link #push(Kind, ValueNode)} to the stack before * creating the {@link FrameState} */ - public FrameState create(int bci, BytecodeParser parent, boolean duringCall, ValueNode... pushedValues) { + public FrameState create(int bci, BytecodeParser parent, boolean duringCall, Kind[] pushedSlotKinds, ValueNode[] pushedValues) { if (outerFrameState == null && parent != null) { outerFrameState = parent.getFrameStateBuilder().create(parent.bci(), null); } if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI && parent != null) { - FrameState newFrameState = outerFrameState.duplicateModified(outerFrameState.bci, true, Kind.Void, this.peek(0)); + FrameState newFrameState = outerFrameState.duplicateModified(outerFrameState.bci, true, Kind.Void, new Kind[]{Kind.Object}, new ValueNode[]{stack[0]}); return newFrameState; } if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) { - throw JVMCIError.shouldNotReachHere(); + throw shouldNotReachHere(); } if (pushedValues != null) { + assert pushedSlotKinds.length == pushedValues.length; int stackSizeToRestore = stackSize; - for (ValueNode arg : pushedValues) { - push(arg.getKind(), arg); + for (int i = 0; i < pushedValues.length; i++) { + push(pushedSlotKinds[i], pushedValues[i]); } FrameState res = graph.add(new FrameState(outerFrameState, method, bci, locals, stack, stackSize, lockedObjects, Arrays.asList(monitorIds), rethrowException, duringCall)); stackSize = stackSizeToRestore; @@ -268,7 +268,7 @@ return FrameState.toBytecodePosition(outerFrameState); } if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) { - throw JVMCIError.shouldNotReachHere(); + throw shouldNotReachHere(); } return new BytecodePosition(outer, method, bci); } @@ -285,8 +285,8 @@ return false; } for (int i = 0; i < stackSize(); i++) { - ValueNode x = stackAt(i); - ValueNode y = other.stackAt(i); + ValueNode x = stack[i]; + ValueNode y = other.stack[i]; if (x != y && (x == null || x.isDeleted() || y == null || y.isDeleted() || x.getKind() != y.getKind())) { return false; } @@ -306,18 +306,10 @@ assert isCompatibleWith(other); for (int i = 0; i < localsSize(); i++) { - ValueNode curLocal = localAt(i); - ValueNode mergedLocal = merge(curLocal, other.localAt(i), block); - if (curLocal != mergedLocal) { - storeLocal(i, mergedLocal); - } + locals[i] = merge(locals[i], other.locals[i], block); } for (int i = 0; i < stackSize(); i++) { - ValueNode curStack = stackAt(i); - ValueNode mergedStack = merge(curStack, other.stackAt(i), block); - if (curStack != mergedStack) { - storeStack(i, mergedStack); - } + stack[i] = merge(stack[i], other.stack[i], block); } for (int i = 0; i < lockedObjects.length; i++) { lockedObjects[i] = merge(lockedObjects[i], other.lockedObjects[i], block); @@ -387,11 +379,11 @@ for (int i = 0; i < localsSize(); i++) { boolean changedInLoop = liveness.localIsChangedInLoop(loopId, i); if (changedInLoop || forcePhis) { - storeLocal(i, createLoopPhi(loopBegin, localAt(i), !changedInLoop)); + locals[i] = createLoopPhi(loopBegin, locals[i], !changedInLoop); } } for (int i = 0; i < stackSize(); i++) { - storeStack(i, createLoopPhi(loopBegin, stackAt(i), false)); + stack[i] = createLoopPhi(loopBegin, stack[i], false); } for (int i = 0; i < lockedObjects.length; i++) { lockedObjects[i] = createLoopPhi(loopBegin, lockedObjects[i], false); @@ -400,17 +392,17 @@ public void insertLoopProxies(LoopExitNode loopExit, FrameStateBuilder loopEntryState) { for (int i = 0; i < localsSize(); i++) { - ValueNode value = localAt(i); + ValueNode value = locals[i]; if (value != null && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) { Debug.log(" inserting proxy for %s", value); - storeLocal(i, ProxyNode.forValue(value, loopExit, graph)); + locals[i] = ProxyNode.forValue(value, loopExit, graph); } } for (int i = 0; i < stackSize(); i++) { - ValueNode value = stackAt(i); + ValueNode value = stack[i]; if (value != null && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) { Debug.log(" inserting proxy for %s", value); - storeStack(i, ProxyNode.forValue(value, loopExit, graph)); + stack[i] = ProxyNode.forValue(value, loopExit, graph); } } for (int i = 0; i < lockedObjects.length; i++) { @@ -424,17 +416,17 @@ public void insertProxies(AbstractBeginNode begin) { for (int i = 0; i < localsSize(); i++) { - ValueNode value = localAt(i); + ValueNode value = locals[i]; if (value != null) { Debug.log(" inserting proxy for %s", value); - storeLocal(i, ProxyNode.forValue(value, begin, graph)); + locals[i] = ProxyNode.forValue(value, begin, graph); } } for (int i = 0; i < stackSize(); i++) { - ValueNode value = stackAt(i); + ValueNode value = stack[i]; if (value != null) { Debug.log(" inserting proxy for %s", value); - storeStack(i, ProxyNode.forValue(value, begin, graph)); + stack[i] = ProxyNode.forValue(value, begin, graph); } } for (int i = 0; i < lockedObjects.length; i++) { @@ -500,12 +492,12 @@ public boolean contains(ValueNode value) { for (int i = 0; i < localsSize(); i++) { - if (localAt(i) == value) { + if (locals[i] == value) { return true; } } for (int i = 0; i < stackSize(); i++) { - if (stackAt(i) == value) { + if (stack[i] == value) { return true; } } @@ -574,61 +566,20 @@ } /** - * Gets the value in the local variables at the specified index, without any sanity checking. - * - * @param i the index into the locals - * @return the instruction that produced the value for the specified local - */ - public ValueNode localAt(int i) { - return locals[i]; - } - - /** - * Get the value on the stack at the specified stack index. - * - * @param i the index into the stack, with {@code 0} being the bottom of the stack - * @return the instruction at the specified position in the stack - */ - public ValueNode stackAt(int i) { - return stack[i]; - } - - /** - * Gets the value in the lock at the specified index, without any sanity checking. - * - * @param i the index into the lock - * @return the instruction that produced the value for the specified lock - */ - public ValueNode lockAt(int i) { - return lockedObjects[i]; - } - - public void storeLock(int i, ValueNode lock) { - lockedObjects[i] = lock; - } - - /** * Loads the local variable at the specified index, checking that the returned value is non-null * and that two-stack values are properly handled. * * @param i the index of the local variable to load + * @param slotKind the kind of the local variable from the point of view of the bytecodes * @return the instruction that produced the specified local */ - public ValueNode loadLocal(int i) { + public ValueNode loadLocal(int i, Kind slotKind) { + assert slotKind.getSlotCount() > 0; + assert slotKind.getSlotCount() == 1 || locals[i + 1] == null; + ValueNode x = locals[i]; - assert assertLoadLocal(i, x); - return x; - } - - private boolean assertLoadLocal(int i, ValueNode x) { assert x != null : i; - assert parser.parsingIntrinsic() || (x.getKind().getSlotCount() == 1 || locals[i + 1] == null); - assert parser.parsingIntrinsic() || (i == 0 || locals[i - 1] == null || locals[i - 1].getKind().getSlotCount() == 1); - return true; - } - - public void storeLocal(int i, ValueNode x) { - storeLocal(i, x, x == null ? null : x.getKind()); + return x; } /** @@ -636,223 +587,69 @@ * the next local variable index is also overwritten. * * @param i the index at which to store + * @param slotKind the kind of the local variable from the point of view of the bytecodes * @param x the instruction which produces the value for the local */ - public void storeLocal(int i, ValueNode x, Kind kind) { - assert assertStoreLocal(x); + public void storeLocal(int i, Kind slotKind, ValueNode x) { + assert slotKind.getSlotCount() > 0; + locals[i] = x; - if (x != null) { - if (kind.needsTwoSlots() && !parser.parsingIntrinsic()) { - // if this is a double word, then kill i+1 - locals[i + 1] = null; - } - if (i > 0 && !parser.parsingIntrinsic()) { - ValueNode p = locals[i - 1]; - if (p != null && p.getKind().needsTwoSlots()) { - // if there was a double word at i - 1, then kill it - locals[i - 1] = null; - } - } + if (slotKind.needsTwoSlots()) { + locals[i + 1] = null; } } - private boolean assertStoreLocal(ValueNode x) { - assert x == null || parser.parsingIntrinsic() || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal) : "unexpected value: " + x; - return true; - } - - public void storeStack(int i, ValueNode x) { - assert assertStoreStack(i, x); - stack[i] = x; - } - - private boolean assertStoreStack(int i, ValueNode x) { - assert x == null || (stack[i] == null || x.getKind() == stack[i].getKind()) : "Method does not handle changes from one-slot to two-slot values or non-alive values"; - return true; - } - /** * Pushes an instruction onto the stack with the expected type. * - * @param kind the type expected for this instruction + * @param slotKind the kind of the stack element from the point of view of the bytecodes * @param x the instruction to push onto the stack */ - public void push(Kind kind, ValueNode x) { - assert assertPush(kind, x); + public void push(Kind slotKind, ValueNode x) { + assert x != null; + assert slotKind.getSlotCount() > 0; xpush(x); - if (kind.needsTwoSlots()) { + if (slotKind.needsTwoSlots()) { xpush(null); } } - private boolean assertPush(Kind kind, ValueNode x) { - assert parser.parsingIntrinsic() || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal); - assert x != null && (parser.parsingIntrinsic() || x.getKind() == kind); - return true; - } - - /** - * Pushes a value onto the stack without checking the type. - * - * @param x the instruction to push onto the stack - */ - public void xpush(ValueNode x) { - assert assertXpush(x); - stack[stackSize++] = x; - } - - private boolean assertXpush(ValueNode x) { - assert parser.parsingIntrinsic() || (x == null || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal)); - return true; - } - - /** - * Pushes a value onto the stack and checks that it is an int. - * - * @param x the instruction to push onto the stack - */ - public void ipush(ValueNode x) { - assert assertInt(x); - xpush(x); - } - - /** - * Pushes a value onto the stack and checks that it is a float. - * - * @param x the instruction to push onto the stack - */ - public void fpush(ValueNode x) { - assert assertFloat(x); - xpush(x); - } - - /** - * Pushes a value onto the stack and checks that it is an object. - * - * @param x the instruction to push onto the stack - */ - public void apush(ValueNode x) { - assert assertObject(x); - xpush(x); - } - - /** - * Pushes a value onto the stack and checks that it is a long. - * - * @param x the instruction to push onto the stack - */ - public void lpush(ValueNode x) { - assert assertLong(x); - xpush(x); - xpush(null); - } - - /** - * Pushes a value onto the stack and checks that it is a double. - * - * @param x the instruction to push onto the stack - */ - public void dpush(ValueNode x) { - assert assertDouble(x); - xpush(x); - xpush(null); - } - - public void pushReturn(Kind kind, ValueNode x) { - if (kind != Kind.Void) { - push(kind.getStackKind(), x); + public void pushReturn(Kind slotKind, ValueNode x) { + if (slotKind != Kind.Void) { + push(slotKind, x); } } /** * Pops an instruction off the stack with the expected type. * - * @param kind the expected type + * @param slotKind the kind of the stack element from the point of view of the bytecodes * @return the instruction on the top of the stack */ - public ValueNode pop(Kind kind) { - if (kind.needsTwoSlots()) { - xpop(); + public ValueNode pop(Kind slotKind) { + assert slotKind.getSlotCount() > 0; + if (slotKind.needsTwoSlots()) { + ValueNode s = xpop(); + assert s == null; } - assert assertPop(kind); - return xpop(); + ValueNode x = xpop(); + assert x != null; + return x; } - private boolean assertPop(Kind kind) { - assert kind != Kind.Void; - ValueNode x = xpeek(); - assert x != null && (parser.parsingIntrinsic() || x.getKind() == kind); - return true; + private void xpush(ValueNode x) { + stack[stackSize++] = x; } - /** - * Pops a value off of the stack without checking the type. - * - * @return x the instruction popped off the stack - */ - public ValueNode xpop() { + private ValueNode xpop() { return stack[--stackSize]; } - public ValueNode xpeek() { + private ValueNode xpeek() { return stack[stackSize - 1]; } /** - * Pops a value off of the stack and checks that it is an int. - * - * @return x the instruction popped off the stack - */ - public ValueNode ipop() { - assert assertIntPeek(); - return xpop(); - } - - /** - * Pops a value off of the stack and checks that it is a float. - * - * @return x the instruction popped off the stack - */ - public ValueNode fpop() { - assert assertFloatPeek(); - return xpop(); - } - - /** - * Pops a value off of the stack and checks that it is an object. - * - * @return x the instruction popped off the stack - */ - public ValueNode apop() { - assert assertObjectPeek(); - return xpop(); - } - - /** - * Pops a value off of the stack and checks that it is a long. - * - * @return x the instruction popped off the stack - */ - public ValueNode lpop() { - assert assertHighPeek(); - xpop(); - assert assertLongPeek(); - return xpop(); - } - - /** - * Pops a value off of the stack and checks that it is a double. - * - * @return x the instruction popped off the stack - */ - public ValueNode dpop() { - assert assertHighPeek(); - xpop(); - assert assertDoublePeek(); - return xpop(); - } - - /** * Pop the specified number of slots off of this stack and return them as an array of * instructions. * @@ -866,9 +663,6 @@ if (stack[newStackSize] == null) { /* Two-slot value. */ newStackSize--; - assert stack[newStackSize].getKind().needsTwoSlots(); - } else { - assert parser.parsingIntrinsic() || (stack[newStackSize].getKind().getSlotCount() == 1); } result[i] = stack[newStackSize]; } @@ -877,80 +671,93 @@ } /** - * Peeks an element from the operand stack. - * - * @param argumentNumber The number of the argument, relative from the top of the stack (0 = - * top). Long and double arguments only count as one argument, i.e., null-slots are - * ignored. - * @return The peeked argument. - */ - public ValueNode peek(int argumentNumber) { - int idx = stackSize() - 1; - for (int i = 0; i < argumentNumber; i++) { - if (stackAt(idx) == null) { - idx--; - assert stackAt(idx).getKind().needsTwoSlots(); - } - idx--; - } - return stackAt(idx); - } - - /** * Clears all values on this stack. */ public void clearStack() { stackSize = 0; } - private boolean assertLongPeek() { - return assertLong(xpeek()); - } - - private static boolean assertLong(ValueNode x) { - assert x != null && (x.getKind() == Kind.Long); - return true; - } - - private boolean assertIntPeek() { - return assertInt(xpeek()); - } - - private static boolean assertInt(ValueNode x) { - assert x != null && (x.getKind() == Kind.Int); - return true; - } - - private boolean assertFloatPeek() { - return assertFloat(xpeek()); - } - - private static boolean assertFloat(ValueNode x) { - assert x != null && (x.getKind() == Kind.Float); - return true; - } - - private boolean assertObjectPeek() { - return assertObject(xpeek()); - } - - private boolean assertObject(ValueNode x) { - assert x != null && (parser.parsingIntrinsic() || (x.getKind() == Kind.Object)); - return true; - } - - private boolean assertDoublePeek() { - return assertDouble(xpeek()); - } - - private static boolean assertDouble(ValueNode x) { - assert x != null && (x.getKind() == Kind.Double); - return true; - } - - private boolean assertHighPeek() { - assert xpeek() == null; - return true; + /** + * Performs a raw stack operation as defined in the Java bytecode specification. + * + * @param opcode The Java bytecode. + */ + public void stackOp(int opcode) { + switch (opcode) { + case POP: { + xpop(); + break; + } + case POP2: { + xpop(); + xpop(); + break; + } + case DUP: { + xpush(xpeek()); + break; + } + case DUP_X1: { + ValueNode w1 = xpop(); + ValueNode w2 = xpop(); + xpush(w1); + xpush(w2); + xpush(w1); + break; + } + case DUP_X2: { + ValueNode w1 = xpop(); + ValueNode w2 = xpop(); + ValueNode w3 = xpop(); + xpush(w1); + xpush(w3); + xpush(w2); + xpush(w1); + break; + } + case DUP2: { + ValueNode w1 = xpop(); + ValueNode w2 = xpop(); + xpush(w2); + xpush(w1); + xpush(w2); + xpush(w1); + break; + } + case DUP2_X1: { + ValueNode w1 = xpop(); + ValueNode w2 = xpop(); + ValueNode w3 = xpop(); + xpush(w2); + xpush(w1); + xpush(w3); + xpush(w2); + xpush(w1); + break; + } + case DUP2_X2: { + ValueNode w1 = xpop(); + ValueNode w2 = xpop(); + ValueNode w3 = xpop(); + ValueNode w4 = xpop(); + xpush(w2); + xpush(w1); + xpush(w4); + xpush(w3); + xpush(w2); + xpush(w1); + break; + } + case SWAP: { + ValueNode w1 = xpop(); + ValueNode w2 = xpop(); + xpush(w1); + xpush(w2); + break; + } + default: + throw shouldNotReachHere(); + } } @Override @@ -1007,19 +814,6 @@ return false; } - public void replace(ValueNode oldValue, ValueNode newValue) { - for (int i = 0; i < locals.length; i++) { - if (locals[i] == oldValue) { - locals[i] = newValue; - } - } - for (int i = 0; i < stackSize; i++) { - if (stack[i] == oldValue) { - stack[i] = newValue; - } - } - } - @Override public boolean isAfterSideEffect() { return sideEffects != null; @@ -1039,4 +833,16 @@ } sideEffects.add(sideEffect); } + + public void traceState() { + Debug.log(String.format("| state [nr locals = %d, stack depth = %d, method = %s]", localsSize(), stackSize(), method)); + for (int i = 0; i < localsSize(); ++i) { + ValueNode value = locals[i]; + Debug.log(String.format("| local[%d] = %-8s : %s", i, value == null ? "bogus" : value.getKind().getJavaName(), value)); + } + for (int i = 0; i < stackSize(); ++i) { + ValueNode value = stack[i]; + Debug.log(String.format("| stack[%d] = %-8s : %s", i, value == null ? "bogus" : value.getKind().getJavaName(), value)); + } + } }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu May 28 17:00:59 2015 -0700 @@ -235,11 +235,11 @@ * @param parser the parsing context of the (non-intrinsic) method calling the intrinsic * @param args the arguments to the call */ - public IntrinsicScope(BytecodeParser parser, ValueNode[] args) { + public IntrinsicScope(BytecodeParser parser, Kind[] argSlotKinds, ValueNode[] args) { assert !parser.parsingIntrinsic(); this.parser = parser; mark = parser.getGraph().getMark(); - stateBefore = parser.frameState.create(parser.bci(), parser.getNonIntrinsicAncestor(), false, args); + stateBefore = parser.frameState.create(parser.bci(), parser.getNonIntrinsicAncestor(), false, argSlotKinds, args); } public void close() { @@ -273,11 +273,13 @@ * Swap the top-of-stack value with the side-effect return value * using the frame state. */ - ValueNode tos = frameStateBuilder.pop(returnVal.getKind()); + Kind returnKind = parser.currentInvokeReturnType.getKind(); + ValueNode tos = frameStateBuilder.pop(returnKind); assert tos.getKind() == returnVal.getKind(); - FrameState newFrameState = frameStateBuilder.create(parser.stream.nextBCI(), parser.getNonIntrinsicAncestor(), false, returnVal); + FrameState newFrameState = frameStateBuilder.create(parser.stream.nextBCI(), parser.getNonIntrinsicAncestor(), false, new Kind[]{returnKind}, + new ValueNode[]{returnVal}); frameState.replaceAndDelete(newFrameState); - frameStateBuilder.push(tos.getKind(), tos); + frameStateBuilder.push(returnKind, tos); } else { if (stateAfterReturn == null) { if (intrinsic != null) { @@ -625,9 +627,9 @@ */ private FrameState createStateAfterStartOfReplacementGraph() { assert parent == null; - assert frameState.method.equals(intrinsicContext.getIntrinsicMethod()); + assert frameState.getMethod().equals(intrinsicContext.getIntrinsicMethod()); assert bci() == 0; - assert frameState.stackSize == 0; + assert frameState.stackSize() == 0; FrameState stateAfterStart; if (intrinsicContext.isPostParseInlined()) { stateAfterStart = graph.add(new FrameState(BytecodeFrame.BEFORE_BCI)); @@ -899,7 +901,7 @@ protected void handleUnresolvedCheckCast(JavaType type, ValueNode object) { assert !graphBuilderConfig.eagerResolving(); append(new FixedGuardNode(graph.unique(new IsNullNode(object)), Unresolved, InvalidateRecompile)); - frameState.apush(appendConstant(JavaConstant.NULL_POINTER)); + frameState.push(Kind.Object, appendConstant(JavaConstant.NULL_POINTER)); } /** @@ -912,7 +914,7 @@ DeoptimizeNode deopt = graph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)); append(new IfNode(graph.unique(new IsNullNode(object)), successor, deopt, 1)); lastInstr = successor; - frameState.ipush(appendConstant(JavaConstant.INT_0)); + frameState.push(Kind.Int, appendConstant(JavaConstant.INT_0)); } /** @@ -999,12 +1001,12 @@ DispatchBeginNode dispatchBegin; if (exceptionObject == null) { dispatchBegin = graph.add(new ExceptionObjectNode(metaAccess)); - dispatchState.apush(dispatchBegin); + dispatchState.push(Kind.Object, dispatchBegin); dispatchState.setRethrowException(true); dispatchBegin.setStateAfter(dispatchState.create(bci, dispatchBegin)); } else { dispatchBegin = graph.add(new DispatchBeginNode()); - dispatchState.apush(exceptionObject); + dispatchState.push(Kind.Object, exceptionObject); dispatchBegin.setStateAfter(dispatchState.create(bci, dispatchBegin)); dispatchState.setRethrowException(true); } @@ -1137,7 +1139,7 @@ } protected void genThrow() { - ValueNode exception = frameState.apop(); + ValueNode exception = frameState.pop(Kind.Object); append(new FixedGuardNode(graph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true)); lastInstr.setNext(handleException(exception, bci())); } @@ -1250,7 +1252,7 @@ if (target instanceof ResolvedJavaMethod) { JavaConstant appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC); if (appendix != null) { - frameState.apush(ConstantNode.forConstant(appendix, metaAccess, graph)); + frameState.push(Kind.Object, ConstantNode.forConstant(appendix, metaAccess, graph)); } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(false)); appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args); @@ -1271,7 +1273,7 @@ boolean hasReceiver = !((ResolvedJavaMethod) target).isStatic(); JavaConstant appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL); if (appendix != null) { - frameState.apush(ConstantNode.forConstant(appendix, metaAccess, graph)); + frameState.push(Kind.Object, ConstantNode.forConstant(appendix, metaAccess, graph)); } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(hasReceiver)); if (hasReceiver) { @@ -1325,7 +1327,7 @@ ResolvedJavaMethod targetMethod = initialTargetMethod; InvokeKind invokeKind = initialInvokeKind; if (initialInvokeKind.isIndirect()) { - ResolvedJavaType contextType = this.frameState.method.getDeclaringClass(); + ResolvedJavaType contextType = this.frameState.getMethod().getDeclaringClass(); ResolvedJavaMethod specialCallTarget = MethodCallTargetNode.findSpecialCallTarget(initialInvokeKind, args[0], initialTargetMethod, contextType); if (specialCallTarget != null) { invokeKind = InvokeKind.Special; @@ -1428,7 +1430,7 @@ this.targetMethod = targetMethod; this.args = args; this.resultType = resultType; - this.beforeStackSize = frameState.stackSize; + this.beforeStackSize = frameState.stackSize(); this.needsNullCheck = !targetMethod.isStatic() && args[0].getKind() == Kind.Object && !StampTool.isPointerNonNull(args[0].stamp()); this.nodeCount = graph.getNodeCount(); this.mark = graph.getMark(); @@ -1441,7 +1443,7 @@ boolean check(boolean pluginResult) { if (pluginResult == true) { int expectedStackSize = beforeStackSize + resultType.getSlotCount(); - assert expectedStackSize == frameState.stackSize : error("plugin manipulated the stack incorrectly: expected=%d, actual=%d", expectedStackSize, frameState.stackSize); + assert expectedStackSize == frameState.stackSize() : error("plugin manipulated the stack incorrectly: expected=%d, actual=%d", expectedStackSize, frameState.stackSize()); NodeIterable<Node> newNodes = graph.getNewNodes(mark); assert !needsNullCheck || isPointerNonNull(args[0].stamp()) : error("plugin needs to null check the receiver of %s: receiver=%s", targetMethod.format("%H.%n(%p)"), args[0]); for (Node n : newNodes) { @@ -1458,7 +1460,7 @@ } } else { assert nodeCount == graph.getNodeCount() : error("plugin that returns false must not create new nodes"); - assert beforeStackSize == frameState.stackSize : error("plugin that returns false must modify the stack"); + assert beforeStackSize == frameState.stackSize() : error("plugin that returns false must not modify the stack"); } return true; } @@ -1586,7 +1588,8 @@ } private void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) { - try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, args) : null) { + try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) + : null) { BytecodeParser parser = new BytecodeParser(this, metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, INVOCATION_ENTRY_BCI, calleeIntrinsicContext); FrameStateBuilder startFrameState = new FrameStateBuilder(parser, targetMethod, graph); @@ -1695,7 +1698,7 @@ private void beforeReturn(ValueNode x, Kind kind) { if (graph.method() != null && graph.method().isJavaLangObjectInit()) { - append(new RegisterFinalizerNode(frameState.localAt(0))); + append(new RegisterFinalizerNode(frameState.loadLocal(0, Kind.Object))); } if (graphBuilderConfig.insertNonSafepointDebugInfo() && !parsingIntrinsic()) { append(createInfoPointNode(InfopointReason.METHOD_END)); @@ -1736,13 +1739,13 @@ throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)"); } ConstantNode nextBciNode = getJsrConstant(nextBci); - frameState.push(Kind.Int, nextBciNode); + frameState.push(Kind.Object, nextBciNode); appendGoto(successor); } protected void genRet(int localIndex) { BciBlock successor = currentBlock.getRetSuccessor(); - ValueNode local = frameState.loadLocal(localIndex); + ValueNode local = frameState.loadLocal(localIndex, Kind.Object); JsrScope scope = currentBlock.getJsrScope(); int retAddress = scope.nextReturnAddress(); ConstantNode returnBciNode = getJsrConstant(retAddress); @@ -2150,7 +2153,7 @@ if (target.isStatic()) { return appendConstant(target.getDeclaringClass().getJavaClass()); } else { - return state.loadLocal(0); + return state.loadLocal(0, Kind.Object); } } @@ -2191,7 +2194,7 @@ frameState.setRethrowException(false); createUnwind(); } else { - ValueNode exception = frameState.apop(); + ValueNode exception = frameState.pop(Kind.Object); this.unwindValue = exception; this.beforeUnwindNode = this.lastInstr; } @@ -2219,7 +2222,7 @@ private void createUnwind() { assert frameState.stackSize() == 1 : frameState; - ValueNode exception = frameState.apop(); + ValueNode exception = frameState.pop(Kind.Object); synchronizedEpilogue(BytecodeFrame.AFTER_EXCEPTION_BCI, null, null); append(new UnwindNode(exception)); } @@ -2252,7 +2255,7 @@ for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) { if (skippedType.isAssignableFrom(resolvedCatchType)) { BciBlock nextBlock = block.getSuccessorCount() == 1 ? blockMap.getUnwindBlock() : block.getSuccessor(1); - ValueNode exception = frameState.stackAt(0); + ValueNode exception = frameState.stack[0]; FixedNode trueSuccessor = graph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode)); FixedNode nextDispatch = createTarget(nextBlock, frameState); append(new IfNode(graph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), trueSuccessor, nextDispatch, 0)); @@ -2263,12 +2266,12 @@ if (initialized) { BciBlock nextBlock = block.getSuccessorCount() == 1 ? blockMap.getUnwindBlock() : block.getSuccessor(1); - ValueNode exception = frameState.stackAt(0); + ValueNode exception = frameState.stack[0]; CheckCastNode checkCast = graph.add(new CheckCastNode((ResolvedJavaType) catchType, exception, null, false)); - frameState.apop(); + frameState.pop(Kind.Object); frameState.push(Kind.Object, checkCast); FixedNode catchSuccessor = createTarget(block.getSuccessor(0), frameState); - frameState.apop(); + frameState.pop(Kind.Object); frameState.push(Kind.Object, exception); FixedNode nextDispatch = createTarget(nextBlock, frameState); checkCast.setNext(catchSuccessor); @@ -2435,24 +2438,13 @@ private boolean traceState() { if (Debug.isEnabled() && Options.TraceBytecodeParserLevel.getValue() >= TRACELEVEL_STATE && Debug.isLogEnabled()) { - traceStateHelper(); + frameState.traceState(); } return true; } - private void traceStateHelper() { - Debug.log(String.format("| state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method)); - for (int i = 0; i < frameState.localsSize(); ++i) { - ValueNode value = frameState.localAt(i); - Debug.log(String.format("| local[%d] = %-8s : %s", i, value == null ? "bogus" : value.getKind().getJavaName(), value)); - } - for (int i = 0; i < frameState.stackSize(); ++i) { - ValueNode value = frameState.stackAt(i); - Debug.log(String.format("| stack[%d] = %-8s : %s", i, value == null ? "bogus" : value.getKind().getJavaName(), value)); - } - } - protected void genIf(ValueNode x, Condition cond, ValueNode y) { + assert x.getKind().getStackKind() == y.getKind().getStackKind(); assert currentBlock.getSuccessorCount() == 2; BciBlock trueBlock = currentBlock.getSuccessor(0); BciBlock falseBlock = currentBlock.getSuccessor(1); @@ -2628,10 +2620,9 @@ return metaAccess; } - public void push(Kind kind, ValueNode value) { + public void push(Kind slotKind, ValueNode value) { assert value.isAlive(); - assert kind == kind.getStackKind(); - frameState.push(kind, value); + frameState.push(slotKind, value); } private int getCurrentDimension() { @@ -2715,19 +2706,13 @@ } public void loadLocal(int index, Kind kind) { - frameState.push(kind, frameState.loadLocal(index)); + ValueNode value = frameState.loadLocal(index, kind); + frameState.push(kind, value); } public void storeLocal(Kind kind, int index) { - ValueNode value; - if (kind == Kind.Object) { - value = frameState.xpop(); - // astore and astore_<n> may be used to store a returnAddress (jsr) - assert parsingIntrinsic() || (value.getKind() == Kind.Object || value.getKind() == Kind.Int) : value + ":" + value.getKind(); - } else { - value = frameState.pop(kind); - } - frameState.storeLocal(index, value, kind); + ValueNode value = frameState.pop(kind); + frameState.storeLocal(index, kind, value); } private void genLoadConstant(int cpi, int opcode) { @@ -2743,17 +2728,17 @@ } } else if (con instanceof JavaConstant) { JavaConstant constant = (JavaConstant) con; - frameState.push(constant.getKind().getStackKind(), appendConstant(constant)); + frameState.push(constant.getKind(), appendConstant(constant)); } else { throw new Error("lookupConstant returned an object of incorrect type"); } } private void genLoadIndexed(Kind kind) { - ValueNode index = frameState.ipop(); - ValueNode array = emitExplicitExceptions(frameState.apop(), index); + ValueNode index = frameState.pop(Kind.Int); + ValueNode array = emitExplicitExceptions(frameState.pop(Kind.Object), index); if (!tryLoadIndexedPlugin(kind, index, array)) { - frameState.push(kind.getStackKind(), append(genLoadIndexed(array, index, kind))); + frameState.push(kind, append(genLoadIndexed(array, index, kind))); } } @@ -2770,80 +2755,15 @@ } private void genStoreIndexed(Kind kind) { - ValueNode value = frameState.pop(kind.getStackKind()); - ValueNode index = frameState.ipop(); - ValueNode array = emitExplicitExceptions(frameState.apop(), index); + ValueNode value = frameState.pop(kind); + ValueNode index = frameState.pop(Kind.Int); + ValueNode array = emitExplicitExceptions(frameState.pop(Kind.Object), index); genStoreIndexed(array, index, kind, value); } - private void stackOp(int opcode) { - switch (opcode) { - case DUP_X1: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - frameState.xpush(w1); - frameState.xpush(w2); - frameState.xpush(w1); - break; - } - case DUP_X2: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - ValueNode w3 = frameState.xpop(); - frameState.xpush(w1); - frameState.xpush(w3); - frameState.xpush(w2); - frameState.xpush(w1); - break; - } - case DUP2: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - frameState.xpush(w2); - frameState.xpush(w1); - frameState.xpush(w2); - frameState.xpush(w1); - break; - } - case DUP2_X1: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - ValueNode w3 = frameState.xpop(); - frameState.xpush(w2); - frameState.xpush(w1); - frameState.xpush(w3); - frameState.xpush(w2); - frameState.xpush(w1); - break; - } - case DUP2_X2: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - ValueNode w3 = frameState.xpop(); - ValueNode w4 = frameState.xpop(); - frameState.xpush(w2); - frameState.xpush(w1); - frameState.xpush(w4); - frameState.xpush(w3); - frameState.xpush(w2); - frameState.xpush(w1); - break; - } - case SWAP: { - ValueNode w1 = frameState.xpop(); - ValueNode w2 = frameState.xpop(); - frameState.xpush(w1); - frameState.xpush(w2); - break; - } - default: - throw JVMCIError.shouldNotReachHere(); - } - } - - private void genArithmeticOp(Kind result, int opcode) { - ValueNode y = frameState.pop(result); - ValueNode x = frameState.pop(result); + private void genArithmeticOp(Kind kind, int opcode) { + ValueNode y = frameState.pop(kind); + ValueNode x = frameState.pop(kind); ValueNode v; switch (opcode) { case IADD: @@ -2879,14 +2799,14 @@ v = genFloatRem(x, y); break; default: - throw new JVMCIError("should not reach"); + throw shouldNotReachHere(); } - frameState.push(result, append(v)); + frameState.push(kind, append(v)); } - private void genIntegerDivOp(Kind result, int opcode) { - ValueNode y = frameState.pop(result); - ValueNode x = frameState.pop(result); + private void genIntegerDivOp(Kind kind, int opcode) { + ValueNode y = frameState.pop(kind); + ValueNode x = frameState.pop(kind); ValueNode v; switch (opcode) { case IDIV: @@ -2898,17 +2818,18 @@ v = genIntegerRem(x, y); break; default: - throw new JVMCIError("should not reach"); + throw shouldNotReachHere(); } - frameState.push(result, append(v)); + frameState.push(kind, append(v)); } private void genNegateOp(Kind kind) { - frameState.push(kind, append(genNegateOp(frameState.pop(kind)))); + ValueNode x = frameState.pop(kind); + frameState.push(kind, append(genNegateOp(x))); } private void genShiftOp(Kind kind, int opcode) { - ValueNode s = frameState.ipop(); + ValueNode s = frameState.pop(Kind.Int); ValueNode x = frameState.pop(kind); ValueNode v; switch (opcode) { @@ -2925,7 +2846,7 @@ v = genUnsignedRightShift(x, s); break; default: - throw new JVMCIError("should not reach"); + throw shouldNotReachHere(); } frameState.push(kind, append(v)); } @@ -2948,7 +2869,7 @@ v = genXor(x, y); break; default: - throw new JVMCIError("should not reach"); + throw shouldNotReachHere(); } frameState.push(kind, append(v)); } @@ -2956,52 +2877,52 @@ private void genCompareOp(Kind kind, boolean isUnorderedLess) { ValueNode y = frameState.pop(kind); ValueNode x = frameState.pop(kind); - frameState.ipush(append(genNormalizeCompare(x, y, isUnorderedLess))); + frameState.push(Kind.Int, append(genNormalizeCompare(x, y, isUnorderedLess))); } private void genFloatConvert(FloatConvert op, Kind from, Kind to) { - ValueNode input = frameState.pop(from.getStackKind()); - frameState.push(to.getStackKind(), append(genFloatConvert(op, input))); + ValueNode input = frameState.pop(from); + frameState.push(to, append(genFloatConvert(op, input))); } private void genSignExtend(Kind from, Kind to) { - ValueNode input = frameState.pop(from.getStackKind()); + ValueNode input = frameState.pop(from); if (from != from.getStackKind()) { input = append(genNarrow(input, from.getBitCount())); } - frameState.push(to.getStackKind(), append(genSignExtend(input, to.getBitCount()))); + frameState.push(to, append(genSignExtend(input, to.getBitCount()))); } private void genZeroExtend(Kind from, Kind to) { - ValueNode input = frameState.pop(from.getStackKind()); + ValueNode input = frameState.pop(from); if (from != from.getStackKind()) { input = append(genNarrow(input, from.getBitCount())); } - frameState.push(to.getStackKind(), append(genZeroExtend(input, to.getBitCount()))); + frameState.push(to, append(genZeroExtend(input, to.getBitCount()))); } private void genNarrow(Kind from, Kind to) { - ValueNode input = frameState.pop(from.getStackKind()); - frameState.push(to.getStackKind(), append(genNarrow(input, to.getBitCount()))); + ValueNode input = frameState.pop(from); + frameState.push(to, append(genNarrow(input, to.getBitCount()))); } private void genIncrement() { int index = getStream().readLocalIndex(); int delta = getStream().readIncrement(); - ValueNode x = frameState.loadLocal(index); + ValueNode x = frameState.loadLocal(index, Kind.Int); ValueNode y = appendConstant(JavaConstant.forInt(delta)); - frameState.storeLocal(index, append(genIntegerAdd(x, y))); + frameState.storeLocal(index, Kind.Int, append(genIntegerAdd(x, y))); } private void genIfZero(Condition cond) { ValueNode y = appendConstant(JavaConstant.INT_0); - ValueNode x = frameState.ipop(); + ValueNode x = frameState.pop(Kind.Int); genIf(x, cond, y); } private void genIfNull(Condition cond) { ValueNode y = appendConstant(JavaConstant.NULL_POINTER); - ValueNode x = frameState.apop(); + ValueNode x = frameState.pop(Kind.Object); genIf(x, cond, y); } @@ -3063,7 +2984,7 @@ private void genCheckCast() { int cpi = getStream().readCPI(); JavaType type = lookupType(cpi, CHECKCAST); - ValueNode object = frameState.apop(); + ValueNode object = frameState.pop(Kind.Object); if (type instanceof ResolvedJavaType) { ResolvedJavaType resolvedType = (ResolvedJavaType) type; JavaTypeProfile profile = getProfileForTypeCheck(resolvedType); @@ -3089,7 +3010,7 @@ if (checkCastNode == null) { checkCastNode = append(createCheckCast(resolvedType, object, profile, false)); } - frameState.apush(checkCastNode); + frameState.push(Kind.Object, checkCastNode); } } else { handleUnresolvedCheckCast(type, object); @@ -3099,7 +3020,7 @@ private void genInstanceOf() { int cpi = getStream().readCPI(); JavaType type = lookupType(cpi, INSTANCEOF); - ValueNode object = frameState.apop(); + ValueNode object = frameState.pop(Kind.Object); if (type instanceof ResolvedJavaType) { ResolvedJavaType resolvedType = (ResolvedJavaType) type; JavaTypeProfile profile = getProfileForTypeCheck(resolvedType); @@ -3120,7 +3041,7 @@ if (instanceOfNode == null) { instanceOfNode = createInstanceOf(resolvedType, object, profile); } - frameState.ipush(append(genConditional(genUnique(instanceOfNode)))); + frameState.push(Kind.Int, append(genConditional(genUnique(instanceOfNode)))); } } else { handleUnresolvedInstanceOf(type, object); @@ -3139,23 +3060,23 @@ } } } - frameState.apush(append(createNewInstance((ResolvedJavaType) type, true))); + frameState.push(Kind.Object, append(createNewInstance((ResolvedJavaType) type, true))); } else { handleUnresolvedNewInstance(type); } } private void genNewPrimitiveArray(int typeCode) { - Class<?> clazz = arrayTypeCodeToClass(typeCode); - ResolvedJavaType elementType = metaAccess.lookupJavaType(clazz); - frameState.apush(append(createNewArray(elementType, frameState.ipop(), true))); + ResolvedJavaType elementType = metaAccess.lookupJavaType(arrayTypeCodeToClass(typeCode)); + ValueNode length = frameState.pop(Kind.Int); + frameState.push(Kind.Object, append(createNewArray(elementType, length, true))); } private void genNewObjectArray(int cpi) { JavaType type = lookupType(cpi, ANEWARRAY); - ValueNode length = frameState.ipop(); + ValueNode length = frameState.pop(Kind.Int); if (type instanceof ResolvedJavaType) { - frameState.apush(append(createNewArray((ResolvedJavaType) type, length, true))); + frameState.push(Kind.Object, append(createNewArray((ResolvedJavaType) type, length, true))); } else { handleUnresolvedNewObjectArray(type, length); } @@ -3167,22 +3088,23 @@ int rank = getStream().readUByte(bci() + 3); List<ValueNode> dims = new ArrayList<>(Collections.nCopies(rank, null)); for (int i = rank - 1; i >= 0; i--) { - dims.set(i, frameState.ipop()); + dims.set(i, frameState.pop(Kind.Int)); } if (type instanceof ResolvedJavaType) { - frameState.apush(append(createNewMultiArray((ResolvedJavaType) type, dims))); + frameState.push(Kind.Object, append(createNewMultiArray((ResolvedJavaType) type, dims))); } else { handleUnresolvedNewMultiArray(type, dims); } } private void genGetField(JavaField field) { - Kind kind = field.getKind(); - ValueNode receiver = emitExplicitExceptions(frameState.apop(), null); + ValueNode receiver = emitExplicitExceptions(frameState.pop(Kind.Object), null); if ((field instanceof ResolvedJavaField) && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) { + ResolvedJavaField resolvedField = (ResolvedJavaField) field; + LoadFieldPlugin loadFieldPlugin = this.graphBuilderConfig.getPlugins().getLoadFieldPlugin(); - if (loadFieldPlugin == null || !loadFieldPlugin.apply((GraphBuilderContext) this, receiver, (ResolvedJavaField) field)) { - appendOptimizedLoadField(kind, genLoadField(receiver, (ResolvedJavaField) field)); + if (loadFieldPlugin == null || !loadFieldPlugin.apply(this, receiver, resolvedField)) { + frameState.push(field.getKind(), append(genLoadField(receiver, resolvedField))); } } else { handleUnresolvedLoadField(field, receiver); @@ -3213,8 +3135,8 @@ } private void genPutField(JavaField field) { - ValueNode value = frameState.pop(field.getKind().getStackKind()); - ValueNode receiver = emitExplicitExceptions(frameState.apop(), null); + ValueNode value = frameState.pop(field.getKind()); + ValueNode receiver = emitExplicitExceptions(frameState.pop(Kind.Object), null); if (field instanceof ResolvedJavaField && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) { genStoreField(receiver, (ResolvedJavaField) field, value); } else { @@ -3223,44 +3145,35 @@ } private void genGetStatic(JavaField field) { - Kind kind = field.getKind(); if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) { ResolvedJavaField resolvedField = (ResolvedJavaField) field; + // Javac does not allow use of "$assertionsDisabled" for a field name but // Eclipse does in which case a suffix is added to the generated field. if ((parsingIntrinsic() || graphBuilderConfig.omitAssertions()) && resolvedField.isSynthetic() && resolvedField.getName().startsWith("$assertionsDisabled")) { - appendOptimizedLoadField(kind, ConstantNode.forBoolean(true)); + frameState.push(field.getKind(), ConstantNode.forBoolean(true, graph)); return; } LoadFieldPlugin loadFieldPlugin = this.graphBuilderConfig.getPlugins().getLoadFieldPlugin(); if (loadFieldPlugin == null || !loadFieldPlugin.apply(this, resolvedField)) { - appendOptimizedLoadField(kind, genLoadField(null, resolvedField)); + frameState.push(field.getKind(), append(genLoadField(null, resolvedField))); } } else { handleUnresolvedLoadField(field, null); } } - public boolean tryLoadFieldPlugin(JavaField field, LoadFieldPlugin loadFieldPlugin) { - return loadFieldPlugin.apply((GraphBuilderContext) this, (ResolvedJavaField) field); - } - private void genPutStatic(JavaField field) { - ValueNode value = frameState.pop(field.getKind().getStackKind()); + ValueNode value = frameState.pop(field.getKind()); if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) { - genStoreField(null, (ResolvedJavaField) field, value); + ResolvedJavaField resolvedField = (ResolvedJavaField) field; + genStoreField(null, resolvedField, value); } else { handleUnresolvedStoreField(field, value, null); } } - protected void appendOptimizedLoadField(Kind kind, ValueNode load) { - // append the load to the instruction - ValueNode optimized = append(load); - frameState.push(kind.getStackKind(), optimized); - } - private double[] switchProbability(int numberOfCases, int bci) { double[] prob = (profilingInfo == null ? null : profilingInfo.getSwitchProbabilities(bci)); if (prob != null) { @@ -3278,7 +3191,7 @@ private void genSwitch(BytecodeSwitch bs) { int bci = bci(); - ValueNode value = frameState.ipop(); + ValueNode value = frameState.pop(Kind.Int); int nofCases = bs.numberOfCases(); double[] keyProbabilities = switchProbability(nofCases + 1, bci); @@ -3381,23 +3294,23 @@ // @formatter:off switch (opcode) { case NOP : /* nothing to do */ break; - case ACONST_NULL : frameState.apush(appendConstant(JavaConstant.NULL_POINTER)); break; + case ACONST_NULL : frameState.push(Kind.Object, appendConstant(JavaConstant.NULL_POINTER)); break; case ICONST_M1 : // fall through case ICONST_0 : // fall through case ICONST_1 : // fall through case ICONST_2 : // fall through case ICONST_3 : // fall through case ICONST_4 : // fall through - case ICONST_5 : frameState.ipush(appendConstant(JavaConstant.forInt(opcode - ICONST_0))); break; + case ICONST_5 : frameState.push(Kind.Int, appendConstant(JavaConstant.forInt(opcode - ICONST_0))); break; case LCONST_0 : // fall through - case LCONST_1 : frameState.lpush(appendConstant(JavaConstant.forLong(opcode - LCONST_0))); break; + case LCONST_1 : frameState.push(Kind.Long, appendConstant(JavaConstant.forLong(opcode - LCONST_0))); break; case FCONST_0 : // fall through case FCONST_1 : // fall through - case FCONST_2 : frameState.fpush(appendConstant(JavaConstant.forFloat(opcode - FCONST_0))); break; + case FCONST_2 : frameState.push(Kind.Float, appendConstant(JavaConstant.forFloat(opcode - FCONST_0))); break; case DCONST_0 : // fall through - case DCONST_1 : frameState.dpush(appendConstant(JavaConstant.forDouble(opcode - DCONST_0))); break; - case BIPUSH : frameState.ipush(appendConstant(JavaConstant.forInt(stream.readByte()))); break; - case SIPUSH : frameState.ipush(appendConstant(JavaConstant.forInt(stream.readShort()))); break; + case DCONST_1 : frameState.push(Kind.Double, appendConstant(JavaConstant.forDouble(opcode - DCONST_0))); break; + case BIPUSH : frameState.push(Kind.Int, appendConstant(JavaConstant.forInt(stream.readByte()))); break; + case SIPUSH : frameState.push(Kind.Int, appendConstant(JavaConstant.forInt(stream.readShort()))); break; case LDC : // fall through case LDC_W : // fall through case LDC2_W : genLoadConstant(stream.readCPI(), opcode); break; @@ -3467,15 +3380,15 @@ case BASTORE : genStoreIndexed(Kind.Byte ); break; case CASTORE : genStoreIndexed(Kind.Char ); break; case SASTORE : genStoreIndexed(Kind.Short ); break; - case POP : frameState.xpop(); break; - case POP2 : frameState.xpop(); frameState.xpop(); break; - case DUP : frameState.xpush(frameState.xpeek()); break; + case POP : // fall through + case POP2 : // fall through + case DUP : // fall through case DUP_X1 : // fall through case DUP_X2 : // fall through case DUP2 : // fall through case DUP2_X1 : // fall through case DUP2_X2 : // fall through - case SWAP : stackOp(opcode); break; + case SWAP : frameState.stackOp(opcode); break; case IADD : // fall through case ISUB : // fall through case IMUL : genArithmeticOp(Kind.Int, opcode); break; @@ -3552,11 +3465,11 @@ case RET : genRet(stream.readLocalIndex()); break; case TABLESWITCH : genSwitch(new BytecodeTableSwitch(getStream(), bci())); break; case LOOKUPSWITCH : genSwitch(new BytecodeLookupSwitch(getStream(), bci())); break; - case IRETURN : genReturn(frameState.ipop(), Kind.Int); break; - case LRETURN : genReturn(frameState.lpop(), Kind.Long); break; - case FRETURN : genReturn(frameState.fpop(), Kind.Float); break; - case DRETURN : genReturn(frameState.dpop(), Kind.Double); break; - case ARETURN : genReturn(frameState.apop(), Kind.Object); break; + case IRETURN : genReturn(frameState.pop(Kind.Int), Kind.Int); break; + case LRETURN : genReturn(frameState.pop(Kind.Long), Kind.Long); break; + case FRETURN : genReturn(frameState.pop(Kind.Float), Kind.Float); break; + case DRETURN : genReturn(frameState.pop(Kind.Double), Kind.Double); break; + case ARETURN : genReturn(frameState.pop(Kind.Object), Kind.Object); break; case RETURN : genReturn(null, Kind.Void); break; case GETSTATIC : cpi = stream.readCPI(); genGetStatic(lookupField(cpi, opcode)); break; case PUTSTATIC : cpi = stream.readCPI(); genPutStatic(lookupField(cpi, opcode)); break; @@ -3574,8 +3487,8 @@ case ATHROW : genThrow(); break; case CHECKCAST : genCheckCast(); break; case INSTANCEOF : genInstanceOf(); break; - case MONITORENTER : genMonitorEnter(frameState.apop(), stream.nextBCI()); break; - case MONITOREXIT : genMonitorExit(frameState.apop(), null, stream.nextBCI()); break; + case MONITORENTER : genMonitorEnter(frameState.pop(Kind.Object), stream.nextBCI()); break; + case MONITOREXIT : genMonitorExit(frameState.pop(Kind.Object), null, stream.nextBCI()); break; case MULTIANEWARRAY : genNewMultiArray(stream.readCPI()); break; case IFNULL : genIfNull(Condition.EQ); break; case IFNONNULL : genIfNull(Condition.NE); break; @@ -3591,7 +3504,7 @@ } private void genArrayLength() { - frameState.ipush(append(genArrayLength(frameState.apop()))); + frameState.push(Kind.Int, append(genArrayLength(frameState.pop(Kind.Object)))); } public ResolvedJavaMethod getMethod() {
--- a/graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/LIRTest.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/LIRTest.java Thu May 28 17:00:59 2015 -0700 @@ -215,27 +215,32 @@ private InvocationPlugin floatingLIRNodePlugin = new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode spec) { - b.addPush(new FloatingLIRTestNode(getSnippetReflection(), targetMethod.getSignature().getReturnKind(), spec, new ValueNode[]{})); + Kind returnKind = targetMethod.getSignature().getReturnKind(); + b.addPush(returnKind, new FloatingLIRTestNode(getSnippetReflection(), returnKind, spec, new ValueNode[]{})); return true; } public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode spec, ValueNode arg0) { - b.addPush(new FloatingLIRTestNode(getSnippetReflection(), targetMethod.getSignature().getReturnKind(), spec, new ValueNode[]{arg0})); + Kind returnKind = targetMethod.getSignature().getReturnKind(); + b.addPush(returnKind, new FloatingLIRTestNode(getSnippetReflection(), returnKind, spec, new ValueNode[]{arg0})); return true; } public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode spec, ValueNode arg0, ValueNode arg1) { - b.addPush(new FloatingLIRTestNode(getSnippetReflection(), targetMethod.getSignature().getReturnKind(), spec, new ValueNode[]{arg0, arg1})); + Kind returnKind = targetMethod.getSignature().getReturnKind(); + b.addPush(returnKind, new FloatingLIRTestNode(getSnippetReflection(), returnKind, spec, new ValueNode[]{arg0, arg1})); return true; } public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode spec, ValueNode arg0, ValueNode arg1, ValueNode arg2) { - b.addPush(new FloatingLIRTestNode(getSnippetReflection(), targetMethod.getSignature().getReturnKind(), spec, new ValueNode[]{arg0, arg1, arg2})); + Kind returnKind = targetMethod.getSignature().getReturnKind(); + b.addPush(returnKind, new FloatingLIRTestNode(getSnippetReflection(), returnKind, spec, new ValueNode[]{arg0, arg1, arg2})); return true; } public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode spec, ValueNode arg0, ValueNode arg1, ValueNode arg2, ValueNode arg3) { - b.addPush(new FloatingLIRTestNode(getSnippetReflection(), targetMethod.getSignature().getReturnKind(), spec, new ValueNode[]{arg0, arg1, arg2, arg3})); + Kind returnKind = targetMethod.getSignature().getReturnKind(); + b.addPush(returnKind, new FloatingLIRTestNode(getSnippetReflection(), returnKind, spec, new ValueNode[]{arg0, arg1, arg2, arg3})); return true; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Thu May 28 17:00:59 2015 -0700 @@ -253,11 +253,11 @@ * the stack. */ public FrameState duplicateModifiedDuringCall(int newBci, Kind popKind) { - return duplicateModified(graph(), newBci, rethrowException, true, popKind); + return duplicateModified(graph(), newBci, rethrowException, true, popKind, null, null); } - public FrameState duplicateModifiedBeforeCall(int newBci, Kind popKind, ValueNode... pushedValues) { - return duplicateModified(graph(), newBci, rethrowException, false, popKind, pushedValues); + public FrameState duplicateModifiedBeforeCall(int newBci, Kind popKind, Kind[] pushedSlotKinds, ValueNode[] pushedValues) { + return duplicateModified(graph(), newBci, rethrowException, false, popKind, pushedSlotKinds, pushedValues); } /** @@ -266,17 +266,17 @@ * {@code pushedValues} will be formatted correctly in slot encoding: a long or double will be * followed by a null slot. */ - public FrameState duplicateModified(int newBci, boolean newRethrowException, Kind popKind, ValueNode... pushedValues) { - return duplicateModified(graph(), newBci, newRethrowException, duringCall, popKind, pushedValues); + public FrameState duplicateModified(int newBci, boolean newRethrowException, Kind popKind, Kind[] pushedSlotKinds, ValueNode[] pushedValues) { + return duplicateModified(graph(), newBci, newRethrowException, duringCall, popKind, pushedSlotKinds, pushedValues); } /** * Creates a copy of this frame state with the top of stack replaced with with * {@code pushedValue} which must be of type {@code popKind}. */ - public FrameState duplicateModified(Kind popKind, ValueNode pushedValue) { + public FrameState duplicateModified(Kind popKind, Kind pushedSlotKind, ValueNode pushedValue) { assert pushedValue != null && pushedValue.getKind() == popKind; - return duplicateModified(graph(), bci, rethrowException, duringCall, popKind, pushedValue); + return duplicateModified(graph(), bci, rethrowException, duringCall, popKind, new Kind[]{pushedSlotKind}, new ValueNode[]{pushedValue}); } /** @@ -285,7 +285,7 @@ * correctly in slot encoding: a long or double will be followed by a null slot. The bci will be * changed to newBci. */ - public FrameState duplicateModified(StructuredGraph graph, int newBci, boolean newRethrowException, boolean newDuringCall, Kind popKind, ValueNode... pushedValues) { + public FrameState duplicateModified(StructuredGraph graph, int newBci, boolean newRethrowException, boolean newDuringCall, Kind popKind, Kind[] pushedSlotKinds, ValueNode[] pushedValues) { ArrayList<ValueNode> copy; if (newRethrowException && !rethrowException && popKind == Kind.Void) { assert popKind == Kind.Void; @@ -301,10 +301,13 @@ copy.remove(copy.size() - 1); } } - for (ValueNode node : pushedValues) { - copy.add(node); - if (node.getKind().needsTwoSlots()) { - copy.add(null); + if (pushedValues != null) { + assert pushedSlotKinds.length == pushedValues.length; + for (int i = 0; i < pushedValues.length; i++) { + copy.add(pushedValues[i]); + if (pushedSlotKinds[i].needsTwoSlots()) { + copy.add(null); + } } } int newStackSize = copy.size() - localsSize;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Thu May 28 17:00:59 2015 -0700 @@ -485,7 +485,7 @@ * value (top of stack) */ if (frameState.stackSize() > 0 && (alwaysDuplicateStateAfter || stateAfterReturn.stackAt(0) != frameState.stackAt(0))) { - stateAfterReturn = stateAtReturn.duplicateModified(invokeReturnKind, frameState.stackAt(0)); + stateAfterReturn = stateAtReturn.duplicateModified(invokeReturnKind, invokeReturnKind, frameState.stackAt(0)); } frameState.replaceAndDelete(stateAfterReturn); @@ -497,7 +497,7 @@ */ FrameState stateAfterException = stateAtExceptionEdge; if (frameState.stackSize() > 0 && stateAtExceptionEdge.stackAt(0) != frameState.stackAt(0)) { - stateAfterException = stateAtExceptionEdge.duplicateModified(Kind.Object, frameState.stackAt(0)); + stateAfterException = stateAtExceptionEdge.duplicateModified(Kind.Object, Kind.Object, frameState.stackAt(0)); } frameState.replaceAndDelete(stateAfterException); return stateAfterException; @@ -509,7 +509,8 @@ assert frameState.outerFrameState() == null; NodeInputList<ValueNode> invokeArgsList = invoke.callTarget().arguments(); ValueNode[] invokeArgs = invokeArgsList.isEmpty() ? NO_ARGS : invokeArgsList.toArray(new ValueNode[invokeArgsList.size()]); - FrameState stateBeforeCall = stateAtReturn.duplicateModifiedBeforeCall(invoke.bci(), invokeReturnKind, invokeArgs); + ResolvedJavaMethod targetMethod = invoke.callTarget().targetMethod(); + FrameState stateBeforeCall = stateAtReturn.duplicateModifiedBeforeCall(invoke.bci(), invokeReturnKind, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), invokeArgs); frameState.replaceAndDelete(stateBeforeCall); return stateBeforeCall; } else {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Thu May 28 17:00:59 2015 -0700 @@ -190,7 +190,7 @@ FixedNode exceptionSux = exceptionEdge.next(); graph.addBeforeFixed(exceptionSux, exceptionMerge); exceptionObjectPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(Kind.Object), exceptionMerge)); - exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, Kind.Object, exceptionObjectPhi)); + exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, Kind.Object, new Kind[]{Kind.Object}, new ValueNode[]{exceptionObjectPhi})); } // create one separate block for each invoked method @@ -472,7 +472,7 @@ ExceptionObjectNode newExceptionEdge = (ExceptionObjectNode) exceptionEdge.copyWithInputs(); // set new state (pop old exception object, push new one) - newExceptionEdge.setStateAfter(stateAfterException.duplicateModified(Kind.Object, newExceptionEdge)); + newExceptionEdge.setStateAfter(stateAfterException.duplicateModified(Kind.Object, Kind.Object, newExceptionEdge)); EndNode endNode = graph.add(new EndNode()); newExceptionEdge.setNext(endNode);
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java Thu May 28 17:00:59 2015 -0700 @@ -58,9 +58,9 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { ValueNode folded = AMD64CountLeadingZerosNode.tryFold(value); if (folded != null) { - b.addPush(folded); + b.addPush(Kind.Int, folded); } else { - b.addPush(new AMD64CountLeadingZerosNode(value)); + b.addPush(Kind.Int, new AMD64CountLeadingZerosNode(value)); } return true; } @@ -73,9 +73,9 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { ValueNode folded = AMD64CountTrailingZerosNode.tryFold(value); if (folded != null) { - b.addPush(folded); + b.addPush(Kind.Int, folded); } else { - b.addPush(new AMD64CountTrailingZerosNode(value)); + b.addPush(Kind.Int, new AMD64CountTrailingZerosNode(value)); } return true; } @@ -116,7 +116,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode value) { // Emits a null-check for the otherwise unused receiver unsafe.get(); - b.addPush(kind.getStackKind(), new AtomicReadAndWriteNode(object, offset, value, kind, LocationIdentity.any())); + b.addPush(kind, new AtomicReadAndWriteNode(object, offset, value, kind, LocationIdentity.any())); return true; } }); @@ -125,7 +125,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode delta) { // Emits a null-check for the otherwise unused receiver unsafe.get(); - b.addPush(kind.getStackKind(), new AtomicReadAndAddNode(object, offset, delta, LocationIdentity.any())); + b.addPush(kind, new AtomicReadAndAddNode(object, offset, delta, LocationIdentity.any())); return true; } });
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java Thu May 28 17:00:59 2015 -0700 @@ -101,8 +101,7 @@ if (!COULD_NOT_FOLD.equals(constant)) { if (constant != null) { // Replace the invoke with the result of the call - ConstantNode res = b.add(ConstantNode.forConstant(constant, b.getMetaAccess())); - b.addPush(res.getKind().getStackKind(), res); + b.push(method.getSignature().getReturnKind(), ConstantNode.forConstant(constant, b.getMetaAccess(), b.getGraph())); } else { // This must be a void invoke assert method.getSignature().getReturnKind() == Kind.Void; @@ -168,7 +167,7 @@ if (returnKind != Kind.Void) { assert nonValueType || res.getKind().getStackKind() != Kind.Void; - res = b.addPush(returnKind.getStackKind(), res); + res = b.addPush(returnKind, res); } else { assert res.getKind().getStackKind() == Kind.Void; res = b.add(res);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MethodHandleInvocationPlugin.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MethodHandleInvocationPlugin.java Thu May 28 17:00:59 2015 -0700 @@ -54,7 +54,7 @@ if (invokeReturnType.getKind() == Kind.Void) { b.add(methodHandleNode); } else { - b.addPush(methodHandleNode); + b.addPush(invokeReturnType.getKind(), methodHandleNode); } } else { CallTargetNode callTarget = invoke.callTarget();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java Thu May 28 17:00:59 2015 -0700 @@ -575,7 +575,7 @@ } Kind invokeReturnKind = methodScope.invokeData.invoke.asNode().getKind(); - FrameState outerState = stateAtReturn.duplicateModified(methodScope.graph, methodScope.invokeData.invoke.bci(), stateAtReturn.rethrowException(), true, invokeReturnKind); + FrameState outerState = stateAtReturn.duplicateModified(methodScope.graph, methodScope.invokeData.invoke.bci(), stateAtReturn.rethrowException(), true, invokeReturnKind, null, null); /* * When the encoded graph has methods inlining, we can already have a proper caller
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Thu May 28 17:00:59 2015 -0700 @@ -104,7 +104,7 @@ r.register1("getValue", String.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { ResolvedJavaField field = b.getMetaAccess().lookupJavaField(STRING_VALUE_FIELD); - b.addPush(new LoadFieldNode(value, field)); + b.addPush(Kind.Object, new LoadFieldNode(value, field)); return true; } }); @@ -209,7 +209,7 @@ ReverseBytesNode reverse = b.add(new ReverseBytesNode(value)); RightShiftNode rightShift = b.add(new RightShiftNode(reverse, b.add(ConstantNode.forInt(16)))); ZeroExtendNode charCast = b.add(new ZeroExtendNode(b.add(new NarrowNode(rightShift, 16)), 32)); - b.push(Kind.Char.getStackKind(), b.recursiveAppend(charCast.canonical(null, value))); + b.push(Kind.Char, b.recursiveAppend(charCast.canonical(null, value))); return true; } }); @@ -223,7 +223,7 @@ ReverseBytesNode reverse = b.add(new ReverseBytesNode(value)); RightShiftNode rightShift = b.add(new RightShiftNode(reverse, b.add(ConstantNode.forInt(16)))); SignExtendNode charCast = b.add(new SignExtendNode(b.add(new NarrowNode(rightShift, 16)), 32)); - b.push(Kind.Short.getStackKind(), b.recursiveAppend(charCast.canonical(null, value))); + b.push(Kind.Short, b.recursiveAppend(charCast.canonical(null, value))); return true; } }); @@ -267,19 +267,19 @@ Class<?> type = kind.toJavaClass(); r.register2("addExact", type, type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind.getStackKind(), new IntegerAddExactNode(x, y)); + b.addPush(kind, new IntegerAddExactNode(x, y)); return true; } }); r.register2("subtractExact", type, type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind.getStackKind(), new IntegerSubExactNode(x, y)); + b.addPush(kind, new IntegerSubExactNode(x, y)); return true; } }); r.register2("multiplyExact", type, type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind.getStackKind(), new IntegerMulExactNode(x, y)); + b.addPush(kind, new IntegerMulExactNode(x, y)); return true; } }); @@ -329,7 +329,7 @@ } LogicNode compare = CompareNode.createCompareNode(graph, cond, lhs, rhs, b.getConstantReflection()); - b.addPush(Kind.Boolean.getStackKind(), new ConditionalNode(compare, trueValue, falseValue)); + b.addPush(Kind.Boolean, new ConditionalNode(compare, trueValue, falseValue)); return true; } } @@ -410,14 +410,14 @@ r.register2("isInstance", Receiver.class, Object.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver type, ValueNode object) { LogicNode condition = b.add(InstanceOfDynamicNode.create(b.getConstantReflection(), type.get(), object)); - b.push(Kind.Boolean.getStackKind(), b.recursiveAppend(new ConditionalNode(condition).canonical(null))); + b.push(Kind.Boolean, b.recursiveAppend(new ConditionalNode(condition).canonical(null))); return true; } }); r.register2("isAssignableFrom", Receiver.class, Class.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver type, ValueNode otherType) { ClassIsAssignableFromNode condition = b.recursiveAppend(new ClassIsAssignableFromNode(type.get(), otherType)); - b.push(Kind.Boolean.getStackKind(), b.recursiveAppend(new ConditionalNode(condition).canonical(null))); + b.push(Kind.Boolean, b.recursiveAppend(new ConditionalNode(condition).canonical(null))); return true; } }); @@ -496,7 +496,7 @@ } } ValueNode valueNode = UnboxNode.create(b.getMetaAccess(), b.getConstantReflection(), receiver.get(), kind); - b.addPush(kind.getStackKind(), valueNode); + b.addPush(kind, valueNode); return true; } @@ -519,7 +519,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode address) { // Emits a null-check for the otherwise unused receiver unsafe.get(); - b.addPush(returnKind.getStackKind(), new DirectReadNode(address, returnKind)); + b.addPush(returnKind, new DirectReadNode(address, returnKind)); return true; } @@ -529,7 +529,7 @@ if (isVolatile) { b.add(new MembarNode(JMM_PRE_VOLATILE_READ)); } - b.addPush(returnKind.getStackKind(), new UnsafeLoadNode(object, offset, returnKind, LocationIdentity.any())); + b.addPush(returnKind, new UnsafeLoadNode(object, offset, returnKind, LocationIdentity.any())); if (isVolatile) { b.add(new MembarNode(JMM_POST_VOLATILE_READ)); } @@ -586,7 +586,7 @@ r.register0("inCompiledCode", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { - b.addPush(Kind.Int, ConstantNode.forInt(1)); + b.addPush(Kind.Boolean, ConstantNode.forBoolean(true)); return true; } }); @@ -600,7 +600,7 @@ r.register2("injectBranchProbability", double.class, boolean.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) { - b.addPush(Kind.Int, new BranchProbabilityNode(probability, condition)); + b.addPush(Kind.Boolean, new BranchProbabilityNode(probability, condition)); return true; } }); @@ -617,10 +617,9 @@ Class<?> javaClass = kind == Kind.Object ? Object.class : kind.toJavaClass(); r.register1("blackhole", javaClass, blackholePlugin); - final Kind stackKind = kind.getStackKind(); r.register1("opaque", javaClass, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { - b.addPush(stackKind, new OpaqueNode(value)); + b.addPush(kind, new OpaqueNode(value)); return true; } });
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Thu May 28 17:00:59 2015 -0700 @@ -101,24 +101,23 @@ protected void processWordOperation(GraphBuilderContext b, ValueNode[] args, ResolvedJavaMethod wordMethod) throws JVMCIError { Operation operation = wordMethod.getAnnotation(Word.Operation.class); Kind returnKind = wordMethod.getSignature().getReturnKind(); - Kind returnStackKind = returnKind.getStackKind(); switch (operation.opcode()) { case NODE_CLASS: assert args.length == 2; ValueNode left = args[0]; ValueNode right = operation.rightOperandIsInt() ? toUnsigned(b, args[1], Kind.Int) : fromSigned(b, args[1]); - b.addPush(returnStackKind, createBinaryNodeInstance(operation.node(), left, right)); + b.addPush(returnKind, createBinaryNodeInstance(operation.node(), left, right)); break; case COMPARISON: assert args.length == 2; - b.push(returnStackKind, comparisonOp(b, operation.condition(), args[0], fromSigned(b, args[1]))); + b.push(returnKind, comparisonOp(b, operation.condition(), args[0], fromSigned(b, args[1]))); break; case NOT: assert args.length == 1; - b.addPush(returnStackKind, new XorNode(args[0], b.add(forIntegerKind(wordKind, -1)))); + b.addPush(returnKind, new XorNode(args[0], b.add(forIntegerKind(wordKind, -1)))); break; case READ_POINTER: @@ -132,7 +131,7 @@ } else { location = makeLocation(b, args[1], args[2]); } - b.push(returnStackKind, readOp(b, readKind, args[0], location, operation.opcode())); + b.push(returnKind, readOp(b, readKind, args[0], location, operation.opcode())); break; } case READ_HEAP: { @@ -140,7 +139,7 @@ Kind readKind = wordTypes.asKind(wordMethod.getSignature().getReturnType(wordMethod.getDeclaringClass())); LocationNode location = makeLocation(b, args[1], any()); BarrierType barrierType = snippetReflection.asObject(BarrierType.class, args[2].asJavaConstant()); - b.push(returnStackKind, readOp(b, readKind, args[0], location, barrierType, true)); + b.push(returnKind, readOp(b, readKind, args[0], location, barrierType, true)); break; } case WRITE_POINTER: @@ -160,44 +159,44 @@ } case ZERO: assert args.length == 0; - b.addPush(returnStackKind, forIntegerKind(wordKind, 0L)); + b.addPush(returnKind, forIntegerKind(wordKind, 0L)); break; case FROM_UNSIGNED: assert args.length == 1; - b.push(returnStackKind, fromUnsigned(b, args[0])); + b.push(returnKind, fromUnsigned(b, args[0])); break; case FROM_SIGNED: assert args.length == 1; - b.push(returnStackKind, fromSigned(b, args[0])); + b.push(returnKind, fromSigned(b, args[0])); break; case TO_RAW_VALUE: assert args.length == 1; - b.push(returnStackKind, toUnsigned(b, args[0], Kind.Long)); + b.push(returnKind, toUnsigned(b, args[0], Kind.Long)); break; case FROM_WORDBASE: assert args.length == 1; - b.push(returnStackKind, args[0]); + b.push(returnKind, args[0]); break; case FROM_OBJECT: assert args.length == 1; WordCastNode objectToWord = b.add(WordCastNode.objectToWord(args[0], wordKind)); - b.push(returnStackKind, objectToWord); + b.push(returnKind, objectToWord); break; case FROM_ARRAY: assert args.length == 2; - b.addPush(returnStackKind, new ComputeAddressNode(args[0], args[1], StampFactory.forKind(wordKind))); + b.addPush(returnKind, new ComputeAddressNode(args[0], args[1], StampFactory.forKind(wordKind))); break; case TO_OBJECT: assert args.length == 1; WordCastNode wordToObject = b.add(WordCastNode.wordToObject(args[0], wordKind)); - b.push(returnStackKind, wordToObject); + b.push(returnKind, wordToObject); break; default:
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Thu May 28 17:00:59 2015 -0700 @@ -85,14 +85,14 @@ OptimizedAssumption assumption = snippetReflection.asObject(OptimizedAssumption.class, (JavaConstant) constant); if (assumption.isValid()) { if (targetMethod.getName().equals("isValid")) { - b.addPush(ConstantNode.forBoolean(true)); + b.addPush(Kind.Boolean, ConstantNode.forBoolean(true)); } else { assert targetMethod.getName().equals("check") : targetMethod; } b.getAssumptions().record(new AssumptionValidAssumption(assumption)); } else { if (targetMethod.getName().equals("isValid")) { - b.addPush(ConstantNode.forBoolean(false)); + b.addPush(Kind.Boolean, ConstantNode.forBoolean(false)); } else { assert targetMethod.getName().equals("check") : targetMethod; b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.None)); @@ -116,31 +116,31 @@ Class<?> type = kind.toJavaClass(); r.register2("addExact", type, type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind.getStackKind(), new IntegerAddExactNode(x, y)); + b.addPush(kind, new IntegerAddExactNode(x, y)); return true; } }); r.register2("subtractExact", type, type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind.getStackKind(), new IntegerSubExactNode(x, y)); + b.addPush(kind, new IntegerSubExactNode(x, y)); return true; } }); r.register2("multiplyExact", type, type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind.getStackKind(), new IntegerMulExactNode(x, y)); + b.addPush(kind, new IntegerMulExactNode(x, y)); return true; } }); r.register2("multiplyHigh", type, type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind.getStackKind(), new IntegerMulHighNode(x, y)); + b.addPush(kind, new IntegerMulHighNode(x, y)); return true; } }); r.register2("multiplyHighUnsigned", type, type, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind.getStackKind(), new UnsignedMulHighNode(x, y)); + b.addPush(kind, new UnsignedMulHighNode(x, y)); return true; } }); @@ -151,13 +151,13 @@ Registration r = new Registration(plugins, CompilerDirectives.class); r.register0("inInterpreter", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { - b.addPush(Kind.Boolean.getStackKind(), ConstantNode.forBoolean(false)); + b.addPush(Kind.Boolean, ConstantNode.forBoolean(false)); return true; } }); r.register0("inCompiledCode", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { - b.addPush(Kind.Boolean.getStackKind(), ConstantNode.forBoolean(true)); + b.addPush(Kind.Boolean, ConstantNode.forBoolean(true)); return true; } }); @@ -185,7 +185,7 @@ }); r.register2("injectBranchProbability", double.class, boolean.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) { - b.addPush(Kind.Boolean.getStackKind(), new BranchProbabilityNode(probability, condition)); + b.addPush(Kind.Boolean, new BranchProbabilityNode(probability, condition)); return true; } }); @@ -200,9 +200,9 @@ r.register1("isCompilationConstant", Object.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) { - b.addPush(Kind.Boolean.getStackKind(), ConstantNode.forBoolean(true)); + b.addPush(Kind.Boolean, ConstantNode.forBoolean(true)); } else { - b.addPush(Kind.Boolean.getStackKind(), new IsCompilationConstantNode(value)); + b.addPush(Kind.Boolean, new IsCompilationConstantNode(value)); } return true; } @@ -375,7 +375,7 @@ locationIdentity = ObjectLocationIdentity.create(location.asJavaConstant()); } LogicNode compare = b.add(CompareNode.createCompareNode(Condition.EQ, condition, ConstantNode.forBoolean(true, object.graph()), b.getConstantReflection())); - b.addPush(returnKind.getStackKind(), b.add(new UnsafeLoadNode(object, offset, returnKind, locationIdentity, compare))); + b.addPush(returnKind, b.add(new UnsafeLoadNode(object, offset, returnKind, locationIdentity, compare))); return true; } // TODO: should we throw b.bailout() here?
--- a/graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Signature.java Fri May 29 01:11:41 2015 +0200 +++ b/graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Signature.java Thu May 28 17:00:59 2015 -0700 @@ -119,4 +119,21 @@ } return result; } + + default Kind[] toParameterKinds(boolean receiver) { + int args = getParameterCount(false); + Kind[] result; + int i = 0; + if (receiver) { + result = new Kind[args + 1]; + result[0] = Kind.Object; + i = 1; + } else { + result = new Kind[args]; + } + for (int j = 0; j < args; j++) { + result[i + j] = getParameterKind(j); + } + return result; + } }