changeset 7339:8f7be0c45a82

arraycopy cannot be intrinsified if the destination array type is not exact
author Doug Simon <doug.simon@oracle.com>
date Fri, 11 Jan 2013 15:05:31 +0100
parents 13d5545e24e2
children b314440029ea 867ec7c2a9ca
files graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/ArrayCopyIntrinsificationTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java
diffstat 2 files changed, 53 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/ArrayCopyIntrinsificationTest.java	Fri Jan 11 12:47:37 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/ArrayCopyIntrinsificationTest.java	Fri Jan 11 15:05:31 2013 +0100
@@ -153,9 +153,24 @@
     }
 
     @Test
-    public void testObject() {
+    public void testObjectExact() {
         Object[] src = {"one", "two", "three", new ArrayList<>(), new HashMap<>()};
-        testHelper("objectArraycopy", src);
+        test("exactObjectArraycopy", (Object) src);
+    }
+
+    @Test
+    public void testString() {
+        String[] src = {"one", "two", "three"};
+        test("stringArraycopy", src, 0, new String[src.length], 0, src.length);
+    }
+
+    @Test
+    public void testObject() {
+        mustIntrinsify = false; // a call to arraycopy where dest is not an exact type will not be intrinsified
+        Object[] src = {"one", "two", "three", new ArrayList<>(), new HashMap<>()};
+        test("objectArraycopy", src, 0, new Object[src.length], 0, src.length);
+        // Expect ArrayStoreException
+        test("objectArraycopy", src, 0, new String[src.length], 0, src.length);
     }
 
     private static Object newArray(Object proto, int length) {
@@ -188,6 +203,17 @@
         return dst;
     }
 
+    public static Object[] exactObjectArraycopy(Object[] src) {
+        Object[] dst = new Object[src.length];
+        System.arraycopy(src, 0, dst, 0, src.length);
+        return dst;
+    }
+
+    public static Object[] stringArraycopy(String[] src, int srcPos, String[] 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;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java	Fri Jan 11 12:47:37 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java	Fri Jan 11 15:05:31 2013 +0100
@@ -31,6 +31,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 
@@ -82,34 +83,37 @@
                 ValueNode src = methodCallTarget.arguments().get(0);
                 ValueNode dest = methodCallTarget.arguments().get(2);
                 assert src != null && dest != null;
-                ResolvedJavaType srcType = src.objectStamp().type();
-                ResolvedJavaType destType = dest.objectStamp().type();
+                ObjectStamp srcStamp = src.objectStamp();
+                ObjectStamp destStamp = dest.objectStamp();
+                ResolvedJavaType srcType = srcStamp.type();
+                ResolvedJavaType destType = destStamp.type();
                 if (srcType != null
                                 && srcType.isArray()
                                 && destType != null
                                 && destType.isArray()) {
                     Kind componentKind = srcType.getComponentType().getKind();
-                    if (srcType.getComponentType() == destType.getComponentType()) {
-                        if (componentKind == Kind.Int) {
-                            snippetMethod = intArrayCopy;
-                        } else if (componentKind == Kind.Char) {
-                            snippetMethod = charArrayCopy;
-                        } else if (componentKind == Kind.Long) {
-                            snippetMethod = longArrayCopy;
-                        } else if (componentKind == Kind.Byte) {
-                            snippetMethod = byteArrayCopy;
-                        } else if (componentKind == Kind.Short) {
-                            snippetMethod = shortArrayCopy;
-                        } else if (componentKind == Kind.Float) {
-                            snippetMethod = floatArrayCopy;
-                        } else if (componentKind == Kind.Double) {
-                            snippetMethod = doubleArrayCopy;
-                        } else if (componentKind == Kind.Object) {
+                    if (componentKind != Kind.Object) {
+                        if (srcType.getComponentType() == destType.getComponentType()) {
+                            if (componentKind == Kind.Int) {
+                                snippetMethod = intArrayCopy;
+                            } else if (componentKind == Kind.Char) {
+                                snippetMethod = charArrayCopy;
+                            } else if (componentKind == Kind.Long) {
+                                snippetMethod = longArrayCopy;
+                            } else if (componentKind == Kind.Byte) {
+                                snippetMethod = byteArrayCopy;
+                            } else if (componentKind == Kind.Short) {
+                                snippetMethod = shortArrayCopy;
+                            } else if (componentKind == Kind.Float) {
+                                snippetMethod = floatArrayCopy;
+                            } else if (componentKind == Kind.Double) {
+                                snippetMethod = doubleArrayCopy;
+                            }
+                        }
+                    } else if (destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
+                        if (destStamp.isExactType()) {
                             snippetMethod = objectArrayCopy;
                         }
-                    } else if (componentKind == Kind.Object
-                                    && destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
-                        snippetMethod = objectArrayCopy;
                     }
                 }
             }