1 /*
  2  * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package jdk.internal.vm.vector;
 27 
 28 import jdk.internal.vm.annotation.IntrinsicCandidate;
 29 import jdk.internal.misc.Unsafe;
 30 
 31 import java.util.function.*;
 32 
 33 public class VectorSupport {
 34     static {
 35         registerNatives();
 36     }
 37 
 38     private static final Unsafe U = Unsafe.getUnsafe();
 39 
 40     // Unary
 41     public static final int VECTOR_OP_ABS  = 0;
 42     public static final int VECTOR_OP_NEG  = 1;
 43     public static final int VECTOR_OP_SQRT = 2;
 44     public static final int VECTOR_OP_BIT_COUNT = 3;
 45 
 46     // Binary
 47     public static final int VECTOR_OP_ADD  = 4;
 48     public static final int VECTOR_OP_SUB  = 5;
 49     public static final int VECTOR_OP_MUL  = 6;
 50     public static final int VECTOR_OP_DIV  = 7;
 51     public static final int VECTOR_OP_MIN  = 8;
 52     public static final int VECTOR_OP_MAX  = 9;
 53 
 54     public static final int VECTOR_OP_AND  = 10;
 55     public static final int VECTOR_OP_OR   = 11;
 56     public static final int VECTOR_OP_XOR  = 12;
 57 
 58     // Ternary
 59     public static final int VECTOR_OP_FMA  = 13;
 60 
 61     // Broadcast int
 62     public static final int VECTOR_OP_LSHIFT  = 14;
 63     public static final int VECTOR_OP_RSHIFT  = 15;
 64     public static final int VECTOR_OP_URSHIFT = 16;
 65 
 66     public static final int VECTOR_OP_CAST        = 17;
 67     public static final int VECTOR_OP_UCAST       = 18;
 68     public static final int VECTOR_OP_REINTERPRET = 19;
 69 
 70     // Mask manipulation operations
 71     public static final int VECTOR_OP_MASK_TRUECOUNT = 20;
 72     public static final int VECTOR_OP_MASK_FIRSTTRUE = 21;
 73     public static final int VECTOR_OP_MASK_LASTTRUE  = 22;
 74     public static final int VECTOR_OP_MASK_TOLONG    = 23;
 75 
 76     // Rotate operations
 77     public static final int VECTOR_OP_LROTATE = 24;
 78     public static final int VECTOR_OP_RROTATE = 25;
 79 
 80     // Compression expansion operations
 81     public static final int VECTOR_OP_COMPRESS = 26;
 82     public static final int VECTOR_OP_EXPAND = 27;
 83     public static final int VECTOR_OP_MASK_COMPRESS = 28;
 84 
 85     // Leading/Trailing zeros count operations
 86     public static final int VECTOR_OP_TZ_COUNT  = 29;
 87     public static final int VECTOR_OP_LZ_COUNT  = 30;
 88 
 89     // Reverse operation
 90     public static final int VECTOR_OP_REVERSE   = 31;
 91     public static final int VECTOR_OP_REVERSE_BYTES = 32;
 92 
 93     // Compress and Expand Bits operation
 94     public static final int VECTOR_OP_COMPRESS_BITS = 33;
 95     public static final int VECTOR_OP_EXPAND_BITS = 34;
 96 
 97     // Math routines
 98     public static final int VECTOR_OP_TAN = 101;
 99     public static final int VECTOR_OP_TANH = 102;
100     public static final int VECTOR_OP_SIN = 103;
101     public static final int VECTOR_OP_SINH = 104;
102     public static final int VECTOR_OP_COS = 105;
103     public static final int VECTOR_OP_COSH = 106;
104     public static final int VECTOR_OP_ASIN = 107;
105     public static final int VECTOR_OP_ACOS = 108;
106     public static final int VECTOR_OP_ATAN = 109;
107     public static final int VECTOR_OP_ATAN2 = 110;
108     public static final int VECTOR_OP_CBRT = 111;
109     public static final int VECTOR_OP_LOG = 112;
110     public static final int VECTOR_OP_LOG10 = 113;
111     public static final int VECTOR_OP_LOG1P = 114;
112     public static final int VECTOR_OP_POW = 115;
113     public static final int VECTOR_OP_EXP = 116;
114     public static final int VECTOR_OP_EXPM1 = 117;
115     public static final int VECTOR_OP_HYPOT = 118;
116 
117     // See src/hotspot/share/opto/subnode.hpp
118     //     struct BoolTest, and enclosed enum mask
119     public static final int BT_eq = 0;  // 0000
120     public static final int BT_ne = 4;  // 0100
121     public static final int BT_le = 5;  // 0101
122     public static final int BT_ge = 7;  // 0111
123     public static final int BT_lt = 3;  // 0011
124     public static final int BT_gt = 1;  // 0001
125     public static final int BT_overflow = 2;     // 0010
126     public static final int BT_no_overflow = 6;  // 0110
127     // never = 8    1000
128     // illegal = 9  1001
129     // Unsigned comparisons apply to BT_le, BT_ge, BT_lt, BT_gt for integral types
130     public static final int BT_unsigned_compare = 0b10000;
131     public static final int BT_ule = BT_le | BT_unsigned_compare;
132     public static final int BT_uge = BT_ge | BT_unsigned_compare;
133     public static final int BT_ult = BT_lt | BT_unsigned_compare;
134     public static final int BT_ugt = BT_gt | BT_unsigned_compare;
135 
136     // Various broadcasting modes.
137     public static final int MODE_BROADCAST = 0;
138     public static final int MODE_BITS_COERCED_LONG_TO_MASK = 1;
139 
140     // BasicType codes, for primitives only:
141     public static final int
142         T_FLOAT   = 6,
143         T_DOUBLE  = 7,
144         T_BYTE    = 8,
145         T_SHORT   = 9,
146         T_INT     = 10,
147         T_LONG    = 11;
148 
149     /* ============================================================================ */
150 
151     public static class VectorSpecies<E> {}
152 
153     public static class VectorPayload {
154         private final Object payload; // array of primitives
155 
156         public VectorPayload(Object payload) {
157             this.payload = payload;
158         }
159 
160         protected final Object getPayload() {
161             return VectorSupport.maybeRebox(this).payload;
162         }
163     }
164 
165     public static class Vector<E> extends VectorPayload {
166         public Vector(Object payload) {
167             super(payload);
168         }
169     }
170 
171     public static class VectorShuffle<E> extends VectorPayload {
172         public VectorShuffle(Object payload) {
173             super(payload);
174         }
175     }
176     public static class VectorMask<E> extends VectorPayload {
177         public VectorMask(Object payload) {
178             super(payload);
179         }
180     }
181 
182     /* ============================================================================ */
183     public interface FromBitsCoercedOperation<VM extends VectorPayload,
184                                               S extends VectorSpecies<?>> {
185         VM fromBits(long l, S s);
186     }
187 
188     @IntrinsicCandidate
189     public static
190     <VM extends VectorPayload,
191      S extends VectorSpecies<E>,
192      E>
193     VM fromBitsCoerced(Class<? extends VM> vmClass, Class<E> eClass,
194                        int length,
195                        long bits, int mode, S s,
196                        FromBitsCoercedOperation<VM, S> defaultImpl) {
197         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
198         return defaultImpl.fromBits(bits, s);
199     }
200 
201     /* ============================================================================ */
202     public interface ShuffleIotaOperation<S extends VectorSpecies<?>,
203                                           SH extends VectorShuffle<?>> {
204         SH apply(int length, int start, int step, S s);
205     }
206 
207     @IntrinsicCandidate
208     public static
209     <E,
210      S extends VectorSpecies<E>,
211      SH extends VectorShuffle<E>>
212     SH shuffleIota(Class<E> eClass, Class<? extends SH> shClass, S s,
213                    int length,
214                    int start, int step, int wrap,
215                    ShuffleIotaOperation<S, SH> defaultImpl) {
216        assert isNonCapturingLambda(defaultImpl) : defaultImpl;
217        return defaultImpl.apply(length, start, step, s);
218     }
219 
220     public interface ShuffleToVectorOperation<V extends Vector<?>,
221                                               SH extends VectorShuffle<?>> {
222        V apply(SH sh);
223     }
224 
225     @IntrinsicCandidate
226     public static
227     <V extends Vector<E>,
228      SH extends VectorShuffle<E>,
229      E>
230     V shuffleToVector(Class<? extends Vector<E>> vClass, Class<E> eClass, Class<? extends SH> shClass, SH sh,
231                       int length,
232                       ShuffleToVectorOperation<V, SH> defaultImpl) {
233       assert isNonCapturingLambda(defaultImpl) : defaultImpl;
234       return defaultImpl.apply(sh);
235     }
236 
237     /* ============================================================================ */
238     public interface IndexOperation<V extends Vector<?>,
239                                     S extends VectorSpecies<?>> {
240         V index(V v, int step, S s);
241     }
242 
243     //FIXME @IntrinsicCandidate
244     public static
245     <V extends Vector<E>,
246      E,
247      S extends VectorSpecies<E>>
248     V indexVector(Class<? extends V> vClass, Class<E> eClass,
249                   int length,
250                   V v, int step, S s,
251                   IndexOperation<V, S> defaultImpl) {
252         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
253         return defaultImpl.index(v, step, s);
254     }
255 
256     /* ============================================================================ */
257 
258     public interface ReductionOperation<V extends Vector<?>,
259                                         M extends VectorMask<?>> {
260         long apply(V v, M m);
261     }
262 
263     @IntrinsicCandidate
264     public static
265     <V extends Vector<E>,
266      M extends VectorMask<E>,
267      E>
268     long reductionCoerced(int oprId,
269                           Class<? extends V> vClass, Class<? extends M> mClass, Class<E> eClass,
270                           int length,
271                           V v, M m,
272                           ReductionOperation<V, M> defaultImpl) {
273         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
274         return defaultImpl.apply(v, m);
275     }
276 
277 
278     /* ============================================================================ */
279 
280     public interface VecExtractOp<V extends Vector<?>> {
281         long apply(V v, int i);
282     }
283 
284     @IntrinsicCandidate
285     public static
286     <V extends Vector<E>,
287      E>
288     long extract(Class<? extends V> vClass, Class<E> eClass,
289                  int length,
290                  V v, int i,
291                  VecExtractOp<V> defaultImpl) {
292         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
293         return defaultImpl.apply(v, i);
294     }
295 
296     /* ============================================================================ */
297 
298     public interface VecInsertOp<V extends Vector<?>> {
299         V apply(V v, int i, long val);
300     }
301 
302     @IntrinsicCandidate
303     public static
304     <V extends Vector<E>,
305      E>
306     V insert(Class<? extends V> vClass, Class<E> eClass,
307              int length,
308              V v, int i, long val,
309              VecInsertOp<V> defaultImpl) {
310         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
311         return defaultImpl.apply(v, i, val);
312     }
313 
314     /* ============================================================================ */
315 
316     public interface UnaryOperation<V extends Vector<?>,
317                                     M extends VectorMask<?>> {
318         V apply(V v, M m);
319     }
320 
321     @IntrinsicCandidate
322     public static
323     <V extends Vector<E>,
324      M extends VectorMask<E>,
325      E>
326     V unaryOp(int oprId,
327               Class<? extends V> vClass, Class<? extends M> mClass, Class<E> eClass,
328               int length,
329               V v, M m,
330               UnaryOperation<V, M> defaultImpl) {
331         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
332         return defaultImpl.apply(v, m);
333     }
334 
335     /* ============================================================================ */
336 
337     public interface BinaryOperation<VM extends VectorPayload,
338                                      M extends VectorMask<?>> {
339         VM apply(VM v1, VM v2, M m);
340     }
341 
342     @IntrinsicCandidate
343     public static
344     <VM extends VectorPayload,
345      M extends VectorMask<E>,
346      E>
347     VM binaryOp(int oprId,
348                 Class<? extends VM> vmClass, Class<? extends M> mClass, Class<E> eClass,
349                 int length,
350                 VM v1, VM v2, M m,
351                 BinaryOperation<VM, M> defaultImpl) {
352         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
353         return defaultImpl.apply(v1, v2, m);
354     }
355 
356     /* ============================================================================ */
357 
358     public interface TernaryOperation<V extends Vector<?>,
359                                       M extends VectorMask<?>> {
360         V apply(V v1, V v2, V v3, M m);
361     }
362 
363     @IntrinsicCandidate
364     public static
365     <V extends Vector<E>,
366      M extends VectorMask<E>,
367      E>
368     V ternaryOp(int oprId,
369                 Class<? extends V> vClass, Class<? extends M> mClass, Class<E> eClass,
370                 int length,
371                 V v1, V v2, V v3, M m,
372                 TernaryOperation<V, M> defaultImpl) {
373         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
374         return defaultImpl.apply(v1, v2, v3, m);
375     }
376 
377     /* ============================================================================ */
378 
379     // Memory operations
380 
381     public interface LoadOperation<C,
382                                    VM extends VectorPayload,
383                                    S extends VectorSpecies<?>> {
384         VM load(C container, long index, S s);
385     }
386 
387     @IntrinsicCandidate
388     public static
389     <C,
390      VM extends VectorPayload,
391      E,
392      S extends VectorSpecies<E>>
393     VM load(Class<? extends VM> vmClass, Class<E> eClass,
394             int length,
395             Object base, long offset,
396             C container, long index, S s,
397             LoadOperation<C, VM, S> defaultImpl) {
398         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
399         return defaultImpl.load(container, index, s);
400     }
401 
402     /* ============================================================================ */
403 
404     public interface LoadVectorMaskedOperation<C,
405                                                V extends Vector<?>,
406                                                S extends VectorSpecies<?>,
407                                                M extends VectorMask<?>> {
408         V load(C container, long index, S s, M m);
409     }
410 
411     @IntrinsicCandidate
412     public static
413     <C,
414      V extends Vector<?>,
415      E,
416      S extends VectorSpecies<E>,
417      M extends VectorMask<E>>
418     V loadMasked(Class<? extends V> vClass, Class<M> mClass, Class<E> eClass,
419                  int length,
420                  Object base, long offset,
421                  M m, C container, long index, S s,
422                  LoadVectorMaskedOperation<C, V, S, M> defaultImpl) {
423         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
424         return defaultImpl.load(container, index, s, m);
425     }
426 
427     /* ============================================================================ */
428 
429     public interface LoadVectorOperationWithMap<C,
430                                                 V extends Vector<?>,
431                                                 S extends VectorSpecies<?>,
432                                                 M extends VectorMask<?>> {
433         V loadWithMap(C container, int index, int[] indexMap, int indexM, S s, M m);
434     }
435 
436     @IntrinsicCandidate
437     public static
438     <C,
439      V extends Vector<?>,
440      W extends Vector<Integer>,
441      S extends VectorSpecies<E>,
442      M extends VectorMask<E>,
443      E>
444     V loadWithMap(Class<? extends V> vClass, Class<M> mClass, Class<E> eClass,
445                   int length,
446                   Class<? extends Vector<Integer>> vectorIndexClass,
447                   Object base, long offset,
448                   W index_vector,
449                   M m, C container, int index, int[] indexMap, int indexM, S s,
450                   LoadVectorOperationWithMap<C, V, S, M> defaultImpl) {
451         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
452         return defaultImpl.loadWithMap(container, index, indexMap, indexM, s, m);
453     }
454 
455     /* ============================================================================ */
456 
457     public interface StoreVectorOperation<C,
458                                           V extends VectorPayload> {
459         void store(C container, long index, V v);
460     }
461 
462     @IntrinsicCandidate
463     public static
464     <C,
465      V extends VectorPayload>
466     void store(Class<?> vClass, Class<?> eClass,
467                int length,
468                Object base, long offset,
469                V v, C container, long index,
470                StoreVectorOperation<C, V> defaultImpl) {
471         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
472         defaultImpl.store(container, index, v);
473     }
474 
475     public interface StoreVectorMaskedOperation<C,
476                                                 V extends Vector<?>,
477                                                 M extends VectorMask<?>> {
478         void store(C container, long index, V v, M m);
479     }
480 
481     @IntrinsicCandidate
482     public static
483     <C,
484      V extends Vector<E>,
485      M extends VectorMask<E>,
486      E>
487     void storeMasked(Class<? extends V> vClass, Class<M> mClass, Class<E> eClass,
488                      int length,
489                      Object base, long offset,
490                      V v, M m, C container, long index,
491                      StoreVectorMaskedOperation<C, V, M> defaultImpl) {
492         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
493         defaultImpl.store(container, index, v, m);
494     }
495 
496     /* ============================================================================ */
497 
498     public interface StoreVectorOperationWithMap<C,
499                                                  V extends Vector<?>,
500                                                  M extends VectorMask<?>> {
501         void storeWithMap(C container, int index, V v, int[] indexMap, int indexM, M m);
502     }
503 
504     @IntrinsicCandidate
505     public static
506     <C,
507      V extends Vector<E>,
508      W extends Vector<Integer>,
509      M extends VectorMask<E>,
510      E>
511     void storeWithMap(Class<? extends V> vClass, Class<M> mClass, Class<E> eClass,
512                       int length,
513                       Class<? extends Vector<Integer>> vectorIndexClass,
514                       Object base, long offset,
515                       W index_vector,
516                       V v, M m, C container, int index, int[] indexMap, int indexM,
517                       StoreVectorOperationWithMap<C, V, M> defaultImpl) {
518         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
519         defaultImpl.storeWithMap(container, index, v, indexMap, indexM, m);
520     }
521 
522     /* ============================================================================ */
523 
524     @IntrinsicCandidate
525     public static
526     <M extends VectorMask<E>,
527      E>
528     boolean test(int cond,
529                  Class<?> mClass, Class<?> eClass,
530                  int length,
531                  M m1, M m2,
532                  BiFunction<M, M, Boolean> defaultImpl) {
533         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
534         return defaultImpl.apply(m1, m2);
535     }
536 
537     /* ============================================================================ */
538 
539     public interface VectorCompareOp<V extends Vector<?>,
540                                      M extends VectorMask<?>> {
541         M apply(int cond, V v1, V v2, M m);
542     }
543 
544     @IntrinsicCandidate
545     public static
546     <V extends Vector<E>,
547      M extends VectorMask<E>,
548      E>
549     M compare(int cond,
550               Class<? extends V> vectorClass, Class<M> mClass, Class<E> eClass,
551               int length,
552               V v1, V v2, M m,
553               VectorCompareOp<V, M> defaultImpl) {
554         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
555         return defaultImpl.apply(cond, v1, v2, m);
556     }
557 
558     /* ============================================================================ */
559     public interface VectorRearrangeOp<V extends Vector<?>,
560                                        SH extends VectorShuffle<?>,
561                                        M extends VectorMask<?>> {
562         V apply(V v, SH sh, M m);
563     }
564 
565     @IntrinsicCandidate
566     public static
567     <V extends Vector<E>,
568      SH extends VectorShuffle<E>,
569      M  extends VectorMask<E>,
570      E>
571     V rearrangeOp(Class<? extends V> vClass, Class<SH> shClass, Class<M> mClass, Class<E> eClass,
572                   int length,
573                   V v, SH sh, M m,
574                   VectorRearrangeOp<V, SH, M> defaultImpl) {
575         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
576         return defaultImpl.apply(v, sh, m);
577     }
578 
579     /* ============================================================================ */
580 
581     public interface VectorBlendOp<V extends Vector<?>,
582                                    M extends VectorMask<?>> {
583         V apply(V v1, V v2, M m);
584     }
585 
586     @IntrinsicCandidate
587     public static
588     <V extends Vector<E>,
589      M extends VectorMask<E>,
590      E>
591     V blend(Class<? extends V> vClass, Class<M> mClass, Class<E> eClass,
592             int length,
593             V v1, V v2, M m,
594             VectorBlendOp<V, M> defaultImpl) {
595         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
596         return defaultImpl.apply(v1, v2, m);
597     }
598 
599     /* ============================================================================ */
600 
601     public interface VectorBroadcastIntOp<V extends Vector<?>,
602                                           M extends VectorMask<?>> {
603         V apply(V v, int n, M m);
604     }
605 
606     @IntrinsicCandidate
607     public static
608     <V extends Vector<E>,
609      M extends VectorMask<E>,
610      E>
611     V broadcastInt(int opr,
612                    Class<? extends V> vClass, Class<? extends M> mClass, Class<E> eClass,
613                    int length,
614                    V v, int n, M m,
615                    VectorBroadcastIntOp<V, M> defaultImpl) {
616         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
617         return defaultImpl.apply(v, n, m);
618     }
619 
620     /* ============================================================================ */
621 
622     public interface VectorConvertOp<VOUT extends VectorPayload,
623                                      VIN extends VectorPayload,
624                                      S extends VectorSpecies<?>> {
625         VOUT apply(VIN v, S s);
626     }
627 
628     // Users of this intrinsic assume that it respects
629     // REGISTER_ENDIAN, which is currently ByteOrder.LITTLE_ENDIAN.
630     // See javadoc for REGISTER_ENDIAN.
631 
632     @IntrinsicCandidate
633     public static <VOUT extends VectorPayload,
634                     VIN extends VectorPayload,
635                       S extends VectorSpecies<?>>
636     VOUT convert(int oprId,
637               Class<?> fromVectorClass, Class<?> fromeClass, int fromVLen,
638               Class<?>   toVectorClass, Class<?>   toeClass, int   toVLen,
639               VIN v, S s,
640               VectorConvertOp<VOUT, VIN, S> defaultImpl) {
641         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
642         return defaultImpl.apply(v, s);
643     }
644 
645     /* ============================================================================ */
646 
647     public interface ComExpOperation<V extends Vector<?>,
648                                      M extends VectorMask<?>> {
649         VectorPayload apply(V v, M m);
650     }
651 
652     @IntrinsicCandidate
653     public static
654     <V extends Vector<E>,
655      M extends VectorMask<E>,
656      E>
657     VectorPayload comExpOp(int opr,
658                            Class<? extends V> vClass, Class<? extends M> mClass, Class<E> eClass,
659                            int length, V v, M m,
660                            ComExpOperation<V, M> defaultImpl) {
661         assert isNonCapturingLambda(defaultImpl) : defaultImpl;
662         return defaultImpl.apply(v, m);
663     }
664 
665     /* ============================================================================ */
666 
667     @IntrinsicCandidate
668     public static
669     <VP extends VectorPayload>
670     VP maybeRebox(VP v) {
671         // The fence is added here to avoid memory aliasing problems in C2 between scalar & vector accesses.
672         // TODO: move the fence generation into C2. Generate only when reboxing is taking place.
673         U.loadFence();
674         return v;
675     }
676 
677     /* ============================================================================ */
678     public interface VectorMaskOp<M extends VectorMask<?>> {
679         long apply(M m);
680     }
681 
682     @IntrinsicCandidate
683     public static
684     <M extends VectorMask<E>,
685      E>
686     long maskReductionCoerced(int oper,
687                               Class<? extends M> mClass, Class<?> eClass,
688                               int length,
689                               M m,
690                               VectorMaskOp<M> defaultImpl) {
691        assert isNonCapturingLambda(defaultImpl) : defaultImpl;
692        return defaultImpl.apply(m);
693     }
694 
695     /* ============================================================================ */
696 
697     // query the JVM's supported vector sizes and types
698     public static native int getMaxLaneCount(Class<?> etype);
699 
700     /* ============================================================================ */
701 
702     public static boolean isNonCapturingLambda(Object o) {
703         return o.getClass().getDeclaredFields().length == 0;
704     }
705 
706     /* ============================================================================ */
707 
708     private static native int registerNatives();
709 }