changeset 12622:f40b8d0d9dcb

PEA: more tests, common base class for tests
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 28 Oct 2013 15:25:27 +0100
parents 7f55cdeec6af
children 0d6ad1cd4191
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EAMergingTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/UnsafeEATest.java
diffstat 6 files changed, 453 insertions(+), 152 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EAMergingTest.java	Mon Oct 28 15:25:27 2013 +0100
@@ -0,0 +1,53 @@
+/*
+ * 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.graal.compiler.test.ea;
+
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.graal.nodes.*;
+
+public class EAMergingTest extends EATestBase {
+
+    @Test
+    public void testSimpleMerge() {
+        testEscapeAnalysis("simpleMergeSnippet", null, false);
+        assertTrue(returnNode.result() instanceof PhiNode);
+        PhiNode phi = (PhiNode) returnNode.result();
+        assertTrue(phi.valueAt(0) instanceof LocalNode);
+        assertTrue(phi.valueAt(1) instanceof LocalNode);
+    }
+
+    public static int simpleMergeSnippet(boolean b, int u, int v) {
+        TestClassInt obj;
+        if (b) {
+            obj = new TestClassInt(u, 0);
+            notInlineable();
+        } else {
+            obj = new TestClassInt(v, 0);
+            notInlineable();
+        }
+        return obj.x;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Mon Oct 28 15:25:27 2013 +0100
@@ -0,0 +1,155 @@
+/*
+ * 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.graal.compiler.test.ea;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.virtual.phases.ea.*;
+
+public class EATestBase extends GraalCompilerTest {
+
+    public static class TestClassInt {
+        public int x;
+        public int y;
+
+        public TestClassInt() {
+            this(0, 0);
+        }
+
+        public TestClassInt(int x) {
+            this(x, 0);
+        }
+
+        public TestClassInt(int x, int y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            TestClassInt other = (TestClassInt) obj;
+            return x == other.x && y == other.y;
+        }
+
+        @Override
+        public String toString() {
+            return "{" + x + "," + y + "}";
+        }
+
+        @Override
+        public int hashCode() {
+            return x + 13 * y;
+        }
+    }
+
+    public static class TestClassObject {
+        public Object x;
+        public Object y;
+
+        public TestClassObject() {
+            this(null, null);
+        }
+
+        public TestClassObject(Object x) {
+            this(x, null);
+        }
+
+        public TestClassObject(Object x, Object y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            TestClassObject other = (TestClassObject) obj;
+            return x == other.x && y == other.y;
+        }
+
+        @Override
+        public String toString() {
+            return "{" + x + "," + y + "}";
+        }
+
+        @Override
+        public int hashCode() {
+            return (x == null ? 0 : x.hashCode()) + 13 * (y == null ? 0 : y.hashCode());
+        }
+    }
+
+    protected static native void notInlineable();
+
+    protected StructuredGraph graph;
+    protected HighTierContext context;
+    protected ReturnNode returnNode;
+
+    /**
+     * Runs Escape Analysis on the given snippet and makes sure that no allocations remain in the
+     * graph.
+     * 
+     * @param snippet the name of the method whose graph should be processed
+     * @param expectedConstantResult if this is non-null, the resulting graph needs to have the
+     *            given constant return value
+     * @param iterativeEscapeAnalysis true if escape analysis should be run for more than one
+     *            iteration
+     */
+    protected void testEscapeAnalysis(String snippet, final Constant expectedConstantResult, final boolean iterativeEscapeAnalysis) {
+        prepareGraph(snippet, iterativeEscapeAnalysis);
+        if (expectedConstantResult != null) {
+            Assert.assertTrue(returnNode.result().toString(), returnNode.result().isConstant());
+            Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant());
+        }
+        int newInstanceCount = graph.getNodes().filter(NewInstanceNode.class).count() + graph.getNodes().filter(NewArrayNode.class).count() +
+                        graph.getNodes().filter(CommitAllocationNode.class).count();
+        Assert.assertEquals(0, newInstanceCount);
+    }
+
+    protected void prepareGraph(String snippet, final boolean iterativeEscapeAnalysis) {
+        ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(snippet));
+        graph = new StructuredGraph(method);
+        Debug.scope(getClass().getSimpleName(), new Object[]{graph, method, getCodeCache()}, new Runnable() {
+
+            public void run() {
+                new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+                Assumptions assumptions = new Assumptions(false);
+                context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
+                new DeadCodeEliminationPhase().apply(graph);
+                new CanonicalizerPhase(true).apply(graph, context);
+                new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true)).apply(graph, context);
+                Assert.assertEquals(1, graph.getNodes().filter(ReturnNode.class).count());
+                returnNode = graph.getNodes().filter(ReturnNode.class).first();
+            }
+        });
+    }
+}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Mon Oct 28 17:03:59 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Mon Oct 28 15:25:27 2013 +0100
@@ -24,28 +24,20 @@
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.java.*;
 import com.oracle.graal.loop.phases.*;
-import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.schedule.*;
-import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.virtual.phases.ea.*;
 
 /**
  * The PartialEscapeAnalysisPhase is expected to remove all allocations and return the correct
  * values.
  */
-public class EscapeAnalysisTest extends GraalCompilerTest {
+public class EscapeAnalysisTest extends EATestBase {
 
     @Test
     public void test1() {
@@ -82,8 +74,6 @@
         testEscapeAnalysis("testMonitorSnippet", Constant.forInt(0), false);
     }
 
-    private static native void notInlineable();
-
     public static int testMonitorSnippet() {
         Integer x = new Integer(0);
         Double y = new Double(0);
@@ -126,19 +116,8 @@
         testEscapeAnalysis("testMerge1Snippet", Constant.forInt(0), true);
     }
 
-    public static class TestObject {
-
-        int x;
-        int y;
-
-        public TestObject(int x, int y) {
-            this.x = x;
-            this.y = y;
-        }
-    }
-
     public static int testMerge1Snippet(int a) {
-        TestObject obj = new TestObject(1, 0);
+        TestClassInt obj = new TestClassInt(1, 0);
         if (a < 0) {
             obj.x = obj.x + 1;
         } else {
@@ -157,7 +136,7 @@
     }
 
     public int testSimpleLoopSnippet(int a) {
-        TestObject obj = new TestObject(1, 2);
+        TestClassInt obj = new TestClassInt(1, 2);
         for (int i = 0; i < a; i++) {
             notInlineable();
         }
@@ -170,7 +149,7 @@
     }
 
     public int testModifyingLoopSnippet(int a) {
-        TestObject obj = new TestObject(1, 2);
+        TestClassInt obj = new TestClassInt(1, 2);
         for (int i = 0; i < a; i++) {
             obj.x = 3;
             notInlineable();
@@ -178,24 +157,15 @@
         return obj.x <= 3 ? 1 : 0;
     }
 
-    public static class TestObject2 {
-
-        Object o;
-
-        public TestObject2(Object o) {
-            this.o = o;
-        }
-    }
-
     @Test
     public void testCheckCast() {
-        testEscapeAnalysis("testCheckCastSnippet", Constant.forObject(TestObject2.class), false);
+        testEscapeAnalysis("testCheckCastSnippet", Constant.forObject(TestClassObject.class), false);
     }
 
     public Object testCheckCastSnippet() {
-        TestObject2 obj = new TestObject2(TestObject2.class);
-        TestObject2 obj2 = new TestObject2(obj);
-        return ((TestObject2) obj2.o).o;
+        TestClassObject obj = new TestClassObject(TestClassObject.class);
+        TestClassObject obj2 = new TestClassObject(obj);
+        return ((TestClassObject) obj2.x).x;
     }
 
     @Test
@@ -204,9 +174,9 @@
     }
 
     public boolean testInstanceOfSnippet() {
-        TestObject2 obj = new TestObject2(TestObject2.class);
-        TestObject2 obj2 = new TestObject2(obj);
-        return obj2.o instanceof TestObject2;
+        TestClassObject obj = new TestClassObject(TestClassObject.class);
+        TestClassObject obj2 = new TestClassObject(obj);
+        return obj2.x instanceof TestClassObject;
     }
 
     @SuppressWarnings("unused")
@@ -223,98 +193,56 @@
         testEscapeAnalysis("testNewNodeSnippet", null, false);
     }
 
-    private static final TestObject2 staticObj = new TestObject2(null);
+    private static final TestClassObject staticObj = new TestClassObject();
 
     public static Object testFullyUnrolledLoopSnippet() {
         /*
          * This tests a case that can appear if PEA is performed both before and after loop
-         * unrolling/peeling: If the VirtualInstanceNode is not anchored correctly to stay within
-         * the loop, it will not be duplicated, and therefore the resulting object will reference
-         * itself, and not a second (different) object.
+         * unrolling/peeling: If the VirtualInstanceNode is not duplicated correctly with the loop,
+         * the resulting object will reference itself, and not a second (different) object.
          */
-        TestObject2 obj = staticObj;
+        TestClassObject obj = staticObj;
         for (int i = 0; i < 2; i++) {
-            obj = new TestObject2(obj);
+            obj = new TestClassObject(obj);
         }
-        return obj.o;
+        return obj.x;
     }
 
     @Test
     public void testFullyUnrolledLoop() {
-        testEscapeAnalysisUnrolled("testFullyUnrolledLoopSnippet");
+        prepareGraph("testFullyUnrolledLoopSnippet", false);
+        new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(graph, context);
+        new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context);
+        Assert.assertTrue(returnNode.result() instanceof AllocatedObjectNode);
+        CommitAllocationNode commit = ((AllocatedObjectNode) returnNode.result()).getCommit();
+        Assert.assertEquals(2, commit.getValues().size());
+        Assert.assertEquals(1, commit.getVirtualObjects().size());
+        Assert.assertTrue("non-cyclic data structure expected", commit.getVirtualObjects().get(0) != commit.getValues().get(0));
     }
 
-    private static Object staticField;
+    @SuppressWarnings("unused") private static Object staticField;
 
-    private static TestObject2 inlinedPart(TestObject2 obj) {
-        TestObject2 ret = new TestObject2(obj);
+    private static TestClassObject inlinedPart(TestClassObject obj) {
+        TestClassObject ret = new TestClassObject(obj);
         staticField = null;
         return ret;
     }
 
     public static Object testPeeledLoopSnippet() {
-        TestObject2 obj = staticObj;
+        TestClassObject obj = staticObj;
         int i = 0;
         do {
             obj = inlinedPart(obj);
         } while (i++ < 10);
         staticField = obj;
-        return obj.o;
+        return obj.x;
     }
 
     @Test
     public void testPeeledLoop() {
-        testEscapeAnalysisPeeled("testPeeledLoopSnippet");
-    }
-
-    private StructuredGraph graph;
-    private HighTierContext context;
-    private ReturnNode returnNode;
-
-    private void testEscapeAnalysis(String snippet, final Constant expectedConstantResult, final boolean iterativeEscapeAnalysis) {
-        prepareGraph(snippet, iterativeEscapeAnalysis);
-        if (expectedConstantResult != null) {
-            Assert.assertTrue(returnNode.result().toString(), returnNode.result().isConstant());
-            Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant());
-        }
-        int newInstanceCount = graph.getNodes().filter(NewInstanceNode.class).count() + graph.getNodes().filter(NewArrayNode.class).count() +
-                        graph.getNodes().filter(CommitAllocationNode.class).count();
-        Assert.assertEquals(0, newInstanceCount);
-    }
-
-    private void testEscapeAnalysisUnrolled(String snippet) {
-        prepareGraph(snippet, false);
-        new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(graph, context);
-        new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context);
-        Assert.assertTrue(returnNode.result() instanceof AllocatedObjectNode);
-        CommitAllocationNode commit = ((AllocatedObjectNode) returnNode.result()).getCommit();
-        Assert.assertEquals(1, commit.getValues().size());
-        Assert.assertEquals(1, commit.getVirtualObjects().size());
-        Assert.assertTrue("non-cyclic data structure expected", commit.getVirtualObjects().get(0) != commit.getValues().get(0));
-    }
-
-    private void testEscapeAnalysisPeeled(String snippet) {
-        prepareGraph(snippet, false);
+        prepareGraph("testPeeledLoopSnippet", false);
         new LoopTransformHighPhase().apply(graph);
         new LoopTransformLowPhase().apply(graph);
         new SchedulePhase().apply(graph);
     }
-
-    private void prepareGraph(String snippet, final boolean iterativeEscapeAnalysis) {
-        graph = new StructuredGraph(getMetaAccess().lookupJavaMethod(getMethod(snippet)));
-        Debug.scope("GraalCompiler", new Object[]{graph, getMetaAccess().lookupJavaMethod(getMethod(snippet)), getCodeCache()}, new Runnable() {
-
-            public void run() {
-                new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
-                Assumptions assumptions = new Assumptions(false);
-                context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-                new DeadCodeEliminationPhase().apply(graph);
-                new CanonicalizerPhase(true).apply(graph, context);
-                new PartialEscapePhase(iterativeEscapeAnalysis, new CanonicalizerPhase(true)).apply(graph, context);
-                Assert.assertEquals(1, graph.getNodes().filter(ReturnNode.class).count());
-                returnNode = graph.getNodes().filter(ReturnNode.class).first();
-            }
-        });
-    }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Mon Oct 28 17:03:59 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Mon Oct 28 15:25:27 2013 +0100
@@ -30,6 +30,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.compiler.test.ea.EATestBase.TestClassInt;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.*;
@@ -50,14 +51,10 @@
         }
     }
 
-    public static class TestInt implements Callable<Integer> {
-
-        public int x;
-        public int y;
+    public static class TestInt extends TestClassInt implements Callable<Integer> {
 
         public TestInt(int x, int y) {
-            this.x = x;
-            this.y = y;
+            super(x, y);
         }
 
         @Override
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Mon Oct 28 17:03:59 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Mon Oct 28 15:25:27 2013 +0100
@@ -23,29 +23,23 @@
 package com.oracle.graal.compiler.test.ea;
 
 import java.lang.ref.*;
-import java.util.concurrent.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.graph.*;
-import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.virtual.phases.ea.*;
 
 /**
  * The PartialEscapeAnalysisPhase is expected to remove all allocations and return the correct
  * values.
  */
-public class PartialEscapeAnalysisTest extends GraalCompilerTest {
+public class PartialEscapeAnalysisTest extends EATestBase {
 
     public static class TestObject {
 
@@ -71,7 +65,7 @@
 
     @Test
     public void test1() {
-        testMaterialize("test1Snippet", 0.25, 1);
+        testPartialEscapeAnalysis("test1Snippet", 0.25, 1);
     }
 
     @SuppressWarnings("all")
@@ -90,7 +84,7 @@
 
     @Test
     public void test2() {
-        testMaterialize("test2Snippet", 1.5, 3, LoadIndexedNode.class);
+        testPartialEscapeAnalysis("test2Snippet", 1.5, 3, LoadIndexedNode.class);
     }
 
     public static Object test2Snippet(int a, Object x, Object y, Object z) {
@@ -109,7 +103,7 @@
 
     @Test
     public void test3() {
-        testMaterialize("test3Snippet", 0.5, 1, StoreFieldNode.class, LoadFieldNode.class);
+        testPartialEscapeAnalysis("test3Snippet", 0.5, 1, StoreFieldNode.class, LoadFieldNode.class);
     }
 
     public static Object test3Snippet(int a) {
@@ -127,7 +121,7 @@
 
     @Test
     public void testCache() {
-        testMaterialize("testCacheSnippet", 0.75, 1);
+        testPartialEscapeAnalysis("testCacheSnippet", 0.75, 1);
     }
 
     public static class CacheKey {
@@ -175,57 +169,40 @@
 
     @Test
     public void testReference1() {
-        assertEquals(1, processMethod("testReference1Snippet").getNodes().filter(NewInstanceNode.class).count());
+        prepareGraph("testReference1Snippet", false);
+        assertEquals(1, graph.getNodes().filter(NewInstanceNode.class).count());
     }
 
     @SafeVarargs
-    final void testMaterialize(final String snippet, double expectedProbability, int expectedCount, Class<? extends Node>... invalidNodeClasses) {
-        StructuredGraph result = processMethod(snippet);
+    protected final void testPartialEscapeAnalysis(final String snippet, double expectedProbability, int expectedCount, Class<? extends Node>... invalidNodeClasses) {
+        prepareGraph(snippet, false);
+        for (MergeNode merge : graph.getNodes(MergeNode.class)) {
+            merge.setStateAfter(null);
+        }
+        new DeadCodeEliminationPhase().apply(graph);
+        new CanonicalizerPhase(true).apply(graph, context);
         try {
-            Assert.assertTrue("partial escape analysis should have removed all NewInstanceNode allocations", result.getNodes().filter(NewInstanceNode.class).isEmpty());
-            Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", result.getNodes().filter(NewArrayNode.class).isEmpty());
+            Assert.assertTrue("partial escape analysis should have removed all NewInstanceNode allocations", graph.getNodes().filter(NewInstanceNode.class).isEmpty());
+            Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", graph.getNodes().filter(NewArrayNode.class).isEmpty());
 
-            NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(result).apply();
+            NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(graph).apply();
             double probabilitySum = 0;
             int materializeCount = 0;
-            for (CommitAllocationNode materialize : result.getNodes().filter(CommitAllocationNode.class)) {
+            for (CommitAllocationNode materialize : graph.getNodes().filter(CommitAllocationNode.class)) {
                 probabilitySum += nodeProbabilities.get(materialize) * materialize.getVirtualObjects().size();
                 materializeCount += materialize.getVirtualObjects().size();
             }
             Assert.assertEquals("unexpected number of MaterializeObjectNodes", expectedCount, materializeCount);
             Assert.assertEquals("unexpected probability of MaterializeObjectNodes", expectedProbability, probabilitySum, 0.01);
-            for (Node node : result.getNodes()) {
+            for (Node node : graph.getNodes()) {
                 for (Class<? extends Node> clazz : invalidNodeClasses) {
                     Assert.assertFalse("instance of invalid class: " + clazz.getSimpleName(), clazz.isInstance(node) && node.usages().isNotEmpty());
                 }
             }
         } catch (AssertionError e) {
-            TypeSystemTest.outputGraph(result, snippet + ": " + e.getMessage());
+            TypeSystemTest.outputGraph(graph, snippet + ": " + e.getMessage());
             throw e;
         }
     }
 
-    private StructuredGraph processMethod(final String snippet) {
-        return Debug.scope("PartialEscapeAnalysisTest " + snippet, new DebugDumpScope(snippet), new Callable<StructuredGraph>() {
-
-            @Override
-            public StructuredGraph call() {
-                StructuredGraph graph = parse(snippet);
-
-                Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-                new DeadCodeEliminationPhase().apply(graph);
-                new CanonicalizerPhase(true).apply(graph, context);
-                new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context);
-
-                for (MergeNode merge : graph.getNodes(MergeNode.class)) {
-                    merge.setStateAfter(null);
-                }
-                new DeadCodeEliminationPhase().apply(graph);
-                new CanonicalizerPhase(true).apply(graph, context);
-                return graph;
-            }
-        });
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/UnsafeEATest.java	Mon Oct 28 15:25:27 2013 +0100
@@ -0,0 +1,191 @@
+/*
+ * 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.graal.compiler.test.ea;
+
+import org.junit.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+public class UnsafeEATest extends EATestBase {
+
+    public static int zero = 0;
+
+    private static final Unsafe unsafe;
+    private static final long fieldOffsetX;
+    private static final long fieldOffsetY;
+
+    static {
+        unsafe = UnsafeAccess.unsafe;
+        try {
+            fieldOffsetX = unsafe.objectFieldOffset(TestClassInt.class.getField("x"));
+            fieldOffsetY = unsafe.objectFieldOffset(TestClassInt.class.getField("y"));
+            assert fieldOffsetY == fieldOffsetX + 4;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Test
+    public void testSimpleInt() {
+        testEscapeAnalysis("testSimpleIntSnippet", Constant.forInt(101), false);
+    }
+
+    public static int testSimpleIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        unsafe.putInt(x, fieldOffsetX, 101);
+        return unsafe.getInt(x, fieldOffsetX);
+    }
+
+    @Test
+    public void testMaterializedInt() {
+        test("testMaterializedIntSnippet");
+    }
+
+    public static TestClassInt testMaterializedIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        unsafe.putInt(x, fieldOffsetX, 101);
+        return x;
+    }
+
+    @Test
+    public void testSimpleDouble() {
+        testEscapeAnalysis("testSimpleDoubleSnippet", Constant.forDouble(10.1), false);
+    }
+
+    public static double testSimpleDoubleSnippet() {
+        TestClassInt x = new TestClassInt();
+        unsafe.putDouble(x, fieldOffsetX, 10.1);
+        return unsafe.getDouble(x, fieldOffsetX);
+    }
+
+    @Test
+    public void testMergedDouble() {
+        testEscapeAnalysis("testMergedDoubleSnippet", null, false);
+        Assert.assertTrue(returnNode.result() instanceof PhiNode);
+        PhiNode phi = (PhiNode) returnNode.result();
+        Assert.assertTrue(phi.valueAt(0) instanceof LoadFieldNode);
+        Assert.assertTrue(phi.valueAt(1) instanceof LoadFieldNode);
+    }
+
+    public static double testMergedDoubleSnippet(boolean a) {
+        TestClassInt x;
+        if (a) {
+            x = new TestClassInt(0, 0);
+            unsafe.putDouble(x, fieldOffsetX, doubleField);
+        } else {
+            x = new TestClassInt();
+            unsafe.putDouble(x, fieldOffsetX, doubleField2);
+        }
+        return unsafe.getDouble(x, fieldOffsetX);
+    }
+
+    @Test
+    public void testMaterializedDouble() {
+        test("testMaterializedDoubleSnippet");
+    }
+
+    public static TestClassInt testMaterializedDoubleSnippet() {
+        TestClassInt x = new TestClassInt();
+        unsafe.putDouble(x, fieldOffsetX, 10.1);
+        return x;
+    }
+
+    @Test
+    public void testDeoptDoubleVar() {
+        test("testDeoptDoubleVarSnippet");
+    }
+
+    public static double doubleField = 10.1e99;
+    public static double doubleField2;
+
+    public static TestClassInt testDeoptDoubleVarSnippet() {
+        TestClassInt x = new TestClassInt();
+        unsafe.putDouble(x, fieldOffsetX, doubleField);
+        doubleField2 = 123;
+        try {
+            doubleField = ((int) unsafe.getDouble(x, fieldOffsetX)) / zero;
+        } catch (RuntimeException e) {
+            return x;
+        }
+        return x;
+    }
+
+    @Test
+    public void testDeoptDoubleConstant() {
+        test("testDeoptDoubleConstantSnippet");
+    }
+
+    public static TestClassInt testDeoptDoubleConstantSnippet() {
+        TestClassInt x = new TestClassInt();
+        unsafe.putDouble(x, fieldOffsetX, 10.123);
+        doubleField2 = 123;
+        try {
+            doubleField = ((int) unsafe.getDouble(x, fieldOffsetX)) / zero;
+        } catch (RuntimeException e) {
+            return x;
+        }
+        return x;
+    }
+
+    @Test
+    public void testDeoptLongVar() {
+        test("testDeoptLongVarSnippet");
+    }
+
+    public static long longField = 0x133443218aaaffffL;
+    public static long longField2;
+
+    public static TestClassInt testDeoptLongVarSnippet() {
+        TestClassInt x = new TestClassInt();
+        unsafe.putLong(x, fieldOffsetX, longField);
+        longField2 = 123;
+        try {
+            longField = unsafe.getLong(x, fieldOffsetX) / zero;
+        } catch (RuntimeException e) {
+            return x;
+        }
+        return x;
+    }
+
+    @Test
+    public void testDeoptLongConstant() {
+        test("testDeoptLongConstantSnippet");
+    }
+
+    public static TestClassInt testDeoptLongConstantSnippet() {
+        TestClassInt x = new TestClassInt();
+        unsafe.putLong(x, fieldOffsetX, 0x2222222210123L);
+        longField2 = 123;
+        try {
+            longField = unsafe.getLong(x, fieldOffsetX) / zero;
+        } catch (RuntimeException e) {
+            return x;
+        }
+        return x;
+    }
+}