# HG changeset patch # User Doug Simon # Date 1368739804 -7200 # Node ID 6c2a7fc32416b84d76883678e2279298f6a39400 # Parent 82689c1c0dab98b70462ac048d963ac0e39ce7d0# Parent 4c2c99854535c9a967e15d5126d28876a210c626 Merge. diff -r 82689c1c0dab -r 6c2a7fc32416 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Thu May 16 23:26:59 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Thu May 16 23:30:04 2013 +0200 @@ -53,7 +53,7 @@ void shutdownCompiler() throws Throwable; - void startCompiler() throws Throwable; + void startCompiler(boolean bootstrapEnabled) throws Throwable; void bootstrap() throws Throwable; diff -r 82689c1c0dab -r 6c2a7fc32416 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu May 16 23:26:59 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu May 16 23:30:04 2013 +0200 @@ -101,7 +101,9 @@ assert unsafe.getObject(mirror, offset) == type; } - public void startCompiler() throws Throwable { + public void startCompiler(boolean bootstrapEnabled) throws Throwable { + + bootstrapRunning = bootstrapEnabled; HotSpotVMConfig config = graalRuntime.getConfig(); long offset = config.graalMirrorInClassOffset; @@ -339,7 +341,6 @@ TTY.flush(); long startTime = System.currentTimeMillis(); - bootstrapRunning = true; boolean firstRun = true; do { // Initialize compile queue with a selected set of methods. diff -r 82689c1c0dab -r 6c2a7fc32416 graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Thu May 16 23:26:59 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Thu May 16 23:30:04 2013 +0200 @@ -358,6 +358,7 @@ * @param object the object whose monitor will be locked. */ public void pushLock(ValueNode object) { + assert object.isAlive() && object.kind() == Kind.Object : "unexpected value: " + object; locks = Arrays.copyOf(locks, locks.length + 1); locks[locks.length - 1] = object; } @@ -406,7 +407,7 @@ * @param x the instruction which produces the value for the local */ public void storeLocal(int i, ValueNode x) { - assert x == null || x.kind() != Kind.Void && x.kind() != Kind.Illegal : "unexpected value: " + x; + assert x == null || x.isAlive() && x.kind() != Kind.Void && x.kind() != Kind.Illegal : "unexpected value: " + x; locals[i] = x; if (x != null && isTwoSlot(x.kind())) { // if this is a double word, then kill i+1 @@ -422,7 +423,7 @@ } private void storeStack(int i, ValueNode x) { - assert x == null || stack[i] == null || x.kind() == stack[i].kind() : "Method does not handle changes from one-slot to two-slot values"; + assert x == null || x.isAlive() && (stack[i] == null || x.kind() == stack[i].kind()) : "Method does not handle changes from one-slot to two-slot values or non-alive values"; stack[i] = x; } @@ -433,7 +434,7 @@ * @param x the instruction to push onto the stack */ public void push(Kind kind, ValueNode x) { - assert !x.isDeleted() && x.kind() != Kind.Void && x.kind() != Kind.Illegal; + assert x.isAlive() && x.kind() != Kind.Void && x.kind() != Kind.Illegal; xpush(assertKind(kind, x)); if (isTwoSlot(kind)) { xpush(null); @@ -446,7 +447,7 @@ * @param x the instruction to push onto the stack */ public void xpush(ValueNode x) { - assert x == null || (!x.isDeleted() && x.kind() != Kind.Void && x.kind() != Kind.Illegal); + assert x == null || (x.isAlive() && x.kind() != Kind.Void && x.kind() != Kind.Illegal); stack[stackSize++] = x; } diff -r 82689c1c0dab -r 6c2a7fc32416 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu May 16 23:26:59 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu May 16 23:30:04 2013 +0200 @@ -304,8 +304,8 @@ * @param type the unresolved type of the constant */ protected void handleUnresolvedLoadConstant(JavaType type) { - append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved))); - frameState.push(Kind.Object, append(ConstantNode.forObject(null, runtime, currentGraph))); + append(new DeoptimizeNode(InvalidateRecompile, Unresolved)); + frameState.push(Kind.Object, appendConstant(Constant.NULL_OBJECT)); } /** @@ -313,7 +313,7 @@ * @param object the object value whose type is being checked against {@code type} */ protected void handleUnresolvedCheckCast(JavaType type, ValueNode object) { - append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(object)), Unresolved, InvalidateRecompile))); + append(new FixedGuardNode(currentGraph.unique(new IsNullNode(object)), Unresolved, InvalidateRecompile)); frameState.apush(appendConstant(Constant.NULL_OBJECT)); } @@ -324,8 +324,7 @@ protected void handleUnresolvedInstanceOf(JavaType type, ValueNode object) { BlockPlaceholderNode successor = currentGraph.add(new BlockPlaceholderNode()); DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)); - IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 1)); - append(ifNode); + append(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 1)); lastInstr = successor; frameState.ipush(appendConstant(Constant.INT_0)); } @@ -334,7 +333,7 @@ * @param type the type being instantiated */ protected void handleUnresolvedNewInstance(JavaType type) { - append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved))); + append(new DeoptimizeNode(InvalidateRecompile, Unresolved)); frameState.apush(appendConstant(Constant.NULL_OBJECT)); } @@ -343,7 +342,7 @@ * @param length the length of the array */ protected void handleUnresolvedNewObjectArray(JavaType type, ValueNode length) { - append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved))); + append(new DeoptimizeNode(InvalidateRecompile, Unresolved)); frameState.apush(appendConstant(Constant.NULL_OBJECT)); } @@ -352,7 +351,7 @@ * @param dims the dimensions for the multi-array */ protected void handleUnresolvedNewMultiArray(JavaType type, ValueNode[] dims) { - append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved))); + append(new DeoptimizeNode(InvalidateRecompile, Unresolved)); frameState.apush(appendConstant(Constant.NULL_OBJECT)); } @@ -362,8 +361,8 @@ */ protected void handleUnresolvedLoadField(JavaField field, ValueNode receiver) { Kind kind = field.getKind(); - append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved))); - frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph))); + append(new DeoptimizeNode(InvalidateRecompile, Unresolved)); + frameState.push(kind.getStackKind(), appendConstant(Constant.defaultForKind(kind))); } /** @@ -372,7 +371,7 @@ * @param receiver the object containing the field or {@code null} if {@code field} is static */ protected void handleUnresolvedStoreField(JavaField field, ValueNode value, ValueNode receiver) { - append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved))); + append(new DeoptimizeNode(InvalidateRecompile, Unresolved)); } /** @@ -380,16 +379,16 @@ * @param type */ protected void handleUnresolvedExceptionType(Representation representation, JavaType type) { - append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved))); + append(new DeoptimizeNode(InvalidateRecompile, Unresolved)); } protected void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKind) { boolean withReceiver = invokeKind != InvokeKind.Static; - append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved))); + append(new DeoptimizeNode(InvalidateRecompile, Unresolved)); frameState.popArguments(javaMethod.getSignature().getParameterSlots(withReceiver), javaMethod.getSignature().getParameterCount(withReceiver)); Kind kind = javaMethod.getSignature().getReturnKind(); if (kind != Kind.Void) { - frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph))); + frameState.push(kind.getStackKind(), appendConstant(Constant.defaultForKind(kind))); } } @@ -432,7 +431,7 @@ // this is a load of class constant which might be unresolved JavaType type = (JavaType) con; if (type instanceof ResolvedJavaType) { - frameState.push(Kind.Object, append(ConstantNode.forConstant(((ResolvedJavaType) type).getEncoding(Representation.JavaClass), runtime, currentGraph))); + frameState.push(Kind.Object, appendConstant(((ResolvedJavaType) type).getEncoding(Representation.JavaClass))); } else { handleUnresolvedLoadConstant(type); } @@ -449,8 +448,7 @@ ValueNode index = frameState.ipop(); ValueNode array = frameState.apop(); - ValueNode v = append(currentGraph.add(new LoadIndexedNode(array, index, kind))); - frameState.push(kind.getStackKind(), v); + frameState.push(kind.getStackKind(), append(new LoadIndexedNode(array, index, kind))); } private void genStoreIndexed(Kind kind) { @@ -459,8 +457,7 @@ ValueNode value = frameState.pop(kind.getStackKind()); ValueNode index = frameState.ipop(); ValueNode array = frameState.apop(); - StoreIndexedNode result = currentGraph.add(new StoreIndexedNode(array, index, kind, value)); - append(result); + append(new StoreIndexedNode(array, index, kind, value)); } private void stackOp(int opcode) { @@ -585,8 +582,7 @@ default: throw new GraalInternalError("should not reach"); } - ValueNode result1 = append(currentGraph.unique(v)); - frameState.push(result, result1); + frameState.push(result, append(v)); } private void genIntegerDivOp(Kind result, int opcode) { @@ -605,12 +601,11 @@ default: throw new GraalInternalError("should not reach"); } - ValueNode result1 = append(currentGraph.add(v)); - frameState.push(result, result1); + frameState.push(result, append(v)); } private void genNegateOp(Kind kind) { - frameState.push(kind, append(currentGraph.unique(new NegateNode(frameState.pop(kind))))); + frameState.push(kind, append(new NegateNode(frameState.pop(kind)))); } private void genShiftOp(Kind kind, int opcode) { @@ -633,7 +628,7 @@ default: throw new GraalInternalError("should not reach"); } - frameState.push(kind, append(currentGraph.unique(v))); + frameState.push(kind, append(v)); } private void genLogicOp(Kind kind, int opcode) { @@ -656,26 +651,26 @@ default: throw new GraalInternalError("should not reach"); } - frameState.push(kind, append(currentGraph.unique(v))); + frameState.push(kind, append(v)); } private void genCompareOp(Kind kind, boolean isUnorderedLess) { ValueNode y = frameState.pop(kind); ValueNode x = frameState.pop(kind); - frameState.ipush(append(currentGraph.unique(new NormalizeCompareNode(x, y, isUnorderedLess)))); + frameState.ipush(append(new NormalizeCompareNode(x, y, isUnorderedLess))); } private void genConvert(ConvertNode.Op opcode) { ValueNode input = frameState.pop(opcode.from.getStackKind()); - frameState.push(opcode.to.getStackKind(), append(currentGraph.unique(new ConvertNode(opcode, input)))); + frameState.push(opcode.to.getStackKind(), append(new ConvertNode(opcode, input))); } private void genIncrement() { int index = stream().readLocalIndex(); int delta = stream().readIncrement(); ValueNode x = frameState.loadLocal(index); - ValueNode y = append(ConstantNode.forInt(delta, currentGraph)); - frameState.storeLocal(index, append(currentGraph.unique(new IntegerAddNode(Kind.Int, x, y)))); + ValueNode y = appendConstant(Constant.forInt(delta)); + frameState.storeLocal(index, append(new IntegerAddNode(Kind.Int, x, y))); } private void genGoto() { @@ -725,7 +720,7 @@ AbstractBeginNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState); IfNode ifNode = negate ? new IfNode(condition, falseSuccessor, trueSuccessor, 1 - probability) : new IfNode(condition, trueSuccessor, falseSuccessor, probability); - append(currentGraph.add(ifNode)); + append(ifNode); } private void genIfZero(Condition cond) { @@ -749,9 +744,8 @@ private void genThrow() { ValueNode exception = frameState.apop(); - FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true)); - append(node); - append(handleException(exception, bci())); + append(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true)); + lastInstr.setNext(handleException(exception, bci())); } private JavaType lookupType(int cpi, int bytecode) { @@ -803,9 +797,8 @@ ValueNode object = frameState.apop(); if (type instanceof ResolvedJavaType) { JavaTypeProfile profileForTypeCheck = getProfileForTypeCheck((ResolvedJavaType) type); - CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) type, object, profileForTypeCheck, false)); - append(checkCast); - frameState.apush(checkCast); + CheckCastNode checkCastNode = append(new CheckCastNode((ResolvedJavaType) type, object, profileForTypeCheck, false)); + frameState.apush(checkCastNode); } else { handleUnresolvedCheckCast(type, object); } @@ -818,8 +811,7 @@ if (type instanceof ResolvedJavaType) { ResolvedJavaType resolvedType = (ResolvedJavaType) type; InstanceOfNode instanceOfNode = new InstanceOfNode((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType)); - ConditionalNode conditional = currentGraph.unique(new ConditionalNode(currentGraph.unique(instanceOfNode), ConstantNode.forInt(1, currentGraph), ConstantNode.forInt(0, currentGraph))); - frameState.ipush(append(conditional)); + frameState.ipush(append(new ConditionalNode(currentGraph.unique(instanceOfNode), ConstantNode.forInt(1, currentGraph), ConstantNode.forInt(0, currentGraph)))); } else { handleUnresolvedInstanceOf(type, object); } @@ -828,8 +820,7 @@ void genNewInstance(int cpi) { JavaType type = lookupType(cpi, NEW); if (type instanceof ResolvedJavaType && ((ResolvedJavaType) type).isInitialized()) { - NewInstanceNode n = currentGraph.add(new NewInstanceNode((ResolvedJavaType) type, true)); - frameState.apush(append(n)); + frameState.apush(append(new NewInstanceNode((ResolvedJavaType) type, true))); } else { handleUnresolvedNewInstance(type); } @@ -870,16 +861,14 @@ private void genNewPrimitiveArray(int typeCode) { Class clazz = arrayTypeCodeToClass(typeCode); ResolvedJavaType elementType = runtime.lookupJavaType(clazz); - NewArrayNode nta = currentGraph.add(new NewArrayNode(elementType, frameState.ipop(), true)); - frameState.apush(append(nta)); + frameState.apush(append(new NewArrayNode(elementType, frameState.ipop(), true))); } private void genNewObjectArray(int cpi) { JavaType type = lookupType(cpi, ANEWARRAY); ValueNode length = frameState.ipop(); if (type instanceof ResolvedJavaType) { - NewArrayNode n = currentGraph.add(new NewArrayNode((ResolvedJavaType) type, length, true)); - frameState.apush(append(n)); + frameState.apush(append(new NewArrayNode((ResolvedJavaType) type, length, true))); } else { handleUnresolvedNewObjectArray(type, length); } @@ -894,8 +883,7 @@ dims[i] = frameState.ipop(); } if (type instanceof ResolvedJavaType) { - FixedWithNextNode n = currentGraph.add(new NewMultiArrayNode((ResolvedJavaType) type, dims)); - frameState.apush(append(n)); + frameState.apush(append(new NewMultiArrayNode((ResolvedJavaType) type, dims))); } else { handleUnresolvedNewMultiArray(type, dims); } @@ -907,8 +895,7 @@ Kind kind = field.getKind(); ValueNode receiver = frameState.apop(); if ((field instanceof ResolvedJavaField) && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) { - LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (ResolvedJavaField) field)); - appendOptimizedLoadField(kind, load); + appendOptimizedLoadField(kind, new LoadFieldNode(receiver, (ResolvedJavaField) field)); } else { handleUnresolvedLoadField(field, receiver); } @@ -931,9 +918,7 @@ } BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode()); BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode()); - IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.1)); - - append(ifNode); + append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.1)); lastInstr = falseSucc; if (GraalOptions.OmitHotExceptionStacktrace) { @@ -957,9 +942,7 @@ private void emitBoundsCheck(ValueNode index, ValueNode length) { BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode()); BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode()); - IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.9)); - - append(ifNode); + append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.9)); lastInstr = trueSucc; if (GraalOptions.OmitHotExceptionStacktrace) { @@ -981,7 +964,7 @@ emitNullCheck(receiver); if (outOfBoundsIndex != null) { - ValueNode length = append(currentGraph.add(new ArrayLengthNode(receiver))); + ValueNode length = append(new ArrayLengthNode(receiver)); emitBoundsCheck(outOfBoundsIndex, length); } Debug.metric("ExplicitExceptions").increment(); @@ -993,8 +976,7 @@ ValueNode value = frameState.pop(field.getKind().getStackKind()); ValueNode receiver = frameState.apop(); if (field instanceof ResolvedJavaField && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) { - StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (ResolvedJavaField) field, value)); - appendOptimizedStoreField(store); + appendOptimizedStoreField(new StoreFieldNode(receiver, (ResolvedJavaField) field, value)); } else { handleUnresolvedStoreField(field, value, receiver); } @@ -1003,8 +985,7 @@ private void genGetStatic(JavaField field) { Kind kind = field.getKind(); if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) { - LoadFieldNode load = currentGraph.add(new LoadFieldNode(null, (ResolvedJavaField) field)); - appendOptimizedLoadField(kind, load); + appendOptimizedLoadField(kind, new LoadFieldNode(null, (ResolvedJavaField) field)); } else { handleUnresolvedLoadField(field, null); } @@ -1013,8 +994,7 @@ private void genPutStatic(JavaField field) { ValueNode value = frameState.pop(field.getKind().getStackKind()); if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) { - StoreFieldNode store = currentGraph.add(new StoreFieldNode(null, (ResolvedJavaField) field, value)); - appendOptimizedStoreField(store); + appendOptimizedStoreField(new StoreFieldNode(null, (ResolvedJavaField) field, value)); } else { handleUnresolvedStoreField(field, value, null); } @@ -1141,8 +1121,7 @@ private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) { Kind resultType = targetMethod.getSignature().getReturnKind(); if (GraalOptions.DeoptALot) { - DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.None, RuntimeConstraint)); - append(deoptimize); + append(new DeoptimizeNode(DeoptimizationAction.None, RuntimeConstraint)); frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph)); return; } @@ -1163,15 +1142,12 @@ // be conservative if information was not recorded (could result in endless recompiles // otherwise) if (graphBuilderConfig.omitAllExceptionEdges() || (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE)) { - InvokeNode invoke = new InvokeNode(callTarget, bci()); - ValueNode result = appendWithBCI(currentGraph.add(invoke)); - frameState.pushReturn(resultType, result); - return invoke; + frameState.pushReturn(resultType, append(new InvokeNode(callTarget, bci()))); + return new InvokeNode(callTarget, bci()); } else { DispatchBeginNode exceptionEdge = handleException(null, bci()); - InvokeWithExceptionNode invoke = currentGraph.add(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci())); - ValueNode result = append(invoke); - frameState.pushReturn(resultType, result); + InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci())); + frameState.pushReturn(resultType, invoke); Block nextBlock = currentBlock.successors.get(0); assert bci() == currentBlock.endBci; @@ -1192,19 +1168,17 @@ } private MonitorEnterNode genMonitorEnter(ValueNode x) { - MonitorEnterNode monitorEnter = currentGraph.add(new MonitorEnterNode(x, frameState.lockDepth())); + MonitorEnterNode monitorEnter = append(new MonitorEnterNode(x, frameState.lockDepth())); frameState.pushLock(x); - appendWithBCI(monitorEnter); return monitorEnter; } private MonitorExitNode genMonitorExit(ValueNode x) { ValueNode lockedObject = frameState.popLock(); - MonitorExitNode monitorExit = currentGraph.add(new MonitorExitNode(x, frameState.lockDepth())); if (GraphUtil.originalValue(lockedObject) != GraphUtil.originalValue(x)) { throw new BailoutException("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject)); } - appendWithBCI(monitorExit); + MonitorExitNode monitorExit = append(new MonitorExitNode(x, frameState.lockDepth())); return monitorExit; } @@ -1227,7 +1201,7 @@ ValueNode local = frameState.loadLocal(localIndex); JsrScope scope = currentBlock.jsrScope; int retAddress = scope.nextReturnAddress(); - append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IntegerEqualsNode(local, ConstantNode.forInt(retAddress, currentGraph))), JavaSubroutineMismatch, InvalidateReprofile))); + append(new FixedGuardNode(currentGraph.unique(new IntegerEqualsNode(local, ConstantNode.forInt(retAddress, currentGraph))), JavaSubroutineMismatch, InvalidateReprofile)); if (!successor.jsrScope.equals(scope.pop())) { throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)"); } @@ -1314,12 +1288,11 @@ } double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities); - IntegerSwitchNode switchNode = currentGraph.add(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors)); + IntegerSwitchNode switchNode = append(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors)); for (int i = 0; i < actualSuccessors.size(); i++) { switchNode.setBlockSuccessor(i, createBlockTarget(successorProbabilities[i], actualSuccessors.get(i), frameState)); } - append(switchNode); } private static class SuccessorInfo { @@ -1338,26 +1311,37 @@ return ConstantNode.forConstant(constant, runtime, currentGraph); } - private ValueNode append(FixedNode fixed) { - lastInstr.setNext(fixed); + private T append(T fixed) { + assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet"; + assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; + T added = currentGraph.add(fixed); + lastInstr.setNext(added); lastInstr = null; - return fixed; - } - - protected ValueNode append(FixedWithNextNode x) { - return appendWithBCI(x); + return added; } - private static ValueNode append(ValueNode v) { - return v; + private T append(T fixed) { + assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet"; + assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; + T added = currentGraph.add(fixed); + lastInstr.setNext(added); + lastInstr = null; + return added; } - protected ValueNode appendWithBCI(FixedWithNextNode x) { - assert x.predecessor() == null : "instruction should not have been appended yet"; + protected T append(T fixed) { + assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet"; assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; - lastInstr.setNext(x); - lastInstr = x; - return x; + T added = currentGraph.add(fixed); + lastInstr.setNext(added); + lastInstr = added; + return added; + } + + private T append(T v) { + assert !(v instanceof ConstantNode); + T added = currentGraph.unique(v); + return added; } private static class Target { @@ -1524,7 +1508,7 @@ private ValueNode synchronizedObject(FrameStateBuilder state, ResolvedJavaMethod target) { if (isStatic(target.getModifiers())) { - return append(ConstantNode.forConstant(target.getDeclaringClass().getEncoding(Representation.JavaClass), runtime, currentGraph)); + return appendConstant(target.getDeclaringClass().getEncoding(Representation.JavaClass)); } else { return state.loadLocal(0); } @@ -1589,11 +1573,9 @@ private void createUnwind() { assert frameState.stackSize() == 1 : frameState; ValueNode exception = frameState.apop(); - FixedGuardNode guard = currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true)); - append(guard); + append(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true)); synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI); - UnwindNode unwindNode = currentGraph.add(new UnwindNode(exception)); - append(unwindNode); + append(new UnwindNode(exception)); } private void createReturn() { @@ -1602,7 +1584,7 @@ assert frameState.stackSize() == 0; if (Modifier.isSynchronized(method.getModifiers())) { - append(currentGraph.add(new ValueAnchorNode(true, x))); + append(new ValueAnchorNode(true, x)); assert !frameState.rethrowException(); } @@ -1610,15 +1592,13 @@ if (frameState.lockDepth() != 0) { throw new BailoutException("unbalanced monitors"); } - ReturnNode returnNode = currentGraph.add(new ReturnNode(x)); if (graphBuilderConfig.eagerInfopointMode()) { - InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.METHOD_END)); + InfopointNode ipn = append(new InfopointNode(InfopointReason.METHOD_END)); ipn.setStateAfter(frameState.create(FrameState.AFTER_BCI)); - append(ipn); } - append(returnNode); + append(new ReturnNode(x)); } private void synchronizedEpilogue(int bci) { @@ -1664,8 +1644,7 @@ frameState.push(Kind.Object, exception); FixedNode nextDispatch = createTarget(nextBlock, frameState); checkCast.setNext(catchSuccessor); - IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), checkCast, nextDispatch, 0.5)); - append(ifNode); + append(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), checkCast, nextDispatch, 0.5)); } } @@ -1731,9 +1710,8 @@ if (graphBuilderConfig.eagerInfopointMode() && lnt != null) { currentLineNumber = lnt.getLineNumber(bci); if (currentLineNumber != previousLineNumber) { - InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.LINE_NUMBER)); + InfopointNode ipn = append(new InfopointNode(InfopointReason.LINE_NUMBER)); ipn.setStateAfter(frameState.create(bci)); - append(ipn); previousLineNumber = currentLineNumber; } } @@ -1746,8 +1724,7 @@ if (block.jsrScope != JsrScope.EMPTY_SCOPE) { throw new BailoutException("OSR into a JSR scope is not supported"); } - EntryMarkerNode x = currentGraph.add(new EntryMarkerNode()); - append(x); + EntryMarkerNode x = append(new EntryMarkerNode()); frameState.insertProxies(x); x.setStateAfter(frameState.create(bci)); } @@ -2036,6 +2013,6 @@ } private void genArrayLength() { - frameState.ipush(append(currentGraph.add(new ArrayLengthNode(frameState.apop())))); + frameState.ipush(append(new ArrayLengthNode(frameState.apop()))); } } diff -r 82689c1c0dab -r 6c2a7fc32416 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Thu May 16 23:26:59 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Thu May 16 23:30:04 2013 +0200 @@ -218,7 +218,7 @@ } /** - * Unlinks a node from all its control flow neighbours and then removes it from its graph. The + * Unlinks a node from all its control flow neighbors and then removes it from its graph. The * node must have no {@linkplain Node#usages() usages}. * * @param node the node to be unlinked and removed diff -r 82689c1c0dab -r 6c2a7fc32416 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Thu May 16 23:26:59 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Thu May 16 23:30:04 2013 +0200 @@ -99,27 +99,34 @@ @Override protected void run(final StructuredGraph graph) { - InliningData data = new InliningData(); - data.pushGraph(graph, 1.0, 1.0); + InliningData data = new InliningData(graph, compilationAssumptions); while (data.hasUnprocessedGraphs()) { + MethodInvocation currentInvocation = data.currentInvocation(); GraphInfo graphInfo = data.currentGraph(); - if (graphInfo.hasRemainingInvokes() && inliningPolicy.continueInlining(data)) { + if (!currentInvocation.isRoot() && !inliningPolicy.isWorthInlining(currentInvocation.callee(), data.inliningDepth(), currentInvocation.probability(), currentInvocation.relevance(), false)) { + int remainingGraphs = currentInvocation.totalGraphs() - currentInvocation.processedGraphs(); + assert remainingGraphs > 0; + data.popGraphs(remainingGraphs); + data.popInvocation(); + } else if (graphInfo.hasRemainingInvokes() && inliningPolicy.continueInlining(graphInfo.graph())) { processNextInvoke(data, graphInfo); } else { data.popGraph(); - MethodInvocation currentInvocation = data.currentInvocation(); - if (currentInvocation != null) { + if (!currentInvocation.isRoot()) { assert currentInvocation.callee().invoke().asNode().isAlive(); currentInvocation.incrementProcessedGraphs(); - if (currentInvocation.processedAllGraphs()) { + if (currentInvocation.processedGraphs() == currentInvocation.totalGraphs()) { data.popInvocation(); MethodInvocation parentInvoke = data.currentInvocation(); - tryToInline(data.currentGraph(), currentInvocation, parentInvoke); + tryToInline(data.currentGraph(), currentInvocation, parentInvoke, data.inliningDepth() + 1); } } } } + + assert data.inliningDepth() == 0; + assert data.graphCount() == 0; } /** @@ -128,32 +135,35 @@ private void processNextInvoke(InliningData data, GraphInfo graphInfo) { Invoke invoke = graphInfo.popInvoke(); MethodInvocation callerInvocation = data.currentInvocation(); - Assumptions parentAssumptions = callerInvocation == null ? compilationAssumptions : callerInvocation.assumptions(); + Assumptions parentAssumptions = callerInvocation.assumptions(); InlineInfo info = InliningUtil.getInlineInfo(data, invoke, maxMethodPerInlining, replacements, parentAssumptions, optimisticOpts); - double invokeProbability = graphInfo.invokeProbability(invoke); - double invokeRelevance = graphInfo.invokeRelevance(invoke); - if (info != null && inliningPolicy.isWorthInlining(info, invokeProbability, invokeRelevance, false)) { - MethodInvocation calleeInvocation = data.pushInvocation(info, parentAssumptions, invokeProbability, invokeRelevance); + if (info != null) { + double invokeProbability = graphInfo.invokeProbability(invoke); + double invokeRelevance = graphInfo.invokeRelevance(invoke); + + if (inliningPolicy.isWorthInlining(info, data.inliningDepth(), invokeProbability, invokeRelevance, false)) { + MethodInvocation calleeInvocation = data.pushInvocation(info, parentAssumptions, invokeProbability, invokeRelevance); - for (int i = 0; i < info.numberOfMethods(); i++) { - InlineableElement elem = getInlineableElement(info.methodAt(i), info.invoke(), calleeInvocation.assumptions()); - info.setInlinableElement(i, elem); - if (elem instanceof StructuredGraph) { - data.pushGraph((StructuredGraph) elem, invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i)); - } else { - assert elem instanceof InlineableMacroNode; - data.pushDummyGraph(); + for (int i = 0; i < info.numberOfMethods(); i++) { + InlineableElement elem = getInlineableElement(info.methodAt(i), info.invoke(), calleeInvocation.assumptions()); + info.setInlinableElement(i, elem); + if (elem instanceof StructuredGraph) { + data.pushGraph((StructuredGraph) elem, invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i)); + } else { + assert elem instanceof InlineableMacroNode; + data.pushDummyGraph(); + } } } } } - private void tryToInline(GraphInfo callerGraphInfo, MethodInvocation calleeInfo, MethodInvocation parentInvocation) { + private void tryToInline(GraphInfo callerGraphInfo, MethodInvocation calleeInfo, MethodInvocation parentInvocation, int inliningDepth) { InlineInfo callee = calleeInfo.callee(); - Assumptions callerAssumptions = parentInvocation == null ? compilationAssumptions : parentInvocation.assumptions(); + Assumptions callerAssumptions = parentInvocation.assumptions(); - if (inliningPolicy.isWorthInlining(callee, calleeInfo.probability(), calleeInfo.relevance(), true)) { + if (inliningPolicy.isWorthInlining(callee, inliningDepth, calleeInfo.probability(), calleeInfo.relevance(), true)) { doInline(callerGraphInfo, calleeInfo, callerAssumptions); } else if (optimisticOpts.devirtualizeInvokes()) { callee.tryToDevirtualizeInvoke(runtime, callerAssumptions); @@ -399,32 +409,26 @@ super(replacements, hints); } - public boolean continueInlining(InliningData data) { - if (data.currentGraph().graph().getNodeCount() >= GraalOptions.MaximumDesiredSize) { + public boolean continueInlining(StructuredGraph currentGraph) { + if (currentGraph.getNodeCount() >= GraalOptions.MaximumDesiredSize) { InliningUtil.logInliningDecision("inlining is cut off by MaximumDesiredSize"); metricInliningStoppedByMaxDesiredSize.increment(); return false; } - - MethodInvocation currentInvocation = data.currentInvocation(); - if (currentInvocation == null) { - return true; - } - - return isWorthInlining(currentInvocation.callee(), currentInvocation.probability(), currentInvocation.relevance(), false); + return true; } @Override - public boolean isWorthInlining(InlineInfo info, double probability, double relevance, boolean fullyProcessed) { + public boolean isWorthInlining(InlineInfo info, int inliningDepth, double probability, double relevance, boolean fullyProcessed) { if (isIntrinsic(info)) { - return InliningUtil.logInlinedMethod(info, fullyProcessed, "intrinsic"); + return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic"); } double inliningBonus = getInliningBonus(info); int lowLevelGraphSize = previousLowLevelGraphSize(info); if (GraalOptions.SmallCompiledLowLevelGraphSize > 0 && lowLevelGraphSize > GraalOptions.SmallCompiledLowLevelGraphSize * inliningBonus) { - return InliningUtil.logNotInlinedMethod(info, "too large previous low-level graph: %d", lowLevelGraphSize); + return InliningUtil.logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph: %d", lowLevelGraphSize); } /* @@ -436,20 +440,20 @@ int nodes = determineNodeCount(info); if (nodes < GraalOptions.TrivialInliningSize * inliningBonus) { - return InliningUtil.logInlinedMethod(info, fullyProcessed, "trivial (nodes=%d)", nodes); + return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (nodes=%d)", nodes); } double invokes = determineInvokeProbability(info); if (GraalOptions.LimitInlinedInvokes > 0 && fullyProcessed && invokes > GraalOptions.LimitInlinedInvokes * inliningBonus) { - return InliningUtil.logNotInlinedMethod(info, "invoke probability is too high (%f)", invokes); + return InliningUtil.logNotInlinedMethod(info, inliningDepth, "invoke probability is too high (%f)", invokes); } double maximumNodes = computeMaximumSize(relevance, (int) (GraalOptions.MaximumInliningSize * inliningBonus)); if (nodes < maximumNodes) { - return InliningUtil.logInlinedMethod(info, fullyProcessed, "relevance-based (relevance=%f, nodes=%d)", relevance, nodes); + return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, nodes=%d)", relevance, nodes); } - return InliningUtil.logNotInlinedMethod(info, "(relevance=%f, probability=%f, bonus=%f)", relevance, probability, inliningBonus); + return InliningUtil.logNotInlinedMethod(info, inliningDepth, "(relevance=%f, probability=%f, bonus=%f)", relevance, probability, inliningBonus); } } @@ -466,8 +470,8 @@ assert start.isAlive(); } - public Stack apply() { - Stack invokes = new Stack<>(); + public LinkedList apply() { + LinkedList invokes = new LinkedList<>(); FixedNode current; forcedQueue(start); @@ -476,7 +480,7 @@ if (current instanceof Invoke) { if (current != start) { - invokes.push((Invoke) current); + invokes.addLast((Invoke) current); } queueSuccessors(current); } else if (current instanceof LoopBeginNode) { @@ -552,22 +556,30 @@ */ static class InliningData { - private static final GraphInfo DummyGraphInfo = new GraphInfo(null, new Stack(), 1.0, 1.0); + private static final GraphInfo DummyGraphInfo = new GraphInfo(null, new LinkedList(), 1.0, 1.0); private final ArrayDeque graphQueue; private final ArrayDeque invocationQueue; - private int maxGraphs = 1; + private int maxGraphs; - public InliningData() { + public InliningData(StructuredGraph rootGraph, Assumptions rootAssumptions) { this.graphQueue = new ArrayDeque<>(); this.invocationQueue = new ArrayDeque<>(); + this.maxGraphs = 1; + + invocationQueue.push(new MethodInvocation(null, rootAssumptions, 1.0, 1.0)); + pushGraph(rootGraph, 1.0, 1.0); + } + + public int graphCount() { + return graphQueue.size(); } public void pushGraph(StructuredGraph graph, double probability, double relevance) { assert !contains(graph); NodeBitMap visitedFixedNodes = graph.createNodeBitMap(); - Stack invokes = new InliningIterator(graph.start(), visitedFixedNodes).apply(); + LinkedList invokes = new InliningIterator(graph.start(), visitedFixedNodes).apply(); assert invokes.size() == count(graph.getInvokes()); graphQueue.push(new GraphInfo(graph, invokes, probability, relevance)); assert graphQueue.size() <= maxGraphs; @@ -590,6 +602,13 @@ assert graphQueue.size() <= maxGraphs; } + public void popGraphs(int count) { + assert count >= 0; + for (int i = 0; i < count; i++) { + graphQueue.pop(); + } + } + public MethodInvocation currentInvocation() { return invocationQueue.peek(); } @@ -619,7 +638,8 @@ } public int inliningDepth() { - return invocationQueue.size(); + assert invocationQueue.size() > 0; + return invocationQueue.size() - 1; } @Override @@ -683,9 +703,13 @@ assert processedGraphs <= callee.numberOfMethods(); } - public boolean processedAllGraphs() { + public int processedGraphs() { assert processedGraphs <= callee.numberOfMethods(); - return processedGraphs == callee.numberOfMethods(); + return processedGraphs; + } + + public int totalGraphs() { + return callee.numberOfMethods(); } public InlineInfo callee() { @@ -703,19 +727,23 @@ public double relevance() { return relevance; } + + public boolean isRoot() { + return callee == null; + } } private static class GraphInfo { private final StructuredGraph graph; - private final Stack remainingInvokes; + private final LinkedList remainingInvokes; private final double probability; private final double relevance; private NodesToDoubles nodeProbabilities; private NodesToDoubles nodeRelevance; - public GraphInfo(StructuredGraph graph, Stack invokes, double probability, double relevance) { + public GraphInfo(StructuredGraph graph, LinkedList invokes, double probability, double relevance) { this.graph = graph; this.remainingInvokes = invokes; this.probability = probability; @@ -739,7 +767,7 @@ } public Invoke popInvoke() { - return remainingInvokes.pop(); + return remainingInvokes.removeFirst(); } public void pushInvoke(Invoke invoke) { diff -r 82689c1c0dab -r 6c2a7fc32416 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu May 16 23:26:59 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu May 16 23:30:04 2013 +0200 @@ -59,9 +59,9 @@ public interface InliningPolicy { - boolean continueInlining(InliningData data); + boolean continueInlining(StructuredGraph graph); - boolean isWorthInlining(InlineInfo info, double probability, double relevance, boolean fullyProcessed); + boolean isWorthInlining(InlineInfo info, int inliningDepth, double probability, double relevance, boolean fullyProcessed); } public static class InlineableMacroNode implements InlineableElement { @@ -90,14 +90,14 @@ /** * Print a HotSpot-style inlining message to the console. */ - private static void printInlining(final InlineInfo info, final boolean success, final String msg, final Object... args) { - printInlining(info.methodAt(0), info.invoke(), success, msg, args); + private static void printInlining(final InlineInfo info, final int inliningDepth, final boolean success, final String msg, final Object... args) { + printInlining(info.methodAt(0), info.invoke(), inliningDepth, success, msg, args); } /** * Print a HotSpot-style inlining message to the console. */ - private static void printInlining(final ResolvedJavaMethod method, final Invoke invoke, final boolean success, final String msg, final Object... args) { + private static void printInlining(final ResolvedJavaMethod method, final Invoke invoke, final int inliningDepth, final boolean success, final String msg, final Object... args) { if (GraalOptions.HotSpotPrintInlining) { final int mod = method.getModifiers(); // 1234567 @@ -108,25 +108,24 @@ TTY.print("%c%c%c%c%c ", ' ', Modifier.isSynchronized(mod) ? 's' : ' ', ' ', ' ', Modifier.isNative(mod) ? 'n' : ' '); TTY.print(" "); // more indent TTY.print(" "); // initial inlining indent - final int level = computeInliningLevel(invoke); - for (int i = 0; i < level; i++) { + for (int i = 0; i < inliningDepth; i++) { TTY.print(" "); } TTY.println(String.format("@ %d %s %s%s", invoke.bci(), methodName(method, null), success ? "" : "not inlining ", String.format(msg, args))); } } - public static boolean logInlinedMethod(InlineInfo info, boolean allowLogging, String msg, Object... args) { - return logInliningDecision(info, allowLogging, true, msg, args); + public static boolean logInlinedMethod(InlineInfo info, int inliningDepth, boolean allowLogging, String msg, Object... args) { + return logInliningDecision(info, inliningDepth, allowLogging, true, msg, args); } - public static boolean logNotInlinedMethod(InlineInfo info, String msg, Object... args) { - return logInliningDecision(info, true, false, msg, args); + public static boolean logNotInlinedMethod(InlineInfo info, int inliningDepth, String msg, Object... args) { + return logInliningDecision(info, inliningDepth, true, false, msg, args); } - public static boolean logInliningDecision(InlineInfo info, boolean allowLogging, boolean success, String msg, final Object... args) { + public static boolean logInliningDecision(InlineInfo info, int inliningDepth, boolean allowLogging, boolean success, String msg, final Object... args) { if (allowLogging) { - printInlining(info, success, msg, args); + printInlining(info, inliningDepth, success, msg, args); if (shouldLogInliningDecision()) { logInliningDecision(methodName(info), success, msg, args); } @@ -151,12 +150,12 @@ return false; } - private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, ResolvedJavaMethod method, String msg) { - return logNotInlinedMethodAndReturnNull(invoke, method, msg, new Object[0]); + private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg) { + return logNotInlinedMethodAndReturnNull(invoke, inliningDepth, method, msg, new Object[0]); } - private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, ResolvedJavaMethod method, String msg, Object... args) { - printInlining(method, invoke, false, msg, args); + private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg, Object... args) { + printInlining(method, invoke, inliningDepth, false, msg, args); if (shouldLogInliningDecision()) { String methodString = methodName(method, invoke); logInliningDecision(methodString, false, msg, args); @@ -164,8 +163,8 @@ return null; } - private static boolean logNotInlinedMethodAndReturnFalse(Invoke invoke, ResolvedJavaMethod method, String msg) { - printInlining(method, invoke, false, msg, new Object[0]); + private static boolean logNotInlinedMethodAndReturnFalse(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg) { + printInlining(method, invoke, inliningDepth, false, msg, new Object[0]); if (shouldLogInliningDecision()) { String methodString = methodName(method, invoke); logInliningDecision(methodString, false, msg, new Object[0]); @@ -1085,18 +1084,18 @@ TypeProfileProxyNode typeProfileProxyNode = (TypeProfileProxyNode) receiver; typeProfile = typeProfileProxyNode.getProfile(); } else { - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no type profile exists"); + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no type profile exists"); } ProfiledType[] ptypes = typeProfile.getTypes(); if (ptypes == null || ptypes.length <= 0) { - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no types in profile"); + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no types in profile"); } double notRecordedTypeProbability = typeProfile.getNotRecordedProbability(); if (ptypes.length == 1 && notRecordedTypeProbability == 0) { if (!optimisticOpts.inlineMonomorphicCalls()) { - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining monomorphic calls is disabled"); + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "inlining monomorphic calls is disabled"); } ResolvedJavaType type = ptypes[0].getType(); @@ -1109,12 +1108,12 @@ invoke.setPolymorphic(true); if (!optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0) { - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length); + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length); } if (!optimisticOpts.inlineMegamorphicCalls() && notRecordedTypeProbability > 0) { // due to filtering impossible types, notRecordedTypeProbability can be > 0 although // the number of types is lower than what can be recorded in a type profile - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length, + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length, notRecordedTypeProbability * 100); } @@ -1135,7 +1134,7 @@ } if (concreteMethods.size() > maxNumberOfMethods) { - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "polymorphic call with more than %d target methods", maxNumberOfMethods); + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "polymorphic call with more than %d target methods", maxNumberOfMethods); } // Clear methods that fall below the threshold. @@ -1151,7 +1150,8 @@ if (newConcreteMethods.size() == 0) { // No method left that is worth inlining. - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)", concreteMethods.size()); + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)", + concreteMethods.size()); } concreteMethods = newConcreteMethods; @@ -1174,12 +1174,12 @@ if (usedTypes.size() == 0) { // No type left that is worth checking for. - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length); + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length); } for (ResolvedJavaMethod concrete : concreteMethods) { if (!checkTargetConditions(data, replacements, invoke, concrete, optimisticOpts)) { - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined"); + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined"); } } return new MultiTypeGuardInlineInfo(invoke, concreteMethods, concreteMethodsProbabilities, usedTypes, typesToConcretes, notRecordedTypeProbability); @@ -1214,34 +1214,24 @@ private static boolean checkTargetConditions(InliningData data, Replacements replacements, Invoke invoke, ResolvedJavaMethod method, OptimisticOptimizations optimisticOpts) { if (method == null) { - return logNotInlinedMethodAndReturnFalse(invoke, method, "the method is not resolved"); + return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method is not resolved"); } else if (Modifier.isNative(method.getModifiers()) && (!GraalOptions.Intrinsify || !InliningUtil.canIntrinsify(replacements, method))) { - return logNotInlinedMethodAndReturnFalse(invoke, method, "it is a non-intrinsic native method"); + return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is a non-intrinsic native method"); } else if (Modifier.isAbstract(method.getModifiers())) { - return logNotInlinedMethodAndReturnFalse(invoke, method, "it is an abstract method"); + return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is an abstract method"); } else if (!method.getDeclaringClass().isInitialized()) { - return logNotInlinedMethodAndReturnFalse(invoke, method, "the method's class is not initialized"); + return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method's class is not initialized"); } else if (!method.canBeInlined()) { - return logNotInlinedMethodAndReturnFalse(invoke, method, "it is marked non-inlinable"); + return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is marked non-inlinable"); } else if (data.countRecursiveInlining(method) > GraalOptions.MaximumRecursiveInlining) { - return logNotInlinedMethodAndReturnFalse(invoke, method, "it exceeds the maximum recursive inlining depth"); + return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it exceeds the maximum recursive inlining depth"); } else if (new OptimisticOptimizations(method).lessOptimisticThan(optimisticOpts)) { - return logNotInlinedMethodAndReturnFalse(invoke, method, "the callee uses less optimistic optimizations than caller"); + return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the callee uses less optimistic optimizations than caller"); } else { return true; } } - private static int computeInliningLevel(Invoke invoke) { - int count = -1; - FrameState curState = invoke.stateAfter(); - while (curState != null) { - count++; - curState = curState.outerFrameState(); - } - return count; - } - static MonitorExitNode findPrecedingMonitorExit(UnwindNode unwind) { Node pred = unwind.predecessor(); while (pred != null) { diff -r 82689c1c0dab -r 6c2a7fc32416 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Thu May 16 23:26:59 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Thu May 16 23:30:04 2013 +0200 @@ -95,6 +95,7 @@ FixedNode fixed = (FixedNode) node; if (identity == LocationNode.ANY_LOCATION || read.location().getLocationIdentity() == identity) { addPhantomReference(read, fixed); + iter.remove(); } } } diff -r 82689c1c0dab -r 6c2a7fc32416 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Thu May 16 23:26:59 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Thu May 16 23:30:04 2013 +0200 @@ -114,6 +114,16 @@ } private boolean isWord(ValueNode node) { + if (node instanceof ProxyNode) { + /* + * The proxy node will eventually get the same stamp as the value it is proxying. + * However, since we cannot guarantee the order in which isWord is called during the + * verification phase, the stamp assignment for the value might not have happened yet. + * Therefore, we check the proxied value directly instead of the proxy. + */ + return isWord(((ProxyNode) node).value()); + } + return wordAccess.isWord(node); } diff -r 82689c1c0dab -r 6c2a7fc32416 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Thu May 16 23:26:59 2013 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Thu May 16 23:30:04 2013 +0200 @@ -95,7 +95,7 @@ } } if (UseCompiler) { - VMToCompiler::startCompiler(); + VMToCompiler::startCompiler(BootstrapGraal); _initialized = true; if (BootstrapGraal) { // We turn off CompileTheWorld and complete the VM startup so that diff -r 82689c1c0dab -r 6c2a7fc32416 src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Thu May 16 23:26:59 2013 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Thu May 16 23:30:04 2013 +0200 @@ -123,12 +123,13 @@ } } -void VMToCompiler::startCompiler() { +void VMToCompiler::startCompiler(jboolean bootstrap_enabled) { JavaThread* THREAD = JavaThread::current(); JavaValue result(T_VOID); JavaCallArguments args; args.push_oop(instance()); - JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::startCompiler_name(), vmSymbols::void_method_signature(), &args, THREAD); + args.push_int(bootstrap_enabled); + JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::startCompiler_name(), vmSymbols::bool_void_signature(), &args, THREAD); check_pending_exception("Error while calling startCompiler"); } diff -r 82689c1c0dab -r 6c2a7fc32416 src/share/vm/graal/graalVMToCompiler.hpp --- a/src/share/vm/graal/graalVMToCompiler.hpp Thu May 16 23:26:59 2013 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.hpp Thu May 16 23:30:04 2013 +0200 @@ -59,8 +59,8 @@ // public abstract void shutdownCompiler(); static void shutdownCompiler(); - // public abstract void startCompiler(); - static void startCompiler(); + // public abstract void startCompiler(boolean bootstrapEnabled); + static void startCompiler(jboolean bootstrap_enabled); // public abstract void bootstrap(); static void bootstrap();