< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java

Print this page


   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 


< prev index next >