hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java
changeset 43972 1ade39b8381b
child 46344 694c102fd8ed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java	Thu Feb 16 15:46:09 2017 -0800
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2011, 2014, 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 org.graalvm.compiler.core.test.ea;
+
+import java.util.List;
+
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+import org.junit.Assert;
+
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.debug.Debug;
+import org.graalvm.compiler.debug.Debug.Scope;
+import org.graalvm.compiler.nodes.ReturnNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.java.NewArrayNode;
+import org.graalvm.compiler.nodes.java.NewInstanceNode;
+import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
+import org.graalvm.compiler.phases.common.inlining.InliningPhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
+
+//JaCoCo Exclude
+
+/**
+ * This base class for all Escape Analysis tests does not contain tests itself, therefore it is not
+ * automatically excluded from JaCoCo. Since it includes code that is used in the test snippets, it
+ * needs to be excluded manually.
+ */
+public class EATestBase extends GraalCompilerTest {
+
+    public static class TestClassInt {
+        public int x;
+        public int y;
+        public int z;
+
+        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 && z == other.z;
+        }
+
+        @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 List<ReturnNode> returnNodes;
+
+    /**
+     * 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, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis) {
+        prepareGraph(snippet, iterativeEscapeAnalysis);
+        if (expectedConstantResult != null) {
+            for (ReturnNode returnNode : returnNodes) {
+                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);
+    }
+
+    @SuppressWarnings("try")
+    protected void prepareGraph(String snippet, boolean iterativeEscapeAnalysis) {
+        ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
+        try (Scope s = Debug.scope(getClass(), method, getCodeCache())) {
+            graph = parseEager(method, AllowAssumptions.YES);
+            context = getDefaultHighTierContext();
+            new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
+            new DeadCodeEliminationPhase().apply(graph);
+            new CanonicalizerPhase().apply(graph, context);
+            new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(), null).apply(graph, context);
+            returnNodes = graph.getNodes(ReturnNode.TYPE).snapshot();
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+    }
+}