# HG changeset patch # User Gilles Duboscq # Date 1305213470 -7200 # Node ID d8601d421b96e1f0da7da0bb1f16eda2f3527224 # Parent 50b181d88c9fa21f9743be0482a411916d0b9848 New Deoptimize node, remove ResolveClass node and replace it with deoptimization diff -r 50b181d88c9f -r d8601d421b96 graal/GraalCompiler/src/com/sun/c1x/asm/AbstractAssembler.java --- a/graal/GraalCompiler/src/com/sun/c1x/asm/AbstractAssembler.java Thu May 12 17:00:09 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/asm/AbstractAssembler.java Thu May 12 17:17:50 2011 +0200 @@ -44,6 +44,7 @@ public final CiTarget target; public final CiTargetMethod targetMethod; public List exceptionInfoList; + protected int lastSafepointPos; public AbstractAssembler(CiTarget target) { this.target = target; @@ -162,6 +163,8 @@ public void recordImplicitException(int pcOffset, LIRDebugInfo info) { // record an implicit exception point if (info != null) { + assert lastSafepointPos < pcOffset; + lastSafepointPos = pcOffset; targetMethod.recordSafepoint(pcOffset, info.debugInfo()); recordExceptionHandlers(pcOffset, info); } @@ -169,17 +172,23 @@ protected void recordDirectCall(int posBefore, int posAfter, Object target, LIRDebugInfo info) { CiDebugInfo debugInfo = info != null ? info.debugInfo() : null; + assert lastSafepointPos < posAfter; + lastSafepointPos = posAfter; targetMethod.recordCall(posBefore, target, debugInfo, true); } protected void recordIndirectCall(int posBefore, int posAfter, Object target, LIRDebugInfo info) { CiDebugInfo debugInfo = info != null ? info.debugInfo() : null; + assert lastSafepointPos < posAfter; + lastSafepointPos = posAfter; targetMethod.recordCall(posBefore, target, debugInfo, false); } public void recordSafepoint(int pos, LIRDebugInfo info) { // safepoints always need debug info CiDebugInfo debugInfo = info.debugInfo(); + assert lastSafepointPos < pos; + lastSafepointPos = pos; targetMethod.recordSafepoint(pos, debugInfo); } @@ -227,4 +236,8 @@ public void blockComment(String s) { targetMethod.addAnnotation(new CodeComment(codeBuffer.position(), s)); } + + public int lastSafepointPos() { + return lastSafepointPos; + } } diff -r 50b181d88c9f -r d8601d421b96 graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java --- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Thu May 12 17:00:09 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Thu May 12 17:17:50 2011 +0200 @@ -210,6 +210,13 @@ return deoptimizationStubs; } + private void addDeoptimizationStub(DeoptimizationStub stub) { + if (deoptimizationStubs == null) { + deoptimizationStubs = new ArrayList(); + } + deoptimizationStubs.add(stub); + } + public static class DeoptimizationStub { public final Label label = new Label(); public final LIRDebugInfo info; @@ -298,13 +305,6 @@ } @Override - public void visitResolveClass(ResolveClass i) { - LIRDebugInfo info = stateFor(i); - XirSnippet snippet = xir.genResolveClass(site(i), i.type, i.portion); - emitXir(snippet, i, info, null, true); - } - - @Override public void visitCheckCast(CheckCast x) { XirArgument obj = toXirArgument(x.object()); XirSnippet snippet = xir.genCheckCast(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass()); @@ -447,11 +447,7 @@ lir.cmove(i.condition(), tVal, fVal, reg); } - protected FrameState stateBeforeInvoke(Invoke invoke) { - Value[] args = new Value[invoke.argumentCount()]; - for (int i = 0; i < invoke.argumentCount(); i++) { - args[i] = invoke.argument(i); - } + protected FrameState stateBeforeInvokeReturn(Invoke invoke) { return invoke.stateAfter().duplicateModified(invoke.bci(), invoke.kind/*, args*/); } @@ -467,7 +463,7 @@ public void visitInvoke(Invoke x) { RiMethod target = x.target(); LIRDebugInfo info = stateFor(x, stateBeforeInvokeWithArguments(x)); - LIRDebugInfo info2 = stateFor(x, stateBeforeInvoke(x)); + LIRDebugInfo info2 = stateFor(x, stateBeforeInvokeReturn(x)); XirSnippet snippet = null; @@ -887,6 +883,13 @@ lir.throwException(CiValue.IllegalValue, argumentOperand, info); } + @Override + public void visitDeoptimize(Deoptimize deoptimize) { + DeoptimizationStub stub = new DeoptimizationStub(deoptimize.stateBefore()); + addDeoptimizationStub(stub); + lir.branch(Condition.TRUE, stub.label, stub.info); + } + private void blockDoEpilog(BlockBegin block) { if (C1XOptions.PrintIRWithLIR) { TTY.println(); diff -r 50b181d88c9f -r d8601d421b96 graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Thu May 12 17:00:09 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Thu May 12 17:17:50 2011 +0200 @@ -243,7 +243,7 @@ List handleException(Instruction x, int bci) { if (!hasHandler()) { - return Util.uncheckedCast(Collections.EMPTY_LIST); + return ExceptionHandler.ZERO_HANDLERS; } ArrayList exceptionHandlers = new ArrayList(); @@ -330,8 +330,8 @@ // this is a load of class constant which might be unresolved RiType riType = (RiType) con; if (!riType.isResolved()) { - ResolveClass rc = new ResolveClass(riType, RiType.Representation.JavaClass, graph, frameState.create(bci())); - frameState.push(CiKind.Object, append(rc)); + append(new Deoptimize(graph, frameState.create(bci()))); + frameState.push(CiKind.Object, append(Constant.forObject(null, graph))); } else { frameState.push(CiKind.Object, append(new Constant(riType.getEncoding(Representation.JavaClass), graph))); } @@ -538,8 +538,8 @@ private void genCheckCast() { int cpi = stream().readCPI(); RiType type = constantPool().lookupType(cpi, CHECKCAST); - boolean isInitialized = type.isResolved() && type.isInitialized(); - Value typeInstruction = genResolveClass(RiType.Representation.ObjectHub, type, isInitialized, cpi); + boolean isInitialized = type.isResolved(); + Value typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi, frameState.create(bci())); CheckCast c = new CheckCast(type, typeInstruction, frameState.apop(), graph); frameState.apush(append(c)); } @@ -547,8 +547,9 @@ private void genInstanceOf() { int cpi = stream().readCPI(); RiType type = constantPool().lookupType(cpi, INSTANCEOF); - boolean isInitialized = type.isResolved() && type.isInitialized(); - Value typeInstruction = genResolveClass(RiType.Representation.ObjectHub, type, isInitialized, cpi); + boolean isInitialized = type.isResolved(); + //System.out.println("instanceof : type.isResolved() = " + type.isResolved() + "; type.isInitialized() = " + type.isInitialized()); + Value typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi, frameState.create(bci())); InstanceOf i = new InstanceOf(type, typeInstruction, frameState.apop(), graph); frameState.ipush(append(i)); } @@ -625,16 +626,14 @@ RiType holder = field.holder(); boolean isInitialized = field.isResolved(); CiConstant constantValue = null; - FrameState stateBefore = null; + FrameState stateBefore = frameState.create(bci()); if (isInitialized) { constantValue = field.constantValue(null); - } else { - stateBefore = frameState.create(bci()); } if (constantValue != null) { frameState.push(constantValue.kind.stackKind(), appendConstant(constantValue)); } else { - Value container = genResolveClass(RiType.Representation.StaticFields, holder, field.isResolved(), cpi); + Value container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, isInitialized, cpi, stateBefore); LoadField load = new LoadField(container, field, graph); appendOptimizedLoadField(field.kind(), load); load.setStateBefore(stateBefore); @@ -643,24 +642,23 @@ private void genPutStatic(int cpi, RiField field) { RiType holder = field.holder(); - FrameState stateBefore = null; - if (!field.isResolved()) { - stateBefore = frameState.create(bci()); - } - Value container = genResolveClass(RiType.Representation.StaticFields, holder, field.isResolved(), cpi); + FrameState stateBefore = frameState.create(bci()); + Value container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field.isResolved(), cpi, stateBefore); Value value = frameState.pop(field.kind().stackKind()); StoreField store = new StoreField(container, field, value, graph); appendOptimizedStoreField(store); - store.setStateBefore(stateBefore); + if (!field.isResolved()) { + store.setStateBefore(stateBefore); + } } - private Value genResolveClass(RiType.Representation representation, RiType holder, boolean initialized, int cpi) { + private Value genTypeOrDeopt(RiType.Representation representation, RiType holder, boolean initialized, int cpi, FrameState stateBefore) { Value holderInstr; if (initialized) { holderInstr = appendConstant(holder.getEncoding(representation)); } else { - ResolveClass rc = new ResolveClass(holder, representation, graph, frameState.create(bci())); - holderInstr = append(rc); + append(new Deoptimize(graph, stateBefore)); + holderInstr = append(Constant.forObject(null, graph)); } return holderInstr; } @@ -682,7 +680,7 @@ // Re-use the same resolution code as for accessing a static field. Even though // the result of resolution is not used by the invocation (only the side effect // of initialization is required), it can be commoned with static field accesses. - genResolveClass(RiType.Representation.StaticFields, holder, isInitialized, cpi); + genTypeOrDeopt(RiType.Representation.StaticFields, holder, isInitialized, cpi, frameState.create(bci())); } Value[] args = frameState.popArguments(target.signature().argumentSlots(false)); appendInvoke(INVOKESTATIC, target, args, cpi, constantPool); @@ -812,9 +810,7 @@ if (needsCheck) { // append a call to the finalizer registration - RegisterFinalizer r = new RegisterFinalizer(frameState.loadLocal(0), graph); - append(r); - r.setStateBefore(frameState.create(bci())); + append(new RegisterFinalizer(frameState.loadLocal(0), frameState.create(bci()), graph)); C1XMetrics.InlinedFinalizerChecks++; } } diff -r 50b181d88c9f -r d8601d421b96 graal/GraalCompiler/src/com/sun/c1x/ir/Deoptimize.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Deoptimize.java Thu May 12 17:17:50 2011 +0200 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.c1x.ir; + +import com.oracle.graal.graph.*; +import com.sun.c1x.debug.*; +import com.sun.c1x.value.*; +import com.sun.cri.ci.*; + + +/** + * + */ +public class Deoptimize extends Instruction { + + private static final int INPUT_COUNT = 1; + private static final int SUCCESSOR_COUNT = 0; + private static final int INPUT_STATE_BEFORE = 0; + + /** + * @param kind + * @param inputCount + * @param successorCount + * @param graph + */ + public Deoptimize(Graph graph, FrameState stateBefore) { + super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); + this.setStateBefore(stateBefore); + } + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + SUCCESSOR_COUNT; + } + + /** + * The state for this instruction. + */ + 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); + } + + @Override + public void accept(ValueVisitor v) { + v.visitDeoptimize(this); + } + + @Override + public void print(LogStream out) { + out.print("deoptimize"); + } + +} diff -r 50b181d88c9f -r d8601d421b96 graal/GraalCompiler/src/com/sun/c1x/ir/RegisterFinalizer.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/RegisterFinalizer.java Thu May 12 17:00:09 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/RegisterFinalizer.java Thu May 12 17:17:50 2011 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.sun.c1x.debug.*; +import com.sun.c1x.value.*; import com.sun.cri.ci.*; /** @@ -57,9 +58,10 @@ return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n); } - public RegisterFinalizer(Value object, Graph graph) { + public RegisterFinalizer(Value object, FrameState stateBefore, Graph graph) { super(CiKind.Void, INPUT_COUNT, SUCCESSOR_COUNT, graph); setObject(object); + setStateBefore(stateBefore); } @Override diff -r 50b181d88c9f -r d8601d421b96 graal/GraalCompiler/src/com/sun/c1x/ir/ResolveClass.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ResolveClass.java Thu May 12 17:00:09 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.sun.c1x.ir; - -import com.oracle.graal.graph.*; -import com.sun.c1x.debug.*; -import com.sun.c1x.value.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * An instruction that represents the runtime resolution of a Java class object. For example, an - * ldc of a class constant that is unresolved. - */ -public final class ResolveClass extends StateSplit { - - private static final int INPUT_COUNT = 0; - private static final int SUCCESSOR_COUNT = 0; - - public final RiType type; - public final RiType.Representation portion; - - public ResolveClass(RiType type, RiType.Representation r, Graph graph, FrameState stateBefore) { - super(type.getRepresentationKind(r), INPUT_COUNT, SUCCESSOR_COUNT, graph); - this.portion = r; - this.type = type; - setFlag(Flag.NonNull); - setStateBefore(stateBefore); - } - - @Override - public void accept(ValueVisitor v) { - v.visitResolveClass(this); - } - - @Override - public int valueNumber() { - return 0x50000000 | type.hashCode(); - } - - @Override - public boolean valueEqual(Instruction x) { - if (x instanceof ResolveClass) { - ResolveClass r = (ResolveClass) x; - return r.portion == portion && r.type.equals(type); - } - return false; - } - - @Override - public String toString() { - return super.toString() + "(type: " + type + ", portion: " + portion + ")"; - } - - @Override - public void print(LogStream out) { - out.print("resolve[").print(CiUtil.toJavaName(type)).print("-" + portion + "]"); - } - -} diff -r 50b181d88c9f -r d8601d421b96 graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java Thu May 12 17:00:09 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java Thu May 12 17:17:50 2011 +0200 @@ -61,11 +61,11 @@ public abstract void visitNullCheck(NullCheck i); public abstract void visitPhi(Phi i); public abstract void visitRegisterFinalizer(RegisterFinalizer i); - public abstract void visitResolveClass(ResolveClass i); public abstract void visitReturn(Return i); public abstract void visitShiftOp(ShiftOp i); public abstract void visitStoreField(StoreField i); public abstract void visitStoreIndexed(StoreIndexed i); public abstract void visitTableSwitch(TableSwitch i); public abstract void visitThrow(Throw i); + public abstract void visitDeoptimize(Deoptimize deoptimize); } diff -r 50b181d88c9f -r d8601d421b96 graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java --- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java Thu May 12 17:00:09 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java Thu May 12 17:17:50 2011 +0200 @@ -534,7 +534,10 @@ if (op.cond() == Condition.TRUE) { if (op.info != null) { - asm.recordImplicitException(codePos(), op.info); + int codePos = codePos(); + if (codePos > asm.lastSafepointPos()) { + asm.recordImplicitException(codePos, op.info); + } } masm.jmp(op.label()); } else {