Optimize out cast path in System.arraycopy when type checks are disabled.

Change-Id: I521685fc22ca5d2a8d96eac6e616e511a8abc20f
diff --git a/user/super/com/google/gwt/emul/java/lang/System.java b/user/super/com/google/gwt/emul/java/lang/System.java
index 9682b6c..3400d30 100644
--- a/user/super/com/google/gwt/emul/java/lang/System.java
+++ b/user/super/com/google/gwt/emul/java/lang/System.java
@@ -17,6 +17,7 @@
 
 import static javaemul.internal.InternalPreconditions.checkArrayType;
 import static javaemul.internal.InternalPreconditions.checkNotNull;
+import static javaemul.internal.InternalPreconditions.isTypeChecked;
 
 import java.io.PrintStream;
 
@@ -61,13 +62,13 @@
     if (srcOfs < 0 || destOfs < 0 || len < 0 || srcOfs + len > srclen || destOfs + len > destlen) {
       throw new IndexOutOfBoundsException();
     }
+
     /*
      * If the arrays are not references or if they are exactly the same type, we
      * can copy them in native code for speed. Otherwise, we have to copy them
      * in Java so we get appropriate errors.
      */
-    if ((!srcComp.isPrimitive() || srcComp.isArray())
-        && !srcType.equals(destType)) {
+    if (isTypeChecked() && !srcComp.isPrimitive() && !srcType.equals(destType)) {
       // copy in Java to make sure we get ArrayStoreExceptions if the values
       // aren't compatible
       Object[] srcArray = (Object[]) src;
diff --git a/user/super/com/google/gwt/emul/javaemul/internal/InternalPreconditions.java b/user/super/com/google/gwt/emul/javaemul/internal/InternalPreconditions.java
index 540f110..6321623 100644
--- a/user/super/com/google/gwt/emul/javaemul/internal/InternalPreconditions.java
+++ b/user/super/com/google/gwt/emul/javaemul/internal/InternalPreconditions.java
@@ -31,6 +31,17 @@
   private static final boolean BOUND_CHECK =
       System.getProperty("jre.checks.bounds", "ENABLED").equals("ENABLED");
 
+  /**
+   * This method reports if the code is compiled with type checks.
+   * It must be used in places where code can be replaced with a simpler one
+   * when we know that no checks will occur.
+   * See {@link System#arraycopy(Object, int, Object, int, int)} for example.
+   * Please note that {@link #checkType(boolean)} should be preferred where feasible.
+   */
+  public static boolean isTypeChecked() {
+    return TYPE_CHECK || CHECKED_MODE;
+  }
+
   public static void checkType(boolean expression) {
     if (TYPE_CHECK) {
       checkCriticalType(expression);