< prev index next >

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java

Print this page
rev 55589 : 8221816: [vector] IndexOutOfBoundsException for fromArray/intoArray with unset mask lanes
Reviewed-by: duke

@@ -194,21 +194,25 @@
      * @return the vector loaded from an array
      * @throws IndexOutOfBoundsException if {@code i < 0}, or
      * {@code i > a.length - this.length()}
      */
     @ForceInline
-    @SuppressWarnings("unchecked")
-    public static FloatVector fromArray(FloatSpecies species, float[] a, int i){
+    public static FloatVector fromArray(FloatSpecies species, float[] a, int i) {
         Objects.requireNonNull(a);
         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
+        return fromArrayWithoutCheck(species, a, i);
+    }
+
+    @ForceInline
+    @SuppressWarnings("unchecked")
+    static FloatVector fromArrayWithoutCheck(FloatSpecies species, float[] a, int i) {
         return VectorIntrinsics.load((Class<FloatVector>) species.boxType(), float.class, species.length(),
                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_FLOAT_BASE_OFFSET,
                                      a, i, species,
                                      (c, idx, s) -> ((FloatSpecies)s).op(n -> c[idx + n]));
     }
 
-
     /**
      * Loads a vector from an array starting at offset and using a mask.
      * <p>
      * For each vector lane, where {@code N} is the vector lane index,
      * if the mask lane at index {@code N} is set then the array element at

@@ -225,11 +229,16 @@
      * for any vector lane index {@code N} where the mask at lane {@code N}
      * is set {@code i > a.length - N}
      */
     @ForceInline
     public static FloatVector fromArray(FloatSpecies species, float[] a, int i, Mask<Float> m) {
-        return zero(species).blend(fromArray(species, a, i), m);
+        Objects.requireNonNull(a);
+        if (i + species.length() <= a.length) {
+            return zero(species).blend(fromArrayWithoutCheck(species, a, i), m);
+        } else {
+            return species.op(m, n -> a[i + n]);
+        }
     }
 
     /**
      * Loads a vector from an array using indexes obtained from an index
      * map.

@@ -250,21 +259,25 @@
      * {@code j > indexMap.length - this.length()},
      * or for any vector lane index {@code N} the result of
      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
      */
     @ForceInline
-    @SuppressWarnings("unchecked")
     public static FloatVector fromArray(FloatSpecies species, float[] a, int i, int[] indexMap, int j) {
         Objects.requireNonNull(a);
         Objects.requireNonNull(indexMap);
 
-
         // Index vector: vix[0:n] = k -> i + indexMap[j + i]
         IntVector vix = IntVector.fromArray(species.indexSpecies(), indexMap, j).add(i);
 
         vix = VectorIntrinsics.checkIndex(vix, a.length);
 
+        return fromArrayWithoutCheck(species, a, i, indexMap, j, vix);
+    }
+
+    @ForceInline
+    @SuppressWarnings("unchecked")
+    static FloatVector fromArrayWithoutCheck(FloatSpecies species, float[] a, int i, int[] indexMap, int j, IntVector vix) {
         return VectorIntrinsics.loadWithMap((Class<FloatVector>) species.boxType(), float.class, species.length(),
                                             species.indexSpecies().vectorType(), a, Unsafe.ARRAY_FLOAT_BASE_OFFSET, vix,
                                             a, i, indexMap, j, species,
                                            (c, idx, iMap, idy, s) -> ((FloatSpecies)s).op(n -> c[idx + iMap[idy+n]]));
         }

@@ -292,14 +305,22 @@
      * or for any vector lane index {@code N} where the mask at lane
      * {@code N} is set the result of {@code i + indexMap[j + N]} is
      * {@code < 0} or {@code >= a.length}
      */
     @ForceInline
-    @SuppressWarnings("unchecked")
     public static FloatVector fromArray(FloatSpecies species, float[] a, int i, Mask<Float> m, int[] indexMap, int j) {
-        // @@@ This can result in out of bounds errors for unset mask lanes
-        return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
+        Objects.requireNonNull(a);
+        Objects.requireNonNull(indexMap);
+
+        // Index vector: vix[0:n] = k -> i + indexMap[j + i]
+        IntVector vix = IntVector.fromArray(species.indexSpecies(), indexMap, j).add(i);
+
+        if (vix.lessThan(0).anyTrue() || vix.greaterThanEq(a.length).anyTrue()) {
+            return species.op(m, n -> a[i + indexMap[j+n]]);
+        } else {
+            return zero(species).blend(fromArrayWithoutCheck(species, a, i, indexMap, j, vix), m);
+        }
     }
 
 
     /**
      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
< prev index next >