# HG changeset patch # User Doug Simon # Date 1355840521 -3600 # Node ID 6ed187f3134bb578a726ae2a11e1b6d6bb79fa9c # Parent 5f21ab202edcd27da29af324228872e8ac52bbf3 added unit test for array copy intrinsification diff -r 5f21ab202edc -r 6ed187f3134b graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/ArrayCopyIntrinsificationTest.java --- /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("")); + 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; + } + +} diff -r 5f21ab202edc -r 6ed187f3134b mx/projects --- 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