< 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 >