33 |
33 |
34 import java.lang.invoke.ConstantCallSite; |
34 import java.lang.invoke.ConstantCallSite; |
35 import java.lang.invoke.MutableCallSite; |
35 import java.lang.invoke.MutableCallSite; |
36 import java.lang.invoke.VolatileCallSite; |
36 import java.lang.invoke.VolatileCallSite; |
37 import java.lang.reflect.Array; |
37 import java.lang.reflect.Array; |
|
38 import java.lang.reflect.Type; |
38 import java.math.BigInteger; |
39 import java.math.BigInteger; |
39 import java.util.zip.CRC32; |
40 import java.util.zip.CRC32; |
40 |
41 |
|
42 import jdk.internal.vm.compiler.collections.Pair; |
41 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; |
43 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; |
42 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; |
44 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; |
43 import org.graalvm.compiler.core.common.type.ObjectStamp; |
45 import org.graalvm.compiler.core.common.type.ObjectStamp; |
44 import org.graalvm.compiler.core.common.type.StampFactory; |
46 import org.graalvm.compiler.core.common.type.StampFactory; |
45 import org.graalvm.compiler.core.common.type.TypeReference; |
47 import org.graalvm.compiler.core.common.type.TypeReference; |
459 constantPoolClass = "jdk.internal.reflect.ConstantPool"; |
462 constantPoolClass = "jdk.internal.reflect.ConstantPool"; |
460 } |
463 } |
461 } |
464 } |
462 |
465 |
463 public static String lookupIntrinsicName(GraalHotSpotVMConfig config, String className, String name1, String name2) { |
466 public static String lookupIntrinsicName(GraalHotSpotVMConfig config, String className, String name1, String name2) { |
|
467 return selectIntrinsicName(config, className, name1, name2).getLeft(); |
|
468 } |
|
469 |
|
470 /** |
|
471 * Returns a pair of Strings where the left one represents the matched intrinsic name and the |
|
472 * right one represents the mismatched intrinsic name. |
|
473 */ |
|
474 public static Pair<String, String> selectIntrinsicName(GraalHotSpotVMConfig config, String className, String name1, String name2) { |
464 boolean foundName1 = false; |
475 boolean foundName1 = false; |
465 boolean foundName2 = false; |
476 boolean foundName2 = false; |
466 String name = name1; |
|
467 for (VMIntrinsicMethod intrinsic : config.getStore().getIntrinsics()) { |
477 for (VMIntrinsicMethod intrinsic : config.getStore().getIntrinsics()) { |
468 if (className.equals(intrinsic.declaringClass)) { |
478 if (className.equals(intrinsic.declaringClass)) { |
469 if (name1.equals(intrinsic.name)) { |
479 if (name1.equals(intrinsic.name)) { |
470 foundName1 = true; |
480 foundName1 = true; |
471 } else if (name2.equals(intrinsic.name)) { |
481 } else if (name2.equals(intrinsic.name)) { |
472 foundName2 = true; |
482 foundName2 = true; |
473 name = name2; |
|
474 } |
483 } |
475 } |
484 } |
476 } |
485 } |
477 if (foundName1 != foundName2) { |
486 if (foundName1 && !foundName2) { |
478 return name; |
487 return Pair.create(name1, name2); |
|
488 } else if (foundName2 && !foundName1) { |
|
489 return Pair.create(name2, name1); |
479 } |
490 } |
480 throw GraalError.shouldNotReachHere(); |
491 throw GraalError.shouldNotReachHere(); |
481 } |
492 } |
482 |
493 |
483 public static boolean isIntrinsicName(GraalHotSpotVMConfig config, String className, String name) { |
494 public static boolean isIntrinsicName(GraalHotSpotVMConfig config, String className, String name) { |
498 assert config.cipherBlockChainingEncryptAESCryptStub != 0L; |
509 assert config.cipherBlockChainingEncryptAESCryptStub != 0L; |
499 assert config.cipherBlockChainingDecryptAESCryptStub != 0L; |
510 assert config.cipherBlockChainingDecryptAESCryptStub != 0L; |
500 String arch = config.osArch; |
511 String arch = config.osArch; |
501 String decryptSuffix = arch.equals("sparc") ? "WithOriginalKey" : ""; |
512 String decryptSuffix = arch.equals("sparc") ? "WithOriginalKey" : ""; |
502 |
513 |
503 String cbcEncryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implEncrypt", "encrypt"); |
|
504 String cbcDecryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt"); |
|
505 Registration r = new Registration(plugins, "com.sun.crypto.provider.CipherBlockChaining", replacements); |
514 Registration r = new Registration(plugins, "com.sun.crypto.provider.CipherBlockChaining", replacements); |
506 r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcEncryptName, Receiver.class, byte[].class, int.class, int.class, byte[].class, int.class); |
515 |
507 r.registerMethodSubstitution(CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, int.class, byte[].class, |
516 Pair<String, String> cbcEncryptName = selectIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implEncrypt", "encrypt"); |
508 int.class); |
517 registerAndCheckMismatch(r, CipherBlockChainingSubstitutions.class, cbcEncryptName, Receiver.class, byte[].class, int.class, int.class, |
509 |
518 byte[].class, int.class); |
510 String aesEncryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implEncryptBlock", "encryptBlock"); |
519 |
511 String aesDecryptName = lookupIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock"); |
520 Pair<String, String> cbcDecryptName = selectIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt"); |
|
521 registerAndCheckMismatch(r, CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName.getLeft() + decryptSuffix, Receiver.class, byte[].class, int.class, int.class, |
|
522 byte[].class, int.class); |
512 |
523 |
513 r = new Registration(plugins, "com.sun.crypto.provider.AESCrypt", replacements); |
524 r = new Registration(plugins, "com.sun.crypto.provider.AESCrypt", replacements); |
514 r.registerMethodSubstitution(AESCryptSubstitutions.class, aesEncryptName, Receiver.class, byte[].class, int.class, byte[].class, int.class); |
525 |
515 r.registerMethodSubstitution(AESCryptSubstitutions.class, aesDecryptName, aesDecryptName + decryptSuffix, Receiver.class, byte[].class, int.class, byte[].class, int.class); |
526 Pair<String, String> aesEncryptName = selectIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implEncryptBlock", "encryptBlock"); |
|
527 registerAndCheckMismatch(r, AESCryptSubstitutions.class, aesEncryptName, Receiver.class, byte[].class, int.class, byte[].class, int.class); |
|
528 |
|
529 Pair<String, String> aesDecryptName = selectIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock"); |
|
530 registerAndCheckMismatch(r, AESCryptSubstitutions.class, aesDecryptName, aesDecryptName.getLeft() + decryptSuffix, Receiver.class, byte[].class, int.class, byte[].class, int.class); |
|
531 } |
|
532 } |
|
533 |
|
534 private static void registerAndCheckMismatch(Registration r, Class<?> substitutionClass, Pair<String, String> intrinsicNames, Type... argumentTypes) { |
|
535 try { |
|
536 r.registerMethodSubstitution(substitutionClass, intrinsicNames.getLeft(), argumentTypes); |
|
537 } catch (NoSuchMethodError e) { |
|
538 throw new GraalError(e, "Found method named '%s' instead of '%s' in class '%s'. This is most likely because the JVMCI JDK in %s was built on an incompatible base JDK.", |
|
539 intrinsicNames.getRight(), intrinsicNames.getLeft(), r.getDeclaringType().getTypeName(), Services.getSavedProperties().get("java.home")); |
|
540 } |
|
541 } |
|
542 |
|
543 private static void registerAndCheckMismatch(Registration r, Class<?> substitutionClass, Pair<String, String> intrinsicNames, String substituteName, Type... argumentTypes) { |
|
544 try { |
|
545 r.registerMethodSubstitution(substitutionClass, intrinsicNames.getLeft(), substituteName, argumentTypes); |
|
546 } catch (NoSuchMethodError e) { |
|
547 throw new GraalError(e, "Found method named '%s' instead of '%s' in class '%s'. This is most likely because the JVMCI JDK in %s was built on an incompatible base JDK.", |
|
548 intrinsicNames.getRight(), intrinsicNames.getLeft(), r.getDeclaringType().getTypeName(), Services.getSavedProperties().get("java.home")); |
516 } |
549 } |
517 } |
550 } |
518 |
551 |
519 private static void registerBigIntegerPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) { |
552 private static void registerBigIntegerPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) { |
520 Registration r = new Registration(plugins, BigInteger.class, replacements); |
553 Registration r = new Registration(plugins, BigInteger.class, replacements); |
542 if (isIntrinsicName(config, "sun/security/provider/DigestBase", "implCompressMultiBlock0") && (useSha1 || useSha256 || useSha512)) { |
575 if (isIntrinsicName(config, "sun/security/provider/DigestBase", "implCompressMultiBlock0") && (useSha1 || useSha256 || useSha512)) { |
543 Registration r = new Registration(plugins, "sun.security.provider.DigestBase", replacements); |
576 Registration r = new Registration(plugins, "sun.security.provider.DigestBase", replacements); |
544 r.registerMethodSubstitution(DigestBaseSubstitutions.class, "implCompressMultiBlock0", Receiver.class, byte[].class, int.class, int.class); |
577 r.registerMethodSubstitution(DigestBaseSubstitutions.class, "implCompressMultiBlock0", Receiver.class, byte[].class, int.class, int.class); |
545 } |
578 } |
546 |
579 |
547 String implCompressName = lookupIntrinsicName(config, "sun/security/provider/SHA", "implCompress", "implCompress0"); |
580 Pair<String, String> implCompressName = selectIntrinsicName(config, "sun/security/provider/SHA", "implCompress", "implCompress0"); |
548 if (useSha1) { |
581 if (useSha1) { |
549 assert config.sha1ImplCompress != 0L; |
582 assert config.sha1ImplCompress != 0L; |
550 Registration r = new Registration(plugins, "sun.security.provider.SHA", replacements); |
583 Registration r = new Registration(plugins, "sun.security.provider.SHA", replacements); |
551 r.registerMethodSubstitution(SHASubstitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class); |
584 registerAndCheckMismatch(r, SHASubstitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class); |
552 } |
585 } |
553 if (useSha256) { |
586 if (useSha256) { |
554 assert config.sha256ImplCompress != 0L; |
587 assert config.sha256ImplCompress != 0L; |
555 Registration r = new Registration(plugins, "sun.security.provider.SHA2", replacements); |
588 Registration r = new Registration(plugins, "sun.security.provider.SHA2", replacements); |
556 r.registerMethodSubstitution(SHA2Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class); |
589 registerAndCheckMismatch(r, SHA2Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class); |
557 } |
590 } |
558 if (useSha512) { |
591 if (useSha512) { |
559 assert config.sha512ImplCompress != 0L; |
592 assert config.sha512ImplCompress != 0L; |
560 Registration r = new Registration(plugins, "sun.security.provider.SHA5", replacements); |
593 Registration r = new Registration(plugins, "sun.security.provider.SHA5", replacements); |
561 r.registerMethodSubstitution(SHA5Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class); |
594 registerAndCheckMismatch(r, SHA5Substitutions.class, implCompressName, "implCompress0", Receiver.class, byte[].class, int.class); |
562 } |
595 } |
563 } |
596 } |
564 |
597 |
565 private static void registerGHASHPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) { |
598 private static void registerGHASHPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) { |
566 if (config.useGHASHIntrinsics()) { |
599 if (config.useGHASHIntrinsics()) { |