8020283: Don't use exceptions for widening of ArrayData
authorhannesw
Mon, 15 Jul 2013 16:35:38 +0200
changeset 18879 382986b34105
parent 18878 078eb52cf5bc
child 18880 89eafd5b9ff7
8020283: Don't use exceptions for widening of ArrayData Reviewed-by: jlaskey, attila
nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java
nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java
nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java	Mon Jul 15 16:31:49 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java	Mon Jul 15 16:35:38 2013 +0200
@@ -75,7 +75,9 @@
     }
 
     private static Object[] toObjectArray(final int[] array, final int length) {
-        final Object[] oarray = new Object[length];
+        assert length <= array.length : "length exceeds internal array size";
+        final Object[] oarray = new Object[array.length];
+
         for (int index = 0; index < length; index++) {
             oarray[index] = Integer.valueOf(array[index]);
         }
@@ -83,18 +85,22 @@
         return oarray;
     }
 
-    private static double[] toDoubleArray(final int[] array) {
+    private static double[] toDoubleArray(final int[] array, final int length) {
+        assert length <= array.length : "length exceeds internal array size";
         final double[] darray = new double[array.length];
-        for (int index = 0; index < array.length; index++) {
+
+        for (int index = 0; index < length; index++) {
             darray[index] = array[index];
         }
 
         return darray;
     }
 
-    private static long[] toLongArray(final int[] array) {
+    private static long[] toLongArray(final int[] array, final int length) {
+        assert length <= array.length : "length exceeds internal array size";
         final long[] larray = new long[array.length];
-        for (int index = 0; index < array.length; index++) {
+
+        for (int index = 0; index < length; index++) {
             larray[index] = array[index];
         }
 
@@ -105,12 +111,14 @@
     public ArrayData convert(final Class<?> type) {
         if (type == Integer.class) {
             return this;
-        } else if (type == Long.class) {
-            return new LongArrayData(IntArrayData.toLongArray(array), (int) length());
+        }
+        final int length = (int) length();
+        if (type == Long.class) {
+            return new LongArrayData(IntArrayData.toLongArray(array, length), length);
         } else if (type == Double.class) {
-            return new NumberArrayData(IntArrayData.toDoubleArray(array), (int) length());
+            return new NumberArrayData(IntArrayData.toDoubleArray(array, length), length);
         } else {
-            return new ObjectArrayData(IntArrayData.toObjectArray(array, array.length), (int) length());
+            return new ObjectArrayData(IntArrayData.toObjectArray(array, length), length);
         }
     }
 
@@ -161,26 +169,13 @@
 
     @Override
     public ArrayData set(final int index, final Object value, final boolean strict) {
-        try {
-            final int intValue = ((Integer)value).intValue();
-            array[index] = intValue;
-            setLength(Math.max(index + 1, length()));
-            return this;
-        } catch (final NullPointerException | ClassCastException e) {
-            if (value instanceof Short || value instanceof Byte) {
-                final int intValue = ((Number)value).intValue();
-                array[index] = intValue;
-                setLength(Math.max(index + 1, length()));
-                return this;
-            }
-
-            if (value == ScriptRuntime.UNDEFINED) {
-                return new UndefinedArrayFilter(this).set(index, value, strict);
-            }
+        if (value instanceof Integer) {
+            return set(index, ((Number)value).intValue(), strict);
+        } else if (value == ScriptRuntime.UNDEFINED) {
+            return new UndefinedArrayFilter(this).set(index, value, strict);
         }
 
         final ArrayData newData = convert(value == null ? Object.class : value.getClass());
-
         return newData.set(index, value, strict);
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java	Mon Jul 15 16:31:49 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java	Mon Jul 15 16:35:38 2013 +0200
@@ -55,7 +55,9 @@
     }
 
     private static Object[] toObjectArray(final long[] array, final int length) {
-        final Object[] oarray = new Object[length];
+        assert length <= array.length : "length exceeds internal array size";
+        final Object[] oarray = new Object[array.length];
+
         for (int index = 0; index < length; index++) {
             oarray[index] = Long.valueOf(array[index]);
         }
@@ -71,9 +73,11 @@
         return super.asArrayOfType(componentType);
     }
 
-    private static double[] toDoubleArray(final long[] array) {
+    private static double[] toDoubleArray(final long[] array, final int length) {
+        assert length <= array.length : "length exceeds internal array size";
         final double[] darray = new double[array.length];
-        for (int index = 0; index < array.length; index++) {
+
+        for (int index = 0; index < length; index++) {
             darray[index] = array[index];
         }
 
@@ -84,10 +88,12 @@
     public ArrayData convert(final Class<?> type) {
         if (type == Long.class) {
             return this;
-        } else if (type == Double.class) {
-            return new NumberArrayData(LongArrayData.toDoubleArray(array), (int) length());
+        }
+        final int length = (int) length();
+        if (type == Double.class) {
+            return new NumberArrayData(LongArrayData.toDoubleArray(array, length), length);
         } else {
-            return new ObjectArrayData(LongArrayData.toObjectArray(array, array.length), (int) length());
+            return new ObjectArrayData(LongArrayData.toObjectArray(array, length), length);
         }
     }
 
@@ -138,19 +144,13 @@
 
     @Override
     public ArrayData set(final int index, final Object value, final boolean strict) {
-        try {
-            final long longValue = ((Long)value).longValue();
-            array[index] = longValue;
-            setLength(Math.max(index + 1, length()));
-            return this;
-        } catch (final NullPointerException | ClassCastException e) {
-            if (value == ScriptRuntime.UNDEFINED) {
-                return new UndefinedArrayFilter(this).set(index, value, strict);
-            }
+        if (value instanceof Long || value instanceof Integer) {
+            return set(index, ((Number)value).longValue(), strict);
+        } else if (value == ScriptRuntime.UNDEFINED) {
+            return new UndefinedArrayFilter(this).set(index, value, strict);
         }
 
         final ArrayData newData = convert(value == null ? Object.class : value.getClass());
-
         return newData.set(index, value, strict);
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java	Mon Jul 15 16:31:49 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java	Mon Jul 15 16:35:38 2013 +0200
@@ -58,7 +58,9 @@
     }
 
     private static Object[] toObjectArray(final double[] array, final int length) {
-        final Object[] oarray = new Object[length];
+        assert length <= array.length : "length exceeds internal array size";
+        final Object[] oarray = new Object[array.length];
+
         for (int index = 0; index < length; index++) {
             oarray[index] = Double.valueOf(array[index]);
         }
@@ -76,7 +78,8 @@
     @Override
     public ArrayData convert(final Class<?> type) {
         if (type != Double.class && type != Integer.class && type != Long.class) {
-            return new ObjectArrayData(NumberArrayData.toObjectArray(array, array.length), (int) length());
+            final int length = (int) length();
+            return new ObjectArrayData(NumberArrayData.toObjectArray(array, length), length);
         }
         return this;
     }
@@ -127,16 +130,12 @@
 
     @Override
     public ArrayData set(final int index, final Object value, final boolean strict) {
-        try {
-            final double doubleValue = ((Number)value).doubleValue();
-            array[index] = doubleValue;
-            setLength(Math.max(index + 1, length()));
-            return this;
-        } catch (final NullPointerException | ClassCastException e) {
-            if (value == UNDEFINED) {
-                return new UndefinedArrayFilter(this).set(index, value, strict);
-            }
+        if (value instanceof Double || value instanceof Integer || value instanceof Long) {
+            return set(index, ((Number)value).doubleValue(), strict);
+        } else if (value == UNDEFINED) {
+            return new UndefinedArrayFilter(this).set(index, value, strict);
         }
+
         final ArrayData newData = convert(value == null ? Object.class : value.getClass());
         return newData.set(index, value, strict);
     }