changeset 3065:fef84503ab7d

Create new FieldWriteBarrier. Enable possibility to lower node directly to LIR.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 22 Jun 2011 21:51:57 +0200
parents 8b0236cbed14
children dc0065f8d9a5
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalTimers.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryAccess.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryWrite.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreField.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/Compiler.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerImpl.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FieldWriteBarrier.java runfilter.sh
diffstat 14 files changed, 191 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Wed Jun 22 21:51:57 2011 +0200
@@ -82,6 +82,7 @@
     }
 
     public CiResult compileMethod(RiMethod method, int osrBCI, RiXirGenerator xirGenerator, CiStatistics stats) {
+        GraalTimers.TOTAL.start();
         long startTime = 0;
         int index = GraalMetrics.CompiledMethods++;
         if (GraalOptions.PrintCompilation) {
@@ -102,6 +103,7 @@
                 long time = (System.nanoTime() - startTime) / 100000;
                 TTY.println(String.format("%3d.%dms", time / 10, time % 10));
             }
+            GraalTimers.TOTAL.stop();
         }
 
         return result;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalTimers.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalTimers.java	Wed Jun 22 21:51:57 2011 +0200
@@ -34,6 +34,8 @@
 public final class GraalTimers {
     private static LinkedHashMap<String, GraalTimers> map = new LinkedHashMap<String, GraalTimers>();
 
+
+    public static final GraalTimers TOTAL = get("Total compilation time");
     public static final GraalTimers COMPUTE_LINEAR_SCAN_ORDER = get("Compute Linear Scan Order");
     public static final GraalTimers LIR_CREATE = get("Create LIR");
     public static final GraalTimers LIFETIME_ANALYSIS = get("Lifetime Analysis");
@@ -73,19 +75,15 @@
     }
 
     public static void print() {
-        long total = 0;
-        for (Entry<String, GraalTimers> e : map.entrySet()) {
-            total += e.getValue().total;
-        }
-        if (total == 0) {
-            return;
-        }
 
         TTY.println();
+        TTY.println("%-30s: %7.4f s", TOTAL.name, TOTAL.total / 1000000000.0);
         for (Entry<String, GraalTimers> e : map.entrySet()) {
             GraalTimers timer = e.getValue();
-            TTY.println("%-30s: %7.4f s (%5.2f%%)", timer.name, timer.total / 1000000000.0, timer.total * 100.0 / total);
-            timer.total = 0;
+            if (timer != TOTAL) {
+                TTY.println("%-30s: %7.4f s (%5.2f%%)", timer.name, timer.total / 1000000000.0, timer.total * 100.0 / TOTAL.total);
+                timer.total = 0;
+            }
         }
         TTY.println();
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Wed Jun 22 21:51:57 2011 +0200
@@ -144,7 +144,7 @@
         return operand;
     }
 
-    protected CiValue load(Value val) {
+    public CiValue load(Value val) {
         CiValue result = makeOperand(val);
         if (!result.isVariableOrRegister()) {
             CiVariable operand = newVariable(val.kind);
@@ -201,6 +201,10 @@
         this.operands = new OperandPool(compilation.target);
     }
 
+    public LIRList lir() {
+        return lir;
+    }
+
     public ArrayList<DeoptimizationStub> deoptimizationStubs() {
         return deoptimizationStubs;
     }
@@ -1366,7 +1370,10 @@
         if (GraalOptions.TraceLIRVisit) {
             TTY.println("Visiting    " + instr);
         }
-        instr.accept(this);
+
+        LIRGeneratorOp op = instr.lookup(LIRGeneratorOp.class);
+        op.generate(instr, this);
+
         if (GraalOptions.TraceLIRVisit) {
             TTY.println("Operand for " + instr + " = " + instr.operand());
         }
@@ -1443,7 +1450,7 @@
 
     @Override
     public void visitMemoryWrite(MemoryWrite memWrite) {
-        lir.move(load(memWrite.location()), new CiAddress(memWrite.valueKind(), load(memWrite.location()), memWrite.displacement()), memWrite.valueKind());
+        lir.move(load(memWrite.value()), new CiAddress(memWrite.valueKind(), load(memWrite.location()), memWrite.displacement()), memWrite.valueKind());
     }
 
 
@@ -1660,7 +1667,7 @@
      *
      * @param instruction an instruction that produces a result value
      */
-    protected CiValue makeOperand(Value instruction) {
+    public CiValue makeOperand(Value instruction) {
         if (instruction == null) {
             return CiValue.IllegalValue;
         }
@@ -1790,4 +1797,15 @@
         lir.callRuntime(CiRuntimeCall.UnwindException, CiValue.IllegalValue, args, null);
         setNoResult(x);
     }
+
+    public interface LIRGeneratorOp extends Op {
+        void generate(Node n, LIRGenerator generator);
+    }
+
+    public static final LIRGeneratorOp DELEGATE_TO_VALUE_VISITOR = new LIRGeneratorOp() {
+        @Override
+        public void generate(Node n, LIRGenerator generator) {
+            ((Value) n).accept(generator);
+        }
+    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryAccess.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryAccess.java	Wed Jun 22 21:51:57 2011 +0200
@@ -37,6 +37,11 @@
     private int displacement;
     private CiKind valueKind;
 
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
     /**
      * The instruction that produces the object tested against null.
      */
@@ -67,10 +72,11 @@
         return valueKind;
     }
 
-    public MemoryAccess(CiKind kind, int displacement, int inputCount, int successorCount, Graph graph) {
+    public MemoryAccess(CiKind kind, Value location, int displacement, int inputCount, int successorCount, Graph graph) {
         super(kind.stackKind(), INPUT_COUNT + inputCount, SUCCESSOR_COUNT + successorCount, graph);
         this.displacement = displacement;
         this.valueKind = kind;
+        setLocation(location);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java	Wed Jun 22 21:51:57 2011 +0200
@@ -32,8 +32,8 @@
     private static final int SUCCESSOR_COUNT = 0;
 
 
-    public MemoryRead(CiKind kind, int displacement, Graph graph) {
-        super(kind, displacement, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    public MemoryRead(CiKind kind, Value location, int displacement, Graph graph) {
+        super(kind, location, displacement, INPUT_COUNT, SUCCESSOR_COUNT, graph);
     }
 
     @Override
@@ -48,6 +48,6 @@
 
     @Override
     public Node copy(Graph into) {
-        return new MemoryRead(super.kind, displacement(), into);
+        return new MemoryRead(super.kind, null, displacement(), into);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryWrite.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryWrite.java	Wed Jun 22 21:51:57 2011 +0200
@@ -32,6 +32,11 @@
     private static final int INPUT_VALUE = 0;
     private static final int SUCCESSOR_COUNT = 0;
 
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
     public Value value() {
         return (Value) inputs().get(super.inputCount() + INPUT_VALUE);
     }
@@ -40,8 +45,8 @@
         inputs().set(super.inputCount() + INPUT_VALUE, v);
     }
 
-    public MemoryWrite(CiKind kind, Value value, int displacement, Graph graph) {
-        super(kind, displacement, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    public MemoryWrite(CiKind kind, Value object, Value value, int displacement, Graph graph) {
+        super(kind, object, displacement, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         setValue(value);
     }
 
@@ -57,6 +62,6 @@
 
     @Override
     public Node copy(Graph into) {
-        return new MemoryWrite(super.kind, null, displacement(), into);
+        return new MemoryWrite(super.kind, null, null, displacement(), into);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreField.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreField.java	Wed Jun 22 21:51:57 2011 +0200
@@ -84,7 +84,7 @@
         if (clazz == LoweringOp.class) {
             return (T) LoweringPhase.DELEGATE_TO_RUNTIME;
         }
-        return null;
+        return super.lookup(clazz);
     };
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java	Wed Jun 22 21:51:57 2011 +0200
@@ -25,6 +25,7 @@
 import java.util.*;
 
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.gen.*;
 import com.oracle.max.graal.compiler.value.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
@@ -57,14 +58,6 @@
         this.kind = kind;
     }
 
-    ///////////////
-    // TODO: remove when Value class changes are completed
-
-    @Override
-    protected Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException();
-    }
-
     /**
      * Checks whether this value is a constant (i.e. it is of type {@link Constant}.
      * @return {@code true} if this value is a constant
@@ -160,10 +153,22 @@
      *
      * @param v the visitor to accept
      */
-    public abstract void accept(ValueVisitor v);
+    public void accept(ValueVisitor v) {
+        throw new IllegalStateException("No visit method for this node");
+    }
 
     public abstract void print(LogStream out);
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == LIRGenerator.LIRGeneratorOp.class) {
+            return (T) LIRGenerator.DELEGATE_TO_VALUE_VISITOR;
+        }
+        return super.lookup(clazz);
+    }
+
+
     @Override
     public Map<Object, Object> getDebugProperties() {
         Map<Object, Object> properties = super.getDebugProperties();
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/Compiler.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/Compiler.java	Wed Jun 22 21:51:57 2011 +0200
@@ -31,5 +31,6 @@
     VMExits getVMExits();
     GraalCompiler getCompiler();
     RiType lookupType(String returnType, HotSpotTypeResolved accessingClass);
+    HotSpotVMConfig getConfig();
 
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerImpl.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/CompilerImpl.java	Wed Jun 22 21:51:57 2011 +0200
@@ -86,6 +86,11 @@
     private final CiTarget target;
     private final RiXirGenerator generator;
     private final RiRegisterConfig registerConfig;
+    private final HotSpotVMConfig config;
+
+    public HotSpotVMConfig getConfig() {
+        return config;
+    }
 
     private CompilerImpl(VMEntries entries) {
 
@@ -112,7 +117,7 @@
         vmExits = exits;
 
         // initialize compiler and GraalOptions
-        HotSpotVMConfig config = vmEntries.getConfiguration();
+        config = vmEntries.getConfiguration();
         config.check();
 
         // these options are important - graal will not generate correct code without them
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Wed Jun 22 21:51:57 2011 +0200
@@ -28,6 +28,7 @@
 
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.runtime.nodes.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ci.CiTargetMethod.Call;
 import com.sun.cri.ci.CiTargetMethod.DataPatch;
@@ -250,24 +251,27 @@
             Graph graph = field.graph();
             int displacement = ((HotSpotField) field.field()).offset();
             assert field.kind != CiKind.Illegal;
-            MemoryRead memoryRead = new MemoryRead(field.field().kind(), displacement, graph);
+            MemoryRead memoryRead = new MemoryRead(field.field().kind(), field.object(), displacement, graph);
             memoryRead.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
             memoryRead.setNext(field.next());
-            memoryRead.setLocation(field.object());
             return memoryRead;
         } else if (n instanceof StoreField) {
-            return null;
-//            StoreField field = (StoreField) n;
-//            if (field.isVolatile()) {
-//                return null;
-//            }
-//            Graph graph = field.graph();
-//            int displacement = ((HotSpotField) field.field()).offset();
-//            MemoryWrite memoryWrite = new MemoryWrite(field.field().kind(), field.value(), displacement, graph);
-//            memoryWrite.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
-//            memoryWrite.setNext(field.next());
-//            memoryWrite.setLocation(field.object());
-//            return memoryWrite;
+            StoreField field = (StoreField) n;
+            if (field.isVolatile()) {
+                return null;
+            }
+            Graph graph = field.graph();
+            int displacement = ((HotSpotField) field.field()).offset();
+            MemoryWrite memoryWrite = new MemoryWrite(field.field().kind(), field.object(), field.value(), displacement, graph);
+            memoryWrite.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
+            if (field.field().kind() == CiKind.Object) {
+                FieldWriteBarrier writeBarrier = new FieldWriteBarrier(field.object(), graph);
+                memoryWrite.setNext(writeBarrier);
+                writeBarrier.setNext(field.next());
+            } else {
+                memoryWrite.setNext(field.next());
+            }
+            return memoryWrite;
         }
         return null;
     }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java	Wed Jun 22 21:51:26 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java	Wed Jun 22 21:51:57 2011 +0200
@@ -72,12 +72,10 @@
 
     private static Set<String> compiledMethods = new HashSet<String>();
 
-    private static PrintStream originalOut;
-    private static PrintStream originalErr;
-
     public void startCompiler() {
-        originalOut = System.out;
-        originalErr = System.err;
+        // Make sure TTY is initialized here such that the correct System.out is used for TTY.
+        TTY.isSuppressed();
+        TTY.println("test");
     }
 
     public void shutdownCompiler() throws Throwable {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FieldWriteBarrier.java	Wed Jun 22 21:51:57 2011 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 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.oracle.max.graal.runtime.nodes;
+
+import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.ir.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.runtime.*;
+import com.sun.cri.ci.*;
+
+
+public final class FieldWriteBarrier extends Instruction {
+    private static final int INPUT_COUNT = 1;
+    private static final int INPUT_OBJECT = 0;
+
+    private static final int SUCCESSOR_COUNT = 0;
+
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    /**
+     * The instruction that produces the object tested against null.
+     */
+     public Value object() {
+        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
+    }
+
+    public void setObject(Value n) {
+        inputs().set(super.inputCount() + INPUT_OBJECT, n);
+    }
+
+    public FieldWriteBarrier(Value object, Graph graph) {
+        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        this.setObject(object);
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == LIRGenerator.LIRGeneratorOp.class) {
+            return (T) new LIRGenerator.LIRGeneratorOp() {
+                @Override
+                public void generate(Node n, LIRGenerator generator) {
+                    assert n == FieldWriteBarrier.this;
+                    CiVariable temp = generator.newVariable(CiKind.Word);
+                    HotSpotVMConfig config = CompilerImpl.getInstance().getConfig();
+                    generator.lir().move(generator.makeOperand(object()), temp);
+                    generator.lir().unsignedShiftRight(temp, CiConstant.forInt(config.cardtableShift), temp, CiValue.IllegalValue);
+
+                    long startAddress = config.cardtableStartAddress;
+                    int displacement = 0;
+                    if (((int) startAddress) == startAddress) {
+                        displacement = (int) startAddress;
+                    } else {
+                        generator.lir().add(temp, CiConstant.forLong(config.cardtableStartAddress), temp);
+                    }
+                    generator.lir().move(CiConstant.FALSE, new CiAddress(CiKind.Boolean, temp, displacement), (LIRDebugInfo) null);
+                }
+            };
+        }
+        return super.lookup(clazz);
+    }
+
+    @Override
+    public void print(LogStream out) {
+        out.print("field write barrier ").print(object());
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new FieldWriteBarrier(null, into);
+    }
+}
--- a/runfilter.sh	Wed Jun 22 21:51:26 2011 +0200
+++ b/runfilter.sh	Wed Jun 22 21:51:57 2011 +0200
@@ -18,4 +18,4 @@
 FILTER=$1
 shift 1
 TESTDIR=${MAXINE}/com.oracle.max.vm/test
-${JDK7}/bin/java -client -d64 -graal -ea -esa -Xcomp -XX:CompileOnly=jtt -Xbootclasspath/p:"${MAXINE}/com.oracle.max.vm/bin" -Xbootclasspath/p:"${MAXINE}/com.oracle.max.base/bin" $@ test.com.sun.max.vm.compiler.JavaTester -filter=${FILTER} -verbose=1 -gen-run-scheme=false -run-scheme-package=all $@ ${TESTDIR}/jtt/bytecode ${TESTDIR}/jtt/except ${TESTDIR}/jtt/hotpath ${TESTDIR}/jtt/jdk ${TESTDIR}/jtt/lang ${TESTDIR}/jtt/loop ${TESTDIR}/jtt/micro ${TESTDIR}/jtt/optimize ${TESTDIR}/jtt/reflect ${TESTDIR}/jtt/threads
+${JDK7}/bin/java -client -d64 -graal -ea -esa -Xcomp -XX:+PrintCompilation -XX:CompileOnly=jtt -Xbootclasspath/p:"${MAXINE}/com.oracle.max.vm/bin" -Xbootclasspath/p:"${MAXINE}/com.oracle.max.base/bin" $@ test.com.sun.max.vm.compiler.JavaTester -filter=${FILTER} -verbose=1 -gen-run-scheme=false -run-scheme-package=all $@ ${TESTDIR}/jtt/bytecode ${TESTDIR}/jtt/except ${TESTDIR}/jtt/hotpath ${TESTDIR}/jtt/jdk ${TESTDIR}/jtt/lang ${TESTDIR}/jtt/loop ${TESTDIR}/jtt/micro ${TESTDIR}/jtt/optimize ${TESTDIR}/jtt/reflect ${TESTDIR}/jtt/threads