changeset 5168:519d27db8eb9

made CompareAndSwapNode implement Lowerable to ensure partial HIR -> HIR lowering happens
author Doug Simon <doug.simon@oracle.com>
date Wed, 28 Mar 2012 22:14:14 +0200
parents 591f8231aa82
children 20f8a3215fa8
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/UnsafeAccess01.java graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/Unsafe_compareAndSwap.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java
diffstat 4 files changed, 79 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java	Wed Mar 28 14:31:56 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java	Wed Mar 28 22:14:14 2012 +0200
@@ -261,9 +261,16 @@
             CompareAndSwapNode cas = (CompareAndSwapNode) n;
             ValueNode expected = cas.expected();
             if (expected.kind() == CiKind.Object && !cas.newValue().isNullConstant()) {
-                // Don't know if this is a store into an array or field - so use an array write barrier which is more precise
-                LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, cas.expected().kind(), 0, cas.offset(), graph, false);
-                graph.addAfterFixed(cas, graph.add(new ArrayWriteBarrier(cas.object(), location)));
+                RiResolvedType declaredType = cas.object().declaredType();
+                if (declaredType != null && !declaredType.isArrayClass() && declaredType.toJava() != Object.class) {
+                    // Use a field write barrier since it's not an array store
+                    FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object()));
+                    graph.addAfterFixed(cas, writeBarrier);
+                } else {
+                    // This may be an array store so use an array write barrier
+                    LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, cas.expected().kind(), 0, cas.offset(), graph, false);
+                    graph.addAfterFixed(cas, graph.add(new ArrayWriteBarrier(cas.object(), location)));
+                }
             }
         } else if (n instanceof LoadIndexedNode) {
             LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/UnsafeAccess01.java	Wed Mar 28 14:31:56 2012 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/UnsafeAccess01.java	Wed Mar 28 22:14:14 2012 +0200
@@ -35,7 +35,7 @@
     @SuppressWarnings("unused")
     private int field = 42;
 
-    public static int test() throws SecurityException, NoSuchFieldException, IllegalAccessException {
+    public static int test() throws SecurityException, NoSuchFieldException {
         final Unsafe unsafe = getUnsafe();
 
         final UnsafeAccess01 object = new UnsafeAccess01();
@@ -45,10 +45,14 @@
         return value;
     }
 
-    private static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException {
-        final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
-        unsafeField.setAccessible(true);
-        return (Unsafe) unsafeField.get(null);
+    static Unsafe getUnsafe() {
+        try {
+            final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+            unsafeField.setAccessible(true);
+            return (Unsafe) unsafeField.get(null);
+        } catch (Exception e) {
+            throw new Error(e);
+        }
     }
 
     @Test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/Unsafe_compareAndSwap.java	Wed Mar 28 22:14:14 2012 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2008, 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.jtt.jdk;
+
+import org.junit.*;
+
+import sun.misc.*;
+
+public class Unsafe_compareAndSwap {
+    static final Unsafe unsafe = UnsafeAccess01.getUnsafe();
+    static final long valueOffset;
+    static {
+        try {
+            valueOffset = unsafe.objectFieldOffset(Unsafe_compareAndSwap.class.getDeclaredField("value"));
+        } catch (Exception ex) { throw new Error(ex); }
+    }
+
+    public static void test(Unsafe_compareAndSwap u, Object o, String expected, String newValue) {
+        // First arg is not an array - can use a field write barrier
+        unsafe.compareAndSwapObject(u, valueOffset, expected, newValue);
+        // Not known if first arg is an array - different write barrier may be used
+        unsafe.compareAndSwapObject(o, valueOffset, expected, newValue);
+    }
+
+    private String value = "a";
+
+    @Test
+    public void run0() throws Throwable {
+        Unsafe_compareAndSwap u = new Unsafe_compareAndSwap();
+        test(u, u, "a", "b");
+        Assert.assertEquals(u.value, "b");
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Wed Mar 28 14:31:56 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Wed Mar 28 22:14:14 2012 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.java;
 
 import com.oracle.max.cri.ci.*;
+import com.oracle.graal.cri.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -32,7 +33,7 @@
  * Represents an atomic compare-and-swap operation
  * The result is a boolean that contains whether the value matched the expected value.
  */
-public class CompareAndSwapNode extends AbstractStateSplit implements LIRLowerable, MemoryCheckpoint {
+public class CompareAndSwapNode extends AbstractStateSplit implements LIRLowerable, Lowerable, MemoryCheckpoint {
 
     @Input private ValueNode object;
     @Input private ValueNode offset;
@@ -69,6 +70,11 @@
         gen.visitCompareAndSwap(this);
     }
 
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+
     // specialized on value type until boxing/unboxing is sorted out in intrinsification
     @SuppressWarnings("unused")
     @NodeIntrinsic