changeset 7109:37e75cc87c66

Merge.
author Christian Haeubl <haeubl@ssw.jku.at>
date Thu, 29 Nov 2012 16:20:42 +0100
parents fa99bf3837ec (current diff) bb6d2860e431 (diff)
children 9bd688f91d3f
files
diffstat 5 files changed, 135 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Thu Nov 29 15:44:49 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Thu Nov 29 16:20:42 2012 +0100
@@ -46,7 +46,7 @@
     /**
      * Number of successive successful installations.
      */
-    private long successfulInstallations;
+    private long successfulInstallations = MINIMUM_SUCCESSFUL_INSTALLATIONS_PER_FAILURE;
 
     /**
      * The minimum expected number of successful code installations between each code
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Nov 29 15:44:49 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Nov 29 16:20:42 2012 +0100
@@ -518,14 +518,14 @@
         } else if (n instanceof UnsafeLoadNode) {
             UnsafeLoadNode load = (UnsafeLoadNode) n;
             assert load.kind() != Kind.Illegal;
-            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.loadKind(), load.displacement(), load.offset(), graph, false);
+            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, false);
             ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp()));
             // An unsafe read must not floating outside its block as may float above an explicit null check on its object.
             memoryRead.dependencies().add(BeginNode.prevBegin(load));
             graph.replaceFixedWithFixed(load, memoryRead);
         } else if (n instanceof UnsafeStoreNode) {
             UnsafeStoreNode store = (UnsafeStoreNode) n;
-            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, store.storeKind(), store.displacement(), store.offset(), graph, false);
+            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, false);
             ValueNode object = store.object();
             WriteNode write = graph.add(new WriteNode(object, store.value(), location));
             write.setStateAfter(store.stateAfter());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java	Thu Nov 29 16:20:42 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 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.graal.nodes.extended;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+
+public abstract class UnsafeAccessNode extends FixedWithNextNode {
+    @Input private ValueNode object;
+    @Input private ValueNode offset;
+    private final int displacement;
+    private final Kind accessKind;
+
+    public UnsafeAccessNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, Kind accessKind) {
+        super(stamp);
+        assert accessKind != null;
+        this.object = object;
+        this.displacement = displacement;
+        this.offset = offset;
+        this.accessKind = accessKind;
+    }
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public int displacement() {
+        return displacement;
+    }
+
+    public ValueNode offset() {
+        return offset;
+    }
+
+    public Kind accessKind() {
+        return accessKind;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Thu Nov 29 15:44:49 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Thu Nov 29 16:20:42 2012 +0100
@@ -23,7 +23,9 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
@@ -32,43 +34,18 @@
  * Load of a value from a location specified as an offset relative to an object.
  * No null check is performed before the load.
  */
-public class UnsafeLoadNode extends FixedWithNextNode implements Lowerable, Virtualizable {
-
-    @Input private ValueNode object;
-    @Input private ValueNode offset;
-    private final int displacement;
-    private final Kind loadKind;
+public class UnsafeLoadNode extends UnsafeAccessNode implements Lowerable, Virtualizable, Canonicalizable {
 
-    public ValueNode object() {
-        return object;
-    }
-
-    public int displacement() {
-        return displacement;
-    }
-
-    public ValueNode offset() {
-        return offset;
+    public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, boolean nonNull) {
+        this(nonNull ? StampFactory.objectNonNull() : StampFactory.object(), object, displacement, offset, Kind.Object);
     }
 
-    public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, boolean nonNull) {
-        super(nonNull ? StampFactory.objectNonNull() : StampFactory.object());
-        this.object = object;
-        this.displacement = displacement;
-        this.offset = offset;
-        this.loadKind = Kind.Object;
+    public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, Kind accessKind) {
+        this(StampFactory.forKind(accessKind.getStackKind()), object, displacement, offset, accessKind);
     }
 
-    public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, Kind kind) {
-        super(StampFactory.forKind(kind.getStackKind()));
-        this.object = object;
-        this.displacement = displacement;
-        this.offset = offset;
-        this.loadKind = kind;
-    }
-
-    public Kind loadKind() {
-        return loadKind;
+    public UnsafeLoadNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, Kind accessKind) {
+        super(stamp, object, displacement, offset, accessKind);
     }
 
     @Override
@@ -96,6 +73,30 @@
         }
     }
 
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (offset().isConstant()) {
+            long constantOffset = offset().asConstant().asLong();
+            if (constantOffset != 0) {
+                int intDisplacement = (int) (constantOffset + displacement());
+                if (constantOffset == intDisplacement) {
+                    Graph graph = this.graph();
+                    return graph.add(new UnsafeLoadNode(this.stamp(), object(), intDisplacement, graph.unique(ConstantNode.forInt(0, graph)), accessKind()));
+                }
+            } else if (object().stamp() instanceof ObjectStamp) { // TODO (gd) remove that once UnsafeAccess only have an object base
+                ObjectStamp receiverStamp = object().objectStamp();
+                if (receiverStamp.nonNull()) {
+                    ResolvedJavaType receiverType = receiverStamp.type();
+                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement());
+                    if (field != null) {
+                        return this.graph().add(new LoadFieldNode(object(), field, StructuredGraph.INVALID_GRAPH_ID));
+                    }
+                }
+            }
+        }
+        return this;
+    }
+
     @NodeIntrinsic
     public static native <T> T load(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind kind);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Thu Nov 29 15:44:49 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Thu Nov 29 16:20:42 2012 +0100
@@ -23,7 +23,9 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
@@ -32,14 +34,20 @@
  * Store of a value at a location specified as an offset relative to an object.
  * No null check is performed before the store.
  */
-public class UnsafeStoreNode extends FixedWithNextNode implements StateSplit, Lowerable, Virtualizable {
+public class UnsafeStoreNode extends UnsafeAccessNode implements StateSplit, Lowerable, Virtualizable, Canonicalizable {
+
+    @Input private ValueNode value;
+    @Input(notDataflow = true) private FrameState stateAfter;
 
-    @Input private ValueNode object;
-    @Input private ValueNode offset;
-    @Input private ValueNode value;
-    private final int displacement;
-    private final Kind storeKind;
-    @Input(notDataflow = true) private FrameState stateAfter;
+    public UnsafeStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, Kind accessKind) {
+        this(StampFactory.forVoid(), object, displacement, offset, value, accessKind);
+    }
+
+    public UnsafeStoreNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, ValueNode value, Kind accessKind) {
+        super(stamp, object, displacement, offset, accessKind);
+        assert accessKind != Kind.Void && accessKind != Kind.Illegal;
+        this.value = value;
+    }
 
     public FrameState stateAfter() {
         return stateAfter;
@@ -55,43 +63,10 @@
         return true;
     }
 
-    public UnsafeStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, Kind kind) {
-        super(StampFactory.forVoid());
-        assert kind != Kind.Void && kind != Kind.Illegal;
-        this.object = object;
-        this.displacement = displacement;
-        this.offset = offset;
-        this.value = value;
-        this.storeKind = kind;
-    }
-
-    public ValueNode object() {
-        return object;
-    }
-
-    public int displacement() {
-        return displacement;
-    }
-
-    public ValueNode offset() {
-        return offset;
-    }
-
     public ValueNode value() {
         return value;
     }
 
-    public Kind storeKind() {
-        return storeKind;
-    }
-
-    @Override
-    public boolean verify() {
-        assertTrue(storeKind != null, "UnsafeStoreNode must have a store kind");
-        assertTrue(object != null, "UnsafeStoreNode should have an object");
-        return super.verify();
-    }
-
     @Override
     public void lower(LoweringTool tool) {
         tool.getRuntime().lower(this, tool);
@@ -112,6 +87,30 @@
         }
     }
 
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (offset().isConstant()) {
+            long constantOffset = offset().asConstant().asLong();
+            if (constantOffset != 0) {
+                int intDisplacement = (int) (constantOffset + displacement());
+                if (constantOffset == intDisplacement) {
+                    Graph graph = this.graph();
+                    return graph.add(new UnsafeStoreNode(this.stamp(), object(), intDisplacement, graph.unique(ConstantNode.forInt(0, graph)), value(), accessKind()));
+                }
+            } else if (object().stamp() instanceof ObjectStamp) { // TODO (gd) remove that once UnsafeAccess only have an object base
+                ObjectStamp receiverStamp = object().objectStamp();
+                if (receiverStamp.nonNull()) {
+                    ResolvedJavaType receiverType = receiverStamp.type();
+                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement());
+                    if (field != null) {
+                        return this.graph().add(new StoreFieldNode(object(), field, value(), StructuredGraph.INVALID_GRAPH_ID));
+                    }
+                }
+            }
+        }
+        return this;
+    }
+
     // specialized on value type until boxing/unboxing is sorted out in intrinsification
     @NodeIntrinsic
     public static native void store(Object object, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter Kind kind);