src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java
changeset 58877 aec7bf35d6f5
parent 58533 46b0b7fe255c
child 58901 2700c409ff10
equal deleted inserted replaced
58876:1a8d65e71a66 58877:aec7bf35d6f5
    37 import java.lang.reflect.Array;
    37 import java.lang.reflect.Array;
    38 import java.math.BigInteger;
    38 import java.math.BigInteger;
    39 import java.util.zip.CRC32;
    39 import java.util.zip.CRC32;
    40 
    40 
    41 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
    41 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
    42 import org.graalvm.compiler.bytecode.BytecodeProvider;
       
    43 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
    42 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
    44 import org.graalvm.compiler.core.common.type.ObjectStamp;
    43 import org.graalvm.compiler.core.common.type.ObjectStamp;
    45 import org.graalvm.compiler.core.common.type.StampFactory;
    44 import org.graalvm.compiler.core.common.type.StampFactory;
    46 import org.graalvm.compiler.core.common.type.TypeReference;
    45 import org.graalvm.compiler.core.common.type.TypeReference;
    47 import org.graalvm.compiler.debug.GraalError;
    46 import org.graalvm.compiler.debug.GraalError;
    90 import org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;
    89 import org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;
    91 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
    90 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
    92 import org.graalvm.compiler.nodes.memory.ReadNode;
    91 import org.graalvm.compiler.nodes.memory.ReadNode;
    93 import org.graalvm.compiler.nodes.memory.address.AddressNode;
    92 import org.graalvm.compiler.nodes.memory.address.AddressNode;
    94 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
    93 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
       
    94 import org.graalvm.compiler.nodes.spi.Replacements;
    95 import org.graalvm.compiler.nodes.util.GraphUtil;
    95 import org.graalvm.compiler.nodes.util.GraphUtil;
    96 import org.graalvm.compiler.options.OptionValues;
    96 import org.graalvm.compiler.options.OptionValues;
    97 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
    97 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
    98 import org.graalvm.compiler.replacements.InlineDuringParsingPlugin;
    98 import org.graalvm.compiler.replacements.InlineDuringParsingPlugin;
    99 import org.graalvm.compiler.replacements.MethodHandlePlugin;
    99 import org.graalvm.compiler.replacements.MethodHandlePlugin;
   106 import org.graalvm.compiler.word.WordOperationPlugin;
   106 import org.graalvm.compiler.word.WordOperationPlugin;
   107 import org.graalvm.compiler.word.WordTypes;
   107 import org.graalvm.compiler.word.WordTypes;
   108 import jdk.internal.vm.compiler.word.LocationIdentity;
   108 import jdk.internal.vm.compiler.word.LocationIdentity;
   109 
   109 
   110 import jdk.vm.ci.code.CodeUtil;
   110 import jdk.vm.ci.code.CodeUtil;
       
   111 import jdk.vm.ci.code.TargetDescription;
   111 import jdk.vm.ci.hotspot.VMIntrinsicMethod;
   112 import jdk.vm.ci.hotspot.VMIntrinsicMethod;
   112 import jdk.vm.ci.meta.ConstantReflectionProvider;
   113 import jdk.vm.ci.meta.ConstantReflectionProvider;
   113 import jdk.vm.ci.meta.DeoptimizationAction;
   114 import jdk.vm.ci.meta.DeoptimizationAction;
   114 import jdk.vm.ci.meta.JavaKind;
   115 import jdk.vm.ci.meta.JavaKind;
   115 import jdk.vm.ci.meta.MetaAccessProvider;
   116 import jdk.vm.ci.meta.MetaAccessProvider;
   126      *
   127      *
   127      * @param constantReflection
   128      * @param constantReflection
   128      * @param snippetReflection
   129      * @param snippetReflection
   129      * @param foreignCalls
   130      * @param foreignCalls
   130      * @param options
   131      * @param options
       
   132      * @param target
   131      */
   133      */
   132     public static Plugins create(HotSpotGraalRuntimeProvider graalRuntime,
   134     public static Plugins create(HotSpotGraalRuntimeProvider graalRuntime,
   133                     CompilerConfiguration compilerConfiguration,
   135                     CompilerConfiguration compilerConfiguration,
   134                     GraalHotSpotVMConfig config,
   136                     GraalHotSpotVMConfig config,
   135                     HotSpotWordTypes wordTypes,
   137                     HotSpotWordTypes wordTypes,
   136                     MetaAccessProvider metaAccess,
   138                     MetaAccessProvider metaAccess,
   137                     ConstantReflectionProvider constantReflection,
   139                     ConstantReflectionProvider constantReflection,
   138                     SnippetReflectionProvider snippetReflection,
   140                     SnippetReflectionProvider snippetReflection,
   139                     ForeignCallsProvider foreignCalls,
   141                     ForeignCallsProvider foreignCalls,
   140                     ReplacementsImpl replacements,
   142                     ReplacementsImpl replacements,
   141                     OptionValues options) {
   143                     OptionValues options, TargetDescription target) {
   142         InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(graalRuntime, config, compilerConfiguration);
   144         InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(graalRuntime, config, compilerConfiguration);
   143 
   145 
   144         Plugins plugins = new Plugins(invocationPlugins);
   146         Plugins plugins = new Plugins(invocationPlugins);
   145         NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, wordTypes);
   147         NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, wordTypes, target);
   146         HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes);
   148         HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes);
   147         HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin, config, wordTypes);
   149         HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin, config, wordTypes);
   148 
   150 
   149         plugins.appendTypePlugin(nodePlugin);
   151         plugins.appendTypePlugin(nodePlugin);
   150         plugins.appendNodePlugin(nodePlugin);
   152         plugins.appendNodePlugin(nodePlugin);
   169 
   171 
   170         invocationPlugins.defer(new Runnable() {
   172         invocationPlugins.defer(new Runnable() {
   171 
   173 
   172             @Override
   174             @Override
   173             public void run() {
   175             public void run() {
   174                 BytecodeProvider replacementBytecodeProvider = replacements.getDefaultReplacementBytecodeProvider();
   176                 registerObjectPlugins(invocationPlugins, options, config, replacements);
   175                 registerObjectPlugins(invocationPlugins, options, config, replacementBytecodeProvider);
   177                 registerClassPlugins(plugins, config, replacements);
   176                 registerClassPlugins(plugins, config, replacementBytecodeProvider);
       
   177                 registerSystemPlugins(invocationPlugins, foreignCalls);
   178                 registerSystemPlugins(invocationPlugins, foreignCalls);
   178                 registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config, replacementBytecodeProvider);
   179                 registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config, replacements);
   179                 if (!GeneratePIC.getValue(options)) {
   180                 if (!GeneratePIC.getValue(options)) {
   180                     registerCallSitePlugins(invocationPlugins);
   181                     registerCallSitePlugins(invocationPlugins);
   181                 }
   182                 }
   182                 registerReflectionPlugins(invocationPlugins, replacementBytecodeProvider);
   183                 registerReflectionPlugins(invocationPlugins, replacements);
   183                 registerConstantPoolPlugins(invocationPlugins, wordTypes, config, replacementBytecodeProvider);
   184                 registerConstantPoolPlugins(invocationPlugins, wordTypes, config, replacements);
   184                 registerAESPlugins(invocationPlugins, config, replacementBytecodeProvider);
   185                 registerAESPlugins(invocationPlugins, config, replacements);
   185                 registerCRC32Plugins(invocationPlugins, config, replacementBytecodeProvider);
   186                 registerCRC32Plugins(invocationPlugins, config, replacements);
   186                 registerCRC32CPlugins(invocationPlugins, config, replacementBytecodeProvider);
   187                 registerCRC32CPlugins(invocationPlugins, config, replacements);
   187                 registerBigIntegerPlugins(invocationPlugins, config, replacementBytecodeProvider);
   188                 registerBigIntegerPlugins(invocationPlugins, config, replacements);
   188                 registerSHAPlugins(invocationPlugins, config, replacementBytecodeProvider);
   189                 registerSHAPlugins(invocationPlugins, config, replacements);
   189                 registerGHASHPlugins(invocationPlugins, config, metaAccess, foreignCalls);
   190                 registerGHASHPlugins(invocationPlugins, config, metaAccess, foreignCalls);
   190                 registerCounterModePlugins(invocationPlugins, config, replacementBytecodeProvider);
   191                 registerCounterModePlugins(invocationPlugins, config, replacements);
   191                 registerBase64Plugins(invocationPlugins, config, metaAccess, foreignCalls);
   192                 registerBase64Plugins(invocationPlugins, config, metaAccess, foreignCalls);
   192                 registerUnsafePlugins(invocationPlugins, config, replacementBytecodeProvider);
   193                 registerUnsafePlugins(invocationPlugins, config, replacements);
   193                 StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacementBytecodeProvider, true, false);
   194                 StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacements, true, false);
   194                 registerArrayPlugins(invocationPlugins, replacementBytecodeProvider);
   195                 registerArrayPlugins(invocationPlugins, replacements);
   195                 registerStringPlugins(invocationPlugins, replacementBytecodeProvider);
   196                 registerStringPlugins(invocationPlugins, replacements);
   196                 registerArraysSupportPlugins(invocationPlugins, config, replacementBytecodeProvider);
   197                 registerArraysSupportPlugins(invocationPlugins, config, replacements);
   197 
   198 
   198                 for (NodeIntrinsicPluginFactory factory : GraalServices.load(NodeIntrinsicPluginFactory.class)) {
   199                 for (NodeIntrinsicPluginFactory factory : GraalServices.load(NodeIntrinsicPluginFactory.class)) {
   199                     factory.registerPlugins(invocationPlugins, nodeIntrinsificationProvider);
   200                     factory.registerPlugins(invocationPlugins, nodeIntrinsificationProvider);
   200                 }
   201                 }
   201             }
   202             }
   202         });
   203         });
   203         return plugins;
   204         return plugins;
   204     }
   205     }
   205 
   206 
   206     private static void registerObjectPlugins(InvocationPlugins plugins, OptionValues options, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
   207     private static void registerObjectPlugins(InvocationPlugins plugins, OptionValues options, GraalHotSpotVMConfig config, Replacements replacements) {
   207         Registration r = new Registration(plugins, Object.class, bytecodeProvider);
   208         Registration r = new Registration(plugins, Object.class, replacements);
   208         if (!GeneratePIC.getValue(options)) {
   209         if (!GeneratePIC.getValue(options)) {
   209             // FIXME: clone() requires speculation and requires a fix in here (to check that
   210             // FIXME: clone() requires speculation and requires a fix in here (to check that
   210             // b.getAssumptions() != null), and in ReplacementImpl.getSubstitution() where there is
   211             // b.getAssumptions() != null), and in ReplacementImpl.getSubstitution() where there is
   211             // an instantiation of IntrinsicGraphBuilder using a constructor that sets
   212             // an instantiation of IntrinsicGraphBuilder using a constructor that sets
   212             // AllowAssumptions to YES automatically. The former has to inherit the assumptions
   213             // AllowAssumptions to YES automatically. The former has to inherit the assumptions
   233         if (config.inlineNotifyAll()) {
   234         if (config.inlineNotifyAll()) {
   234             r.registerMethodSubstitution(ObjectSubstitutions.class, "notifyAll", Receiver.class);
   235             r.registerMethodSubstitution(ObjectSubstitutions.class, "notifyAll", Receiver.class);
   235         }
   236         }
   236     }
   237     }
   237 
   238 
   238     private static void registerClassPlugins(Plugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
   239     private static void registerClassPlugins(Plugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
   239         Registration r = new Registration(plugins.getInvocationPlugins(), Class.class, bytecodeProvider);
   240         Registration r = new Registration(plugins.getInvocationPlugins(), Class.class, replacements);
   240 
   241 
   241         r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "getModifiers", Receiver.class);
   242         r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "getModifiers", Receiver.class);
   242         r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isInterface", Receiver.class);
   243         r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isInterface", Receiver.class);
   243         r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isArray", Receiver.class);
   244         r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isArray", Receiver.class);
   244         r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isPrimitive", Receiver.class);
   245         r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isPrimitive", Receiver.class);
   271         plugins.register(plugin, ConstantCallSite.class, "getTarget", Receiver.class);
   272         plugins.register(plugin, ConstantCallSite.class, "getTarget", Receiver.class);
   272         plugins.register(plugin, MutableCallSite.class, "getTarget", Receiver.class);
   273         plugins.register(plugin, MutableCallSite.class, "getTarget", Receiver.class);
   273         plugins.register(plugin, VolatileCallSite.class, "getTarget", Receiver.class);
   274         plugins.register(plugin, VolatileCallSite.class, "getTarget", Receiver.class);
   274     }
   275     }
   275 
   276 
   276     private static void registerReflectionPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
   277     private static void registerReflectionPlugins(InvocationPlugins plugins, Replacements replacements) {
   277         Registration r = new Registration(plugins, reflectionClass, bytecodeProvider);
   278         Registration r = new Registration(plugins, reflectionClass, replacements);
   278         r.register0("getCallerClass", new InvocationPlugin() {
   279         r.register0("getCallerClass", new InvocationPlugin() {
   279             @Override
   280             @Override
   280             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
   281             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
   281                 b.addPush(JavaKind.Object, new ReflectionGetCallerClassNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnStamp(b.getAssumptions())));
   282                 b.addPush(JavaKind.Object, new ReflectionGetCallerClassNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnStamp(b.getAssumptions())));
   282                 return true;
   283                 return true;
   288             }
   289             }
   289         });
   290         });
   290         r.registerMethodSubstitution(ReflectionSubstitutions.class, "getClassAccessFlags", Class.class);
   291         r.registerMethodSubstitution(ReflectionSubstitutions.class, "getClassAccessFlags", Class.class);
   291     }
   292     }
   292 
   293 
   293     private static void registerUnsafePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider replacementBytecodeProvider) {
   294     private static void registerUnsafePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
   294         Registration r;
   295         Registration r;
   295         if (JavaVersionUtil.JAVA_SPEC <= 8) {
   296         if (JavaVersionUtil.JAVA_SPEC <= 8) {
   296             r = new Registration(plugins, Unsafe.class, replacementBytecodeProvider);
   297             r = new Registration(plugins, Unsafe.class, replacements);
   297         } else {
   298         } else {
   298             r = new Registration(plugins, "jdk.internal.misc.Unsafe", replacementBytecodeProvider);
   299             r = new Registration(plugins, "jdk.internal.misc.Unsafe", replacements);
   299         }
   300         }
   300         String substituteMethodName = config.doingUnsafeAccessOffset != Integer.MAX_VALUE ? "copyMemoryGuarded" : "copyMemory";
   301         String substituteMethodName = config.doingUnsafeAccessOffset != Integer.MAX_VALUE ? "copyMemoryGuarded" : "copyMemory";
   301         r.registerMethodSubstitution(HotSpotUnsafeSubstitutions.class, HotSpotUnsafeSubstitutions.copyMemoryName, substituteMethodName, Receiver.class, Object.class, long.class, Object.class,
   302         r.registerMethodSubstitution(HotSpotUnsafeSubstitutions.class, HotSpotUnsafeSubstitutions.copyMemoryName, substituteMethodName, Receiver.class, Object.class, long.class, Object.class,
   302                         long.class, long.class);
   303                         long.class, long.class);
   303     }
   304     }
   338         ValueNode elementValue = WordOperationPlugin.readOp(b, elementKind, elementAddress, NamedLocationIdentity.getArrayLocation(elementKind), BarrierType.NONE, notCompressible);
   339         ValueNode elementValue = WordOperationPlugin.readOp(b, elementKind, elementAddress, NamedLocationIdentity.getArrayLocation(elementKind), BarrierType.NONE, notCompressible);
   339         b.addPush(elementKind, elementValue);
   340         b.addPush(elementKind, elementValue);
   340         return true;
   341         return true;
   341     }
   342     }
   342 
   343 
   343     private static void registerConstantPoolPlugins(InvocationPlugins plugins, WordTypes wordTypes, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
   344     private static void registerConstantPoolPlugins(InvocationPlugins plugins, WordTypes wordTypes, GraalHotSpotVMConfig config, Replacements replacements) {
   344         Registration r = new Registration(plugins, constantPoolClass, bytecodeProvider);
   345         Registration r = new Registration(plugins, constantPoolClass, replacements);
   345 
   346 
   346         r.register2("getSize0", Receiver.class, Object.class, new InvocationPlugin() {
   347         r.register2("getSize0", Receiver.class, Object.class, new InvocationPlugin() {
   347             @Override
   348             @Override
   348             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode constantPoolOop) {
   349             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode constantPoolOop) {
   349                 boolean notCompressible = false;
   350                 boolean notCompressible = false;
   409                 return true;
   410                 return true;
   410             }
   411             }
   411         });
   412         });
   412     }
   413     }
   413 
   414 
   414     private static void registerArrayPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
   415     private static void registerArrayPlugins(InvocationPlugins plugins, Replacements replacements) {
   415         Registration r = new Registration(plugins, Array.class, bytecodeProvider);
   416         Registration r = new Registration(plugins, Array.class, replacements);
   416         r.setAllowOverwrite(true);
   417         r.setAllowOverwrite(true);
   417         r.registerMethodSubstitution(HotSpotArraySubstitutions.class, "newInstance", Class.class, int.class);
   418         r.registerMethodSubstitution(HotSpotArraySubstitutions.class, "newInstance", Class.class, int.class);
   418     }
   419     }
   419 
   420 
   420     private static void registerStringPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
   421     private static void registerStringPlugins(InvocationPlugins plugins, Replacements replacements) {
   421         if (JavaVersionUtil.JAVA_SPEC > 8) {
   422         if (JavaVersionUtil.JAVA_SPEC > 8) {
   422             final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", bytecodeProvider);
   423             final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", replacements);
   423             utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "toBytes", char[].class, int.class, int.class);
   424             utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "toBytes", char[].class, int.class, int.class);
   424             utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "getChars", byte[].class, int.class, int.class, char[].class, int.class);
   425             utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "getChars", byte[].class, int.class, int.class, char[].class, int.class);
   425         }
   426         }
   426     }
   427     }
   427 
   428 
   428     private static void registerThreadPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, WordTypes wordTypes, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
   429     private static void registerThreadPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, WordTypes wordTypes, GraalHotSpotVMConfig config, Replacements replacements) {
   429         Registration r = new Registration(plugins, Thread.class, bytecodeProvider);
   430         Registration r = new Registration(plugins, Thread.class, replacements);
   430         r.register0("currentThread", new InvocationPlugin() {
   431         r.register0("currentThread", new InvocationPlugin() {
   431             @Override
   432             @Override
   432             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
   433             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
   433                 CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(wordTypes.getWordKind()));
   434                 CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(wordTypes.getWordKind()));
   434                 ValueNode offset = b.add(ConstantNode.forLong(config.threadObjectOffset));
   435                 ValueNode offset = b.add(ConstantNode.forLong(config.threadObjectOffset));
   441         });
   442         });
   442 
   443 
   443         r.registerMethodSubstitution(ThreadSubstitutions.class, "isInterrupted", Receiver.class, boolean.class);
   444         r.registerMethodSubstitution(ThreadSubstitutions.class, "isInterrupted", Receiver.class, boolean.class);
   444     }
   445     }
   445 
   446 
   446     public static final String aesEncryptName;
       
   447     public static final String aesDecryptName;
       
   448 
       
   449     public static final String reflectionClass;
   447     public static final String reflectionClass;
   450     public static final String constantPoolClass;
   448     public static final String constantPoolClass;
   451 
   449 
   452     static {
   450     static {
   453         if (JavaVersionUtil.JAVA_SPEC <= 8) {
   451         if (JavaVersionUtil.JAVA_SPEC <= 8) {
   454             aesEncryptName = "encryptBlock";
       
   455             aesDecryptName = "decryptBlock";
       
   456             reflectionClass = "sun.reflect.Reflection";
   452             reflectionClass = "sun.reflect.Reflection";
   457             constantPoolClass = "sun.reflect.ConstantPool";
   453             constantPoolClass = "sun.reflect.ConstantPool";
   458         } else {
   454         } else {
   459             aesEncryptName = "implEncryptBlock";
       
   460             aesDecryptName = "implDecryptBlock";
       
   461             reflectionClass = "jdk.internal.reflect.Reflection";
   455             reflectionClass = "jdk.internal.reflect.Reflection";
   462             constantPoolClass = "jdk.internal.reflect.ConstantPool";
   456             constantPoolClass = "jdk.internal.reflect.ConstantPool";
   463         }
   457         }
   464     }
   458     }
   465 
   459 
   466     public static boolean cbcUsesImplNames(GraalHotSpotVMConfig config) {
   460     public static String lookupIntrinsicName(GraalHotSpotVMConfig config, String className, String name1, String name2) {
       
   461         boolean foundName1 = false;
       
   462         boolean foundName2 = false;
       
   463         String name = name1;
   467         for (VMIntrinsicMethod intrinsic : config.getStore().getIntrinsics()) {
   464         for (VMIntrinsicMethod intrinsic : config.getStore().getIntrinsics()) {
   468             if ("com/sun/crypto/provider/CipherBlockChaining".equals(intrinsic.declaringClass)) {
   465             if (className.equals(intrinsic.declaringClass)) {
   469                 if ("encrypt".equals(intrinsic.name)) {
   466                 if (name1.equals(intrinsic.name)) {
   470                     return false;
   467                     foundName1 = true;
   471                 } else if ("implEncrypt".equals(intrinsic.name)) {
   468                 } else if (name2.equals(intrinsic.name)) {
       
   469                     foundName2 = true;
       
   470                     name = name2;
       
   471                 }
       
   472             }
       
   473         }
       
   474         if (foundName1 != foundName2) {
       
   475             return name;
       
   476         }
       
   477         throw GraalError.shouldNotReachHere();
       
   478     }
       
   479 
       
   480     public static boolean isIntrinsicName(GraalHotSpotVMConfig config, String className, String name) {
       
   481         for (VMIntrinsicMethod intrinsic : config.getStore().getIntrinsics()) {
       
   482             if (className.equals(intrinsic.declaringClass)) {
       
   483                 if (name.equals(intrinsic.name)) {
   472                     return true;
   484                     return true;
   473                 }
   485                 }
   474             }
   486             }
   475         }
   487         }
   476         throw GraalError.shouldNotReachHere();
   488         return false;
   477     }
   489     }
   478 
   490 
   479     private static void registerAESPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
   491     private static void registerAESPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
   480         if (config.useAESIntrinsics) {
   492         if (config.useAESIntrinsics) {
   481             assert config.aescryptEncryptBlockStub != 0L;
   493             assert config.aescryptEncryptBlockStub != 0L;
   482             assert config.aescryptDecryptBlockStub != 0L;
   494             assert config.aescryptDecryptBlockStub != 0L;
   483             assert config.cipherBlockChainingEncryptAESCryptStub != 0L;
   495             assert config.cipherBlockChainingEncryptAESCryptStub != 0L;
   484             assert config.cipherBlockChainingDecryptAESCryptStub != 0L;
   496             assert config.cipherBlockChainingDecryptAESCryptStub != 0L;
   485             String arch = config.osArch;
   497             String arch = config.osArch;
   486             String decryptSuffix = arch.equals("sparc") ? "WithOriginalKey" : "";
   498             String decryptSuffix = arch.equals("sparc") ? "WithOriginalKey" : "";
   487             Registration r = new Registration(plugins, "com.sun.crypto.provider.CipherBlockChaining", bytecodeProvider);
   499 
   488 
   500             String cbcEncryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implEncrypt", "encrypt");
   489             boolean implNames = cbcUsesImplNames(config);
   501             String cbcDecryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt");
   490             String cbcEncryptName = implNames ? "implEncrypt" : "encrypt";
   502             Registration r = new Registration(plugins, "com.sun.crypto.provider.CipherBlockChaining", replacements);
   491             String cbcDecryptName = implNames ? "implDecrypt" : "decrypt";
       
   492 
       
   493             r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcEncryptName, Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class);
   503             r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcEncryptName, Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class);
   494             r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, int.class, byte[].class,
   504             r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, int.class, byte[].class,
   495                             int.class);
   505                             int.class);
   496 
   506 
   497             r = new Registration(plugins, "com.sun.crypto.provider.AESCrypt", bytecodeProvider);
   507             String aesEncryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implEncryptBlock", "encryptBlock");
       
   508             String aesDecryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock");
       
   509 
       
   510             r = new Registration(plugins, "com.sun.crypto.provider.AESCrypt", replacements);
   498             r.registerMethodSubstitution(AESCryptSubstitutions.class, aesEncryptName, Receiver.class, byte[].class, int.class, byte[].class, int.class);
   511             r.registerMethodSubstitution(AESCryptSubstitutions.class, aesEncryptName, Receiver.class, byte[].class, int.class, byte[].class, int.class);
   499             r.registerMethodSubstitution(AESCryptSubstitutions.class, aesDecryptName, aesDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, byte[].class, int.class);
   512             r.registerMethodSubstitution(AESCryptSubstitutions.class, aesDecryptName, aesDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, byte[].class, int.class);
   500         }
   513         }
   501     }
   514     }
   502 
   515 
   503     private static void registerBigIntegerPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
   516     private static void registerBigIntegerPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
   504         Registration r = new Registration(plugins, BigInteger.class, bytecodeProvider);
   517         Registration r = new Registration(plugins, BigInteger.class, replacements);
   505         if (config.useMultiplyToLenIntrinsic()) {
   518         assert !config.useMultiplyToLenIntrinsic() || config.multiplyToLen != 0L;
   506             assert config.multiplyToLen != 0L;
   519         if (JavaVersionUtil.JAVA_SPEC <= 8) {
   507             if (JavaVersionUtil.JAVA_SPEC <= 8) {
   520             r.registerConditionalMethodSubstitution(config.useMultiplyToLenIntrinsic(), BigIntegerSubstitutions.class, "multiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class,
   508                 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "multiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class, int.class,
   521                             int.class, int[].class);
   509                                 int[].class);
   522         } else {
   510             } else {
   523             r.registerConditionalMethodSubstitution(config.useMultiplyToLenIntrinsic(), BigIntegerSubstitutions.class, "implMultiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class,
   511                 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMultiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class, int.class,
   524                             int.class, int[].class);
   512                                 int[].class);
   525         }
   513             }
   526         r.registerConditionalMethodSubstitution(config.useMulAddIntrinsic(), BigIntegerSubstitutions.class, "implMulAdd", int[].class, int[].class, int.class, int.class, int.class);
   514         }
   527         r.registerConditionalMethodSubstitution(config.useMontgomeryMultiplyIntrinsic(), BigIntegerSubstitutions.class, "implMontgomeryMultiply", int[].class, int[].class, int[].class, int.class,
   515         if (config.useMulAddIntrinsic()) {
   528                         long.class, int[].class);
   516             r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMulAdd", int[].class, int[].class, int.class, int.class, int.class);
   529         r.registerConditionalMethodSubstitution(config.useMontgomerySquareIntrinsic(), BigIntegerSubstitutions.class, "implMontgomerySquare", int[].class, int[].class, int.class, long.class,
   517         }
   530                         int[].class);
   518         if (config.useMontgomeryMultiplyIntrinsic()) {
   531         r.registerConditionalMethodSubstitution(config.useSquareToLenIntrinsic(), BigIntegerSubstitutions.class, "implSquareToLen", int[].class, int.class, int[].class, int.class);
   519             r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMontgomeryMultiply", int[].class, int[].class, int[].class, int.class, long.class, int[].class);
   532     }
   520         }
   533 
   521         if (config.useMontgomerySquareIntrinsic()) {
   534     private static void registerSHAPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
   522             r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMontgomerySquare", int[].class, int[].class, int.class, long.class, int[].class);
       
   523         }
       
   524         if (config.useSquareToLenIntrinsic()) {
       
   525             r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implSquareToLen", int[].class, int.class, int[].class, int.class);
       
   526         }
       
   527     }
       
   528 
       
   529     private static void registerSHAPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
       
   530         boolean useSha1 = config.useSHA1Intrinsics();
   535         boolean useSha1 = config.useSHA1Intrinsics();
   531         boolean useSha256 = config.useSHA256Intrinsics();
   536         boolean useSha256 = config.useSHA256Intrinsics();
   532         boolean useSha512 = config.useSHA512Intrinsics();
   537         boolean useSha512 = config.useSHA512Intrinsics();
   533 
   538 
   534         if (JavaVersionUtil.JAVA_SPEC > 8 && (useSha1 || useSha256 || useSha512)) {
   539         if (isIntrinsicName(config, "sun/security/provider/DigestBase", "implCompressMultiBlock0") && (useSha1 || useSha256 || useSha512)) {
   535             Registration r = new Registration(plugins, "sun.security.provider.DigestBase", bytecodeProvider);
   540             Registration r = new Registration(plugins, "sun.security.provider.DigestBase", replacements);
   536             r.registerMethodSubstitution(DigestBaseSubstitutions.class, "implCompressMultiBlock0", Receiver.class, byte[].class, int.class, int.class);
   541             r.registerMethodSubstitution(DigestBaseSubstitutions.class, "implCompressMultiBlock0", Receiver.class, byte[].class, int.class, int.class);
   537         }
   542         }
   538 
   543 
       
   544         String implCompressName = lookupIntrinsicName(config, "sun/security/provider/SHA", "implCompress", "implCompress0");
   539         if (useSha1) {
   545         if (useSha1) {
   540             assert config.sha1ImplCompress != 0L;
   546             assert config.sha1ImplCompress != 0L;
   541             Registration r = new Registration(plugins, "sun.security.provider.SHA", bytecodeProvider);
   547             Registration r = new Registration(plugins, "sun.security.provider.SHA", replacements);
   542             r.registerMethodSubstitution(SHASubstitutions.class, SHASubstitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
   548             r.registerMethodSubstitution(SHASubstitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
   543         }
   549         }
   544         if (useSha256) {
   550         if (useSha256) {
   545             assert config.sha256ImplCompress != 0L;
   551             assert config.sha256ImplCompress != 0L;
   546             Registration r = new Registration(plugins, "sun.security.provider.SHA2", bytecodeProvider);
   552             Registration r = new Registration(plugins, "sun.security.provider.SHA2", replacements);
   547             r.registerMethodSubstitution(SHA2Substitutions.class, SHA2Substitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
   553             r.registerMethodSubstitution(SHA2Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
   548         }
   554         }
   549         if (useSha512) {
   555         if (useSha512) {
   550             assert config.sha512ImplCompress != 0L;
   556             assert config.sha512ImplCompress != 0L;
   551             Registration r = new Registration(plugins, "sun.security.provider.SHA5", bytecodeProvider);
   557             Registration r = new Registration(plugins, "sun.security.provider.SHA5", replacements);
   552             r.registerMethodSubstitution(SHA5Substitutions.class, SHA5Substitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
   558             r.registerMethodSubstitution(SHA5Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
   553         }
   559         }
   554     }
   560     }
   555 
   561 
   556     private static void registerGHASHPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
   562     private static void registerGHASHPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
   557         if (config.useGHASHIntrinsics()) {
   563         if (config.useGHASHIntrinsics()) {
   584                                 }
   590                                 }
   585                             });
   591                             });
   586         }
   592         }
   587     }
   593     }
   588 
   594 
   589     private static void registerCounterModePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
   595     private static void registerCounterModePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
   590         if (config.useAESCTRIntrinsics) {
   596         if (JavaVersionUtil.JAVA_SPEC > 8) {
   591             assert config.counterModeAESCrypt != 0L;
   597             assert !config.useAESCTRIntrinsics || config.counterModeAESCrypt != 0L;
   592             Registration r = new Registration(plugins, "com.sun.crypto.provider.CounterMode", bytecodeProvider);
   598             Registration r = new Registration(plugins, "com.sun.crypto.provider.CounterMode", replacements);
   593             r.registerMethodSubstitution(CounterModeSubstitutions.class, "implCrypt", Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class);
   599             r.registerConditionalMethodSubstitution(config.useAESCTRIntrinsics, CounterModeSubstitutions.class, "implCrypt", Receiver.class, byte[].class, int.class, int.class, byte[].class,
       
   600                             int.class);
   594         }
   601         }
   595     }
   602     }
   596 
   603 
   597     private static void registerBase64Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
   604     private static void registerBase64Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
   598         if (config.useBase64Intrinsics()) {
   605         if (config.useBase64Intrinsics()) {
   624                                 }
   631                                 }
   625                             });
   632                             });
   626         }
   633         }
   627     }
   634     }
   628 
   635 
   629     private static void registerCRC32Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
   636     private static void registerCRC32Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
   630         if (config.useCRC32Intrinsics) {
   637         Registration r = new Registration(plugins, CRC32.class, replacements);
   631             Registration r = new Registration(plugins, CRC32.class, bytecodeProvider);
   638         r.registerConditionalMethodSubstitution(config.useCRC32Intrinsics, CRC32Substitutions.class, "update", int.class, int.class);
   632             r.registerMethodSubstitution(CRC32Substitutions.class, "update", int.class, int.class);
   639         if (JavaVersionUtil.JAVA_SPEC <= 8) {
   633             if (JavaVersionUtil.JAVA_SPEC <= 8) {
   640             r.registerConditionalMethodSubstitution(config.useCRC32Intrinsics, CRC32Substitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
   634                 r.registerMethodSubstitution(CRC32Substitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
   641             r.registerConditionalMethodSubstitution(config.useCRC32Intrinsics, CRC32Substitutions.class, "updateByteBuffer", int.class, long.class, int.class, int.class);
   635                 r.registerMethodSubstitution(CRC32Substitutions.class, "updateByteBuffer", int.class, long.class, int.class, int.class);
   642         } else {
   636             } else {
   643             r.registerConditionalMethodSubstitution(config.useCRC32Intrinsics, CRC32Substitutions.class, "updateBytes0", int.class, byte[].class, int.class, int.class);
   637                 r.registerMethodSubstitution(CRC32Substitutions.class, "updateBytes0", int.class, byte[].class, int.class, int.class);
   644             r.registerConditionalMethodSubstitution(config.useCRC32Intrinsics, CRC32Substitutions.class, "updateByteBuffer0", int.class, long.class, int.class, int.class);
   638                 r.registerMethodSubstitution(CRC32Substitutions.class, "updateByteBuffer0", int.class, long.class, int.class, int.class);
   645         }
   639             }
   646     }
   640         }
   647 
   641     }
   648     private static void registerCRC32CPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
   642 
   649         if (JavaVersionUtil.JAVA_SPEC > 8) {
   643     private static void registerCRC32CPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
   650             Registration r = new Registration(plugins, "java.util.zip.CRC32C", replacements);
   644         if (config.useCRC32CIntrinsics) {
   651             r.registerConditionalMethodSubstitution(config.useCRC32CIntrinsics, CRC32CSubstitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
   645             Registration r = new Registration(plugins, "java.util.zip.CRC32C", bytecodeProvider);
   652             r.registerConditionalMethodSubstitution(config.useCRC32CIntrinsics, CRC32CSubstitutions.class, "updateDirectByteBuffer", int.class, long.class, int.class, int.class);
   646             r.registerMethodSubstitution(CRC32CSubstitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
   653         }
   647             r.registerMethodSubstitution(CRC32CSubstitutions.class, "updateDirectByteBuffer", int.class, long.class, int.class, int.class);
   654     }
   648         }
   655 
   649     }
   656     private static void registerArraysSupportPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) {
   650 
   657         if (JavaVersionUtil.JAVA_SPEC > 8) {
   651     private static void registerArraysSupportPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
   658             Registration r = new Registration(plugins, "jdk.internal.util.ArraysSupport", replacements);
   652         if (config.useVectorizedMismatchIntrinsic) {
   659             r.registerConditionalMethodSubstitution(config.useVectorizedMismatchIntrinsic, ArraysSupportSubstitutions.class, "vectorizedMismatch", Object.class, long.class, Object.class, long.class,
   653             Registration r = new Registration(plugins, "jdk.internal.util.ArraysSupport", bytecodeProvider);
   660                             int.class, int.class);
   654             r.registerMethodSubstitution(ArraysSupportSubstitutions.class, "vectorizedMismatch", Object.class, long.class, Object.class, long.class, int.class, int.class);
       
   655         }
   661         }
   656     }
   662     }
   657 }
   663 }