< prev index next >

src/hotspot/share/opto/library_call.cpp

Print this page
rev 60737 : 8252204: AArch64: Implement SHA3 accelerator/intrinsic
Reviewed-by: duke
Contributed-by: dongbo4@huawei.com


 291   bool inline_unsafe_fence(vmIntrinsics::ID id);
 292   bool inline_onspinwait();
 293   bool inline_fp_conversions(vmIntrinsics::ID id);
 294   bool inline_number_methods(vmIntrinsics::ID id);
 295   bool inline_reference_get();
 296   bool inline_Class_cast();
 297   bool inline_aescrypt_Block(vmIntrinsics::ID id);
 298   bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
 299   bool inline_electronicCodeBook_AESCrypt(vmIntrinsics::ID id);
 300   bool inline_counterMode_AESCrypt(vmIntrinsics::ID id);
 301   Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
 302   Node* inline_electronicCodeBook_AESCrypt_predicate(bool decrypting);
 303   Node* inline_counterMode_AESCrypt_predicate();
 304   Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
 305   Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
 306   bool inline_ghash_processBlocks();
 307   bool inline_base64_encodeBlock();
 308   bool inline_digestBase_implCompress(vmIntrinsics::ID id);
 309   bool inline_digestBase_implCompressMB(int predicate);
 310   bool inline_digestBase_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass,
 311                                         bool long_state, address stubAddr, const char *stubName,
 312                                         Node* src_start, Node* ofs, Node* limit);
 313   Node* get_state_from_digest_object(Node *digestBase_object);
 314   Node* get_long_state_from_digest_object(Node *digestBase_object);
 315   Node* inline_digestBase_implCompressMB_predicate(int predicate);
 316   bool inline_encodeISOArray();
 317   bool inline_updateCRC32();
 318   bool inline_updateBytesCRC32();
 319   bool inline_updateByteBufferCRC32();
 320   Node* get_table_from_crc32c_class(ciInstanceKlass *crc32c_class);
 321   bool inline_updateBytesCRC32C();
 322   bool inline_updateDirectByteBufferCRC32C();
 323   bool inline_updateBytesAdler32();
 324   bool inline_updateByteBufferAdler32();
 325   bool inline_multiplyToLen();
 326   bool inline_hasNegatives();
 327   bool inline_squareToLen();
 328   bool inline_mulAdd();
 329   bool inline_montgomeryMultiply();
 330   bool inline_montgomerySquare();
 331   bool inline_bigIntegerShift(bool isRightShift);
 332   bool inline_vectorizedMismatch();
 333   bool inline_fma(vmIntrinsics::ID id);
 334   bool inline_character_compare(vmIntrinsics::ID id);


 813   case vmIntrinsics::_Class_cast:               return inline_Class_cast();
 814 
 815   case vmIntrinsics::_aescrypt_encryptBlock:
 816   case vmIntrinsics::_aescrypt_decryptBlock:    return inline_aescrypt_Block(intrinsic_id());
 817 
 818   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
 819   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
 820     return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
 821 
 822   case vmIntrinsics::_electronicCodeBook_encryptAESCrypt:
 823   case vmIntrinsics::_electronicCodeBook_decryptAESCrypt:
 824     return inline_electronicCodeBook_AESCrypt(intrinsic_id());
 825 
 826   case vmIntrinsics::_counterMode_AESCrypt:
 827     return inline_counterMode_AESCrypt(intrinsic_id());
 828 
 829   case vmIntrinsics::_md5_implCompress:
 830   case vmIntrinsics::_sha_implCompress:
 831   case vmIntrinsics::_sha2_implCompress:
 832   case vmIntrinsics::_sha5_implCompress:

 833     return inline_digestBase_implCompress(intrinsic_id());
 834 
 835   case vmIntrinsics::_digestBase_implCompressMB:
 836     return inline_digestBase_implCompressMB(predicate);
 837 
 838   case vmIntrinsics::_multiplyToLen:
 839     return inline_multiplyToLen();
 840 
 841   case vmIntrinsics::_squareToLen:
 842     return inline_squareToLen();
 843 
 844   case vmIntrinsics::_mulAdd:
 845     return inline_mulAdd();
 846 
 847   case vmIntrinsics::_montgomeryMultiply:
 848     return inline_montgomeryMultiply();
 849   case vmIntrinsics::_montgomerySquare:
 850     return inline_montgomerySquare();
 851 
 852   case vmIntrinsics::_bigIntegerRightShiftWorker:


6411                                    OptoRuntime::base64_encodeBlock_Type(),
6412                                    stubAddr, stubName, TypePtr::BOTTOM,
6413                                    src_start, offset, len, dest_start, dp, isURL);
6414   return true;
6415 }
6416 
6417 //------------------------------inline_digestBase_implCompress-----------------------
6418 //
6419 // Calculate MD5 for single-block byte[] array.
6420 // void com.sun.security.provider.MD5.implCompress(byte[] buf, int ofs)
6421 //
6422 // Calculate SHA (i.e., SHA-1) for single-block byte[] array.
6423 // void com.sun.security.provider.SHA.implCompress(byte[] buf, int ofs)
6424 //
6425 // Calculate SHA2 (i.e., SHA-244 or SHA-256) for single-block byte[] array.
6426 // void com.sun.security.provider.SHA2.implCompress(byte[] buf, int ofs)
6427 //
6428 // Calculate SHA5 (i.e., SHA-384 or SHA-512) for single-block byte[] array.
6429 // void com.sun.security.provider.SHA5.implCompress(byte[] buf, int ofs)
6430 //



6431 bool LibraryCallKit::inline_digestBase_implCompress(vmIntrinsics::ID id) {
6432   assert(callee()->signature()->size() == 2, "sha_implCompress has 2 parameters");
6433 
6434   Node* digestBase_obj = argument(0);
6435   Node* src            = argument(1); // type oop
6436   Node* ofs            = argument(2); // type int
6437 
6438   const Type* src_type = src->Value(&_gvn);
6439   const TypeAryPtr* top_src = src_type->isa_aryptr();
6440   if (top_src  == NULL || top_src->klass()  == NULL) {
6441     // failed array check
6442     return false;
6443   }
6444   // Figure out the size and type of the elements we will be copying.
6445   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
6446   if (src_elem != T_BYTE) {
6447     return false;
6448   }
6449   // 'src_start' points to src array + offset
6450   src = must_be_not_null(src, true);
6451   Node* src_start = array_element_address(src, ofs, src_elem);
6452   Node* state = NULL;

6453   address stubAddr;
6454   const char *stubName;
6455 
6456   switch(id) {
6457   case vmIntrinsics::_md5_implCompress:
6458     assert(UseMD5Intrinsics, "need MD5 instruction support");
6459     state = get_state_from_digest_object(digestBase_obj);
6460     stubAddr = StubRoutines::md5_implCompress();
6461     stubName = "md5_implCompress";
6462     break;
6463   case vmIntrinsics::_sha_implCompress:
6464     assert(UseSHA1Intrinsics, "need SHA1 instruction support");
6465     state = get_state_from_digest_object(digestBase_obj);
6466     stubAddr = StubRoutines::sha1_implCompress();
6467     stubName = "sha1_implCompress";
6468     break;
6469   case vmIntrinsics::_sha2_implCompress:
6470     assert(UseSHA256Intrinsics, "need SHA256 instruction support");
6471     state = get_state_from_digest_object(digestBase_obj);
6472     stubAddr = StubRoutines::sha256_implCompress();
6473     stubName = "sha256_implCompress";
6474     break;
6475   case vmIntrinsics::_sha5_implCompress:
6476     assert(UseSHA512Intrinsics, "need SHA512 instruction support");
6477     state = get_long_state_from_digest_object(digestBase_obj);
6478     stubAddr = StubRoutines::sha512_implCompress();
6479     stubName = "sha512_implCompress";
6480     break;








6481   default:
6482     fatal_unexpected_iid(id);
6483     return false;
6484   }
6485   if (state == NULL) return false;
6486 
6487   assert(stubAddr != NULL, "Stub is generated");
6488   if (stubAddr == NULL) return false;
6489 
6490   // Call the stub.
6491   Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::digestBase_implCompress_Type(),


6492                                  stubAddr, stubName, TypePtr::BOTTOM,
6493                                  src_start, state);





6494 
6495   return true;
6496 }
6497 
6498 //------------------------------inline_digestBase_implCompressMB-----------------------
6499 //
6500 // Calculate MD5/SHA/SHA2/SHA5 for multi-block byte[] array.
6501 // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit)
6502 //
6503 bool LibraryCallKit::inline_digestBase_implCompressMB(int predicate) {
6504   assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics,
6505          "need MD5/SHA1/SHA256/SHA512 instruction support");
6506   assert((uint)predicate < 4, "sanity");
6507   assert(callee()->signature()->size() == 3, "digestBase_implCompressMB has 3 parameters");
6508 
6509   Node* digestBase_obj = argument(0); // The receiver was checked for NULL already.
6510   Node* src            = argument(1); // byte[] array
6511   Node* ofs            = argument(2); // type int
6512   Node* limit          = argument(3); // type int
6513 
6514   const Type* src_type = src->Value(&_gvn);
6515   const TypeAryPtr* top_src = src_type->isa_aryptr();
6516   if (top_src  == NULL || top_src->klass()  == NULL) {
6517     // failed array check
6518     return false;
6519   }
6520   // Figure out the size and type of the elements we will be copying.
6521   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
6522   if (src_elem != T_BYTE) {
6523     return false;
6524   }
6525   // 'src_start' points to src array + offset
6526   src = must_be_not_null(src, false);
6527   Node* src_start = array_element_address(src, ofs, src_elem);
6528 
6529   const char* klass_digestBase_name = NULL;
6530   const char* stub_name = NULL;
6531   address     stub_addr = NULL;
6532   bool        long_state = false;
6533 
6534   switch (predicate) {
6535   case 0:
6536     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_md5_implCompress)) {
6537       klass_digestBase_name = "sun/security/provider/MD5";
6538       stub_name = "md5_implCompressMB";
6539       stub_addr = StubRoutines::md5_implCompressMB();
6540     }
6541     break;
6542   case 1:
6543     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha_implCompress)) {
6544       klass_digestBase_name = "sun/security/provider/SHA";
6545       stub_name = "sha1_implCompressMB";
6546       stub_addr = StubRoutines::sha1_implCompressMB();
6547     }
6548     break;
6549   case 2:
6550     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha2_implCompress)) {
6551       klass_digestBase_name = "sun/security/provider/SHA2";
6552       stub_name = "sha256_implCompressMB";
6553       stub_addr = StubRoutines::sha256_implCompressMB();
6554     }
6555     break;
6556   case 3:
6557     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha5_implCompress)) {
6558       klass_digestBase_name = "sun/security/provider/SHA5";
6559       stub_name = "sha512_implCompressMB";
6560       stub_addr = StubRoutines::sha512_implCompressMB();
6561       long_state = true;








6562     }
6563     break;
6564   default:
6565     fatal("unknown DigestBase intrinsic predicate: %d", predicate);
6566   }
6567   if (klass_digestBase_name != NULL) {
6568     assert(stub_addr != NULL, "Stub is generated");
6569     if (stub_addr == NULL) return false;
6570 
6571     // get DigestBase klass to lookup for SHA klass
6572     const TypeInstPtr* tinst = _gvn.type(digestBase_obj)->isa_instptr();
6573     assert(tinst != NULL, "digestBase_obj is not instance???");
6574     assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
6575 
6576     ciKlass* klass_digestBase = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_digestBase_name));
6577     assert(klass_digestBase->is_loaded(), "predicate checks that this class is loaded");
6578     ciInstanceKlass* instklass_digestBase = klass_digestBase->as_instance_klass();
6579     return inline_digestBase_implCompressMB(digestBase_obj, instklass_digestBase, long_state, stub_addr, stub_name, src_start, ofs, limit);
6580   }
6581   return false;
6582 }
6583 
6584 //------------------------------inline_digestBase_implCompressMB-----------------------
6585 bool LibraryCallKit::inline_digestBase_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_digestBase,
6586                                                       bool long_state, address stubAddr, const char *stubName,
6587                                                       Node* src_start, Node* ofs, Node* limit) {
6588   const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_digestBase);
6589   const TypeOopPtr* xtype = aklass->as_instance_type();
6590   Node* digest_obj = new CheckCastPPNode(control(), digestBase_obj, xtype);
6591   digest_obj = _gvn.transform(digest_obj);
6592 
6593   Node* state;
6594   if (long_state) {
6595     state = get_long_state_from_digest_object(digest_obj);
6596   } else {
6597     state = get_state_from_digest_object(digest_obj);
6598   }
6599   if (state == NULL) return false;
6600 






6601   // Call the stub.
6602   Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
6603                                  OptoRuntime::digestBase_implCompressMB_Type(),


6604                                  stubAddr, stubName, TypePtr::BOTTOM,
6605                                  src_start, state, ofs, limit);







6606   // return ofs (int)
6607   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
6608   set_result(result);
6609 
6610   return true;
6611 }
6612 
6613 //------------------------------get_state_from_digest_object-----------------------
6614 Node * LibraryCallKit::get_state_from_digest_object(Node *digest_object) {
6615   Node* digest_state = load_field_from_object(digest_object, "state", "[I", /*is_exact*/ false);
6616   assert (digest_state != NULL, "wrong version of sun.security.provider.MD5/SHA/SHA2");
6617   if (digest_state == NULL) return (Node *) NULL;
6618 
6619   // now have the array, need to get the start address of the state array
6620   Node* state = array_element_address(digest_state, intcon(0), T_INT);
6621   return state;
6622 }
6623 
6624 //------------------------------get_long_state_from_digest_object-----------------------
6625 Node * LibraryCallKit::get_long_state_from_digest_object(Node *digest_object) {
6626   Node* digest_state = load_field_from_object(digest_object, "state", "[J", /*is_exact*/ false);
6627   assert (digest_state != NULL, "wrong version of sun.security.provider.SHA5");
6628   if (digest_state == NULL) return (Node *) NULL;
6629 
6630   // now have the array, need to get the start address of the state array
6631   Node* state = array_element_address(digest_state, intcon(0), T_LONG);
6632   return state;
6633 }
6634 
6635 //----------------------------inline_digestBase_implCompressMB_predicate----------------------------
6636 // Return node representing slow path of predicate check.
6637 // the pseudo code we want to emulate with this predicate is:
6638 //    if (digestBaseObj instanceof MD5/SHA/SHA2/SHA5) do_intrinsic, else do_javapath
6639 //
6640 Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate) {
6641   assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics,
6642          "need MD5/SHA1/SHA256/SHA512 instruction support");
6643   assert((uint)predicate < 4, "sanity");
6644 
6645   // The receiver was checked for NULL already.
6646   Node* digestBaseObj = argument(0);
6647 
6648   // get DigestBase klass for instanceOf check
6649   const TypeInstPtr* tinst = _gvn.type(digestBaseObj)->isa_instptr();
6650   assert(tinst != NULL, "digestBaseObj is null");
6651   assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
6652 
6653   const char* klass_name = NULL;
6654   switch (predicate) {
6655   case 0:
6656     if (UseMD5Intrinsics) {
6657       // we want to do an instanceof comparison against the MD5 class
6658       klass_name = "sun/security/provider/MD5";
6659     }
6660     break;
6661   case 1:
6662     if (UseSHA1Intrinsics) {
6663       // we want to do an instanceof comparison against the SHA class
6664       klass_name = "sun/security/provider/SHA";
6665     }
6666     break;
6667   case 2:
6668     if (UseSHA256Intrinsics) {
6669       // we want to do an instanceof comparison against the SHA2 class
6670       klass_name = "sun/security/provider/SHA2";
6671     }
6672     break;
6673   case 3:
6674     if (UseSHA512Intrinsics) {
6675       // we want to do an instanceof comparison against the SHA5 class
6676       klass_name = "sun/security/provider/SHA5";






6677     }
6678     break;
6679   default:
6680     fatal("unknown SHA intrinsic predicate: %d", predicate);
6681   }
6682 
6683   ciKlass* klass = NULL;
6684   if (klass_name != NULL) {
6685     klass = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_name));
6686   }
6687   if ((klass == NULL) || !klass->is_loaded()) {
6688     // if none of MD5/SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path
6689     Node* ctrl = control();
6690     set_control(top()); // no intrinsic path
6691     return ctrl;
6692   }
6693   ciInstanceKlass* instklass = klass->as_instance_klass();
6694 
6695   Node* instof = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass)));
6696   Node* cmp_instof = _gvn.transform(new CmpINode(instof, intcon(1)));




 291   bool inline_unsafe_fence(vmIntrinsics::ID id);
 292   bool inline_onspinwait();
 293   bool inline_fp_conversions(vmIntrinsics::ID id);
 294   bool inline_number_methods(vmIntrinsics::ID id);
 295   bool inline_reference_get();
 296   bool inline_Class_cast();
 297   bool inline_aescrypt_Block(vmIntrinsics::ID id);
 298   bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
 299   bool inline_electronicCodeBook_AESCrypt(vmIntrinsics::ID id);
 300   bool inline_counterMode_AESCrypt(vmIntrinsics::ID id);
 301   Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
 302   Node* inline_electronicCodeBook_AESCrypt_predicate(bool decrypting);
 303   Node* inline_counterMode_AESCrypt_predicate();
 304   Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
 305   Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
 306   bool inline_ghash_processBlocks();
 307   bool inline_base64_encodeBlock();
 308   bool inline_digestBase_implCompress(vmIntrinsics::ID id);
 309   bool inline_digestBase_implCompressMB(int predicate);
 310   bool inline_digestBase_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass,
 311                                         const char* state_type, address stubAddr, const char *stubName,
 312                                         Node* src_start, Node* ofs, Node* limit);
 313   Node* get_state_from_digest_object(Node *digestBase_object, const char* state_type);
 314   Node* get_digest_length_from_digest_object(Node *digestBase_object);
 315   Node* inline_digestBase_implCompressMB_predicate(int predicate);
 316   bool inline_encodeISOArray();
 317   bool inline_updateCRC32();
 318   bool inline_updateBytesCRC32();
 319   bool inline_updateByteBufferCRC32();
 320   Node* get_table_from_crc32c_class(ciInstanceKlass *crc32c_class);
 321   bool inline_updateBytesCRC32C();
 322   bool inline_updateDirectByteBufferCRC32C();
 323   bool inline_updateBytesAdler32();
 324   bool inline_updateByteBufferAdler32();
 325   bool inline_multiplyToLen();
 326   bool inline_hasNegatives();
 327   bool inline_squareToLen();
 328   bool inline_mulAdd();
 329   bool inline_montgomeryMultiply();
 330   bool inline_montgomerySquare();
 331   bool inline_bigIntegerShift(bool isRightShift);
 332   bool inline_vectorizedMismatch();
 333   bool inline_fma(vmIntrinsics::ID id);
 334   bool inline_character_compare(vmIntrinsics::ID id);


 813   case vmIntrinsics::_Class_cast:               return inline_Class_cast();
 814 
 815   case vmIntrinsics::_aescrypt_encryptBlock:
 816   case vmIntrinsics::_aescrypt_decryptBlock:    return inline_aescrypt_Block(intrinsic_id());
 817 
 818   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
 819   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
 820     return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
 821 
 822   case vmIntrinsics::_electronicCodeBook_encryptAESCrypt:
 823   case vmIntrinsics::_electronicCodeBook_decryptAESCrypt:
 824     return inline_electronicCodeBook_AESCrypt(intrinsic_id());
 825 
 826   case vmIntrinsics::_counterMode_AESCrypt:
 827     return inline_counterMode_AESCrypt(intrinsic_id());
 828 
 829   case vmIntrinsics::_md5_implCompress:
 830   case vmIntrinsics::_sha_implCompress:
 831   case vmIntrinsics::_sha2_implCompress:
 832   case vmIntrinsics::_sha5_implCompress:
 833   case vmIntrinsics::_sha3_implCompress:
 834     return inline_digestBase_implCompress(intrinsic_id());
 835 
 836   case vmIntrinsics::_digestBase_implCompressMB:
 837     return inline_digestBase_implCompressMB(predicate);
 838 
 839   case vmIntrinsics::_multiplyToLen:
 840     return inline_multiplyToLen();
 841 
 842   case vmIntrinsics::_squareToLen:
 843     return inline_squareToLen();
 844 
 845   case vmIntrinsics::_mulAdd:
 846     return inline_mulAdd();
 847 
 848   case vmIntrinsics::_montgomeryMultiply:
 849     return inline_montgomeryMultiply();
 850   case vmIntrinsics::_montgomerySquare:
 851     return inline_montgomerySquare();
 852 
 853   case vmIntrinsics::_bigIntegerRightShiftWorker:


6412                                    OptoRuntime::base64_encodeBlock_Type(),
6413                                    stubAddr, stubName, TypePtr::BOTTOM,
6414                                    src_start, offset, len, dest_start, dp, isURL);
6415   return true;
6416 }
6417 
6418 //------------------------------inline_digestBase_implCompress-----------------------
6419 //
6420 // Calculate MD5 for single-block byte[] array.
6421 // void com.sun.security.provider.MD5.implCompress(byte[] buf, int ofs)
6422 //
6423 // Calculate SHA (i.e., SHA-1) for single-block byte[] array.
6424 // void com.sun.security.provider.SHA.implCompress(byte[] buf, int ofs)
6425 //
6426 // Calculate SHA2 (i.e., SHA-244 or SHA-256) for single-block byte[] array.
6427 // void com.sun.security.provider.SHA2.implCompress(byte[] buf, int ofs)
6428 //
6429 // Calculate SHA5 (i.e., SHA-384 or SHA-512) for single-block byte[] array.
6430 // void com.sun.security.provider.SHA5.implCompress(byte[] buf, int ofs)
6431 //
6432 // Calculate SHA3 (i.e., SHA3-224 or SHA3-256 or SHA3-384 or SHA3-512) for single-block byte[] array.
6433 // void com.sun.security.provider.SHA3.implCompress(byte[] buf, int ofs)
6434 //
6435 bool LibraryCallKit::inline_digestBase_implCompress(vmIntrinsics::ID id) {
6436   assert(callee()->signature()->size() == 2, "sha_implCompress has 2 parameters");
6437 
6438   Node* digestBase_obj = argument(0);
6439   Node* src            = argument(1); // type oop
6440   Node* ofs            = argument(2); // type int
6441 
6442   const Type* src_type = src->Value(&_gvn);
6443   const TypeAryPtr* top_src = src_type->isa_aryptr();
6444   if (top_src  == NULL || top_src->klass()  == NULL) {
6445     // failed array check
6446     return false;
6447   }
6448   // Figure out the size and type of the elements we will be copying.
6449   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
6450   if (src_elem != T_BYTE) {
6451     return false;
6452   }
6453   // 'src_start' points to src array + offset
6454   src = must_be_not_null(src, true);
6455   Node* src_start = array_element_address(src, ofs, src_elem);
6456   Node* state = NULL;
6457   Node* digest_length = NULL;
6458   address stubAddr;
6459   const char *stubName;
6460 
6461   switch(id) {
6462   case vmIntrinsics::_md5_implCompress:
6463     assert(UseMD5Intrinsics, "need MD5 instruction support");
6464     state = get_state_from_digest_object(digestBase_obj, "[I");
6465     stubAddr = StubRoutines::md5_implCompress();
6466     stubName = "md5_implCompress";
6467     break;
6468   case vmIntrinsics::_sha_implCompress:
6469     assert(UseSHA1Intrinsics, "need SHA1 instruction support");
6470     state = get_state_from_digest_object(digestBase_obj, "[I");
6471     stubAddr = StubRoutines::sha1_implCompress();
6472     stubName = "sha1_implCompress";
6473     break;
6474   case vmIntrinsics::_sha2_implCompress:
6475     assert(UseSHA256Intrinsics, "need SHA256 instruction support");
6476     state = get_state_from_digest_object(digestBase_obj, "[I");
6477     stubAddr = StubRoutines::sha256_implCompress();
6478     stubName = "sha256_implCompress";
6479     break;
6480   case vmIntrinsics::_sha5_implCompress:
6481     assert(UseSHA512Intrinsics, "need SHA512 instruction support");
6482     state = get_state_from_digest_object(digestBase_obj, "[J");
6483     stubAddr = StubRoutines::sha512_implCompress();
6484     stubName = "sha512_implCompress";
6485     break;
6486   case vmIntrinsics::_sha3_implCompress:
6487     assert(UseSHA3Intrinsics, "need SHA3 instruction support");
6488     state = get_state_from_digest_object(digestBase_obj, "[B");
6489     stubAddr = StubRoutines::sha3_implCompress();
6490     stubName = "sha3_implCompress";
6491     digest_length = get_digest_length_from_digest_object(digestBase_obj);
6492     if (digest_length == NULL) return false;
6493     break;
6494   default:
6495     fatal_unexpected_iid(id);
6496     return false;
6497   }
6498   if (state == NULL) return false;
6499 
6500   assert(stubAddr != NULL, "Stub is generated");
6501   if (stubAddr == NULL) return false;
6502 
6503   // Call the stub.
6504   Node* call;
6505   if (digest_length == NULL) {
6506     call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::digestBase_implCompress_Type(false),
6507                              stubAddr, stubName, TypePtr::BOTTOM,
6508                              src_start, state);
6509   } else {
6510     call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::digestBase_implCompress_Type(true),
6511                              stubAddr, stubName, TypePtr::BOTTOM,
6512                              src_start, state, digest_length);
6513   }
6514 
6515   return true;
6516 }
6517 
6518 //------------------------------inline_digestBase_implCompressMB-----------------------
6519 //
6520 // Calculate MD5/SHA/SHA2/SHA5/SHA3 for multi-block byte[] array.
6521 // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit)
6522 //
6523 bool LibraryCallKit::inline_digestBase_implCompressMB(int predicate) {
6524   assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics || UseSHA3Intrinsics,
6525          "need MD5/SHA1/SHA256/SHA512/SHA3 instruction support");
6526   assert((uint)predicate < 5, "sanity");
6527   assert(callee()->signature()->size() == 3, "digestBase_implCompressMB has 3 parameters");
6528 
6529   Node* digestBase_obj = argument(0); // The receiver was checked for NULL already.
6530   Node* src            = argument(1); // byte[] array
6531   Node* ofs            = argument(2); // type int
6532   Node* limit          = argument(3); // type int
6533 
6534   const Type* src_type = src->Value(&_gvn);
6535   const TypeAryPtr* top_src = src_type->isa_aryptr();
6536   if (top_src  == NULL || top_src->klass()  == NULL) {
6537     // failed array check
6538     return false;
6539   }
6540   // Figure out the size and type of the elements we will be copying.
6541   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
6542   if (src_elem != T_BYTE) {
6543     return false;
6544   }
6545   // 'src_start' points to src array + offset
6546   src = must_be_not_null(src, false);
6547   Node* src_start = array_element_address(src, ofs, src_elem);
6548 
6549   const char* klass_digestBase_name = NULL;
6550   const char* stub_name = NULL;
6551   address     stub_addr = NULL;
6552   const char* state_type = "[I";
6553 
6554   switch (predicate) {
6555   case 0:
6556     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_md5_implCompress)) {
6557       klass_digestBase_name = "sun/security/provider/MD5";
6558       stub_name = "md5_implCompressMB";
6559       stub_addr = StubRoutines::md5_implCompressMB();
6560     }
6561     break;
6562   case 1:
6563     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha_implCompress)) {
6564       klass_digestBase_name = "sun/security/provider/SHA";
6565       stub_name = "sha1_implCompressMB";
6566       stub_addr = StubRoutines::sha1_implCompressMB();
6567     }
6568     break;
6569   case 2:
6570     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha2_implCompress)) {
6571       klass_digestBase_name = "sun/security/provider/SHA2";
6572       stub_name = "sha256_implCompressMB";
6573       stub_addr = StubRoutines::sha256_implCompressMB();
6574     }
6575     break;
6576   case 3:
6577     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha5_implCompress)) {
6578       klass_digestBase_name = "sun/security/provider/SHA5";
6579       stub_name = "sha512_implCompressMB";
6580       stub_addr = StubRoutines::sha512_implCompressMB();
6581       state_type = "[J";
6582     }
6583     break;
6584   case 4:
6585     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha3_implCompress)) {
6586       klass_digestBase_name = "sun/security/provider/SHA3";
6587       stub_name = "sha3_implCompressMB";
6588       stub_addr = StubRoutines::sha3_implCompressMB();
6589       state_type = "[B";
6590     }
6591     break;
6592   default:
6593     fatal("unknown DigestBase intrinsic predicate: %d", predicate);
6594   }
6595   if (klass_digestBase_name != NULL) {
6596     assert(stub_addr != NULL, "Stub is generated");
6597     if (stub_addr == NULL) return false;
6598 
6599     // get DigestBase klass to lookup for SHA klass
6600     const TypeInstPtr* tinst = _gvn.type(digestBase_obj)->isa_instptr();
6601     assert(tinst != NULL, "digestBase_obj is not instance???");
6602     assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
6603 
6604     ciKlass* klass_digestBase = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_digestBase_name));
6605     assert(klass_digestBase->is_loaded(), "predicate checks that this class is loaded");
6606     ciInstanceKlass* instklass_digestBase = klass_digestBase->as_instance_klass();
6607     return inline_digestBase_implCompressMB(digestBase_obj, instklass_digestBase, state_type, stub_addr, stub_name, src_start, ofs, limit);
6608   }
6609   return false;
6610 }
6611 
6612 //------------------------------inline_digestBase_implCompressMB-----------------------
6613 bool LibraryCallKit::inline_digestBase_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_digestBase,
6614                                                       const char* state_type, address stubAddr, const char *stubName,
6615                                                       Node* src_start, Node* ofs, Node* limit) {
6616   const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_digestBase);
6617   const TypeOopPtr* xtype = aklass->as_instance_type();
6618   Node* digest_obj = new CheckCastPPNode(control(), digestBase_obj, xtype);
6619   digest_obj = _gvn.transform(digest_obj);
6620 
6621   Node* state = get_state_from_digest_object(digest_obj, state_type);





6622   if (state == NULL) return false;
6623 
6624   Node* digest_length = NULL;
6625   if (strcmp("sha3_implCompressMB", stubName) == 0) {
6626     digest_length = get_digest_length_from_digest_object(digest_obj);
6627     if (digest_length == NULL) return false;
6628   }
6629 
6630   // Call the stub.
6631   Node* call;
6632   if (digest_length == NULL) {
6633     call = make_runtime_call(RC_LEAF|RC_NO_FP,
6634                              OptoRuntime::digestBase_implCompressMB_Type(false),
6635                              stubAddr, stubName, TypePtr::BOTTOM,
6636                              src_start, state, ofs, limit);
6637   } else {
6638      call = make_runtime_call(RC_LEAF|RC_NO_FP,
6639                              OptoRuntime::digestBase_implCompressMB_Type(true),
6640                              stubAddr, stubName, TypePtr::BOTTOM,
6641                              src_start, state, digest_length, ofs, limit);
6642   }
6643 
6644   // return ofs (int)
6645   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
6646   set_result(result);
6647 
6648   return true;
6649 }
6650 
6651 //------------------------------get_state_from_digest_object-----------------------
6652 Node * LibraryCallKit::get_state_from_digest_object(Node *digest_object, const char *state_type) {
6653   Node* digest_state = load_field_from_object(digest_object, "state", state_type, /*is_exact*/ false);
6654   assert (digest_state != NULL, "wrong version of sun.security.provider.MD5/SHA/SHA2/SHA5/SHA3");
6655   if (digest_state == NULL) return (Node *) NULL;
6656 
6657   // now have the array, need to get the start address of the state array
6658   Node* state = array_element_address(digest_state, intcon(0), T_INT);
6659   return state;
6660 }
6661 
6662 //------------------------------get_digest_length_from_sha3_object----------------------------------
6663 Node * LibraryCallKit::get_digest_length_from_digest_object(Node *digest_object) {
6664   Node* digest_length = load_field_from_object(digest_object, "digestLength", "I", /*is_exact*/ false);
6665   assert (digest_length != NULL, "sanity");
6666   return digest_length;




6667 }
6668 
6669 //----------------------------inline_digestBase_implCompressMB_predicate----------------------------
6670 // Return node representing slow path of predicate check.
6671 // the pseudo code we want to emulate with this predicate is:
6672 //    if (digestBaseObj instanceof MD5/SHA/SHA2/SHA5/SHA3) do_intrinsic, else do_javapath
6673 //
6674 Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate) {
6675   assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics || UseSHA3Intrinsics,
6676          "need MD5/SHA1/SHA256/SHA512/SHA3 instruction support");
6677   assert((uint)predicate < 5, "sanity");
6678 
6679   // The receiver was checked for NULL already.
6680   Node* digestBaseObj = argument(0);
6681 
6682   // get DigestBase klass for instanceOf check
6683   const TypeInstPtr* tinst = _gvn.type(digestBaseObj)->isa_instptr();
6684   assert(tinst != NULL, "digestBaseObj is null");
6685   assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
6686 
6687   const char* klass_name = NULL;
6688   switch (predicate) {
6689   case 0:
6690     if (UseMD5Intrinsics) {
6691       // we want to do an instanceof comparison against the MD5 class
6692       klass_name = "sun/security/provider/MD5";
6693     }
6694     break;
6695   case 1:
6696     if (UseSHA1Intrinsics) {
6697       // we want to do an instanceof comparison against the SHA class
6698       klass_name = "sun/security/provider/SHA";
6699     }
6700     break;
6701   case 2:
6702     if (UseSHA256Intrinsics) {
6703       // we want to do an instanceof comparison against the SHA2 class
6704       klass_name = "sun/security/provider/SHA2";
6705     }
6706     break;
6707   case 3:
6708     if (UseSHA512Intrinsics) {
6709       // we want to do an instanceof comparison against the SHA5 class
6710       klass_name = "sun/security/provider/SHA5";
6711     }
6712     break;
6713   case 4:
6714     if (UseSHA3Intrinsics) {
6715       // we want to do an instanceof comparison against the SHA3 class
6716       klass_name = "sun/security/provider/SHA3";
6717     }
6718     break;
6719   default:
6720     fatal("unknown SHA intrinsic predicate: %d", predicate);
6721   }
6722 
6723   ciKlass* klass = NULL;
6724   if (klass_name != NULL) {
6725     klass = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_name));
6726   }
6727   if ((klass == NULL) || !klass->is_loaded()) {
6728     // if none of MD5/SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path
6729     Node* ctrl = control();
6730     set_control(top()); // no intrinsic path
6731     return ctrl;
6732   }
6733   ciInstanceKlass* instklass = klass->as_instance_klass();
6734 
6735   Node* instof = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass)));
6736   Node* cmp_instof = _gvn.transform(new CmpINode(instof, intcon(1)));


< prev index next >