# HG changeset patch # User Lukas Stadler # Date 1304953225 -7200 # Node ID 3558ca7088c06531d7619ed9bedf070e1beb757c # Parent 5768534fd4e5e18a2b5af0e1b4555a3e31b0de35 FrameState and Graphviz changes: * removed popx, pushx methods from GraphBuilder * FrameState subclass of Value * added String shortName() to Node * added GraphvizPrinter option to use short names * small hack in GraphvizPrinter: omit FrameState->Local connections * added GraalGraphviz to implicit classpatch (read from GRAAL env var) diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java --- a/graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java Mon May 09 17:00:25 2011 +0200 @@ -25,6 +25,7 @@ import java.util.*; +import com.oracle.graal.graph.*; import com.sun.c1x.alloc.*; import com.sun.c1x.asm.*; import com.sun.c1x.gen.*; @@ -56,6 +57,8 @@ public final CiAssumptions assumptions = new CiAssumptions(); public final FrameState placeholderState; + public final Graph graph = new Graph(); + private boolean hasExceptionHandlers; private final C1XCompilation parent; @@ -94,7 +97,7 @@ this.method = method; this.stats = stats == null ? new CiStatistics() : stats; this.registerConfig = method == null ? compiler.globalStubRegisterConfig : runtime.getRegisterConfig(method); - this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(0, 0, 0, 0) : null; + this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(0, 0, 0, 0, graph) : null; if (compiler.isObserved()) { compiler.fireCompilationStarted(new CompilationEvent(this)); @@ -166,7 +169,7 @@ */ public BlockMap getBlockMap(RiMethod method) { // PERF: cache the block map for methods that are compiled or inlined often - BlockMap map = new BlockMap(method, hir.numberOfBlocks(), hir.graph()); + BlockMap map = new BlockMap(method, hir.numberOfBlocks(), graph); if (!map.build(C1XOptions.PhiLoopStores)) { throw new CiBailout("build of BlockMap failed for " + method); } else { diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/C1XCompiler.java --- a/graal/GraalCompiler/src/com/sun/c1x/C1XCompiler.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/C1XCompiler.java Mon May 09 17:00:25 2011 +0200 @@ -155,7 +155,7 @@ ByteArrayOutputStream out = new ByteArrayOutputStream(); GraphvizPrinter printer = new GraphvizPrinter(out); printer.begin(name); - printer.print(graph); + printer.print(graph, true); printer.end(); try { diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Mon May 09 17:00:25 2011 +0200 @@ -182,8 +182,7 @@ flags |= Flag.HasHandler.mask; } - FrameState initialState = frameState.create(-1); - startBlock.mergeOrClone(initialState, rootMethod); + startBlock.mergeOrClone(frameState, rootMethod); BlockBegin syncHandler = null; // 3. setup internal state for appending instructions @@ -193,7 +192,7 @@ if (isSynchronized(rootMethod.accessFlags())) { // 4A.1 add a monitor enter to the start block - rootMethodSynchronizedObject = synchronizedObject(initialState, compilation.method); + rootMethodSynchronizedObject = synchronizedObject(frameState, compilation.method); genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI); // 4A.2 finish the start block finishStartBlock(startBlock, stdEntry); @@ -251,84 +250,12 @@ return stream.nextBCI(); } - private void ipush(Value x) { - frameState.ipush(x); - } - - private void lpush(Value x) { - frameState.lpush(x); - } - - private void fpush(Value x) { - frameState.fpush(x); - } - - private void dpush(Value x) { - frameState.dpush(x); - } - - private void apush(Value x) { - frameState.apush(x); - } - - private void wpush(Value x) { - frameState.wpush(x); - } - - private void push(CiKind kind, Value x) { - frameState.push(kind, x); - } - - private void pushReturn(CiKind kind, Value x) { - if (kind != CiKind.Void) { - frameState.push(kind.stackKind(), x); - } - } - - private Value ipop() { - return frameState.ipop(); - } - - private Value lpop() { - return frameState.lpop(); - } - - private Value fpop() { - return frameState.fpop(); - } - - private Value dpop() { - return frameState.dpop(); - } - - private Value apop() { - return frameState.apop(); - } - - private Value wpop() { - return frameState.wpop(); - } - - private Value pop(CiKind kind) { - return frameState.pop(kind); - } - - private CiKind peekKind() { - Value top = frameState.stackAt(frameState.stackSize() - 1); - if (top == null) { - top = frameState.stackAt(frameState.stackSize() - 2); - assert top != null; - assert top.kind.isDoubleWord(); - } - return top.kind; - } - private void loadLocal(int index, CiKind kind) { - push(kind, frameState.loadLocal(index)); + frameState.push(kind, frameState.loadLocal(index)); } private void storeLocal(CiKind kind, int index) { - frameState.storeLocal(index, pop(kind)); + frameState.storeLocal(index, frameState.pop(kind)); } List handleException(Instruction x, int bci) { @@ -380,7 +307,7 @@ assert entryState == null || curState.locksSize() == entryState.locksSize() : "locks do not match : cur:" + curState.locksSize() + " entry:" + entryState.locksSize(); // exception handler starts with an empty expression stack - curState = curState.copyWithEmptyStack(); + curState = curState.duplicateWithEmptyStack(); entry.mergeOrClone(curState, method()); @@ -422,13 +349,13 @@ // this is a load of class constant which might be unresolved RiType riType = (RiType) con; if (!riType.isResolved() || C1XOptions.TestPatching) { - push(CiKind.Object, append(new ResolveClass(riType, RiType.Representation.JavaClass, null, graph))); + frameState.push(CiKind.Object, append(new ResolveClass(riType, RiType.Representation.JavaClass, null, graph))); } else { - push(CiKind.Object, append(new Constant(riType.getEncoding(Representation.JavaClass), graph))); + frameState.push(CiKind.Object, append(new Constant(riType.getEncoding(Representation.JavaClass), graph))); } } else if (con instanceof CiConstant) { CiConstant constant = (CiConstant) con; - push(constant.kind.stackKind(), appendConstant(constant)); + frameState.push(constant.kind.stackKind(), appendConstant(constant)); } else { throw new Error("lookupConstant returned an object of incorrect type"); } @@ -436,21 +363,21 @@ void genLoadIndexed(CiKind kind) { FrameState stateBefore = frameState.create(bci()); - Value index = ipop(); - Value array = apop(); + Value index = frameState.ipop(); + Value array = frameState.apop(); Value length = null; if (cseArrayLength(array)) { length = append(new ArrayLength(array, stateBefore, graph)); } Value v = append(new LoadIndexed(array, index, length, kind, stateBefore, graph)); - push(kind.stackKind(), v); + frameState.push(kind.stackKind(), v); } void genStoreIndexed(CiKind kind) { FrameState stateBefore = frameState.create(bci()); - Value value = pop(kind.stackKind()); - Value index = ipop(); - Value array = apop(); + Value value = frameState.pop(kind.stackKind()); + Value index = frameState.ipop(); + Value array = frameState.apop(); Value length = null; if (cseArrayLength(array)) { length = append(new ArrayLength(array, stateBefore, graph)); @@ -552,41 +479,41 @@ } void genArithmeticOp(CiKind result, int opcode, CiKind x, CiKind y, FrameState state) { - Value yValue = pop(y); - Value xValue = pop(x); + Value yValue = frameState.pop(y); + Value xValue = frameState.pop(x); Value result1 = append(new ArithmeticOp(opcode, result, xValue, yValue, isStrict(method().accessFlags()), state, graph)); - push(result, result1); + frameState.push(result, result1); } void genNegateOp(CiKind kind) { - push(kind, append(new NegateOp(pop(kind), graph))); + frameState.push(kind, append(new NegateOp(frameState.pop(kind), graph))); } void genShiftOp(CiKind kind, int opcode) { - Value s = ipop(); - Value x = pop(kind); + Value s = frameState.ipop(); + Value x = frameState.pop(kind); // note that strength reduction of e << K >>> K is correctly handled in canonicalizer now - push(kind, append(new ShiftOp(opcode, x, s, graph))); + frameState.push(kind, append(new ShiftOp(opcode, x, s, graph))); } void genLogicOp(CiKind kind, int opcode) { - Value y = pop(kind); - Value x = pop(kind); - push(kind, append(new LogicOp(opcode, x, y, graph))); + Value y = frameState.pop(kind); + Value x = frameState.pop(kind); + frameState.push(kind, append(new LogicOp(opcode, x, y, graph))); } void genCompareOp(CiKind kind, int opcode, CiKind resultKind) { - Value y = pop(kind); - Value x = pop(kind); + Value y = frameState.pop(kind); + Value x = frameState.pop(kind); Value value = append(new CompareOp(opcode, resultKind, x, y, graph)); if (!resultKind.isVoid()) { - ipush(value); + frameState.ipush(value); } } void genConvert(int opcode, CiKind from, CiKind to) { CiKind tt = to.stackKind(); - push(tt, append(new Convert(opcode, pop(from.stackKind()), tt, graph))); + frameState.push(tt, append(new Convert(opcode, frameState.pop(from.stackKind()), tt, graph))); } void genIncrement() { @@ -613,27 +540,27 @@ void genIfZero(Condition cond) { Value y = appendConstant(CiConstant.INT_0); FrameState stateBefore = frameState.create(bci()); - Value x = ipop(); + Value x = frameState.ipop(); ifNode(x, cond, y, stateBefore); } void genIfNull(Condition cond) { FrameState stateBefore = frameState.create(bci()); Value y = appendConstant(CiConstant.NULL_OBJECT); - Value x = apop(); + Value x = frameState.apop(); ifNode(x, cond, y, stateBefore); } void genIfSame(CiKind kind, Condition cond) { FrameState stateBefore = frameState.create(bci()); - Value y = pop(kind); - Value x = pop(kind); + Value y = frameState.pop(kind); + Value x = frameState.pop(kind); ifNode(x, cond, y, stateBefore); } void genThrow(int bci) { FrameState stateBefore = frameState.create(bci()); - Throw t = new Throw(apop(), stateBefore, !noSafepoints(), graph); + Throw t = new Throw(frameState.apop(), stateBefore, !noSafepoints(), graph); appendWithoutOptimization(t, bci); } @@ -642,8 +569,8 @@ RiType type = constantPool().lookupType(cpi, CHECKCAST); boolean isInitialized = !C1XOptions.TestPatching && type.isResolved() && type.isInitialized(); Value typeInstruction = genResolveClass(RiType.Representation.ObjectHub, type, isInitialized, cpi); - CheckCast c = new CheckCast(type, typeInstruction, apop(), null, graph); - apush(append(c)); + CheckCast c = new CheckCast(type, typeInstruction, frameState.apop(), null, graph); + frameState.apush(append(c)); checkForDirectCompare(c); } @@ -652,8 +579,8 @@ RiType type = constantPool().lookupType(cpi, INSTANCEOF); boolean isInitialized = !C1XOptions.TestPatching && type.isResolved() && type.isInitialized(); Value typeInstruction = genResolveClass(RiType.Representation.ObjectHub, type, isInitialized, cpi); - InstanceOf i = new InstanceOf(type, typeInstruction, apop(), null, graph); - ipush(append(i)); + InstanceOf i = new InstanceOf(type, typeInstruction, frameState.apop(), null, graph); + frameState.ipush(append(i)); checkForDirectCompare(i); } @@ -671,21 +598,21 @@ if (memoryMap != null) { memoryMap.newInstance(n); } - apush(append(n)); + frameState.apush(append(n)); } void genNewTypeArray(int typeCode) { FrameState stateBefore = frameState.create(bci()); CiKind kind = CiKind.fromArrayTypeCode(typeCode); RiType elementType = compilation.runtime.asRiType(kind); - apush(append(new NewTypeArray(ipop(), elementType, stateBefore, graph))); + frameState.apush(append(new NewTypeArray(frameState.ipop(), elementType, stateBefore, graph))); } void genNewObjectArray(int cpi) { RiType type = constantPool().lookupType(cpi, ANEWARRAY); FrameState stateBefore = frameState.create(bci()); - NewArray n = new NewObjectArray(type, ipop(), stateBefore, graph); - apush(append(n)); + NewArray n = new NewObjectArray(type, frameState.ipop(), stateBefore, graph); + frameState.apush(append(n)); } void genNewMultiArray(int cpi) { @@ -694,24 +621,24 @@ int rank = stream().readUByte(bci() + 3); Value[] dims = new Value[rank]; for (int i = rank - 1; i >= 0; i--) { - dims[i] = ipop(); + dims[i] = frameState.ipop(); } NewArray n = new NewMultiArray(type, dims, stateBefore, cpi, constantPool(), graph); - apush(append(n)); + frameState.apush(append(n)); } void genGetField(int cpi, RiField field) { // Must copy the state here, because the field holder must still be on the stack. FrameState stateBefore = frameState.create(bci()); - LoadField load = new LoadField(apop(), field, stateBefore, graph); + LoadField load = new LoadField(frameState.apop(), field, stateBefore, graph); appendOptimizedLoadField(field.kind(), load); } void genPutField(int cpi, RiField field) { // Must copy the state here, because the field holder must still be on the stack. FrameState stateBefore = frameState.create(bci()); - Value value = pop(field.kind().stackKind()); - appendOptimizedStoreField(new StoreField(apop(), field, value, stateBefore, graph)); + Value value = frameState.pop(field.kind().stackKind()); + appendOptimizedStoreField(new StoreField(frameState.apop(), field, value, stateBefore, graph)); } void genGetStatic(int cpi, RiField field) { @@ -722,7 +649,7 @@ constantValue = field.constantValue(null); } if (constantValue != null) { - push(constantValue.kind.stackKind(), appendConstant(constantValue)); + frameState.push(constantValue.kind.stackKind(), appendConstant(constantValue)); } else { Value container = genResolveClass(RiType.Representation.StaticFields, holder, field.isResolved(), cpi); LoadField load = new LoadField(container, field, null, graph); @@ -733,7 +660,7 @@ void genPutStatic(int cpi, RiField field) { RiType holder = field.holder(); Value container = genResolveClass(RiType.Representation.StaticFields, holder, field.isResolved(), cpi); - Value value = pop(field.kind().stackKind()); + Value value = frameState.pop(field.kind().stackKind()); StoreField store = new StoreField(container, field, value, null, graph); appendOptimizedStoreField(store); } @@ -764,7 +691,7 @@ Value replacement = memoryMap.load(load); if (replacement != load) { // the memory buffer found a replacement for this load (no need to append) - push(kind.stackKind(), replacement); + frameState.push(kind.stackKind(), replacement); return; } } @@ -774,7 +701,7 @@ // local optimization happened, replace its value in the memory map memoryMap.setResult(load, optimized); } - push(kind.stackKind(), optimized); + frameState.push(kind.stackKind(), optimized); } void genInvokeStatic(RiMethod target, int cpi, RiConstantPool constantPool) { @@ -904,7 +831,7 @@ private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool, FrameState stateBefore) { CiKind resultType = returnKind(target); Value result = append(new Invoke(opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), stateBefore, graph)); - pushReturn(resultType, result); + frameState.pushReturn(resultType, result); } private RiType getExactType(RiType staticType, Value receiver) { @@ -1092,7 +1019,7 @@ list.add(blockAt(bci + offset)); boolean isSafepoint = isBackwards && !noSafepoints(); FrameState stateBefore = isSafepoint ? frameState.create(bci()) : null; - append(new TableSwitch(ipop(), list, ts.lowKey(), stateBefore, isSafepoint, graph)); + append(new TableSwitch(frameState.ipop(), list, ts.lowKey(), stateBefore, isSafepoint, graph)); } void genLookupswitch() { @@ -1114,7 +1041,7 @@ list.add(blockAt(bci + offset)); boolean isSafepoint = isBackwards && !noSafepoints(); FrameState stateBefore = isSafepoint ? frameState.create(bci()) : null; - append(new LookupSwitch(ipop(), list, keys, stateBefore, isSafepoint, graph)); + append(new LookupSwitch(frameState.ipop(), list, keys, stateBefore, isSafepoint, graph)); } /** @@ -1217,7 +1144,7 @@ return result; } - private Value synchronizedObject(FrameState curState2, RiMethod target) { + private Value synchronizedObject(FrameStateAccess curState2, RiMethod target) { if (isStatic(target.accessFlags())) { Constant classConstant = new Constant(target.holder().getEncoding(Representation.JavaClass), graph); return appendWithoutOptimization(classConstant, Instruction.SYNCHRONIZATION_ENTRY_BCI); @@ -1252,7 +1179,7 @@ // exit the monitor genMonitorExit(lock, Instruction.SYNCHRONIZATION_ENTRY_BCI); - apush(exception); + frameState.apush(exception); genThrow(bci); BlockEnd end = (BlockEnd) lastInstr; curBlock.setEnd(end); @@ -1260,6 +1187,7 @@ curBlock = origBlock; frameState.initializeFrom(origState); + origState.delete(); lastInstr = origLast; } @@ -1314,7 +1242,7 @@ // push an exception object onto the stack if we are parsing an exception handler if (pushException) { FrameState stateBefore = frameState.create(bci()); - apush(append(new ExceptionObject(stateBefore, graph))); + frameState.apush(append(new ExceptionObject(stateBefore, graph))); pushException = false; } @@ -1382,23 +1310,23 @@ // Checkstyle: stop switch (opcode) { case NOP : /* nothing to do */ break; - case ACONST_NULL : apush(appendConstant(CiConstant.NULL_OBJECT)); break; - case ICONST_M1 : ipush(appendConstant(CiConstant.INT_MINUS_1)); break; - case ICONST_0 : ipush(appendConstant(CiConstant.INT_0)); break; - case ICONST_1 : ipush(appendConstant(CiConstant.INT_1)); break; - case ICONST_2 : ipush(appendConstant(CiConstant.INT_2)); break; - case ICONST_3 : ipush(appendConstant(CiConstant.INT_3)); break; - case ICONST_4 : ipush(appendConstant(CiConstant.INT_4)); break; - case ICONST_5 : ipush(appendConstant(CiConstant.INT_5)); break; - case LCONST_0 : lpush(appendConstant(CiConstant.LONG_0)); break; - case LCONST_1 : lpush(appendConstant(CiConstant.LONG_1)); break; - case FCONST_0 : fpush(appendConstant(CiConstant.FLOAT_0)); break; - case FCONST_1 : fpush(appendConstant(CiConstant.FLOAT_1)); break; - case FCONST_2 : fpush(appendConstant(CiConstant.FLOAT_2)); break; - case DCONST_0 : dpush(appendConstant(CiConstant.DOUBLE_0)); break; - case DCONST_1 : dpush(appendConstant(CiConstant.DOUBLE_1)); break; - case BIPUSH : ipush(appendConstant(CiConstant.forInt(s.readByte()))); break; - case SIPUSH : ipush(appendConstant(CiConstant.forInt(s.readShort()))); break; + case ACONST_NULL : frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); break; + case ICONST_M1 : frameState.ipush(appendConstant(CiConstant.INT_MINUS_1)); break; + case ICONST_0 : frameState.ipush(appendConstant(CiConstant.INT_0)); break; + case ICONST_1 : frameState.ipush(appendConstant(CiConstant.INT_1)); break; + case ICONST_2 : frameState.ipush(appendConstant(CiConstant.INT_2)); break; + case ICONST_3 : frameState.ipush(appendConstant(CiConstant.INT_3)); break; + case ICONST_4 : frameState.ipush(appendConstant(CiConstant.INT_4)); break; + case ICONST_5 : frameState.ipush(appendConstant(CiConstant.INT_5)); break; + case LCONST_0 : frameState.lpush(appendConstant(CiConstant.LONG_0)); break; + case LCONST_1 : frameState.lpush(appendConstant(CiConstant.LONG_1)); break; + case FCONST_0 : frameState.fpush(appendConstant(CiConstant.FLOAT_0)); break; + case FCONST_1 : frameState.fpush(appendConstant(CiConstant.FLOAT_1)); break; + case FCONST_2 : frameState.fpush(appendConstant(CiConstant.FLOAT_2)); break; + case DCONST_0 : frameState.dpush(appendConstant(CiConstant.DOUBLE_0)); break; + case DCONST_1 : frameState.dpush(appendConstant(CiConstant.DOUBLE_1)); break; + case BIPUSH : frameState.ipush(appendConstant(CiConstant.forInt(s.readByte()))); break; + case SIPUSH : frameState.ipush(appendConstant(CiConstant.forInt(s.readShort()))); break; case LDC : // fall through case LDC_W : // fall through case LDC2_W : genLoadConstant(s.readCPI()); break; @@ -1546,18 +1474,18 @@ case IF_ICMPGE : genIfSame(CiKind.Int, Condition.GE); break; case IF_ICMPGT : genIfSame(CiKind.Int, Condition.GT); break; case IF_ICMPLE : genIfSame(CiKind.Int, Condition.LE); break; - case IF_ACMPEQ : genIfSame(peekKind(), Condition.EQ); break; - case IF_ACMPNE : genIfSame(peekKind(), Condition.NE); break; + case IF_ACMPEQ : genIfSame(frameState.peekKind(), Condition.EQ); break; + case IF_ACMPNE : genIfSame(frameState.peekKind(), Condition.NE); break; case GOTO : genGoto(s.currentBCI(), s.readBranchDest()); break; case JSR : genJsr(s.readBranchDest()); break; case RET : genRet(s.readLocalIndex()); break; case TABLESWITCH : genTableswitch(); break; case LOOKUPSWITCH : genLookupswitch(); break; - case IRETURN : genReturn(ipop()); break; - case LRETURN : genReturn(lpop()); break; - case FRETURN : genReturn(fpop()); break; - case DRETURN : genReturn(dpop()); break; - case ARETURN : genReturn(apop()); break; + case IRETURN : genReturn(frameState.ipop()); break; + case LRETURN : genReturn(frameState.lpop()); break; + case FRETURN : genReturn(frameState.fpop()); break; + case DRETURN : genReturn(frameState.dpop()); break; + case ARETURN : genReturn(frameState.apop()); break; case RETURN : genReturn(null ); break; case GETSTATIC : cpi = s.readCPI(); genGetStatic(cpi, constantPool().lookupField(cpi, opcode)); break; case PUTSTATIC : cpi = s.readCPI(); genPutStatic(cpi, constantPool().lookupField(cpi, opcode)); break; @@ -1574,8 +1502,8 @@ case ATHROW : genThrow(s.currentBCI()); break; case CHECKCAST : genCheckCast(); break; case INSTANCEOF : genInstanceOf(); break; - case MONITORENTER : genMonitorEnter(apop(), s.currentBCI()); break; - case MONITOREXIT : genMonitorExit(apop(), s.currentBCI()); break; + case MONITORENTER : genMonitorEnter(frameState.apop(), s.currentBCI()); break; + case MONITOREXIT : genMonitorExit(frameState.apop(), s.currentBCI()); break; case MULTIANEWARRAY : genNewMultiArray(s.readCPI()); break; case IFNULL : genIfNull(Condition.EQ); break; case IFNONNULL : genIfNull(Condition.NE); break; @@ -1608,7 +1536,7 @@ private void genArrayLength() { FrameState stateBefore = frameState.create(bci()); - ipush(append(new ArrayLength(apop(), stateBefore, graph))); + frameState.ipush(append(new ArrayLength(frameState.apop(), stateBefore, graph))); } void killMemoryMap() { diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/graph/IR.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Mon May 09 17:00:25 2011 +0200 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.graal.graph.*; import com.sun.c1x.*; import com.sun.c1x.debug.*; import com.sun.c1x.ir.*; @@ -62,8 +61,6 @@ */ private List orderedBlocks; - private final Graph graph = new Graph(); - /** * Creates a new IR instance for the specified compilation. * @param compilation the compilation @@ -96,7 +93,7 @@ private void buildGraph() { // Graph builder must set the startBlock and the osrEntryBlock - new GraphBuilder(compilation, this, graph).build(); + new GraphBuilder(compilation, this, compilation.graph).build(); assert startBlock != null; verifyAndPrint("After graph building"); @@ -176,12 +173,12 @@ } // create new successor and mark it for special block order treatment - BlockBegin newSucc = new BlockBegin(bci, nextBlockNumber(), graph); + BlockBegin newSucc = new BlockBegin(bci, nextBlockNumber(), compilation.graph); newSucc.setCriticalEdgeSplit(true); // This goto is not a safepoint. - Goto e = new Goto(target, null, false, graph); + Goto e = new Goto(target, null, false, compilation.graph); newSucc.appendNext(e, bci); newSucc.setEnd(e); // setup states @@ -276,8 +273,4 @@ public final int maxLocks() { return maxLocks; } - - public Graph graph() { - return graph; - } } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/ArithmeticOp.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ArithmeticOp.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ArithmeticOp.java Mon May 09 17:00:25 2011 +0200 @@ -33,10 +33,33 @@ */ public final class ArithmeticOp extends Op2 { - private static final int INPUT_COUNT = 0; + private static final int INPUT_COUNT = 1; + private static final int INPUT_STATE_BEFORE = 0; + private static final int SUCCESSOR_COUNT = 0; - private final FrameState stateBefore; + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + /** + * The state for this instruction. + */ + @Override + public FrameState stateBefore() { + return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_BEFORE); + } + + private FrameState setStateBefore(FrameState n) { + return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_BEFORE, n); + } + private final boolean isStrictFP; /** @@ -51,12 +74,7 @@ public ArithmeticOp(int opcode, CiKind kind, Value x, Value y, boolean isStrictFP, FrameState stateBefore, Graph graph) { super(kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph); this.isStrictFP = isStrictFP; - this.stateBefore = stateBefore; - } - - @Override - public FrameState stateBefore() { - return stateBefore; + setStateBefore(stateBefore); } /** @@ -74,7 +92,7 @@ */ @Override public boolean canTrap() { - return stateBefore != null; + return stateBefore() != null; } @Override @@ -90,4 +108,9 @@ public void print(LogStream out) { out.print(x()).print(' ').print(Bytecodes.operator(opcode)).print(' ').print(y()); } + + @Override + public String shortName() { + return Bytecodes.operator(opcode); + } } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Mon May 09 17:00:25 2011 +0200 @@ -41,9 +41,34 @@ */ public final class BlockBegin extends Instruction { - private static final int INPUT_COUNT = 0; + private static final int INPUT_COUNT = 1; + private static final int INPUT_STATE_BEFORE = 0; + private static final int SUCCESSOR_COUNT = 0; + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + /** + * The frame state before execution of the first instruction in this block. + */ + @Override + public FrameState stateBefore() { + return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_BEFORE); + } + + public FrameState setStateBefore(FrameState n) { + assert stateBefore() == null; + return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_BEFORE, n); + } + private static final List NO_HANDLERS = Collections.emptyList(); /** @@ -76,11 +101,6 @@ private int blockFlags; /** - * The frame state before execution of the first instruction in this block. - */ - private FrameState stateBefore; - - /** * A link to the last node in the block (which contains the successors). */ private BlockEnd end; @@ -183,24 +203,6 @@ } /** - * Gets the state at the start of this block. - * @return the state at the start of this block - */ - @Override - public FrameState stateBefore() { - return stateBefore; - } - - /** - * Sets the initial state for this block. - * @param stateBefore the state for this block - */ - public void setStateBefore(FrameState stateBefore) { - assert this.stateBefore == null; - this.stateBefore = stateBefore; - } - - /** * Gets the exception handlers that cover one or more instructions of this basic block. * * @return the exception handlers @@ -399,8 +401,8 @@ v.visitBlockBegin(this); } - public void mergeOrClone(FrameState newState, RiMethod method) { - FrameState existingState = stateBefore; + public void mergeOrClone(FrameStateAccess newState, RiMethod method) { + FrameState existingState = stateBefore(); if (existingState == null) { // this is the first state for the block @@ -410,7 +412,7 @@ } // copy state because it is modified - newState = newState.copy(); + FrameState duplicate = newState.duplicate(); if (C1XOptions.UseStackMapTableLiveness) { // if a liveness map is available, use it to invalidate dead locals @@ -419,17 +421,17 @@ assert bci() < livenessMap.length; CiBitMap liveness = livenessMap[bci()]; if (liveness != null) { - invalidateDeadLocals(newState, liveness); + invalidateDeadLocals(duplicate, liveness); } } } // if the block is a loop header, insert all necessary phis if (isParserLoopHeader()) { - insertLoopPhis(newState); + insertLoopPhis(duplicate); } - stateBefore = newState; + setStateBefore(duplicate); } else { if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { // stacks or locks do not match--bytecodes would not verify @@ -443,7 +445,7 @@ throw new CiBailout("jsr/ret too complicated"); } - existingState.merge(this, newState, graph()); + existingState.merge(this, newState); } } @@ -465,13 +467,13 @@ int stackSize = newState.stackSize(); for (int i = 0; i < stackSize; i++) { // always insert phis for the stack - newState.setupPhiForStack(this, i, graph()); + newState.setupPhiForStack(this, i); } int localsSize = newState.localsSize(); for (int i = 0; i < localsSize; i++) { Value x = newState.localAt(i); if (x != null) { - newState.setupPhiForLocal(this, i, graph()); + newState.setupPhiForLocal(this, i); } } } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java Mon May 09 17:00:25 2011 +0200 @@ -34,7 +34,8 @@ */ public abstract class BlockEnd extends Instruction { - private static final int INPUT_COUNT = 0; + private static final int INPUT_COUNT = 1; + private static final int INPUT_STATE_AFTER = 0; private final int blockSuccessorCount; @@ -49,6 +50,17 @@ } /** + * The state for this instruction. + */ + @Override + public FrameState stateAfter() { + return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_AFTER); + } + + public FrameState setStateAfter(FrameState n) { + return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_AFTER, n); + } + /** * The list of instructions that produce input for this instruction. */ public BlockBegin blockSuccessor(int index) { @@ -66,7 +78,6 @@ } BlockBegin begin; - FrameState stateAfter; boolean isSafepoint; /** @@ -95,18 +106,6 @@ } /** - * Gets the state after the end of this block. - */ - @Override - public FrameState stateAfter() { - return stateAfter; - } - - public void setStateAfter(FrameState state) { - stateAfter = state; - } - - /** * Checks whether this instruction is a safepoint. * @return {@code true} if this instruction is a safepoint */ diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/Constant.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Constant.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Constant.java Mon May 09 17:00:25 2011 +0200 @@ -164,4 +164,10 @@ public void print(LogStream out) { out.print(value.valueString()); } + + @Override + public String shortName() { + return value.name(); + } + } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/If.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/If.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/If.java Mon May 09 17:00:25 2011 +0200 @@ -191,4 +191,11 @@ out.print(" (safepoint)"); } } + + @Override + public String shortName() { + return "If " + condition.operator; + } + + } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/Instruction.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Instruction.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Instruction.java Mon May 09 17:00:25 2011 +0200 @@ -239,11 +239,11 @@ inputValuesDo(closure); FrameState stateBefore = stateBefore(); if (stateBefore != null) { - stateBefore.valuesDo(closure); + stateBefore.inputValuesDo(closure); } FrameState stateAfter = stateAfter(); if (stateAfter != null) { - stateAfter.valuesDo(closure); + stateAfter.inputValuesDo(closure); } } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/MonitorEnter.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/MonitorEnter.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/MonitorEnter.java Mon May 09 17:00:25 2011 +0200 @@ -31,10 +31,32 @@ */ public final class MonitorEnter extends AccessMonitor { - private static final int INPUT_COUNT = 0; + private static final int INPUT_COUNT = 1; + private static final int INPUT_STATE_AFTER = 0; + private static final int SUCCESSOR_COUNT = 0; - private FrameState stateAfter; + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + /** + * The state for this instruction. + */ + @Override + public FrameState stateAfter() { + return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_AFTER); + } + + public FrameState setStateAfter(FrameState n) { + return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_AFTER, n); + } /** * Creates a new MonitorEnter instruction. @@ -54,15 +76,6 @@ v.visitMonitorEnter(this); } - public void setStateAfter(FrameState frameState) { - this.stateAfter = frameState; - } - - @Override - public FrameState stateAfter() { - return stateAfter; - } - @Override public void print(LogStream out) { out.print("enter monitor[").print(lockNumber).print("](").print(object()).print(')'); diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java Mon May 09 17:00:25 2011 +0200 @@ -167,4 +167,11 @@ public void print(LogStream out) { out.print("phi function"); } + + @Override + public String shortName() { + return "Phi: " + index; + } + + } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/StateSplit.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/StateSplit.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/StateSplit.java Mon May 09 17:00:25 2011 +0200 @@ -32,10 +32,32 @@ */ public abstract class StateSplit extends Instruction { - private static final int INPUT_COUNT = 0; + private static final int INPUT_COUNT = 1; + private static final int INPUT_STATE_BEFORE = 0; + private static final int SUCCESSOR_COUNT = 0; - private FrameState stateBefore; + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + /** + * The state for this instruction. + */ + @Override + public FrameState stateBefore() { + return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_BEFORE); + } + + public FrameState setStateBefore(FrameState n) { + return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_BEFORE, n); + } /** * Creates a new state split with the specified value type. @@ -46,30 +68,12 @@ */ public StateSplit(CiKind kind, FrameState stateBefore, int inputCount, int successorCount, Graph graph) { super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); - this.stateBefore = stateBefore; + setStateBefore(stateBefore); } @Override public boolean canTrap() { - return stateBefore != null; + return stateBefore() != null; } - /** - * Records the state of this instruction before it is executed. - * - * @param stateBefore the state - */ - public final void setStateBefore(FrameState stateBefore) { - assert this.stateBefore == null; - this.stateBefore = stateBefore; - } - - /** - * Gets the state for this instruction. - * @return the state - */ - @Override - public final FrameState stateBefore() { - return stateBefore; - } } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java Mon May 09 17:00:25 2011 +0200 @@ -32,8 +32,9 @@ */ public final class Throw extends BlockEnd { - private static final int INPUT_COUNT = 1; + private static final int INPUT_COUNT = 2; private static final int INPUT_EXCEPTION = 0; + private static final int INPUT_STATE_BEFORE = 1; private static final int SUCCESSOR_COUNT = 0; @@ -58,7 +59,17 @@ return (Value) inputs().set(super.inputCount() + INPUT_EXCEPTION, n); } - FrameState stateBefore; + /** + * The state before this throw would occur. + */ + @Override + public FrameState stateBefore() { + return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_BEFORE); + } + + private FrameState setStateBefore(FrameState n) { + return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_BEFORE, n); + } /** * Creates a new Throw instruction. @@ -69,20 +80,11 @@ */ public Throw(Value exception, FrameState stateAfter, boolean isSafepoint, Graph graph) { super(CiKind.Illegal, null, isSafepoint, 0, INPUT_COUNT, SUCCESSOR_COUNT, graph); - this.stateBefore = stateAfter; + setStateBefore(stateAfter); setException(exception); } /** - * Returns the state before this throw would occur. - * @return the state before the throw - */ - @Override - public FrameState stateBefore() { - return stateBefore; - } - - /** * Checks whether this instruction can trap. * @return {@code true} because this instruction definitely throws an exception! */ diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java Mon May 09 17:00:25 2011 +0200 @@ -22,6 +22,8 @@ */ package com.sun.c1x.ir; +import com.sun.c1x.value.*; + /** * The {@link ValueVisitor} implements one half of the visitor * pattern for {@linkplain Value IR values}, allowing clients to implement functionality @@ -38,6 +40,7 @@ public abstract void visitConstant(Constant i); public abstract void visitConvert(Convert i); public abstract void visitExceptionObject(ExceptionObject i); + public abstract void visitFrameState(FrameState i); public abstract void visitGoto(Goto i); public abstract void visitIf(If i); public abstract void visitIfOp(IfOp i); diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/opt/InstructionSubstituter.java --- a/graal/GraalCompiler/src/com/sun/c1x/opt/InstructionSubstituter.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/opt/InstructionSubstituter.java Mon May 09 17:00:25 2011 +0200 @@ -30,8 +30,6 @@ * This class allows instructions to be substituted within an IR graph. It allows * registering substitutions and iterates over the instructions of a program and replaces * the occurrence of each instruction with its substitution, if it has one. - * - * @author Ben L. Titzer */ public final class InstructionSubstituter implements BlockClosure, ValueClosure { @@ -46,7 +44,7 @@ Instruction last = null; if (block.exceptionHandlerStates() != null) { for (FrameState s : block.exceptionHandlerStates()) { - s.valuesDo(this); + s.inputValuesDo(this); } } for (Instruction n = block; n != null; n = last.next()) { diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java --- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java Mon May 09 17:00:25 2011 +0200 @@ -30,6 +30,7 @@ import com.sun.c1x.ir.*; import com.sun.c1x.lir.*; import com.sun.c1x.util.*; +import com.sun.c1x.value.*; import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; @@ -568,4 +569,9 @@ protected CiValue osrBufferPointer() { return Util.nonFatalUnimplemented(null); } + + @Override + public void visitFrameState(FrameState i) { + // nothing to do for now + } } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java --- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java Mon May 09 17:00:25 2011 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.sun.c1x.*; +import com.sun.c1x.debug.*; import com.sun.c1x.ir.*; import com.sun.cri.ci.*; @@ -35,28 +36,26 @@ * The {@code FrameState} class encapsulates the frame state (i.e. local variables and * operand stack) at a particular point in the abstract interpretation. */ -public class FrameState { +public class FrameState extends Value implements FrameStateAccess { - /** - * The operand stack and local variables. - * The local variables occupy the index range {@code [0 .. maxLocals)}. - * The operand stack occupies the index range {@code [maxLocals .. values.length)}. - * The top of the operand stack is at index {@code maxLocals + stackIndex}. - * This does not include the operand stack or local variables of parent frames. - * - * {@linkplain CiKind#isDoubleWord() Double-word} local variables and - * operand stack values occupy 2 slots in this array with the second slot - * being {@code null}. - */ - protected final Value[] values; - - /** - * The number of local variables. - */ protected final int localsSize; protected final int stackSize; + protected final int locksSize; + + private static final int SUCCESSOR_COUNT = 0; + + @Override + protected int inputCount() { + return super.inputCount() + localsSize + stackSize + locksSize; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + /** * The bytecode index to which this frame state applies. This will be {@code -1} * iff this state is mutable. @@ -71,44 +70,53 @@ * @param stackSize size of the stack * @param lockSize number of locks */ - public FrameState(int bci, int localsSize, int stackSize, int lockSize) { + public FrameState(int bci, int localsSize, int stackSize, int locksSize, Graph graph) { + super(CiKind.Illegal, localsSize + stackSize + locksSize, SUCCESSOR_COUNT, graph); this.bci = bci; - this.values = new Value[localsSize + stackSize + lockSize]; this.localsSize = localsSize; this.stackSize = stackSize; + this.locksSize = locksSize; C1XMetrics.FrameStatesCreated++; - C1XMetrics.FrameStateValuesCreated += this.values.length; + C1XMetrics.FrameStateValuesCreated += localsSize + stackSize + locksSize; } - FrameState(int bci, Value[] locals, Value[] stack, int stackSize, ArrayList locks) { - this(bci, locals.length, stackSize, locks.size()); - System.arraycopy(locals, 0, values, 0, locals.length); - System.arraycopy(stack, 0, values, locals.length, stackSize); + FrameState(int bci, Value[] locals, Value[] stack, int stackSize, ArrayList locks, Graph graph) { + this(bci, locals.length, stackSize, locks.size(), graph); + for (int i = 0; i < locals.length; i++) { + inputs().set(i, locals[i]); + } + for (int i = 0; i < stackSize; i++) { + inputs().set(i + localsSize, stack[i]); + } for (int i = 0; i < locks.size(); i++) { - values[locals.length + stackSize + i] = locks.get(i); + inputs().set(locals.length + stackSize + i, locks.get(i)); } } /** - * Gets a immutable copy ({@link FrameState}) of this frame state. + * Gets a copy of this frame state. */ - public FrameState copy() { - FrameState other = new FrameState(bci, localsSize, stackSize, locksSize()); - System.arraycopy(values, 0, other.values, 0, values.length); + public FrameState duplicate() { + FrameState other = copy(); + other.inputs().setAll(inputs()); return other; } /** - * Gets an immutable copy of this frame state but without the stack. + * Gets a copy of this frame state without the stack. */ - public FrameState copyWithEmptyStack() { - FrameState other = new FrameState(bci, localsSize, 0, locksSize()); - System.arraycopy(values, 0, other.values, 0, localsSize); - System.arraycopy(values, localsSize + stackSize, other.values, localsSize, locksSize()); + public FrameState duplicateWithEmptyStack() { + FrameState other = new FrameState(bci, localsSize, 0, locksSize(), graph()); + for (int i = 0; i < localsSize; i++) { + other.inputs().set(i, localAt(i)); + } + for (int i = 0; i < locksSize; i++) { + other.inputs().set(localsSize + i, lockAt(i)); + } return other; } - public boolean isCompatibleWith(FrameState other) { + public boolean isCompatibleWith(FrameStateAccess other) { if (stackSize() != other.stackSize() || localsSize() != other.localsSize() || locksSize() != other.locksSize()) { return false; } @@ -128,9 +136,7 @@ } /** - * Returns the size of the local variables. - * - * @return the size of the local variables + * Gets the size of the local variables. */ public int localsSize() { return localsSize; @@ -147,7 +153,7 @@ * Gets number of locks held by this frame state. */ public int locksSize() { - return values.length - localsSize - stackSize; + return locksSize; } /** @@ -160,7 +166,7 @@ // note that for double word locals, the high slot should already be null // unless the local is actually dead and the high slot is being reused; // in either case, it is not necessary to null the high slot - values[i] = null; + inputs().set(i, null); } /** @@ -173,16 +179,16 @@ public void storeLocal(int i, Value x) { assert i < localsSize : "local variable index out of range: " + i; invalidateLocal(i); - values[i] = x; + inputs().set(i, x); if (isDoubleWord(x)) { // (tw) if this was a double word then kill i+1 - values[i + 1] = null; + inputs().set(i + 1, null); } if (i > 0) { // if there was a double word at i - 1, then kill it - Value p = values[i - 1]; + Value p = localAt(i - 1); if (isDoubleWord(p)) { - values[i - 1] = null; + inputs().set(i - 1, null); } } } @@ -195,7 +201,7 @@ */ public final Value localAt(int i) { assert i < localsSize : "local variable index out of range: " + i; - return values[i]; + return (Value) inputs().get(i); } /** @@ -206,7 +212,7 @@ */ public final Value stackAt(int i) { assert i >= 0 && i < (localsSize + stackSize); - return values[localsSize + i]; + return (Value) inputs().get(localsSize + i); } /** @@ -216,16 +222,15 @@ */ public final Value lockAt(int i) { assert i >= 0; - return values[localsSize + stackSize + i]; + return (Value) inputs().get(localsSize + stackSize + i); } /** * Inserts a phi statement into the stack at the specified stack index. * @param block the block begin for which we are creating the phi * @param i the index into the stack for which to create a phi - * @param graph */ - public void setupPhiForStack(BlockBegin block, int i, Graph graph) { + public void setupPhiForStack(BlockBegin block, int i) { Value p = stackAt(i); if (p != null) { if (p instanceof Phi) { @@ -234,7 +239,7 @@ return; } } - values[localsSize + i] = new Phi(p.kind, block, -i - 1, graph); + inputs().set(localsSize + i, new Phi(p.kind, block, -i - 1, graph())); } } @@ -242,17 +247,16 @@ * Inserts a phi statement for the local at the specified index. * @param block the block begin for which we are creating the phi * @param i the index of the local variable for which to create the phi - * @param graph */ - public void setupPhiForLocal(BlockBegin block, int i, Graph graph) { - Value p = values[i]; + public void setupPhiForLocal(BlockBegin block, int i) { + Value p = localAt(i); if (p instanceof Phi) { Phi phi = (Phi) p; if (phi.block() == block && phi.isLocal() && phi.localIndex() == i) { return; } } - storeLocal(i, new Phi(p.kind, block, i, graph)); + storeLocal(i, new Phi(p.kind, block, i, graph())); } /** @@ -267,7 +271,7 @@ */ public final Value valueAt(int i) { assert i < (localsSize + stackSize); - return values[i]; + return (Value) inputs().get(i); } /** @@ -284,10 +288,9 @@ public void checkPhis(BlockBegin block, FrameState other) { checkSize(other); - final int max = valuesSize(); - for (int i = 0; i < max; i++) { - Value x = values[i]; - Value y = other.values[i]; + for (int i = 0; i < valuesSize(); i++) { + Value x = valueAt(i); + Value y = other.valueAt(i); if (x != null && x != y) { if (x instanceof Phi) { Phi phi = (Phi) x; @@ -305,20 +308,20 @@ } } - private void checkSize(FrameState other) { + private void checkSize(FrameStateAccess other) { if (other.stackSize() != stackSize()) { throw new CiBailout("stack sizes do not match"); - } else if (other.localsSize != localsSize) { + } else if (other.localsSize() != localsSize) { throw new CiBailout("local sizes do not match"); } } - public void merge(BlockBegin block, FrameState other, Graph graph) { + public void merge(BlockBegin block, FrameStateAccess other) { checkSize(other); for (int i = 0; i < valuesSize(); i++) { - Value x = values[i]; + Value x = valueAt(i); if (x != null) { - Value y = other.values[i]; + Value y = other.valueAt(i); if (x != y) { if (typeMismatch(x, y)) { if (x instanceof Phi) { @@ -327,15 +330,15 @@ phi.makeDead(); } } - values[i] = null; + inputs().set(i, null); continue; } if (i < localsSize) { // this a local - setupPhiForLocal(block, i, graph); + setupPhiForLocal(block, i); } else { // this is a stack slot - setupPhiForStack(block, i - localsSize, graph); + setupPhiForStack(block, i - localsSize); } } } @@ -358,9 +361,8 @@ * @param proc the call back invoked for each live phi traversed */ public final boolean forEachLivePhi(BlockBegin block, PhiProcedure proc) { - int max = this.valuesSize(); - for (int i = 0; i < max; i++) { - Value instr = values[i]; + for (int i = 0; i < valuesSize(); i++) { + Value instr = valueAt(i); if (instr instanceof Phi && !instr.isDeadPhi()) { Phi phi = (Phi) instr; if (block == null || phi.block() == block) { @@ -377,9 +379,8 @@ * Checks whether this frame state has any {@linkplain Phi phi} statements. */ public boolean hasPhis() { - int max = valuesSize(); - for (int i = 0; i < max; i++) { - Value value = values[i]; + for (int i = 0; i < valuesSize(); i++) { + Value value = valueAt(i); if (value instanceof Phi) { return true; } @@ -388,19 +389,6 @@ } /** - * Iterates over all the values in this frame state and its callers, including the stack, locals, and locks. - * @param closure the closure to apply to each value - */ - public void valuesDo(ValueClosure closure) { - for (int i = 0; i < values.length; i++) { - if (values[i] != null) { - Value newValue = closure.apply(values[i]); - values[i] = newValue; - } - } - } - - /** * The interface implemented by a client of {@link FrameState#forEachLiveStateValue(ValueProcedure)}. */ public static interface ValueProcedure { @@ -413,9 +401,8 @@ * @param proc the call back called to process each live value traversed */ public final void forEachLiveStateValue(ValueProcedure proc) { - final int max = this.valuesSize(); - for (int i = 0; i < max; i++) { - Value value = this.values[i]; + for (int i = 0; i < valuesSize(); i++) { + Value value = valueAt(i); if (value != null) { proc.doValue(value); } @@ -441,4 +428,26 @@ } return sb.toString(); } + + @Override + public BlockBegin block() { + return null; + } + + @Override + public void accept(ValueVisitor v) { + v.visitFrameState(this); + } + + @Override + public void print(LogStream out) { + out.print("FrameState"); + } + + @Override + public FrameState copy() { + return new FrameState(bci, localsSize, stackSize, locksSize, graph()); + } + + } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java Mon May 09 17:00:25 2011 +0200 @@ -34,7 +34,7 @@ import static java.lang.reflect.Modifier.*; -public class FrameStateBuilder { +public class FrameStateBuilder implements FrameStateAccess { private final Graph graph; @@ -75,12 +75,16 @@ } public void initializeFrom(FrameState other) { - assert locals.length == other.localsSize; + assert locals.length == other.localsSize(); assert stack.length >= other.stackSize(); this.stackIndex = other.stackSize(); - System.arraycopy(other.values, 0, locals, 0, locals.length); - System.arraycopy(other.values, other.localsSize(), stack, 0, stackIndex); + for (int i = 0; i < other.localsSize(); i++) { + locals[i] = other.localAt(i); + } + for (int i = 0; i < other.stackSize(); i++) { + stack[i] = other.stackAt(i); + } locks.clear(); for (int i = 0; i < other.locksSize(); i++) { locks.add(other.lockAt(i)); @@ -88,7 +92,7 @@ } public FrameState create(int bci) { - return new FrameState(bci, locals, stack, stackIndex, locks); + return new FrameState(bci, locals, stack, stackIndex, locks, graph); } /** @@ -171,6 +175,12 @@ xpush(null); } + public void pushReturn(CiKind kind, Value x) { + if (kind != CiKind.Void) { + push(kind.stackKind(), x); + } + } + /** * Pops an instruction off the stack with the expected type. * @param kind the expected type @@ -265,6 +275,16 @@ return r; } + public CiKind peekKind() { + Value top = stackAt(stackSize() - 1); + if (top == null) { + top = stackAt(stackSize() - 2); + assert top != null; + assert top.kind.isDoubleWord(); + } + return top.kind; + } + /** * Truncates this stack to the specified size. * @param size the size to truncate to @@ -434,4 +454,21 @@ } + + @Override + public FrameState duplicate() { + return create(-1); + } + + @Override + public Value valueAt(int i) { + if (i < locals.length) { + return locals[i]; + } else if (i < locals.length + stackIndex) { + return stack[i - locals.length]; + } else { + return locks.get(i - locals.length - stack.length); + } + } + } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalGraph/src/com/oracle/graal/graph/Node.java --- a/graal/GraalGraph/src/com/oracle/graal/graph/Node.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalGraph/src/com/oracle/graal/graph/Node.java Mon May 09 17:00:25 2011 +0200 @@ -75,6 +75,10 @@ return graph; } + public String shortName() { + return getClass().getSimpleName(); + } + public void replace(Node other) { assert !isDeleted() && !other.isDeleted(); assert other == null || other.graph == graph; @@ -161,8 +165,7 @@ } public Node set(int index, Node node) { - // TODO: re-enable after Value class layout changes -// assert node == Null || node.graph == self().graph; + assert node == Null || node.graph == self().graph; Node old = nodes[index]; if (old != node) { @@ -188,6 +191,13 @@ return old; } + public void setAll(NodeArray other) { + assert size() == other.size(); + for (int i = 0; i < other.size(); i++) { + set(i, other.get(i)); + } + } + public Node get(int index) { return nodes[index]; } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalGraphviz/src/com/oracle/graal/graph/vis/GraphvizPrinter.java --- a/graal/GraalGraphviz/src/com/oracle/graal/graph/vis/GraphvizPrinter.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalGraphviz/src/com/oracle/graal/graph/vis/GraphvizPrinter.java Mon May 09 17:00:25 2011 +0200 @@ -77,23 +77,27 @@ /** * Prints all nodes and edges in the specified graph. */ - public void print(Graph graph) { + public void print(Graph graph, boolean shortNames) { // graph.getNodes() returns all the graph's nodes, not just "roots" for (Node n : graph.getNodes()) { - printNode(n); + printNode(n, shortNames); } } /** * Prints a single node and edges for all its inputs and successors. */ - public void printNode(Node node) { + public void printNode(Node node, boolean shortNames) { int id = node.id(); String name = "n" + id; NodeArray inputs = node.inputs(); NodeArray successors = node.successors(); - printNode(name, node.toString(), inputs.size(), successors.size()); + if (shortNames) { + printNode(name, node.shortName(), inputs.size(), successors.size()); + } else { + printNode(name, node.toString(), inputs.size(), successors.size()); + } for (int i = 0; i < successors.size(); ++i) { Node successor = successors.get(i); @@ -105,6 +109,9 @@ for (int i = 0; i < inputs.size(); ++i) { Node input = inputs.get(i); if (input != Node.Null) { + if (node.getClass().getSimpleName().equals("FrameState") && input.getClass().getSimpleName().equals("Local")) { + continue; + } printDataEdge(id, i, input.id()); } } diff -r 5768534fd4e5 -r 3558ca7088c0 graal/GraalGraphviz/test/com/oracle/graal/graph/vis/GraphvizTest.java --- a/graal/GraalGraphviz/test/com/oracle/graal/graph/vis/GraphvizTest.java Mon May 09 14:11:13 2011 +0200 +++ b/graal/GraalGraphviz/test/com/oracle/graal/graph/vis/GraphvizTest.java Mon May 09 17:00:25 2011 +0200 @@ -67,7 +67,7 @@ ByteArrayOutputStream out = new ByteArrayOutputStream(); GraphvizPrinter printer = new GraphvizPrinter(out); printer.begin("Simple test"); - printer.print(g); + printer.print(g, false); printer.end(); int exitCode = GraphvizRunner.process(GraphvizRunner.DOT_LAYOUT, new ByteArrayInputStream(out.toByteArray()), new NullOutputStream(), "xdot"); diff -r 5768534fd4e5 -r 3558ca7088c0 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Mon May 09 14:11:13 2011 +0200 +++ b/src/share/vm/runtime/arguments.cpp Mon May 09 17:00:25 2011 +0200 @@ -2694,6 +2694,8 @@ scp_p->add_prefix(temp); sprintf(temp, "%s/graal/GraalGraph/bin", graal_dir); scp_p->add_prefix(temp); + sprintf(temp, "%s/graal/GraalGraphviz/bin", graal_dir); + scp_p->add_prefix(temp); *scp_assembly_required_p = true; } else if (match_option(option, "-C1X:", &tail)) { // -C1X:xxxx // Option for the C1X compiler.