changeset 7263:6ed187f3134b

added unit test for array copy intrinsification
author Doug Simon <doug.simon@oracle.com>
date Tue, 18 Dec 2012 15:22:01 +0100
parents 5f21ab202edc
children 4558c8aedd5f
files graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/ArrayCopyIntrinsificationTest.java mx/projects
diffstat 2 files changed, 238 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/ArrayCopyIntrinsificationTest.java	Tue Dec 18 15:22:01 2012 +0100
@@ -0,0 +1,231 @@
+/*
+ * 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.hotspot;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+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.graph.*;
+import com.oracle.graal.hotspot.snippets.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.PhasePlan.PhasePosition;
+
+
+/**
+ * Tests intrinsification of {@link System#arraycopy(Object, int, Object, int, int)}.
+ */
+public class ArrayCopyIntrinsificationTest extends GraalCompilerTest {
+
+    @Override
+    protected void editPhasePlan(ResolvedJavaMethod method, StructuredGraph graph, PhasePlan phasePlan) {
+        phasePlan.addPhase(PhasePosition.HIGH_LEVEL, new IntrinsifyArrayCopyPhase(runtime, new Assumptions(false)));
+    }
+
+    @Override
+    protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph) {
+        int nodeCount = graph.getNodeCount();
+        InstalledCode result = super.getCode(method, graph);
+        boolean graphWasProcessed = nodeCount != graph.getNodeCount();
+        if (graphWasProcessed) {
+            if (mustIntrinsify) {
+                for (Node node: graph.getNodes()) {
+                    if (node instanceof Invoke) {
+                        Invoke invoke = (Invoke) node;
+                        Assert.assertTrue(invoke.callTarget() instanceof DirectCallTargetNode);
+                        DirectCallTargetNode directCall = (DirectCallTargetNode) invoke.callTarget();
+                        Assert.assertTrue(directCall.target() instanceof JavaMethod);
+                        JavaMethod callee = (JavaMethod) directCall.target();
+                        Assert.assertTrue(callee.getName().equals("<init>"));
+                        Assert.assertTrue(runtime.lookupJavaType(ArrayIndexOutOfBoundsException.class).equals(callee.getDeclaringClass()) ||
+                                          runtime.lookupJavaType(NullPointerException.class).equals(callee.getDeclaringClass()));
+                    }
+                }
+            } else {
+                boolean found = false;
+                for (Node node: graph.getNodes()) {
+                    if (node instanceof Invoke) {
+                        Invoke invoke = (Invoke) node;
+                        DirectCallTargetNode directCall = (DirectCallTargetNode) invoke.callTarget();
+                        JavaMethod callee = (JavaMethod) directCall.target();
+                        if (callee.getDeclaringClass().equals(runtime.lookupJavaType(System.class)) && callee.getName().equals("arraycopy")) {
+                            found = true;
+                        } else {
+                            fail("found invoke to some method other than arraycopy: " + callee);
+                        }
+                    }
+                }
+                Assert.assertTrue("did not find invoke to arraycopy", found);
+            }
+        }
+        return result;
+    }
+
+    boolean mustIntrinsify = true;
+
+    @Test
+    public void test0() {
+        mustIntrinsify = false; // a generic call to arraycopy will not be intrinsified
+        // Array store checks
+        test("genericArraycopy", new Object(), 0, new Object[0], 0, 0);
+        test("genericArraycopy", new Object[0], 0, new Object(), 0, 0);
+    }
+
+    @Test
+    public void test1() {
+        String name = "intArraycopy";
+        int[] src = {234, 5345, 756, 23, 8, 345, 873, 440};
+        // Null checks
+        test(name, null, 0, src, 0, 0);
+        test(name, src, 0, null, 0, 0);
+        // Bounds checks
+        test(name, src, 0, src, 0, -1);
+        test(name, src, 0, src, 0, src.length + 1);
+    }
+
+    @Test
+    public void testByte() {
+        byte[] src = {-1, 0, 1, 2, 3, 4};
+        testHelper("byteArraycopy", src);
+    }
+
+    @Test
+    public void testChar() {
+        char[] src = "some string of chars".toCharArray();
+        testHelper("charArraycopy", src);
+    }
+
+    @Test
+    public void testShort() {
+        short[] src = {234, 5345, 756, 23, 8, 345, 873, 440};
+        testHelper("shortArraycopy", src);
+    }
+
+    @Test
+    public void testInt() {
+        int[] src = {234, 5345, 756, 23, 8, 345, 873, 440};
+        testHelper("intArraycopy", src);
+    }
+
+    @Test
+    public void testFloat() {
+        float[] src = {234, 5345, 756, 23, 8, 345, 873, 440};
+        testHelper("floatArraycopy", src);
+    }
+
+    @Test
+    public void testLong() {
+        long[] src = {234, 5345, 756, 23, 8, 345, 873, 440};
+        testHelper("longArraycopy", src);
+    }
+
+    @Test
+    public void testDouble() {
+        double[] src = {234, 5345, 756, 23, 8, 345, 873, 440};
+        testHelper("doubleArraycopy", src);
+    }
+
+    @Test
+    public void testObject() {
+        Object[] src = {"one", "two", "three", new ArrayList<>(), new HashMap<>()};
+        testHelper("objectArraycopy", src);
+    }
+
+    private static Object newArray(Object proto, int length) {
+        assert proto != null;
+        assert proto.getClass().isArray();
+        return Array.newInstance(proto.getClass().getComponentType(), length);
+    }
+
+    private void testHelper(String name, Object src) {
+        int srcLength = Array.getLength(src);
+
+        // Complete array copy
+        test(name, src, 0, newArray(src, srcLength), 0, srcLength);
+
+        for (int length : new int[] {0, 1, srcLength - 1, srcLength}) {
+            // Partial array copying
+            test(name, src, 0, newArray(src, length), 0, length);
+            test(name, src, srcLength - length, newArray(src, length), 0, length);
+            test(name, src, 0, newArray(src, srcLength), 0, length);
+        }
+    }
+
+    public static Object genericArraycopy(Object src, int srcPos, Object dst, int dstPos, int length) {
+        System.arraycopy(src, srcPos, dst, dstPos, length);
+        return dst;
+    }
+
+    public static Object[] objectArraycopy(Object[] src, int srcPos, Object[] dst, int dstPos, int length) {
+        System.arraycopy(src, srcPos, dst, dstPos, length);
+        return dst;
+    }
+
+    public static boolean[] booleanArraycopy(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length) {
+        System.arraycopy(src, srcPos, dst, dstPos, length);
+        return dst;
+    }
+
+    public static byte[] byteArraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length) {
+        System.arraycopy(src, srcPos, dst, dstPos, length);
+        return dst;
+    }
+
+    public static char[] charArraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length) {
+        System.arraycopy(src, srcPos, dst, dstPos, length);
+        return dst;
+    }
+
+    public static short[] shortArraycopy(short[] src, int srcPos, short[] dst, int dstPos, int length) {
+        System.arraycopy(src, srcPos, dst, dstPos, length);
+        return dst;
+    }
+
+    public static int[] intArraycopy(int[] src, int srcPos, int[] dst, int dstPos, int length) {
+        System.arraycopy(src, srcPos, dst, dstPos, length);
+        return dst;
+    }
+
+    public static float[] floatArraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length) {
+        System.arraycopy(src, srcPos, dst, dstPos, length);
+        return dst;
+    }
+
+    public static long[] longArraycopy(long[] src, int srcPos, long[] dst, int dstPos, int length) {
+        System.arraycopy(src, srcPos, dst, dstPos, length);
+        return dst;
+    }
+
+    public static double[] doubleArraycopy(double[] src, int srcPos, double[] dst, int dstPos, int length) {
+        System.arraycopy(src, srcPos, dst, dstPos, length);
+        return dst;
+    }
+
+}
--- a/mx/projects	Tue Dec 18 15:20:58 2012 +0100
+++ b/mx/projects	Tue Dec 18 15:22:01 2012 +0100
@@ -90,6 +90,13 @@
 project@com.oracle.graal.hotspot.server@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot.server@javaCompliance=1.7
 
+# graal.hotspot.test
+project@com.oracle.graal.hotspot.test@subDir=graal
+project@com.oracle.graal.hotspot.test@sourceDirs=src
+project@com.oracle.graal.hotspot.test@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.test
+project@com.oracle.graal.hotspot.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.hotspot.test@javaCompliance=1.7
+
 # graal.graph
 project@com.oracle.graal.graph@subDir=graal
 project@com.oracle.graal.graph@sourceDirs=src