src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java
changeset 58877 aec7bf35d6f5
parent 58299 6df94ce3ab2f
equal deleted inserted replaced
58876:1a8d65e71a66 58877:aec7bf35d6f5
    33 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
    33 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
    34 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
    34 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
    35 
    35 
    36 import java.util.Arrays;
    36 import java.util.Arrays;
    37 
    37 
    38 import org.graalvm.compiler.bytecode.BytecodeProvider;
       
    39 import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool.RoundingMode;
    38 import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool.RoundingMode;
    40 import org.graalvm.compiler.nodes.PauseNode;
    39 import org.graalvm.compiler.nodes.PauseNode;
    41 import org.graalvm.compiler.nodes.ValueNode;
    40 import org.graalvm.compiler.nodes.ValueNode;
    42 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
    41 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
    43 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
    42 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
    46 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
    45 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
    47 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
    46 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
    48 import org.graalvm.compiler.nodes.java.AtomicReadAndAddNode;
    47 import org.graalvm.compiler.nodes.java.AtomicReadAndAddNode;
    49 import org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode;
    48 import org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode;
    50 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
    49 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
       
    50 import org.graalvm.compiler.nodes.spi.Replacements;
    51 import org.graalvm.compiler.replacements.ArraysSubstitutions;
    51 import org.graalvm.compiler.replacements.ArraysSubstitutions;
    52 import org.graalvm.compiler.replacements.IntegerSubstitutions;
       
    53 import org.graalvm.compiler.replacements.LongSubstitutions;
       
    54 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafeAccessPlugin;
    52 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafeAccessPlugin;
    55 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafeGetPlugin;
    53 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafeGetPlugin;
    56 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafePutPlugin;
    54 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafePutPlugin;
    57 import org.graalvm.compiler.replacements.TargetGraphBuilderPlugins;
    55 import org.graalvm.compiler.replacements.TargetGraphBuilderPlugins;
    58 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
    56 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
    70 import jdk.vm.ci.meta.ResolvedJavaMethod;
    68 import jdk.vm.ci.meta.ResolvedJavaMethod;
    71 import sun.misc.Unsafe;
    69 import sun.misc.Unsafe;
    72 
    70 
    73 public class AMD64GraphBuilderPlugins implements TargetGraphBuilderPlugins {
    71 public class AMD64GraphBuilderPlugins implements TargetGraphBuilderPlugins {
    74     @Override
    72     @Override
    75     public void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, Architecture architecture, boolean explicitUnsafeNullChecks,
    73     public void register(Plugins plugins, Replacements replacements, Architecture architecture, boolean explicitUnsafeNullChecks,
    76                     boolean registerMathPlugins, boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) {
    74                     boolean registerMathPlugins, boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) {
    77         register(plugins, replacementsBytecodeProvider, (AMD64) architecture, explicitUnsafeNullChecks, emitJDK9StringSubstitutions, useFMAIntrinsics);
    75         register(plugins, replacements, (AMD64) architecture, explicitUnsafeNullChecks, emitJDK9StringSubstitutions, useFMAIntrinsics);
    78     }
    76     }
    79 
    77 
    80     public static void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, AMD64 arch, boolean explicitUnsafeNullChecks, boolean emitJDK9StringSubstitutions,
    78     public static void register(Plugins plugins, Replacements replacements, AMD64 arch, boolean explicitUnsafeNullChecks,
       
    79                     boolean emitJDK9StringSubstitutions,
    81                     boolean useFMAIntrinsics) {
    80                     boolean useFMAIntrinsics) {
    82         InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
    81         InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
    83         invocationPlugins.defer(new Runnable() {
    82         invocationPlugins.defer(new Runnable() {
    84             @Override
    83             @Override
    85             public void run() {
    84             public void run() {
    86                 registerThreadPlugins(invocationPlugins, arch);
    85                 registerThreadPlugins(invocationPlugins, arch);
    87                 registerIntegerLongPlugins(invocationPlugins, IntegerSubstitutions.class, JavaKind.Int, arch, replacementsBytecodeProvider);
    86                 registerIntegerLongPlugins(invocationPlugins, AMD64IntegerSubstitutions.class, JavaKind.Int, arch, replacements);
    88                 registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, JavaKind.Long, arch, replacementsBytecodeProvider);
    87                 registerIntegerLongPlugins(invocationPlugins, AMD64LongSubstitutions.class, JavaKind.Long, arch, replacements);
    89                 registerPlatformSpecificUnsafePlugins(invocationPlugins, replacementsBytecodeProvider, explicitUnsafeNullChecks,
    88                 registerPlatformSpecificUnsafePlugins(invocationPlugins, replacements, explicitUnsafeNullChecks,
    90                                 new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object, JavaKind.Boolean, JavaKind.Byte, JavaKind.Short, JavaKind.Char, JavaKind.Float, JavaKind.Double});
    89                                 new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object, JavaKind.Boolean, JavaKind.Byte, JavaKind.Short, JavaKind.Char, JavaKind.Float, JavaKind.Double});
    91                 registerUnsafePlugins(invocationPlugins, replacementsBytecodeProvider, explicitUnsafeNullChecks);
    90                 registerUnsafePlugins(invocationPlugins, replacements, explicitUnsafeNullChecks);
    92                 registerStringPlugins(invocationPlugins, replacementsBytecodeProvider);
    91                 registerStringPlugins(invocationPlugins, replacements);
    93                 if (emitJDK9StringSubstitutions) {
    92                 if (emitJDK9StringSubstitutions) {
    94                     registerStringLatin1Plugins(invocationPlugins, replacementsBytecodeProvider);
    93                     registerStringLatin1Plugins(invocationPlugins, replacements);
    95                     registerStringUTF16Plugins(invocationPlugins, replacementsBytecodeProvider);
    94                     registerStringUTF16Plugins(invocationPlugins, replacements);
    96                 }
    95                 }
    97                 registerMathPlugins(invocationPlugins, useFMAIntrinsics, arch, replacementsBytecodeProvider);
    96                 registerMathPlugins(invocationPlugins, useFMAIntrinsics, arch, replacements);
    98                 registerArraysEqualsPlugins(invocationPlugins, replacementsBytecodeProvider);
    97                 registerArraysEqualsPlugins(invocationPlugins, replacements);
    99             }
    98             }
   100         });
    99         });
   101     }
   100     }
   102 
   101 
   103     private static void registerThreadPlugins(InvocationPlugins plugins, AMD64 arch) {
   102     private static void registerThreadPlugins(InvocationPlugins plugins, AMD64 arch) {
   104         if (JavaVersionUtil.JAVA_SPEC > 8) {
   103         if (JavaVersionUtil.JAVA_SPEC > 8) {
   105             // Pause instruction introduced with SSE2
   104             // Pause instruction introduced with SSE2
   106             if (arch.getFeatures().contains(AMD64.CPUFeature.SSE2)) {
   105             assert (arch.getFeatures().contains(AMD64.CPUFeature.SSE2));
   107                 Registration r = new Registration(plugins, Thread.class);
   106             Registration r = new Registration(plugins, Thread.class);
   108                 r.register0("onSpinWait", new InvocationPlugin() {
   107             r.register0("onSpinWait", new InvocationPlugin() {
   109                     @Override
       
   110                     public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
       
   111                         b.append(new PauseNode());
       
   112                         return true;
       
   113                     }
       
   114                 });
       
   115             }
       
   116         }
       
   117     }
       
   118 
       
   119     private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, JavaKind kind, AMD64 arch, BytecodeProvider bytecodeProvider) {
       
   120         Class<?> declaringClass = kind.toBoxedJavaClass();
       
   121         Class<?> type = kind.toJavaClass();
       
   122         Registration r = new Registration(plugins, declaringClass, bytecodeProvider);
       
   123         r.registerMethodSubstitution(substituteDeclaringClass, "numberOfLeadingZeros", type);
       
   124         if (arch.getFeatures().contains(AMD64.CPUFeature.LZCNT) && arch.getFlags().contains(AMD64.Flag.UseCountLeadingZerosInstruction)) {
       
   125             r.setAllowOverwrite(true);
       
   126             r.register1("numberOfLeadingZeros", type, new InvocationPlugin() {
       
   127                 @Override
   108                 @Override
   128                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
   109                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
   129                     ValueNode folded = AMD64CountLeadingZerosNode.tryFold(value);
   110                     b.append(new PauseNode());
   130                     if (folded != null) {
       
   131                         b.addPush(JavaKind.Int, folded);
       
   132                     } else {
       
   133                         b.addPush(JavaKind.Int, new AMD64CountLeadingZerosNode(value));
       
   134                     }
       
   135                     return true;
   111                     return true;
   136                 }
   112                 }
   137             });
   113             });
   138         }
   114         }
   139 
   115     }
       
   116 
       
   117     private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, JavaKind kind, AMD64 arch, Replacements replacements) {
       
   118         Class<?> declaringClass = kind.toBoxedJavaClass();
       
   119         Class<?> type = kind.toJavaClass();
       
   120         Registration r = new Registration(plugins, declaringClass, replacements);
       
   121         r.registerMethodSubstitution(substituteDeclaringClass, "numberOfLeadingZeros", type);
   140         r.registerMethodSubstitution(substituteDeclaringClass, "numberOfTrailingZeros", type);
   122         r.registerMethodSubstitution(substituteDeclaringClass, "numberOfTrailingZeros", type);
   141         if (arch.getFeatures().contains(AMD64.CPUFeature.BMI1) && arch.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction)) {
   123 
   142             r.setAllowOverwrite(true);
   124         r.registerConditional1(arch.getFeatures().contains(AMD64.CPUFeature.POPCNT),
   143             r.register1("numberOfTrailingZeros", type, new InvocationPlugin() {
   125                         "bitCount", type, new InvocationPlugin() {
   144 
   126                             @Override
   145                 @Override
   127                             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
   146                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
   128                                 b.push(JavaKind.Int, b.append(new BitCountNode(value).canonical(null)));
   147                     ValueNode folded = AMD64CountTrailingZerosNode.tryFold(value);
   129                                 return true;
   148                     if (folded != null) {
   130                             }
   149                         b.addPush(JavaKind.Int, folded);
   131                         });
   150                     } else {
   132     }
   151                         b.addPush(JavaKind.Int, new AMD64CountTrailingZerosNode(value));
   133 
   152                     }
   134     private static void registerMathPlugins(InvocationPlugins plugins, boolean useFMAIntrinsics, AMD64 arch, Replacements replacements) {
   153                     return true;
   135         Registration r = new Registration(plugins, Math.class, replacements);
   154                 }
       
   155             });
       
   156         }
       
   157 
       
   158         if (arch.getFeatures().contains(AMD64.CPUFeature.POPCNT)) {
       
   159             r.register1("bitCount", type, new InvocationPlugin() {
       
   160                 @Override
       
   161                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
       
   162                     b.push(JavaKind.Int, b.append(new BitCountNode(value).canonical(null)));
       
   163                     return true;
       
   164                 }
       
   165             });
       
   166         }
       
   167 
       
   168     }
       
   169 
       
   170     private static void registerMathPlugins(InvocationPlugins plugins, boolean useFMAIntrinsics, AMD64 arch, BytecodeProvider bytecodeProvider) {
       
   171         Registration r = new Registration(plugins, Math.class, bytecodeProvider);
       
   172         registerUnaryMath(r, "log", LOG);
   136         registerUnaryMath(r, "log", LOG);
   173         registerUnaryMath(r, "log10", LOG10);
   137         registerUnaryMath(r, "log10", LOG10);
   174         registerUnaryMath(r, "exp", EXP);
   138         registerUnaryMath(r, "exp", EXP);
   175         registerBinaryMath(r, "pow", POW);
   139         registerBinaryMath(r, "pow", POW);
   176         registerUnaryMath(r, "sin", SIN);
   140         registerUnaryMath(r, "sin", SIN);
   177         registerUnaryMath(r, "cos", COS);
   141         registerUnaryMath(r, "cos", COS);
   178         registerUnaryMath(r, "tan", TAN);
   142         registerUnaryMath(r, "tan", TAN);
   179 
   143 
   180         if (arch.getFeatures().contains(CPUFeature.SSE4_1)) {
   144         boolean roundEnabled = arch.getFeatures().contains(CPUFeature.SSE4_1);
   181             registerRound(r, "rint", RoundingMode.NEAREST);
   145         registerRound(roundEnabled, r, "rint", RoundingMode.NEAREST);
   182             registerRound(r, "ceil", RoundingMode.UP);
   146         registerRound(roundEnabled, r, "ceil", RoundingMode.UP);
   183             registerRound(r, "floor", RoundingMode.DOWN);
   147         registerRound(roundEnabled, r, "floor", RoundingMode.DOWN);
   184         }
   148 
   185 
   149         if (JavaVersionUtil.JAVA_SPEC > 8) {
   186         if (useFMAIntrinsics && JavaVersionUtil.JAVA_SPEC > 8 && arch.getFeatures().contains(CPUFeature.FMA)) {
   150             registerFMA(r, useFMAIntrinsics && arch.getFeatures().contains(CPUFeature.FMA));
   187             registerFMA(r);
   151         }
   188         }
   152     }
   189     }
   153 
   190 
   154     private static void registerFMA(Registration r, boolean isEnabled) {
   191     private static void registerFMA(Registration r) {
   155         r.registerConditional3(isEnabled, "fma",
   192         r.register3("fma",
       
   193                         Double.TYPE,
   156                         Double.TYPE,
   194                         Double.TYPE,
   157                         Double.TYPE,
   195                         Double.TYPE,
   158                         Double.TYPE,
   196                         new InvocationPlugin() {
   159                         new InvocationPlugin() {
   197                             @Override
   160                             @Override
   203                                             ValueNode nc) {
   166                                             ValueNode nc) {
   204                                 b.push(JavaKind.Double, b.append(new FusedMultiplyAddNode(na, nb, nc)));
   167                                 b.push(JavaKind.Double, b.append(new FusedMultiplyAddNode(na, nb, nc)));
   205                                 return true;
   168                                 return true;
   206                             }
   169                             }
   207                         });
   170                         });
   208         r.register3("fma",
   171         r.registerConditional3(isEnabled, "fma",
   209                         Float.TYPE,
   172                         Float.TYPE,
   210                         Float.TYPE,
   173                         Float.TYPE,
   211                         Float.TYPE,
   174                         Float.TYPE,
   212                         new InvocationPlugin() {
   175                         new InvocationPlugin() {
   213                             @Override
   176                             @Override
   241                 return true;
   204                 return true;
   242             }
   205             }
   243         });
   206         });
   244     }
   207     }
   245 
   208 
   246     private static void registerRound(Registration r, String name, RoundingMode mode) {
   209     private static void registerRound(boolean isEnabled, Registration r, String name, RoundingMode mode) {
   247         r.register1(name, Double.TYPE, new InvocationPlugin() {
   210         r.registerConditional1(isEnabled, name, Double.TYPE, new InvocationPlugin() {
   248             @Override
   211             @Override
   249             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
   212             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
   250                 b.push(JavaKind.Double, b.append(new AMD64RoundNode(arg, mode)));
   213                 b.push(JavaKind.Double, b.append(new AMD64RoundNode(arg, mode)));
   251                 return true;
   214                 return true;
   252             }
   215             }
   253         });
   216         });
   254     }
   217     }
   255 
   218 
   256     private static void registerStringPlugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
   219     private static void registerStringPlugins(InvocationPlugins plugins, Replacements replacements) {
   257         if (JavaVersionUtil.JAVA_SPEC <= 8) {
   220         if (JavaVersionUtil.JAVA_SPEC <= 8) {
   258             Registration r;
   221             Registration r;
   259             r = new Registration(plugins, String.class, replacementsBytecodeProvider);
   222             r = new Registration(plugins, String.class, replacements);
   260             r.setAllowOverwrite(true);
   223             r.setAllowOverwrite(true);
   261             r.registerMethodSubstitution(AMD64StringSubstitutions.class, "indexOf", char[].class, int.class,
   224             r.registerMethodSubstitution(AMD64StringSubstitutions.class, "indexOf", char[].class, int.class,
   262                             int.class, char[].class, int.class, int.class, int.class);
   225                             int.class, char[].class, int.class, int.class, int.class);
   263             r.registerMethodSubstitution(AMD64StringSubstitutions.class, "indexOf", Receiver.class, int.class, int.class);
   226             r.registerMethodSubstitution(AMD64StringSubstitutions.class, "indexOf", Receiver.class, int.class, int.class);
   264             r.registerMethodSubstitution(AMD64StringSubstitutions.class, "compareTo", Receiver.class, String.class);
   227             r.registerMethodSubstitution(AMD64StringSubstitutions.class, "compareTo", Receiver.class, String.class);
   265         }
   228         }
   266     }
   229     }
   267 
   230 
   268     private static void registerStringLatin1Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
   231     private static void registerStringLatin1Plugins(InvocationPlugins plugins, Replacements replacements) {
   269         Registration r = new Registration(plugins, "java.lang.StringLatin1", replacementsBytecodeProvider);
   232         Registration r = new Registration(plugins, "java.lang.StringLatin1", replacements);
   270         r.setAllowOverwrite(true);
   233         r.setAllowOverwrite(true);
   271         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class);
   234         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class);
   272         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class);
   235         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class);
   273         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "inflate", byte[].class, int.class, char[].class, int.class, int.class);
   236         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "inflate", byte[].class, int.class, char[].class, int.class, int.class);
   274         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "inflate", byte[].class, int.class, byte[].class, int.class, int.class);
   237         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "inflate", byte[].class, int.class, byte[].class, int.class, int.class);
   275         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "indexOf", byte[].class, int.class, int.class);
   238         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "indexOf", byte[].class, int.class, int.class);
   276         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "indexOf", byte[].class, int.class, byte[].class, int.class, int.class);
   239         r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "indexOf", byte[].class, int.class, byte[].class, int.class, int.class);
   277     }
   240     }
   278 
   241 
   279     private static void registerStringUTF16Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
   242     private static void registerStringUTF16Plugins(InvocationPlugins plugins, Replacements replacements) {
   280         Registration r = new Registration(plugins, "java.lang.StringUTF16", replacementsBytecodeProvider);
   243         Registration r = new Registration(plugins, "java.lang.StringUTF16", replacements);
   281         r.setAllowOverwrite(true);
   244         r.setAllowOverwrite(true);
   282         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class);
   245         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class);
   283         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class);
   246         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class);
   284         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compress", char[].class, int.class, byte[].class, int.class, int.class);
   247         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compress", char[].class, int.class, byte[].class, int.class, int.class);
   285         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compress", byte[].class, int.class, byte[].class, int.class, int.class);
   248         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compress", byte[].class, int.class, byte[].class, int.class, int.class);
   286         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfCharUnsafe", byte[].class, int.class, int.class, int.class);
   249         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfCharUnsafe", byte[].class, int.class, int.class, int.class);
   287         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfUnsafe", byte[].class, int.class, byte[].class, int.class, int.class);
   250         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfUnsafe", byte[].class, int.class, byte[].class, int.class, int.class);
   288         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfLatin1Unsafe", byte[].class, int.class, byte[].class, int.class, int.class);
   251         r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfLatin1Unsafe", byte[].class, int.class, byte[].class, int.class, int.class);
   289     }
   252     }
   290 
   253 
   291     private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider, boolean explicitUnsafeNullChecks) {
   254     private static void registerUnsafePlugins(InvocationPlugins plugins, Replacements replacements, boolean explicitUnsafeNullChecks) {
   292         registerUnsafePlugins(new Registration(plugins, Unsafe.class), explicitUnsafeNullChecks, new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, true);
   255         registerUnsafePlugins(new Registration(plugins, Unsafe.class), explicitUnsafeNullChecks, new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, true);
   293         if (JavaVersionUtil.JAVA_SPEC > 8) {
   256         if (JavaVersionUtil.JAVA_SPEC > 8) {
   294             registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacementsBytecodeProvider), explicitUnsafeNullChecks,
   257             registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacements), explicitUnsafeNullChecks,
   295                             new JavaKind[]{JavaKind.Boolean, JavaKind.Byte, JavaKind.Char, JavaKind.Short, JavaKind.Int, JavaKind.Long, JavaKind.Object},
   258                             new JavaKind[]{JavaKind.Boolean, JavaKind.Byte, JavaKind.Char, JavaKind.Short, JavaKind.Int, JavaKind.Long, JavaKind.Object},
   296                             JavaVersionUtil.JAVA_SPEC <= 11);
   259                             JavaVersionUtil.JAVA_SPEC <= 11);
   297         }
   260         }
   298     }
   261     }
   299 
   262 
   328             r.registerOptional3("get" + kind.name() + "Unaligned", Receiver.class, Object.class, long.class, new UnsafeGetPlugin(kind, explicitUnsafeNullChecks));
   291             r.registerOptional3("get" + kind.name() + "Unaligned", Receiver.class, Object.class, long.class, new UnsafeGetPlugin(kind, explicitUnsafeNullChecks));
   329             r.registerOptional4("put" + kind.name() + "Unaligned", Receiver.class, Object.class, long.class, javaClass, new UnsafePutPlugin(kind, explicitUnsafeNullChecks));
   292             r.registerOptional4("put" + kind.name() + "Unaligned", Receiver.class, Object.class, long.class, javaClass, new UnsafePutPlugin(kind, explicitUnsafeNullChecks));
   330         }
   293         }
   331     }
   294     }
   332 
   295 
   333     private static void registerArraysEqualsPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
   296     private static void registerArraysEqualsPlugins(InvocationPlugins plugins, Replacements replacements) {
   334         Registration r = new Registration(plugins, Arrays.class, bytecodeProvider);
   297         Registration r = new Registration(plugins, Arrays.class, replacements);
   335         r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", float[].class, float[].class);
   298         r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", float[].class, float[].class);
   336         r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", double[].class, double[].class);
   299         r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", double[].class, double[].class);
   337     }
   300     }
   338 }
   301 }