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 */
23
24
25 package org.graalvm.compiler.hotspot.meta;
26
27 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
28 import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Options.TieredAOT;
29 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.JAVA_THREAD_THREAD_OBJECT_LOCATION;
30 import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
31 import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier;
32
33 import java.lang.invoke.ConstantCallSite;
34 import java.lang.invoke.MutableCallSite;
35 import java.lang.invoke.VolatileCallSite;
36 import java.lang.reflect.Array;
37 import java.math.BigInteger;
38 import java.util.zip.CRC32;
39
40 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
41 import org.graalvm.compiler.bytecode.BytecodeProvider;
42 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
43 import org.graalvm.compiler.core.common.type.ObjectStamp;
44 import org.graalvm.compiler.core.common.type.StampFactory;
45 import org.graalvm.compiler.core.common.type.TypeReference;
46 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
47 import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
48 import org.graalvm.compiler.hotspot.replacements.AESCryptSubstitutions;
49 import org.graalvm.compiler.hotspot.replacements.BigIntegerSubstitutions;
50 import org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions;
51 import org.graalvm.compiler.hotspot.replacements.CRC32Substitutions;
52 import org.graalvm.compiler.hotspot.replacements.CallSiteTargetNode;
53 import org.graalvm.compiler.hotspot.replacements.CipherBlockChainingSubstitutions;
54 import org.graalvm.compiler.hotspot.replacements.ClassGetHubNode;
55 import org.graalvm.compiler.hotspot.replacements.HotSpotArraySubstitutions;
56 import org.graalvm.compiler.hotspot.replacements.HotSpotClassSubstitutions;
57 import org.graalvm.compiler.hotspot.replacements.IdentityHashCodeNode;
58 import org.graalvm.compiler.hotspot.replacements.ObjectCloneNode;
59 import org.graalvm.compiler.hotspot.replacements.ObjectSubstitutions;
60 import org.graalvm.compiler.hotspot.replacements.ReflectionGetCallerClassNode;
61 import org.graalvm.compiler.hotspot.replacements.ReflectionSubstitutions;
62 import org.graalvm.compiler.hotspot.replacements.SHA2Substitutions;
63 import org.graalvm.compiler.hotspot.replacements.SHA5Substitutions;
64 import org.graalvm.compiler.hotspot.replacements.SHASubstitutions;
65 import org.graalvm.compiler.hotspot.replacements.ThreadSubstitutions;
66 import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
67 import org.graalvm.compiler.nodes.ConstantNode;
68 import org.graalvm.compiler.nodes.NamedLocationIdentity;
69 import org.graalvm.compiler.nodes.NodeView;
70 import org.graalvm.compiler.nodes.ValueNode;
71 import org.graalvm.compiler.nodes.calc.AddNode;
72 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
73 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
74 import org.graalvm.compiler.nodes.graphbuilderconf.ForeignCallPlugin;
75 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
76 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
77 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
78 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver;
79 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
80 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
81 import org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;
82 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
83 import org.graalvm.compiler.nodes.memory.ReadNode;
84 import org.graalvm.compiler.nodes.memory.address.AddressNode;
85 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
86 import org.graalvm.compiler.nodes.util.GraphUtil;
87 import org.graalvm.compiler.options.OptionValues;
88 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
89 import org.graalvm.compiler.replacements.InlineDuringParsingPlugin;
90 import org.graalvm.compiler.replacements.MethodHandlePlugin;
91 import org.graalvm.compiler.replacements.NodeIntrinsificationProvider;
92 import org.graalvm.compiler.replacements.ReplacementsImpl;
93 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins;
146
147 invocationPlugins.defer(new Runnable() {
148
149 @Override
150 public void run() {
151 BytecodeProvider replacementBytecodeProvider = replacements.getDefaultReplacementBytecodeProvider();
152 registerObjectPlugins(invocationPlugins, options, config, replacementBytecodeProvider);
153 registerClassPlugins(plugins, config, replacementBytecodeProvider);
154 registerSystemPlugins(invocationPlugins, foreignCalls);
155 registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config, replacementBytecodeProvider);
156 if (!GeneratePIC.getValue(options)) {
157 registerCallSitePlugins(invocationPlugins);
158 }
159 registerReflectionPlugins(invocationPlugins, replacementBytecodeProvider);
160 registerConstantPoolPlugins(invocationPlugins, wordTypes, config, replacementBytecodeProvider);
161 registerAESPlugins(invocationPlugins, config, replacementBytecodeProvider);
162 registerCRC32Plugins(invocationPlugins, config, replacementBytecodeProvider);
163 registerCRC32CPlugins(invocationPlugins, config, replacementBytecodeProvider);
164 registerBigIntegerPlugins(invocationPlugins, config, replacementBytecodeProvider);
165 registerSHAPlugins(invocationPlugins, config, replacementBytecodeProvider);
166 registerUnsafePlugins(invocationPlugins, replacementBytecodeProvider);
167 StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacementBytecodeProvider, true, false);
168 registerArrayPlugins(invocationPlugins, replacementBytecodeProvider);
169
170 for (NodeIntrinsicPluginFactory factory : GraalServices.load(NodeIntrinsicPluginFactory.class)) {
171 factory.registerPlugins(invocationPlugins, nodeIntrinsificationProvider);
172 }
173 }
174 });
175 return plugins;
176 }
177
178 private static void registerObjectPlugins(InvocationPlugins plugins, OptionValues options, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
179 Registration r = new Registration(plugins, Object.class, bytecodeProvider);
180 if (!GeneratePIC.getValue(options)) {
181 // FIXME: clone() requires speculation and requires a fix in here (to check that
182 // b.getAssumptions() != null), and in ReplacementImpl.getSubstitution() where there is
183 // an instantiation of IntrinsicGraphBuilder using a constructor that sets
184 // AllowAssumptions to YES automatically. The former has to inherit the assumptions
185 // settings from the root compile instead. So, for now, I'm disabling it for
186 // GeneratePIC.
187 r.register1("clone", Receiver.class, new InvocationPlugin() {
188 @Override
371 r.register5("arraycopy", Object.class, int.class, Object.class, int.class, int.class, new InvocationPlugin() {
372 @Override
373 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode src, ValueNode srcPos, ValueNode dst, ValueNode dstPos, ValueNode length) {
374 b.add(new ArrayCopyNode(b.bci(), src, srcPos, dst, dstPos, length));
375 return true;
376 }
377
378 @Override
379 public boolean inlineOnly() {
380 return true;
381 }
382 });
383 }
384
385 private static void registerArrayPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
386 Registration r = new Registration(plugins, Array.class, bytecodeProvider);
387 r.setAllowOverwrite(true);
388 r.registerMethodSubstitution(HotSpotArraySubstitutions.class, "newInstance", Class.class, int.class);
389 }
390
391 private static void registerThreadPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, WordTypes wordTypes, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
392 Registration r = new Registration(plugins, Thread.class, bytecodeProvider);
393 r.register0("currentThread", new InvocationPlugin() {
394 @Override
395 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
396 CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(wordTypes.getWordKind()));
397 ValueNode offset = b.add(ConstantNode.forLong(config.threadObjectOffset));
398 AddressNode address = b.add(new OffsetAddressNode(thread, offset));
399 // JavaThread::_threadObj is never compressed
400 ObjectStamp stamp = StampFactory.objectNonNull(TypeReference.create(b.getAssumptions(), metaAccess.lookupJavaType(Thread.class)));
401 b.addPush(JavaKind.Object, new ReadNode(address, JAVA_THREAD_THREAD_OBJECT_LOCATION, stamp, BarrierType.NONE));
402 return true;
403 }
404 });
405
406 r.registerMethodSubstitution(ThreadSubstitutions.class, "isInterrupted", Receiver.class, boolean.class);
407 }
408
409 public static final String cbcEncryptName;
410 public static final String cbcDecryptName;
460 } else {
461 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMultiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class, int.class,
462 int[].class);
463 }
464 }
465 if (config.useMulAddIntrinsic()) {
466 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMulAdd", int[].class, int[].class, int.class, int.class, int.class);
467 }
468 if (config.useMontgomeryMultiplyIntrinsic()) {
469 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMontgomeryMultiply", int[].class, int[].class, int[].class, int.class, long.class, int[].class);
470 }
471 if (config.useMontgomerySquareIntrinsic()) {
472 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMontgomerySquare", int[].class, int[].class, int.class, long.class, int[].class);
473 }
474 if (config.useSquareToLenIntrinsic()) {
475 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implSquareToLen", int[].class, int.class, int[].class, int.class);
476 }
477 }
478
479 private static void registerSHAPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
480 if (config.useSHA1Intrinsics()) {
481 assert config.sha1ImplCompress != 0L;
482 Registration r = new Registration(plugins, "sun.security.provider.SHA", bytecodeProvider);
483 r.registerMethodSubstitution(SHASubstitutions.class, SHASubstitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
484 }
485 if (config.useSHA256Intrinsics()) {
486 assert config.sha256ImplCompress != 0L;
487 Registration r = new Registration(plugins, "sun.security.provider.SHA2", bytecodeProvider);
488 r.registerMethodSubstitution(SHA2Substitutions.class, SHA2Substitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
489 }
490 if (config.useSHA512Intrinsics()) {
491 assert config.sha512ImplCompress != 0L;
492 Registration r = new Registration(plugins, "sun.security.provider.SHA5", bytecodeProvider);
493 r.registerMethodSubstitution(SHA5Substitutions.class, SHA5Substitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
494 }
495 }
496
497 private static void registerCRC32Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
498 if (config.useCRC32Intrinsics) {
499 Registration r = new Registration(plugins, CRC32.class, bytecodeProvider);
500 r.registerMethodSubstitution(CRC32Substitutions.class, "update", int.class, int.class);
501 if (Java8OrEarlier) {
502 r.registerMethodSubstitution(CRC32Substitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
503 r.registerMethodSubstitution(CRC32Substitutions.class, "updateByteBuffer", int.class, long.class, int.class, int.class);
504 } else {
505 r.registerMethodSubstitution(CRC32Substitutions.class, "updateBytes0", int.class, byte[].class, int.class, int.class);
506 r.registerMethodSubstitution(CRC32Substitutions.class, "updateByteBuffer0", int.class, long.class, int.class, int.class);
507 }
508 }
509 }
510
511 private static void registerCRC32CPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
512 if (config.useCRC32CIntrinsics) {
513 Registration r = new Registration(plugins, "java.util.zip.CRC32C", bytecodeProvider);
514 r.registerMethodSubstitution(CRC32CSubstitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
515 r.registerMethodSubstitution(CRC32CSubstitutions.class, "updateDirectByteBuffer", int.class, long.class, int.class, int.class);
516 }
517 }
518 }
|
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 */
23
24
25 package org.graalvm.compiler.hotspot.meta;
26
27 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
28 import static org.graalvm.compiler.hotspot.HotSpotBackend.GHASH_PROCESS_BLOCKS;
29 import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Options.TieredAOT;
30 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.JAVA_THREAD_THREAD_OBJECT_LOCATION;
31 import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
32 import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
33
34 import java.lang.invoke.ConstantCallSite;
35 import java.lang.invoke.MutableCallSite;
36 import java.lang.invoke.VolatileCallSite;
37 import java.lang.reflect.Array;
38 import java.math.BigInteger;
39 import java.util.zip.CRC32;
40
41 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
42 import org.graalvm.compiler.bytecode.BytecodeProvider;
43 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
44 import org.graalvm.compiler.core.common.type.ObjectStamp;
45 import org.graalvm.compiler.core.common.type.StampFactory;
46 import org.graalvm.compiler.core.common.type.TypeReference;
47 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
48 import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
49 import org.graalvm.compiler.hotspot.replacements.AESCryptSubstitutions;
50 import org.graalvm.compiler.hotspot.replacements.ArraysSupportSubstitutions;
51 import org.graalvm.compiler.hotspot.replacements.BigIntegerSubstitutions;
52 import org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions;
53 import org.graalvm.compiler.hotspot.replacements.CRC32Substitutions;
54 import org.graalvm.compiler.hotspot.replacements.CallSiteTargetNode;
55 import org.graalvm.compiler.hotspot.replacements.CipherBlockChainingSubstitutions;
56 import org.graalvm.compiler.hotspot.replacements.ClassGetHubNode;
57 import org.graalvm.compiler.hotspot.replacements.CounterModeSubstitutions;
58 import org.graalvm.compiler.hotspot.replacements.DigestBaseSubstitutions;
59 import org.graalvm.compiler.hotspot.replacements.HotSpotArraySubstitutions;
60 import org.graalvm.compiler.hotspot.replacements.HotSpotClassSubstitutions;
61 import org.graalvm.compiler.hotspot.replacements.IdentityHashCodeNode;
62 import org.graalvm.compiler.hotspot.replacements.ObjectCloneNode;
63 import org.graalvm.compiler.hotspot.replacements.ObjectSubstitutions;
64 import org.graalvm.compiler.hotspot.replacements.ReflectionGetCallerClassNode;
65 import org.graalvm.compiler.hotspot.replacements.ReflectionSubstitutions;
66 import org.graalvm.compiler.hotspot.replacements.SHA2Substitutions;
67 import org.graalvm.compiler.hotspot.replacements.SHA5Substitutions;
68 import org.graalvm.compiler.hotspot.replacements.SHASubstitutions;
69 import org.graalvm.compiler.hotspot.replacements.StringUTF16Substitutions;
70 import org.graalvm.compiler.hotspot.replacements.ThreadSubstitutions;
71 import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
72 import org.graalvm.compiler.nodes.ComputeObjectAddressNode;
73 import org.graalvm.compiler.nodes.ConstantNode;
74 import org.graalvm.compiler.nodes.NamedLocationIdentity;
75 import org.graalvm.compiler.nodes.NodeView;
76 import org.graalvm.compiler.nodes.ValueNode;
77 import org.graalvm.compiler.nodes.calc.AddNode;
78 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
79 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
80 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
81 import org.graalvm.compiler.nodes.graphbuilderconf.ForeignCallPlugin;
82 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
83 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
84 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
85 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver;
86 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
87 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
88 import org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;
89 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
90 import org.graalvm.compiler.nodes.memory.ReadNode;
91 import org.graalvm.compiler.nodes.memory.address.AddressNode;
92 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
93 import org.graalvm.compiler.nodes.util.GraphUtil;
94 import org.graalvm.compiler.options.OptionValues;
95 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
96 import org.graalvm.compiler.replacements.InlineDuringParsingPlugin;
97 import org.graalvm.compiler.replacements.MethodHandlePlugin;
98 import org.graalvm.compiler.replacements.NodeIntrinsificationProvider;
99 import org.graalvm.compiler.replacements.ReplacementsImpl;
100 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins;
153
154 invocationPlugins.defer(new Runnable() {
155
156 @Override
157 public void run() {
158 BytecodeProvider replacementBytecodeProvider = replacements.getDefaultReplacementBytecodeProvider();
159 registerObjectPlugins(invocationPlugins, options, config, replacementBytecodeProvider);
160 registerClassPlugins(plugins, config, replacementBytecodeProvider);
161 registerSystemPlugins(invocationPlugins, foreignCalls);
162 registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config, replacementBytecodeProvider);
163 if (!GeneratePIC.getValue(options)) {
164 registerCallSitePlugins(invocationPlugins);
165 }
166 registerReflectionPlugins(invocationPlugins, replacementBytecodeProvider);
167 registerConstantPoolPlugins(invocationPlugins, wordTypes, config, replacementBytecodeProvider);
168 registerAESPlugins(invocationPlugins, config, replacementBytecodeProvider);
169 registerCRC32Plugins(invocationPlugins, config, replacementBytecodeProvider);
170 registerCRC32CPlugins(invocationPlugins, config, replacementBytecodeProvider);
171 registerBigIntegerPlugins(invocationPlugins, config, replacementBytecodeProvider);
172 registerSHAPlugins(invocationPlugins, config, replacementBytecodeProvider);
173 registerGHASHPlugins(invocationPlugins, config, metaAccess, foreignCalls);
174 registerCounterModePlugins(invocationPlugins, config, replacementBytecodeProvider);
175 registerUnsafePlugins(invocationPlugins, replacementBytecodeProvider);
176 StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacementBytecodeProvider, true, false);
177 registerArrayPlugins(invocationPlugins, replacementBytecodeProvider);
178 registerStringPlugins(invocationPlugins, replacementBytecodeProvider);
179 registerArraysSupportPlugins(invocationPlugins, config, replacementBytecodeProvider);
180
181 for (NodeIntrinsicPluginFactory factory : GraalServices.load(NodeIntrinsicPluginFactory.class)) {
182 factory.registerPlugins(invocationPlugins, nodeIntrinsificationProvider);
183 }
184 }
185 });
186 return plugins;
187 }
188
189 private static void registerObjectPlugins(InvocationPlugins plugins, OptionValues options, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
190 Registration r = new Registration(plugins, Object.class, bytecodeProvider);
191 if (!GeneratePIC.getValue(options)) {
192 // FIXME: clone() requires speculation and requires a fix in here (to check that
193 // b.getAssumptions() != null), and in ReplacementImpl.getSubstitution() where there is
194 // an instantiation of IntrinsicGraphBuilder using a constructor that sets
195 // AllowAssumptions to YES automatically. The former has to inherit the assumptions
196 // settings from the root compile instead. So, for now, I'm disabling it for
197 // GeneratePIC.
198 r.register1("clone", Receiver.class, new InvocationPlugin() {
199 @Override
382 r.register5("arraycopy", Object.class, int.class, Object.class, int.class, int.class, new InvocationPlugin() {
383 @Override
384 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode src, ValueNode srcPos, ValueNode dst, ValueNode dstPos, ValueNode length) {
385 b.add(new ArrayCopyNode(b.bci(), src, srcPos, dst, dstPos, length));
386 return true;
387 }
388
389 @Override
390 public boolean inlineOnly() {
391 return true;
392 }
393 });
394 }
395
396 private static void registerArrayPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
397 Registration r = new Registration(plugins, Array.class, bytecodeProvider);
398 r.setAllowOverwrite(true);
399 r.registerMethodSubstitution(HotSpotArraySubstitutions.class, "newInstance", Class.class, int.class);
400 }
401
402 private static void registerStringPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
403 if (!Java8OrEarlier) {
404 final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", bytecodeProvider);
405 utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "toBytes", char[].class, int.class, int.class);
406 utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "getChars", byte[].class, int.class, int.class, char[].class, int.class);
407 }
408 }
409
410 private static void registerThreadPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, WordTypes wordTypes, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
411 Registration r = new Registration(plugins, Thread.class, bytecodeProvider);
412 r.register0("currentThread", new InvocationPlugin() {
413 @Override
414 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
415 CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(wordTypes.getWordKind()));
416 ValueNode offset = b.add(ConstantNode.forLong(config.threadObjectOffset));
417 AddressNode address = b.add(new OffsetAddressNode(thread, offset));
418 // JavaThread::_threadObj is never compressed
419 ObjectStamp stamp = StampFactory.objectNonNull(TypeReference.create(b.getAssumptions(), metaAccess.lookupJavaType(Thread.class)));
420 b.addPush(JavaKind.Object, new ReadNode(address, JAVA_THREAD_THREAD_OBJECT_LOCATION, stamp, BarrierType.NONE));
421 return true;
422 }
423 });
424
425 r.registerMethodSubstitution(ThreadSubstitutions.class, "isInterrupted", Receiver.class, boolean.class);
426 }
427
428 public static final String cbcEncryptName;
429 public static final String cbcDecryptName;
479 } else {
480 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMultiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class, int.class,
481 int[].class);
482 }
483 }
484 if (config.useMulAddIntrinsic()) {
485 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMulAdd", int[].class, int[].class, int.class, int.class, int.class);
486 }
487 if (config.useMontgomeryMultiplyIntrinsic()) {
488 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMontgomeryMultiply", int[].class, int[].class, int[].class, int.class, long.class, int[].class);
489 }
490 if (config.useMontgomerySquareIntrinsic()) {
491 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implMontgomerySquare", int[].class, int[].class, int.class, long.class, int[].class);
492 }
493 if (config.useSquareToLenIntrinsic()) {
494 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "implSquareToLen", int[].class, int.class, int[].class, int.class);
495 }
496 }
497
498 private static void registerSHAPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
499 boolean useSha1 = config.useSHA1Intrinsics();
500 boolean useSha256 = config.useSHA256Intrinsics();
501 boolean useSha512 = config.useSHA512Intrinsics();
502
503 if (!Java8OrEarlier && (useSha1 || useSha256 || useSha512)) {
504 Registration r = new Registration(plugins, "sun.security.provider.DigestBase", bytecodeProvider);
505 r.registerMethodSubstitution(DigestBaseSubstitutions.class, "implCompressMultiBlock0", Receiver.class, byte[].class, int.class, int.class);
506 }
507
508 if (useSha1) {
509 assert config.sha1ImplCompress != 0L;
510 Registration r = new Registration(plugins, "sun.security.provider.SHA", bytecodeProvider);
511 r.registerMethodSubstitution(SHASubstitutions.class, SHASubstitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
512 }
513 if (useSha256) {
514 assert config.sha256ImplCompress != 0L;
515 Registration r = new Registration(plugins, "sun.security.provider.SHA2", bytecodeProvider);
516 r.registerMethodSubstitution(SHA2Substitutions.class, SHA2Substitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
517 }
518 if (useSha512) {
519 assert config.sha512ImplCompress != 0L;
520 Registration r = new Registration(plugins, "sun.security.provider.SHA5", bytecodeProvider);
521 r.registerMethodSubstitution(SHA5Substitutions.class, SHA5Substitutions.implCompressName, "implCompress0", Receiver.class, byte[].class, int.class);
522 }
523 }
524
525 private static void registerGHASHPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
526 if (config.useGHASHIntrinsics()) {
527 assert config.ghashProcessBlocks != 0L;
528 Registration r = new Registration(plugins, "com.sun.crypto.provider.GHASH");
529 r.register5("processBlocks",
530 byte[].class,
531 int.class,
532 int.class,
533 long[].class,
534 long[].class,
535 new InvocationPlugin() {
536 @Override
537 public boolean apply(GraphBuilderContext b,
538 ResolvedJavaMethod targetMethod,
539 Receiver receiver,
540 ValueNode data,
541 ValueNode inOffset,
542 ValueNode blocks,
543 ValueNode state,
544 ValueNode hashSubkey) {
545 int longArrayBaseOffset = metaAccess.getArrayBaseOffset(JavaKind.Long);
546 int byteArrayBaseOffset = metaAccess.getArrayBaseOffset(JavaKind.Byte);
547 ValueNode dataOffset = AddNode.create(ConstantNode.forInt(byteArrayBaseOffset), inOffset, NodeView.DEFAULT);
548 ComputeObjectAddressNode dataAddress = b.add(new ComputeObjectAddressNode(data, dataOffset));
549 ComputeObjectAddressNode stateAddress = b.add(new ComputeObjectAddressNode(state, ConstantNode.forInt(longArrayBaseOffset)));
550 ComputeObjectAddressNode hashSubkeyAddress = b.add(new ComputeObjectAddressNode(hashSubkey, ConstantNode.forInt(longArrayBaseOffset)));
551 b.add(new ForeignCallNode(foreignCalls, GHASH_PROCESS_BLOCKS, stateAddress, hashSubkeyAddress, dataAddress, blocks));
552 return true;
553 }
554 });
555 }
556 }
557
558 private static void registerCounterModePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
559 if (config.useAESCTRIntrinsics) {
560 assert config.counterModeAESCrypt != 0L;
561 Registration r = new Registration(plugins, "com.sun.crypto.provider.CounterMode", bytecodeProvider);
562 r.registerMethodSubstitution(CounterModeSubstitutions.class, "implCrypt", Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class);
563 }
564 }
565
566 private static void registerCRC32Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
567 if (config.useCRC32Intrinsics) {
568 Registration r = new Registration(plugins, CRC32.class, bytecodeProvider);
569 r.registerMethodSubstitution(CRC32Substitutions.class, "update", int.class, int.class);
570 if (Java8OrEarlier) {
571 r.registerMethodSubstitution(CRC32Substitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
572 r.registerMethodSubstitution(CRC32Substitutions.class, "updateByteBuffer", int.class, long.class, int.class, int.class);
573 } else {
574 r.registerMethodSubstitution(CRC32Substitutions.class, "updateBytes0", int.class, byte[].class, int.class, int.class);
575 r.registerMethodSubstitution(CRC32Substitutions.class, "updateByteBuffer0", int.class, long.class, int.class, int.class);
576 }
577 }
578 }
579
580 private static void registerCRC32CPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
581 if (config.useCRC32CIntrinsics) {
582 Registration r = new Registration(plugins, "java.util.zip.CRC32C", bytecodeProvider);
583 r.registerMethodSubstitution(CRC32CSubstitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
584 r.registerMethodSubstitution(CRC32CSubstitutions.class, "updateDirectByteBuffer", int.class, long.class, int.class, int.class);
585 }
586 }
587
588 private static void registerArraysSupportPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
589 if (config.useVectorizedMismatchIntrinsic) {
590 Registration r = new Registration(plugins, "jdk.internal.util.ArraysSupport", bytecodeProvider);
591 r.registerMethodSubstitution(ArraysSupportSubstitutions.class, "vectorizedMismatch", Object.class, long.class, Object.class, long.class, int.class, int.class);
592 }
593 }
594 }
|