1 /*
2 * Copyright (c) 2014, 2018, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Formatter;
33 import java.util.List;
34 import java.util.ServiceLoader;
35 import java.util.Set;
36 import java.util.TreeSet;
37 import java.util.stream.Collectors;
38
39 import jdk.internal.vm.compiler.collections.EconomicMap;
40 import jdk.internal.vm.compiler.collections.MapCursor;
41 import org.graalvm.compiler.api.test.Graal;
42 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
43 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
44 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
45 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
46 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
47 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
48 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding;
49 import org.graalvm.compiler.runtime.RuntimeProvider;
50 import org.graalvm.compiler.serviceprovider.GraalServices;
51 import org.graalvm.compiler.test.GraalTest;
52 import org.junit.Test;
53
54 import jdk.vm.ci.aarch64.AArch64;
55 import jdk.vm.ci.amd64.AMD64;
56 import jdk.vm.ci.code.Architecture;
57 import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
58 import jdk.vm.ci.hotspot.VMIntrinsicMethod;
59 import jdk.vm.ci.meta.MetaAccessProvider;
60 import jdk.vm.ci.meta.MetaUtil;
61 import jdk.vm.ci.meta.MethodHandleAccessProvider.IntrinsicMethod;
62 import jdk.vm.ci.meta.ResolvedJavaMethod;
63
64 /**
65 * Checks the intrinsics implemented by Graal against the set of intrinsics declared by HotSpot. The
66 * purpose of this test is to detect when new intrinsics are added to HotSpot and process them
67 * appropriately in Graal. This will be achieved by working through {@link #toBeInvestigated} and
68 * either implementing the intrinsic or moving it to {@link #ignore} .
69 */
70 public class CheckGraalIntrinsics extends GraalTest {
240 "java/lang/Long.numberOfTrailingZeros(J)I");
241
242 // Relevant for Java flight recorder
243 add(toBeInvestigated,
244 "oracle/jrockit/jfr/Timing.counterTime()J",
245 "oracle/jrockit/jfr/VMJFR.classID0(Ljava/lang/Class;)J",
246 "oracle/jrockit/jfr/VMJFR.threadID()I");
247
248 add(toBeInvestigated,
249 // Similar to addExact
250 "java/lang/Math.negateExact(I)I",
251 // Similar to addExact
252 "java/lang/Math.negateExact(J)J",
253 // HotSpot MacroAssembler-based intrinsic
254 "java/lang/String.indexOf(Ljava/lang/String;)I",
255 // Can share most implementation parts with with
256 // Unsafe.allocateUninitializedArray0
257 "java/lang/reflect/Array.newArray(Ljava/lang/Class;I)Ljava/lang/Object;",
258 // HotSpot MacroAssembler-based intrinsic
259 "sun/nio/cs/ISO_8859_1$Encoder.encodeISOArray([CI[BII)I",
260 // Stub based intrinsics but implementation seems complex in C2
261 "sun/security/provider/DigestBase.implCompressMultiBlock([BII)I");
262
263 // See JDK-8207146.
264 String oopName = isJDK12OrHigher() ? "Reference" : "Object";
265
266 if (isJDK9OrHigher()) {
267 // Relevant for Java flight recorder
268 add(toBeInvestigated,
269 "jdk/jfr/internal/JVM.counterTime()J",
270 "jdk/jfr/internal/JVM.getBufferWriter()Ljava/lang/Object;",
271 "jdk/jfr/internal/JVM.getClassId(Ljava/lang/Class;)J");
272
273 add(toBeInvestigated,
274 // Some logic and a stub call
275 "com/sun/crypto/provider/CounterMode.implCrypt([BII[BI)I",
276 // Stub and very little logic
277 "com/sun/crypto/provider/GHASH.processBlocks([BII[J[J)V",
278 // HotSpot MacroAssembler-based intrinsic
279 "java/lang/Math.fma(DDD)D",
280 // HotSpot MacroAssembler-based intrinsic
281 "java/lang/Math.fma(FFF)F",
282 // Just check if the argument is a compile time constant
283 "java/lang/invoke/MethodHandleImpl.isCompileConstant(Ljava/lang/Object;)Z",
284 // Some logic and a runtime call
285 "java/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I",
286 // Only used as a marker for vectorization?
287 "java/util/stream/Streams$RangeIntSpliterator.forEachRemaining(Ljava/util/function/IntConsumer;)V",
288 // Only implemented on non-AMD64 platforms (some logic and runtime call)
289 "java/util/zip/Adler32.updateByteBuffer(IJII)I",
290 // Only implemented on non-AMD64 platforms (some logic and runtime call)
291 "java/util/zip/Adler32.updateBytes(I[BII)I",
292 // Emits a slow and a fast path and some dispatching logic
293 "jdk/internal/misc/Unsafe.allocateUninitializedArray0(Ljava/lang/Class;I)Ljava/lang/Object;",
294
295 // Control flow, deopts, and a cast
296 "jdk/internal/util/Preconditions.checkIndex(IILjava/util/function/BiFunction;)I",
297 // HotSpot MacroAssembler-based intrinsic
298 "sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray([CI[BII)I",
299 // Runtime call and some complex compiler logic
300 "sun/security/provider/DigestBase.implCompressMultiBlock0([BII)I");
301
302 /*
303 * Per default, all these operations are mapped to some generic method for which we
304 * already have compiler intrinsics. Performance-wise it would be better to support them
305 * explicitly as the more generic method might be more restrictive and therefore slower
306 * than necessary.
307 */
308
309 add(toBeInvestigated,
310 // Mapped to compareAndExchange*
311 "jdk/internal/misc/Unsafe.compareAndExchangeByteAcquire(Ljava/lang/Object;JBB)B",
312 "jdk/internal/misc/Unsafe.compareAndExchangeByteRelease(Ljava/lang/Object;JBB)B",
313 "jdk/internal/misc/Unsafe.compareAndExchangeIntAcquire(Ljava/lang/Object;JII)I",
314 "jdk/internal/misc/Unsafe.compareAndExchangeIntRelease(Ljava/lang/Object;JII)I",
315 "jdk/internal/misc/Unsafe.compareAndExchangeLongAcquire(Ljava/lang/Object;JJJ)J",
316 "jdk/internal/misc/Unsafe.compareAndExchangeLongRelease(Ljava/lang/Object;JJJ)J",
317 "jdk/internal/misc/Unsafe.compareAndExchange" + oopName + "Acquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
318 "jdk/internal/misc/Unsafe.compareAndExchange" + oopName + "Release(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
319 "jdk/internal/misc/Unsafe.compareAndExchangeShortAcquire(Ljava/lang/Object;JSS)S",
320 "jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S",
327 "jdk/internal/misc/Unsafe.weakCompareAndSetInt(Ljava/lang/Object;JII)Z",
328 "jdk/internal/misc/Unsafe.weakCompareAndSetIntAcquire(Ljava/lang/Object;JII)Z",
329 "jdk/internal/misc/Unsafe.weakCompareAndSetIntPlain(Ljava/lang/Object;JII)Z",
330 "jdk/internal/misc/Unsafe.weakCompareAndSetIntRelease(Ljava/lang/Object;JII)Z",
331 "jdk/internal/misc/Unsafe.weakCompareAndSetLong(Ljava/lang/Object;JJJ)Z",
332 "jdk/internal/misc/Unsafe.weakCompareAndSetLongAcquire(Ljava/lang/Object;JJJ)Z",
333 "jdk/internal/misc/Unsafe.weakCompareAndSetLongPlain(Ljava/lang/Object;JJJ)Z",
334 "jdk/internal/misc/Unsafe.weakCompareAndSetLongRelease(Ljava/lang/Object;JJJ)Z",
335 "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
336 "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "Acquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
337 "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "Plain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
338 "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "Release(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
339 "jdk/internal/misc/Unsafe.weakCompareAndSetShort(Ljava/lang/Object;JSS)Z",
340 "jdk/internal/misc/Unsafe.weakCompareAndSetShortAcquire(Ljava/lang/Object;JSS)Z",
341 "jdk/internal/misc/Unsafe.weakCompareAndSetShortPlain(Ljava/lang/Object;JSS)Z",
342 "jdk/internal/misc/Unsafe.weakCompareAndSetShortRelease(Ljava/lang/Object;JSS)Z");
343
344 // Compact string support - HotSpot MacroAssembler-based intrinsic or complex C2 logic.
345 add(toBeInvestigated,
346 "java/lang/StringCoding.hasNegatives([BII)Z",
347 "java/lang/StringCoding.implEncodeISOArray([BI[BII)I",
348 "java/lang/StringLatin1.indexOf([B[B)I",
349 "java/lang/StringUTF16.getChar([BI)C",
350 "java/lang/StringUTF16.getChars([BII[CI)V",
351 "java/lang/StringUTF16.indexOf([BI[BII)I",
352 "java/lang/StringUTF16.indexOf([B[B)I",
353 "java/lang/StringUTF16.indexOfChar([BIII)I",
354 "java/lang/StringUTF16.indexOfLatin1([BI[BII)I",
355 "java/lang/StringUTF16.indexOfLatin1([B[B)I",
356 "java/lang/StringUTF16.putChar([BII)V",
357 "java/lang/StringUTF16.toBytes([CII)[B");
358 // These are handled through an intrinsic for String.equals itself
359 add(ignore,
360 "java/lang/StringLatin1.equals([B[B)Z",
361 "java/lang/StringUTF16.equals([B[B)Z");
362 }
363
364 if (isJDK10OrHigher()) {
365 add(toBeInvestigated,
366 "java/lang/Math.multiplyHigh(JJ)J",
367 "jdk/internal/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I");
368 }
369
370 if (isJDK11OrHigher()) {
371 // Relevant for Java flight recorder
372 add(toBeInvestigated,
373 "java/util/Base64$Encoder.encodeBlock([BII[BIZ)V",
374 "jdk/jfr/internal/JVM.getEventWriter()Ljava/lang/Object;");
375 }
376
377 if (isJDK12OrHigher()) {
378 add(toBeInvestigated,
379 "java/lang/CharacterDataLatin1.isDigit(I)Z",
380 "java/lang/CharacterDataLatin1.isLowerCase(I)Z",
381 "java/lang/CharacterDataLatin1.isUpperCase(I)Z",
382 "java/lang/CharacterDataLatin1.isWhitespace(I)Z");
383 }
384
385 if (isJDK13OrHigher()) {
386 add(toBeInvestigated,
387 "java/lang/Math.max(DD)D",
388 "java/lang/Math.max(FF)F",
389 "java/lang/Math.min(DD)D",
390 "java/lang/Math.min(FF)F");
391 }
392
393 if (!config.inlineNotify()) {
394 add(ignore, "java/lang/Object.notify()V");
395 }
396 if (!config.inlineNotifyAll()) {
397 add(ignore, "java/lang/Object.notifyAll()V");
398 }
399
400 if (!(arch instanceof AMD64)) {
401 // Can we implement these on non-AMD64 platforms? C2 seems to.
402 add(toBeInvestigated,
403 "java/lang/String.compareTo(Ljava/lang/String;)I",
404 "java/lang/StringLatin1.inflate([BI[BII)V",
405 "java/lang/StringLatin1.inflate([BI[CII)V",
406 "java/lang/StringUTF16.compress([BI[BII)I",
407 "java/lang/StringUTF16.compress([CI[BII)I",
408 "jdk/internal/misc/Unsafe.compareAndExchangeByte(Ljava/lang/Object;JBB)B",
409 "jdk/internal/misc/Unsafe.compareAndExchangeShort(Ljava/lang/Object;JSS)S",
410 "jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z",
411 "jdk/internal/misc/Unsafe.compareAndSetShort(Ljava/lang/Object;JSS)Z",
412 "jdk/internal/misc/Unsafe.getAndAddByte(Ljava/lang/Object;JB)B",
413 "jdk/internal/misc/Unsafe.getAndAddShort(Ljava/lang/Object;JS)S",
414 "jdk/internal/misc/Unsafe.getAndSetByte(Ljava/lang/Object;JB)B",
415 "jdk/internal/misc/Unsafe.getAndSetShort(Ljava/lang/Object;JS)S",
416 "sun/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
417 "sun/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
418 "sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
419 "sun/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
420 "sun/misc/Unsafe.getAndSet" + oopName + "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;");
421
422 if (isJDK9OrHigher()) {
423 if (!(arch instanceof AArch64)) {
424 add(toBeInvestigated,
425 "java/lang/StringLatin1.compareTo([B[B)I",
426 "java/lang/StringLatin1.compareToUTF16([B[B)I",
427 "java/lang/StringUTF16.compareTo([B[B)I",
428 "java/lang/StringUTF16.compareToLatin1([B[B)I",
429 "jdk/internal/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
430 "jdk/internal/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
431 "jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
432 "jdk/internal/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
433 "jdk/internal/misc/Unsafe.getAndSet" + oopName + "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;");
434 }
435 add(toBeInvestigated,
436 "java/lang/Thread.onSpinWait()V",
437 "jdk/internal/misc/Unsafe.getCharUnaligned(Ljava/lang/Object;J)C",
438 "jdk/internal/misc/Unsafe.getIntUnaligned(Ljava/lang/Object;J)I",
439 "jdk/internal/misc/Unsafe.getLongUnaligned(Ljava/lang/Object;J)J",
440 "jdk/internal/misc/Unsafe.getShortUnaligned(Ljava/lang/Object;J)S",
441 "jdk/internal/misc/Unsafe.putCharUnaligned(Ljava/lang/Object;JC)V",
442 "jdk/internal/misc/Unsafe.putIntUnaligned(Ljava/lang/Object;JI)V",
443 "jdk/internal/misc/Unsafe.putLongUnaligned(Ljava/lang/Object;JJ)V",
444 "jdk/internal/misc/Unsafe.putShortUnaligned(Ljava/lang/Object;JS)V");
445 }
446 }
447
448 /*
449 * The intrinsics down here are known to be implemented but they are not always enabled on
450 * the HotSpot side (e.g., because they require certain CPU features). So, we are ignoring
451 * them if the HotSpot config tells us that they can't be used.
452 */
453
454 // CRC32 intrinsics
455 if (!config.useCRC32Intrinsics) {
456 add(ignore, "java/util/zip/CRC32.update(II)I");
457 if (isJDK9OrHigher()) {
458 add(ignore,
459 "java/util/zip/CRC32.updateByteBuffer0(IJII)I",
460 "java/util/zip/CRC32.updateBytes0(I[BII)I");
461 } else {
462 add(ignore,
463 "java/util/zip/CRC32.updateByteBuffer(IJII)I",
464 "java/util/zip/CRC32.updateBytes(I[BII)I");
465 }
518 add(ignore, "sun/security/provider/SHA.implCompress([BI)V");
519 }
520 }
521 if (!config.useSHA256Intrinsics()) {
522 if (isJDK9OrHigher()) {
523 add(ignore, "sun/security/provider/SHA2.implCompress0([BI)V");
524 } else {
525 add(ignore, "sun/security/provider/SHA2.implCompress([BI)V");
526 }
527 }
528 if (!config.useSHA512Intrinsics()) {
529 if (isJDK9OrHigher()) {
530 add(ignore, "sun/security/provider/SHA5.implCompress0([BI)V");
531 } else {
532 add(ignore, "sun/security/provider/SHA5.implCompress([BI)V");
533 }
534 }
535 }
536
537 private static boolean isJDK9OrHigher() {
538 return GraalServices.JAVA_SPECIFICATION_VERSION >= 9;
539 }
540
541 private static boolean isJDK10OrHigher() {
542 return GraalServices.JAVA_SPECIFICATION_VERSION >= 10;
543 }
544
545 private static boolean isJDK11OrHigher() {
546 return GraalServices.JAVA_SPECIFICATION_VERSION >= 11;
547 }
548
549 private static boolean isJDK12OrHigher() {
550 return GraalServices.JAVA_SPECIFICATION_VERSION >= 12;
551 }
552
553 private static boolean isJDK13OrHigher() {
554 return GraalServices.JAVA_SPECIFICATION_VERSION >= 13;
555 }
556
557 public interface Refiner {
558 void refine(CheckGraalIntrinsics checker);
559 }
560
561 @Test
562 @SuppressWarnings("try")
563 public void test() throws ClassNotFoundException {
564 HotSpotProviders providers = rt.getHostBackend().getProviders();
565 Plugins graphBuilderPlugins = providers.getGraphBuilderPlugins();
566 InvocationPlugins invocationPlugins = graphBuilderPlugins.getInvocationPlugins();
567
568 HotSpotVMConfigStore store = config.getStore();
569 List<VMIntrinsicMethod> intrinsics = store.getIntrinsics();
570
571 for (Refiner refiner : ServiceLoader.load(Refiner.class)) {
572 refiner.refine(this);
573 }
574
|
1 /*
2 * Copyright (c) 2014, 2019, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Formatter;
33 import java.util.List;
34 import java.util.ServiceLoader;
35 import java.util.Set;
36 import java.util.TreeSet;
37 import java.util.stream.Collectors;
38
39 import jdk.internal.vm.compiler.collections.EconomicMap;
40 import jdk.internal.vm.compiler.collections.MapCursor;
41 import org.graalvm.compiler.api.test.Graal;
42 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
43 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
44 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
45 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
46 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
47 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
48 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding;
49 import org.graalvm.compiler.runtime.RuntimeProvider;
50 import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
51 import org.graalvm.compiler.test.GraalTest;
52 import org.junit.Test;
53
54 import jdk.vm.ci.aarch64.AArch64;
55 import jdk.vm.ci.amd64.AMD64;
56 import jdk.vm.ci.code.Architecture;
57 import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
58 import jdk.vm.ci.hotspot.VMIntrinsicMethod;
59 import jdk.vm.ci.meta.MetaAccessProvider;
60 import jdk.vm.ci.meta.MetaUtil;
61 import jdk.vm.ci.meta.MethodHandleAccessProvider.IntrinsicMethod;
62 import jdk.vm.ci.meta.ResolvedJavaMethod;
63
64 /**
65 * Checks the intrinsics implemented by Graal against the set of intrinsics declared by HotSpot. The
66 * purpose of this test is to detect when new intrinsics are added to HotSpot and process them
67 * appropriately in Graal. This will be achieved by working through {@link #toBeInvestigated} and
68 * either implementing the intrinsic or moving it to {@link #ignore} .
69 */
70 public class CheckGraalIntrinsics extends GraalTest {
240 "java/lang/Long.numberOfTrailingZeros(J)I");
241
242 // Relevant for Java flight recorder
243 add(toBeInvestigated,
244 "oracle/jrockit/jfr/Timing.counterTime()J",
245 "oracle/jrockit/jfr/VMJFR.classID0(Ljava/lang/Class;)J",
246 "oracle/jrockit/jfr/VMJFR.threadID()I");
247
248 add(toBeInvestigated,
249 // Similar to addExact
250 "java/lang/Math.negateExact(I)I",
251 // Similar to addExact
252 "java/lang/Math.negateExact(J)J",
253 // HotSpot MacroAssembler-based intrinsic
254 "java/lang/String.indexOf(Ljava/lang/String;)I",
255 // Can share most implementation parts with with
256 // Unsafe.allocateUninitializedArray0
257 "java/lang/reflect/Array.newArray(Ljava/lang/Class;I)Ljava/lang/Object;",
258 // HotSpot MacroAssembler-based intrinsic
259 "sun/nio/cs/ISO_8859_1$Encoder.encodeISOArray([CI[BII)I",
260 // We have implemented implCompressMultiBlock0 on JDK9+. Does it worth
261 // backporting as corresponding HotSpot stubs are only generated on SPARC?
262 "sun/security/provider/DigestBase.implCompressMultiBlock([BII)I");
263
264 // See JDK-8207146.
265 String oopName = isJDK12OrHigher() ? "Reference" : "Object";
266
267 if (isJDK9OrHigher()) {
268 // Relevant for Java flight recorder
269 add(toBeInvestigated,
270 "jdk/jfr/internal/JVM.counterTime()J",
271 "jdk/jfr/internal/JVM.getBufferWriter()Ljava/lang/Object;",
272 "jdk/jfr/internal/JVM.getClassId(Ljava/lang/Class;)J");
273
274 add(toBeInvestigated,
275 // HotSpot MacroAssembler-based intrinsic
276 "java/lang/Math.fma(DDD)D",
277 // HotSpot MacroAssembler-based intrinsic
278 "java/lang/Math.fma(FFF)F",
279 // Just check if the argument is a compile time constant
280 "java/lang/invoke/MethodHandleImpl.isCompileConstant(Ljava/lang/Object;)Z",
281 // Only used as a marker for vectorization?
282 "java/util/stream/Streams$RangeIntSpliterator.forEachRemaining(Ljava/util/function/IntConsumer;)V",
283 // Only implemented on non-AMD64 platforms (some logic and runtime call)
284 "java/util/zip/Adler32.updateByteBuffer(IJII)I",
285 // Only implemented on non-AMD64 platforms (some logic and runtime call)
286 "java/util/zip/Adler32.updateBytes(I[BII)I",
287 // Emits a slow and a fast path and some dispatching logic
288 "jdk/internal/misc/Unsafe.allocateUninitializedArray0(Ljava/lang/Class;I)Ljava/lang/Object;",
289
290 // Control flow, deopts, and a cast
291 "jdk/internal/util/Preconditions.checkIndex(IILjava/util/function/BiFunction;)I",
292 // HotSpot MacroAssembler-based intrinsic
293 "sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray([CI[BII)I");
294
295 /*
296 * Per default, all these operations are mapped to some generic method for which we
297 * already have compiler intrinsics. Performance-wise it would be better to support them
298 * explicitly as the more generic method might be more restrictive and therefore slower
299 * than necessary.
300 */
301
302 add(toBeInvestigated,
303 // Mapped to compareAndExchange*
304 "jdk/internal/misc/Unsafe.compareAndExchangeByteAcquire(Ljava/lang/Object;JBB)B",
305 "jdk/internal/misc/Unsafe.compareAndExchangeByteRelease(Ljava/lang/Object;JBB)B",
306 "jdk/internal/misc/Unsafe.compareAndExchangeIntAcquire(Ljava/lang/Object;JII)I",
307 "jdk/internal/misc/Unsafe.compareAndExchangeIntRelease(Ljava/lang/Object;JII)I",
308 "jdk/internal/misc/Unsafe.compareAndExchangeLongAcquire(Ljava/lang/Object;JJJ)J",
309 "jdk/internal/misc/Unsafe.compareAndExchangeLongRelease(Ljava/lang/Object;JJJ)J",
310 "jdk/internal/misc/Unsafe.compareAndExchange" + oopName + "Acquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
311 "jdk/internal/misc/Unsafe.compareAndExchange" + oopName + "Release(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
312 "jdk/internal/misc/Unsafe.compareAndExchangeShortAcquire(Ljava/lang/Object;JSS)S",
313 "jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S",
320 "jdk/internal/misc/Unsafe.weakCompareAndSetInt(Ljava/lang/Object;JII)Z",
321 "jdk/internal/misc/Unsafe.weakCompareAndSetIntAcquire(Ljava/lang/Object;JII)Z",
322 "jdk/internal/misc/Unsafe.weakCompareAndSetIntPlain(Ljava/lang/Object;JII)Z",
323 "jdk/internal/misc/Unsafe.weakCompareAndSetIntRelease(Ljava/lang/Object;JII)Z",
324 "jdk/internal/misc/Unsafe.weakCompareAndSetLong(Ljava/lang/Object;JJJ)Z",
325 "jdk/internal/misc/Unsafe.weakCompareAndSetLongAcquire(Ljava/lang/Object;JJJ)Z",
326 "jdk/internal/misc/Unsafe.weakCompareAndSetLongPlain(Ljava/lang/Object;JJJ)Z",
327 "jdk/internal/misc/Unsafe.weakCompareAndSetLongRelease(Ljava/lang/Object;JJJ)Z",
328 "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
329 "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "Acquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
330 "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "Plain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
331 "jdk/internal/misc/Unsafe.weakCompareAndSet" + oopName + "Release(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
332 "jdk/internal/misc/Unsafe.weakCompareAndSetShort(Ljava/lang/Object;JSS)Z",
333 "jdk/internal/misc/Unsafe.weakCompareAndSetShortAcquire(Ljava/lang/Object;JSS)Z",
334 "jdk/internal/misc/Unsafe.weakCompareAndSetShortPlain(Ljava/lang/Object;JSS)Z",
335 "jdk/internal/misc/Unsafe.weakCompareAndSetShortRelease(Ljava/lang/Object;JSS)Z");
336
337 // Compact string support - HotSpot MacroAssembler-based intrinsic or complex C2 logic.
338 add(toBeInvestigated,
339 "java/lang/StringCoding.hasNegatives([BII)Z",
340 "java/lang/StringCoding.implEncodeISOArray([BI[BII)I");
341 add(ignore,
342 // handled through an intrinsic for String.equals itself
343 "java/lang/StringLatin1.equals([B[B)Z",
344
345 // handled by an intrinsic for StringLatin1.indexOf([BI[BII)I
346 "java/lang/StringLatin1.indexOf([B[B)I",
347
348 // handled through an intrinsic for String.equals itself
349 "java/lang/StringUTF16.equals([B[B)Z",
350
351 // handled by an intrinsic for StringUTF16.indexOfUnsafe
352 "java/lang/StringUTF16.indexOf([BI[BII)I",
353 "java/lang/StringUTF16.indexOf([B[B)I",
354
355 // handled by an intrinsic for StringUTF16.indexOfCharUnsafe
356 "java/lang/StringUTF16.indexOfChar([BIII)I",
357
358 // handled by an intrinsic for StringUTF16.indexOfLatin1Unsafe
359 "java/lang/StringUTF16.indexOfLatin1([BI[BII)I",
360 "java/lang/StringUTF16.indexOfLatin1([B[B)I");
361
362 if (!config.useAESCTRIntrinsics) {
363 add(ignore,
364 "com/sun/crypto/provider/CounterMode.implCrypt([BII[BI)I");
365 }
366 if (!config.useGHASHIntrinsics()) {
367 add(ignore,
368 "com/sun/crypto/provider/GHASH.processBlocks([BII[J[J)V");
369 }
370 if (!(config.useSHA1Intrinsics() || config.useSHA256Intrinsics() || config.useSHA512Intrinsics())) {
371 add(ignore,
372 "sun/security/provider/DigestBase.implCompressMultiBlock0([BII)I");
373 }
374 }
375
376 if (isJDK10OrHigher()) {
377 add(toBeInvestigated,
378 "java/lang/Math.multiplyHigh(JJ)J");
379 }
380
381 if (isJDK11OrHigher()) {
382 // Relevant for Java flight recorder
383 add(toBeInvestigated,
384 "java/util/Base64$Encoder.encodeBlock([BII[BIZ)V",
385 "jdk/jfr/internal/JVM.getEventWriter()Ljava/lang/Object;");
386 }
387
388 if (isJDK12OrHigher()) {
389 add(toBeInvestigated,
390 "java/lang/CharacterDataLatin1.isDigit(I)Z",
391 "java/lang/CharacterDataLatin1.isLowerCase(I)Z",
392 "java/lang/CharacterDataLatin1.isUpperCase(I)Z",
393 "java/lang/CharacterDataLatin1.isWhitespace(I)Z");
394 }
395
396 if (isJDK13OrHigher()) {
397 add(toBeInvestigated,
398 "java/lang/Math.max(DD)D",
399 "java/lang/Math.max(FF)F",
400 "java/lang/Math.min(DD)D",
401 "java/lang/Math.min(FF)F");
402 }
403
404 if (!config.inlineNotify()) {
405 add(ignore, "java/lang/Object.notify()V");
406 }
407 if (!config.inlineNotifyAll()) {
408 add(ignore, "java/lang/Object.notifyAll()V");
409 }
410
411 if (!(arch instanceof AMD64)) {
412 // Can we implement these on non-AMD64 platforms? C2 seems to.
413 add(toBeInvestigated,
414 "java/lang/String.compareTo(Ljava/lang/String;)I",
415 "java/lang/StringLatin1.indexOf([B[B)I",
416 "java/lang/StringLatin1.inflate([BI[BII)V",
417 "java/lang/StringLatin1.inflate([BI[CII)V",
418 "java/lang/StringUTF16.compress([BI[BII)I",
419 "java/lang/StringUTF16.compress([CI[BII)I",
420 "java/lang/StringUTF16.indexOf([BI[BII)I",
421 "java/lang/StringUTF16.indexOf([B[B)I",
422 "java/lang/StringUTF16.indexOfChar([BIII)I",
423 "java/lang/StringUTF16.indexOfLatin1([BI[BII)I",
424 "java/lang/StringUTF16.indexOfLatin1([B[B)I",
425 "jdk/internal/misc/Unsafe.compareAndExchangeByte(Ljava/lang/Object;JBB)B",
426 "jdk/internal/misc/Unsafe.compareAndExchangeShort(Ljava/lang/Object;JSS)S",
427 "jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z",
428 "jdk/internal/misc/Unsafe.compareAndSetShort(Ljava/lang/Object;JSS)Z",
429 "jdk/internal/misc/Unsafe.getAndAddByte(Ljava/lang/Object;JB)B",
430 "jdk/internal/misc/Unsafe.getAndAddShort(Ljava/lang/Object;JS)S",
431 "jdk/internal/misc/Unsafe.getAndSetByte(Ljava/lang/Object;JB)B",
432 "jdk/internal/misc/Unsafe.getAndSetShort(Ljava/lang/Object;JS)S",
433 "sun/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
434 "sun/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
435 "sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
436 "sun/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
437 "sun/misc/Unsafe.getAndSet" + oopName + "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;");
438
439 if (isJDK9OrHigher()) {
440 if (!(arch instanceof AArch64)) {
441 add(toBeInvestigated,
442 "java/lang/StringLatin1.compareTo([B[B)I",
443 "java/lang/StringLatin1.compareToUTF16([B[B)I",
444 "java/lang/StringUTF16.compareTo([B[B)I",
445 "java/lang/StringUTF16.compareToLatin1([B[B)I",
446 "jdk/internal/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
447 "jdk/internal/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
448 "jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
449 "jdk/internal/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
450 "jdk/internal/misc/Unsafe.getAndSet" + oopName + "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;");
451 }
452 add(toBeInvestigated,
453 "com/sun/crypto/provider/CounterMode.implCrypt([BII[BI)I",
454 "java/lang/Thread.onSpinWait()V",
455 "java/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I",
456 "jdk/internal/misc/Unsafe.getCharUnaligned(Ljava/lang/Object;J)C",
457 "jdk/internal/misc/Unsafe.getIntUnaligned(Ljava/lang/Object;J)I",
458 "jdk/internal/misc/Unsafe.getLongUnaligned(Ljava/lang/Object;J)J",
459 "jdk/internal/misc/Unsafe.getShortUnaligned(Ljava/lang/Object;J)S",
460 "jdk/internal/misc/Unsafe.putCharUnaligned(Ljava/lang/Object;JC)V",
461 "jdk/internal/misc/Unsafe.putIntUnaligned(Ljava/lang/Object;JI)V",
462 "jdk/internal/misc/Unsafe.putLongUnaligned(Ljava/lang/Object;JJ)V",
463 "jdk/internal/misc/Unsafe.putShortUnaligned(Ljava/lang/Object;JS)V");
464 }
465 if (isJDK10OrHigher()) {
466 add(toBeInvestigated,
467 "jdk/internal/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I");
468 }
469 }
470
471 /*
472 * The intrinsics down here are known to be implemented but they are not always enabled on
473 * the HotSpot side (e.g., because they require certain CPU features). So, we are ignoring
474 * them if the HotSpot config tells us that they can't be used.
475 */
476
477 // CRC32 intrinsics
478 if (!config.useCRC32Intrinsics) {
479 add(ignore, "java/util/zip/CRC32.update(II)I");
480 if (isJDK9OrHigher()) {
481 add(ignore,
482 "java/util/zip/CRC32.updateByteBuffer0(IJII)I",
483 "java/util/zip/CRC32.updateBytes0(I[BII)I");
484 } else {
485 add(ignore,
486 "java/util/zip/CRC32.updateByteBuffer(IJII)I",
487 "java/util/zip/CRC32.updateBytes(I[BII)I");
488 }
541 add(ignore, "sun/security/provider/SHA.implCompress([BI)V");
542 }
543 }
544 if (!config.useSHA256Intrinsics()) {
545 if (isJDK9OrHigher()) {
546 add(ignore, "sun/security/provider/SHA2.implCompress0([BI)V");
547 } else {
548 add(ignore, "sun/security/provider/SHA2.implCompress([BI)V");
549 }
550 }
551 if (!config.useSHA512Intrinsics()) {
552 if (isJDK9OrHigher()) {
553 add(ignore, "sun/security/provider/SHA5.implCompress0([BI)V");
554 } else {
555 add(ignore, "sun/security/provider/SHA5.implCompress([BI)V");
556 }
557 }
558 }
559
560 private static boolean isJDK9OrHigher() {
561 return JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 9;
562 }
563
564 private static boolean isJDK10OrHigher() {
565 return JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 10;
566 }
567
568 private static boolean isJDK11OrHigher() {
569 return JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 11;
570 }
571
572 private static boolean isJDK12OrHigher() {
573 return JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 12;
574 }
575
576 private static boolean isJDK13OrHigher() {
577 return JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 13;
578 }
579
580 public interface Refiner {
581 void refine(CheckGraalIntrinsics checker);
582 }
583
584 @Test
585 @SuppressWarnings("try")
586 public void test() throws ClassNotFoundException {
587 HotSpotProviders providers = rt.getHostBackend().getProviders();
588 Plugins graphBuilderPlugins = providers.getGraphBuilderPlugins();
589 InvocationPlugins invocationPlugins = graphBuilderPlugins.getInvocationPlugins();
590
591 HotSpotVMConfigStore store = config.getStore();
592 List<VMIntrinsicMethod> intrinsics = store.getIntrinsics();
593
594 for (Refiner refiner : ServiceLoader.load(Refiner.class)) {
595 refiner.refine(this);
596 }
597
|