changeset 2671:d8601d421b96

New Deoptimize node, remove ResolveClass node and replace it with deoptimization
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Thu, 12 May 2011 17:17:50 +0200
parents 50b181d88c9f
children 35453d725a2a
files graal/GraalCompiler/src/com/sun/c1x/asm/AbstractAssembler.java graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java graal/GraalCompiler/src/com/sun/c1x/ir/Deoptimize.java graal/GraalCompiler/src/com/sun/c1x/ir/RegisterFinalizer.java graal/GraalCompiler/src/com/sun/c1x/ir/ResolveClass.java graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java
diffstat 8 files changed, 139 insertions(+), 120 deletions(-) [+]
line wrap: on
line diff
--- 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<ExceptionInfo> 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;
+    }
 }
--- 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<LIRGenerator.DeoptimizationStub>();
+        }
+        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();
--- 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<ExceptionHandler> handleException(Instruction x, int bci) {
         if (!hasHandler()) {
-            return Util.uncheckedCast(Collections.EMPTY_LIST);
+            return ExceptionHandler.ZERO_HANDLERS;
         }
 
         ArrayList<ExceptionHandler> exceptionHandlers = new ArrayList<ExceptionHandler>();
@@ -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++;
         }
     }
--- /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");
+    }
+
+}
--- 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
--- 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 + "]");
-    }
-
-}
--- 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);
 }
--- 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 {