307 bool inline_number_methods(vmIntrinsics::ID id); 308 bool inline_reference_get(); 309 bool inline_aescrypt_Block(vmIntrinsics::ID id); 310 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id); 311 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); 312 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); 313 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); 314 bool inline_sha_implCompress(vmIntrinsics::ID id); 315 bool inline_digestBase_implCompressMB(int predicate); 316 bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, 317 bool long_state, address stubAddr, const char *stubName, 318 Node* src_start, Node* ofs, Node* limit); 319 Node* get_state_from_sha_object(Node *sha_object); 320 Node* get_state_from_sha5_object(Node *sha_object); 321 Node* inline_digestBase_implCompressMB_predicate(int predicate); 322 bool inline_encodeISOArray(); 323 bool inline_updateCRC32(); 324 bool inline_updateBytesCRC32(); 325 bool inline_updateByteBufferCRC32(); 326 bool inline_multiplyToLen(); 327 328 bool inline_profileBoolean(); 329 }; 330 331 332 //---------------------------make_vm_intrinsic---------------------------- 333 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { 334 vmIntrinsics::ID id = m->intrinsic_id(); 335 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); 336 337 ccstr disable_intr = NULL; 338 339 if ((DisableIntrinsic[0] != '\0' 340 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) || 341 (method_has_option_value("DisableIntrinsic", disable_intr) 342 && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) { 343 // disabled by a user request on the command line: 344 // example: -XX:DisableIntrinsic=_hashCode,_getClass 345 return NULL; 346 } 510 511 case vmIntrinsics::_getAndSetObject: 512 #ifdef _LP64 513 if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; 514 if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL; 515 break; 516 #else 517 if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; 518 break; 519 #endif 520 521 case vmIntrinsics::_aescrypt_encryptBlock: 522 case vmIntrinsics::_aescrypt_decryptBlock: 523 if (!UseAESIntrinsics) return NULL; 524 break; 525 526 case vmIntrinsics::_multiplyToLen: 527 if (!UseMultiplyToLenIntrinsic) return NULL; 528 break; 529 530 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 531 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 532 if (!UseAESIntrinsics) return NULL; 533 // these two require the predicated logic 534 predicates = 1; 535 break; 536 537 case vmIntrinsics::_sha_implCompress: 538 if (!UseSHA1Intrinsics) return NULL; 539 break; 540 541 case vmIntrinsics::_sha2_implCompress: 542 if (!UseSHA256Intrinsics) return NULL; 543 break; 544 545 case vmIntrinsics::_sha5_implCompress: 546 if (!UseSHA512Intrinsics) return NULL; 547 break; 548 549 case vmIntrinsics::_digestBase_implCompressMB: 910 case vmIntrinsics::_Reference_get: return inline_reference_get(); 911 912 case vmIntrinsics::_aescrypt_encryptBlock: 913 case vmIntrinsics::_aescrypt_decryptBlock: return inline_aescrypt_Block(intrinsic_id()); 914 915 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 916 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 917 return inline_cipherBlockChaining_AESCrypt(intrinsic_id()); 918 919 case vmIntrinsics::_sha_implCompress: 920 case vmIntrinsics::_sha2_implCompress: 921 case vmIntrinsics::_sha5_implCompress: 922 return inline_sha_implCompress(intrinsic_id()); 923 924 case vmIntrinsics::_digestBase_implCompressMB: 925 return inline_digestBase_implCompressMB(predicate); 926 927 case vmIntrinsics::_multiplyToLen: 928 return inline_multiplyToLen(); 929 930 case vmIntrinsics::_encodeISOArray: 931 return inline_encodeISOArray(); 932 933 case vmIntrinsics::_updateCRC32: 934 return inline_updateCRC32(); 935 case vmIntrinsics::_updateBytesCRC32: 936 return inline_updateBytesCRC32(); 937 case vmIntrinsics::_updateByteBufferCRC32: 938 return inline_updateByteBufferCRC32(); 939 940 case vmIntrinsics::_profileBoolean: 941 return inline_profileBoolean(); 942 943 default: 944 // If you get here, it may be that someone has added a new intrinsic 945 // to the list in vmSymbols.hpp without implementing it here. 946 #ifndef PRODUCT 947 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) { 948 tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)", 949 vmIntrinsics::name_at(intrinsic_id()), intrinsic_id()); 5750 Node* enc = new (C) EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length); 5751 enc = _gvn.transform(enc); 5752 Node* res_mem = _gvn.transform(new (C) SCMemProjNode(enc)); 5753 set_memory(res_mem, mtype); 5754 set_result(enc); 5755 return true; 5756 } 5757 5758 //-------------inline_multiplyToLen----------------------------------- 5759 bool LibraryCallKit::inline_multiplyToLen() { 5760 assert(UseMultiplyToLenIntrinsic, "not implementated on this platform"); 5761 5762 address stubAddr = StubRoutines::multiplyToLen(); 5763 if (stubAddr == NULL) { 5764 return false; // Intrinsic's stub is not implemented on this platform 5765 } 5766 const char* stubName = "multiplyToLen"; 5767 5768 assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters"); 5769 5770 Node* x = argument(1); 5771 Node* xlen = argument(2); 5772 Node* y = argument(3); 5773 Node* ylen = argument(4); 5774 Node* z = argument(5); 5775 5776 const Type* x_type = x->Value(&_gvn); 5777 const Type* y_type = y->Value(&_gvn); 5778 const TypeAryPtr* top_x = x_type->isa_aryptr(); 5779 const TypeAryPtr* top_y = y_type->isa_aryptr(); 5780 if (top_x == NULL || top_x->klass() == NULL || 5781 top_y == NULL || top_y->klass() == NULL) { 5782 // failed array check 5783 return false; 5784 } 5785 5786 BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5787 BasicType y_elem = y_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5788 if (x_elem != T_INT || y_elem != T_INT) { 5789 return false; 5790 } 5791 5792 // Set the original stack and the reexecute bit for the interpreter to reexecute 5793 // the bytecode that invokes BigInteger.multiplyToLen() if deoptimization happens 5794 // on the return from z array allocation in runtime. 5836 } __ end_if(); 5837 5838 sync_kit(ideal); 5839 z = __ value(z_alloc); 5840 // Can't use TypeAryPtr::INTS which uses Bottom offset. 5841 _gvn.set_type(z, TypeOopPtr::make_from_klass(klass)); 5842 // Final sync IdealKit and GraphKit. 5843 final_sync(ideal); 5844 #undef __ 5845 5846 Node* z_start = array_element_address(z, intcon(0), T_INT); 5847 5848 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, 5849 OptoRuntime::multiplyToLen_Type(), 5850 stubAddr, stubName, TypePtr::BOTTOM, 5851 x_start, xlen, y_start, ylen, z_start, zlen); 5852 } // original reexecute is set back here 5853 5854 C->set_has_split_ifs(true); // Has chance for split-if optimization 5855 set_result(z); 5856 return true; 5857 } 5858 5859 5860 /** 5861 * Calculate CRC32 for byte. 5862 * int java.util.zip.CRC32.update(int crc, int b) 5863 */ 5864 bool LibraryCallKit::inline_updateCRC32() { 5865 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support"); 5866 assert(callee()->signature()->size() == 2, "update has 2 parameters"); 5867 // no receiver since it is static method 5868 Node* crc = argument(0); // type: int 5869 Node* b = argument(1); // type: int 5870 5871 /* 5872 * int c = ~ crc; 5873 * b = timesXtoThe32[(b ^ c) & 0xFF]; 5874 * b = b ^ (c >>> 8); 5875 * crc = ~b; | 307 bool inline_number_methods(vmIntrinsics::ID id); 308 bool inline_reference_get(); 309 bool inline_aescrypt_Block(vmIntrinsics::ID id); 310 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id); 311 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); 312 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); 313 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); 314 bool inline_sha_implCompress(vmIntrinsics::ID id); 315 bool inline_digestBase_implCompressMB(int predicate); 316 bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, 317 bool long_state, address stubAddr, const char *stubName, 318 Node* src_start, Node* ofs, Node* limit); 319 Node* get_state_from_sha_object(Node *sha_object); 320 Node* get_state_from_sha5_object(Node *sha_object); 321 Node* inline_digestBase_implCompressMB_predicate(int predicate); 322 bool inline_encodeISOArray(); 323 bool inline_updateCRC32(); 324 bool inline_updateBytesCRC32(); 325 bool inline_updateByteBufferCRC32(); 326 bool inline_multiplyToLen(); 327 bool inline_montgomeryMultiply(); 328 bool inline_montgomerySquare(); 329 330 bool inline_profileBoolean(); 331 }; 332 333 334 //---------------------------make_vm_intrinsic---------------------------- 335 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { 336 vmIntrinsics::ID id = m->intrinsic_id(); 337 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); 338 339 ccstr disable_intr = NULL; 340 341 if ((DisableIntrinsic[0] != '\0' 342 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) || 343 (method_has_option_value("DisableIntrinsic", disable_intr) 344 && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) { 345 // disabled by a user request on the command line: 346 // example: -XX:DisableIntrinsic=_hashCode,_getClass 347 return NULL; 348 } 512 513 case vmIntrinsics::_getAndSetObject: 514 #ifdef _LP64 515 if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; 516 if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL; 517 break; 518 #else 519 if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; 520 break; 521 #endif 522 523 case vmIntrinsics::_aescrypt_encryptBlock: 524 case vmIntrinsics::_aescrypt_decryptBlock: 525 if (!UseAESIntrinsics) return NULL; 526 break; 527 528 case vmIntrinsics::_multiplyToLen: 529 if (!UseMultiplyToLenIntrinsic) return NULL; 530 break; 531 532 case vmIntrinsics::_montgomeryMultiply: 533 if (!UseMontgomeryMultiplyIntrinsic) return NULL; 534 break; 535 case vmIntrinsics::_montgomerySquare: 536 if (!UseMontgomerySquareIntrinsic) return NULL; 537 break; 538 539 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 540 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 541 if (!UseAESIntrinsics) return NULL; 542 // these two require the predicated logic 543 predicates = 1; 544 break; 545 546 case vmIntrinsics::_sha_implCompress: 547 if (!UseSHA1Intrinsics) return NULL; 548 break; 549 550 case vmIntrinsics::_sha2_implCompress: 551 if (!UseSHA256Intrinsics) return NULL; 552 break; 553 554 case vmIntrinsics::_sha5_implCompress: 555 if (!UseSHA512Intrinsics) return NULL; 556 break; 557 558 case vmIntrinsics::_digestBase_implCompressMB: 919 case vmIntrinsics::_Reference_get: return inline_reference_get(); 920 921 case vmIntrinsics::_aescrypt_encryptBlock: 922 case vmIntrinsics::_aescrypt_decryptBlock: return inline_aescrypt_Block(intrinsic_id()); 923 924 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 925 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 926 return inline_cipherBlockChaining_AESCrypt(intrinsic_id()); 927 928 case vmIntrinsics::_sha_implCompress: 929 case vmIntrinsics::_sha2_implCompress: 930 case vmIntrinsics::_sha5_implCompress: 931 return inline_sha_implCompress(intrinsic_id()); 932 933 case vmIntrinsics::_digestBase_implCompressMB: 934 return inline_digestBase_implCompressMB(predicate); 935 936 case vmIntrinsics::_multiplyToLen: 937 return inline_multiplyToLen(); 938 939 case vmIntrinsics::_montgomeryMultiply: 940 return inline_montgomeryMultiply(); 941 case vmIntrinsics::_montgomerySquare: 942 return inline_montgomerySquare(); 943 944 case vmIntrinsics::_encodeISOArray: 945 return inline_encodeISOArray(); 946 947 case vmIntrinsics::_updateCRC32: 948 return inline_updateCRC32(); 949 case vmIntrinsics::_updateBytesCRC32: 950 return inline_updateBytesCRC32(); 951 case vmIntrinsics::_updateByteBufferCRC32: 952 return inline_updateByteBufferCRC32(); 953 954 case vmIntrinsics::_profileBoolean: 955 return inline_profileBoolean(); 956 957 default: 958 // If you get here, it may be that someone has added a new intrinsic 959 // to the list in vmSymbols.hpp without implementing it here. 960 #ifndef PRODUCT 961 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) { 962 tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)", 963 vmIntrinsics::name_at(intrinsic_id()), intrinsic_id()); 5764 Node* enc = new (C) EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length); 5765 enc = _gvn.transform(enc); 5766 Node* res_mem = _gvn.transform(new (C) SCMemProjNode(enc)); 5767 set_memory(res_mem, mtype); 5768 set_result(enc); 5769 return true; 5770 } 5771 5772 //-------------inline_multiplyToLen----------------------------------- 5773 bool LibraryCallKit::inline_multiplyToLen() { 5774 assert(UseMultiplyToLenIntrinsic, "not implementated on this platform"); 5775 5776 address stubAddr = StubRoutines::multiplyToLen(); 5777 if (stubAddr == NULL) { 5778 return false; // Intrinsic's stub is not implemented on this platform 5779 } 5780 const char* stubName = "multiplyToLen"; 5781 5782 assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters"); 5783 5784 // no receiver because it is a static method 5785 Node* x = argument(0); 5786 Node* xlen = argument(1); 5787 Node* y = argument(2); 5788 Node* ylen = argument(3); 5789 Node* z = argument(4); 5790 5791 const Type* x_type = x->Value(&_gvn); 5792 const Type* y_type = y->Value(&_gvn); 5793 const TypeAryPtr* top_x = x_type->isa_aryptr(); 5794 const TypeAryPtr* top_y = y_type->isa_aryptr(); 5795 if (top_x == NULL || top_x->klass() == NULL || 5796 top_y == NULL || top_y->klass() == NULL) { 5797 // failed array check 5798 return false; 5799 } 5800 5801 BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5802 BasicType y_elem = y_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5803 if (x_elem != T_INT || y_elem != T_INT) { 5804 return false; 5805 } 5806 5807 // Set the original stack and the reexecute bit for the interpreter to reexecute 5808 // the bytecode that invokes BigInteger.multiplyToLen() if deoptimization happens 5809 // on the return from z array allocation in runtime. 5851 } __ end_if(); 5852 5853 sync_kit(ideal); 5854 z = __ value(z_alloc); 5855 // Can't use TypeAryPtr::INTS which uses Bottom offset. 5856 _gvn.set_type(z, TypeOopPtr::make_from_klass(klass)); 5857 // Final sync IdealKit and GraphKit. 5858 final_sync(ideal); 5859 #undef __ 5860 5861 Node* z_start = array_element_address(z, intcon(0), T_INT); 5862 5863 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, 5864 OptoRuntime::multiplyToLen_Type(), 5865 stubAddr, stubName, TypePtr::BOTTOM, 5866 x_start, xlen, y_start, ylen, z_start, zlen); 5867 } // original reexecute is set back here 5868 5869 C->set_has_split_ifs(true); // Has chance for split-if optimization 5870 set_result(z); 5871 return true; 5872 } 5873 5874 //-------------inline_montgomeryMultiply----------------------------------- 5875 bool LibraryCallKit::inline_montgomeryMultiply() { 5876 address stubAddr = StubRoutines::montgomeryMultiply(); 5877 if (stubAddr == NULL) { 5878 return false; // Intrinsic's stub is not implemented on this platform 5879 } 5880 5881 assert(UseMontgomeryMultiplyIntrinsic, "not implemented on this platform"); 5882 const char* stubName = "montgomery_square"; 5883 5884 assert(callee()->signature()->size() == 7, "montgomeryMultiply has 7 parameters"); 5885 5886 Node* a = argument(0); 5887 Node* b = argument(1); 5888 Node* n = argument(2); 5889 Node* len = argument(3); 5890 Node* inv = argument(4); 5891 Node* m = argument(6); 5892 5893 const Type* a_type = a->Value(&_gvn); 5894 const TypeAryPtr* top_a = a_type->isa_aryptr(); 5895 const Type* b_type = b->Value(&_gvn); 5896 const TypeAryPtr* top_b = b_type->isa_aryptr(); 5897 const Type* n_type = a->Value(&_gvn); 5898 const TypeAryPtr* top_n = n_type->isa_aryptr(); 5899 const Type* m_type = a->Value(&_gvn); 5900 const TypeAryPtr* top_m = m_type->isa_aryptr(); 5901 if (top_a == NULL || top_a->klass() == NULL || 5902 top_b == NULL || top_b->klass() == NULL || 5903 top_n == NULL || top_n->klass() == NULL || 5904 top_m == NULL || top_m->klass() == NULL) { 5905 // failed array check 5906 return false; 5907 } 5908 5909 BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5910 BasicType b_elem = b_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5911 BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5912 BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5913 if (a_elem != T_INT || b_elem != T_INT || n_elem != T_INT || m_elem != T_INT) { 5914 return false; 5915 } 5916 5917 // Make the call 5918 { 5919 Node* a_start = array_element_address(a, intcon(0), a_elem); 5920 Node* b_start = array_element_address(b, intcon(0), b_elem); 5921 Node* n_start = array_element_address(n, intcon(0), n_elem); 5922 Node* m_start = array_element_address(m, intcon(0), m_elem); 5923 5924 Node* call = make_runtime_call(RC_LEAF, 5925 OptoRuntime::montgomeryMultiply_Type(), 5926 stubAddr, stubName, TypePtr::BOTTOM, 5927 a_start, b_start, n_start, len, inv, top(), 5928 m_start); 5929 set_result(m); 5930 } 5931 5932 return true; 5933 } 5934 5935 bool LibraryCallKit::inline_montgomerySquare() { 5936 address stubAddr = StubRoutines::montgomerySquare(); 5937 if (stubAddr == NULL) { 5938 return false; // Intrinsic's stub is not implemented on this platform 5939 } 5940 5941 assert(UseMontgomerySquareIntrinsic, "not implemented on this platform"); 5942 const char* stubName = "montgomery_square"; 5943 5944 assert(callee()->signature()->size() == 6, "montgomerySquare has 6 parameters"); 5945 5946 Node* a = argument(0); 5947 Node* n = argument(1); 5948 Node* len = argument(2); 5949 Node* inv = argument(3); 5950 Node* m = argument(5); 5951 5952 const Type* a_type = a->Value(&_gvn); 5953 const TypeAryPtr* top_a = a_type->isa_aryptr(); 5954 const Type* n_type = a->Value(&_gvn); 5955 const TypeAryPtr* top_n = n_type->isa_aryptr(); 5956 const Type* m_type = a->Value(&_gvn); 5957 const TypeAryPtr* top_m = m_type->isa_aryptr(); 5958 if (top_a == NULL || top_a->klass() == NULL || 5959 top_n == NULL || top_n->klass() == NULL || 5960 top_m == NULL || top_m->klass() == NULL) { 5961 // failed array check 5962 return false; 5963 } 5964 5965 BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5966 BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5967 BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5968 if (a_elem != T_INT || n_elem != T_INT || m_elem != T_INT) { 5969 return false; 5970 } 5971 5972 // Make the call 5973 { 5974 Node* a_start = array_element_address(a, intcon(0), a_elem); 5975 Node* n_start = array_element_address(n, intcon(0), n_elem); 5976 Node* m_start = array_element_address(m, intcon(0), m_elem); 5977 5978 Node* call = make_runtime_call(RC_LEAF, 5979 OptoRuntime::montgomerySquare_Type(), 5980 stubAddr, stubName, TypePtr::BOTTOM, 5981 a_start, n_start, len, inv, top(), 5982 m_start); 5983 set_result(m); 5984 } 5985 5986 return true; 5987 } 5988 5989 5990 /** 5991 * Calculate CRC32 for byte. 5992 * int java.util.zip.CRC32.update(int crc, int b) 5993 */ 5994 bool LibraryCallKit::inline_updateCRC32() { 5995 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support"); 5996 assert(callee()->signature()->size() == 2, "update has 2 parameters"); 5997 // no receiver since it is static method 5998 Node* crc = argument(0); // type: int 5999 Node* b = argument(1); // type: int 6000 6001 /* 6002 * int c = ~ crc; 6003 * b = timesXtoThe32[(b ^ c) & 0xFF]; 6004 * b = b ^ (c >>> 8); 6005 * crc = ~b; |