# HG changeset patch # User Gilles Duboscq # Date 1355841928 -3600 # Node ID a6dfccdc3694b0feb35db574c940ecf02067959d # Parent 32e29e5df27e1e724849ef480664aa3600b1ce96# Parent 4558c8aedd5f3be70b4e72fed886174432d0d29f Merge diff -r 32e29e5df27e -r a6dfccdc3694 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java Tue Dec 18 15:02:42 2012 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java Tue Dec 18 15:45:28 2012 +0100 @@ -28,6 +28,9 @@ public enum DeoptimizationAction { /** * Do not invalidate the machine code. + * This is typically used when deoptimizing at a point where it's highly likely + * nothing will change the likelihood of the deoptimization happening again. + * For example, a compiled array allocation where the size is negative. */ None, @@ -43,6 +46,9 @@ /** * Invalidate the machine code and immediately schedule a recompilation. + * This is typically used when deoptimizing to resolve an unresolved symbol in + * which case extra profiling is not required to determine that the deoptimization + * will not re-occur. */ InvalidateRecompile, diff -r 32e29e5df27e -r a6dfccdc3694 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Dec 18 15:02:42 2012 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Dec 18 15:45:28 2012 +0100 @@ -26,7 +26,7 @@ import java.util.*; import java.util.concurrent.*; -import junit.framework.*; +import org.junit.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -162,8 +162,37 @@ private static int compilationId = 0; + /** + * Compares two given objects for {@linkplain Assert#assertEquals(Object, Object) equality}. + * Does a deep copy equality comparison if {@code expected} is an array. + */ protected void assertEquals(Object expected, Object actual) { - Assert.assertEquals(expected, actual); + if (expected != null && expected.getClass().isArray()) { + Assert.assertTrue(expected != null); + Assert.assertTrue(actual != null); + Assert.assertEquals(expected.getClass(), actual.getClass()); + if (expected instanceof int[]) { + Assert.assertArrayEquals((int[]) expected, (int[]) actual); + } else if (expected instanceof byte[]) { + Assert.assertArrayEquals((byte[]) expected, (byte[]) actual); + } else if (expected instanceof char[]) { + Assert.assertArrayEquals((char[]) expected, (char[]) actual); + } else if (expected instanceof short[]) { + Assert.assertArrayEquals((short[]) expected, (short[]) actual); + } else if (expected instanceof float[]) { + Assert.assertArrayEquals((float[]) expected, (float[]) actual, 0.0f); + } else if (expected instanceof long[]) { + Assert.assertArrayEquals((long[]) expected, (long[]) actual); + } else if (expected instanceof double[]) { + Assert.assertArrayEquals((double[]) expected, (double[]) actual, 0.0d); + } else if (expected instanceof Object[]) { + Assert.assertArrayEquals((Object[]) expected, (Object[]) actual); + } else { + Assert.fail("non-array value encountered: " + expected); + } + } else { + Assert.assertEquals(expected, actual); + } } protected void testN(int n, final String name, final Object... args) { diff -r 32e29e5df27e -r a6dfccdc3694 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:45:28 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 32e29e5df27e -r a6dfccdc3694 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java Tue Dec 18 15:02:42 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java Tue Dec 18 15:45:28 2012 +0100 @@ -21,8 +21,11 @@ * questions. */ package com.oracle.graal.hotspot.snippets; +import static com.oracle.graal.api.code.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.nodes.*; @@ -42,7 +45,6 @@ private static final Kind VECTOR_KIND = Kind.Long; private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long); - @Snippet public static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter("baseKind") Kind baseKind) { checkInputs(src, srcPos, dest, destPos, length); int header = arrayBaseOffset(baseKind); @@ -71,13 +73,12 @@ } } - @Snippet public static void checkInputs(Object src, int srcPos, Object dest, int destPos, int length) { if (src == null || dest == null) { throw new NullPointerException(); } if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > ArrayLengthNode.arrayLength(src) || destPos + length > ArrayLengthNode.arrayLength(dest)) { - throw new IndexOutOfBoundsException(); + throw new ArrayIndexOutOfBoundsException(); } } diff -r 32e29e5df27e -r a6dfccdc3694 graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewMultiArrayTest.java --- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewMultiArrayTest.java Tue Dec 18 15:02:42 2012 +0100 +++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewMultiArrayTest.java Tue Dec 18 15:45:28 2012 +0100 @@ -38,32 +38,6 @@ */ public class NewMultiArrayTest extends GraalCompilerTest { - @Override - protected void assertEquals(Object expected, Object actual) { - Assert.assertTrue(expected != null); - Assert.assertTrue(actual != null); - super.assertEquals(expected.getClass(), actual.getClass()); - if (expected instanceof int[]) { - Assert.assertArrayEquals((int[]) expected, (int[]) actual); - } else if (expected instanceof byte[]) { - Assert.assertArrayEquals((byte[]) expected, (byte[]) actual); - } else if (expected instanceof char[]) { - Assert.assertArrayEquals((char[]) expected, (char[]) actual); - } else if (expected instanceof short[]) { - Assert.assertArrayEquals((short[]) expected, (short[]) actual); - } else if (expected instanceof float[]) { - Assert.assertArrayEquals((float[]) expected, (float[]) actual, 0.0f); - } else if (expected instanceof long[]) { - Assert.assertArrayEquals((long[]) expected, (long[]) actual); - } else if (expected instanceof double[]) { - Assert.assertArrayEquals((double[]) expected, (double[]) actual, 0.0d); - } else if (expected instanceof Object[]) { - Assert.assertArrayEquals((Object[]) expected, (Object[]) actual); - } else { - Assert.fail("non-array value encountered: " + expected); - } - } - private static int rank(ResolvedJavaType type) { String name = type.getName(); int dims = 0; diff -r 32e29e5df27e -r a6dfccdc3694 mx/projects --- a/mx/projects Tue Dec 18 15:02:42 2012 +0100 +++ b/mx/projects Tue Dec 18 15:45:28 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