274 bool inline_reference_get(); 275 bool inline_Class_cast(); 276 bool inline_aescrypt_Block(vmIntrinsics::ID id); 277 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id); 278 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); 279 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); 280 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); 281 bool inline_sha_implCompress(vmIntrinsics::ID id); 282 bool inline_digestBase_implCompressMB(int predicate); 283 bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, 284 bool long_state, address stubAddr, const char *stubName, 285 Node* src_start, Node* ofs, Node* limit); 286 Node* get_state_from_sha_object(Node *sha_object); 287 Node* get_state_from_sha5_object(Node *sha_object); 288 Node* inline_digestBase_implCompressMB_predicate(int predicate); 289 bool inline_encodeISOArray(); 290 bool inline_updateCRC32(); 291 bool inline_updateBytesCRC32(); 292 bool inline_updateByteBufferCRC32(); 293 bool inline_multiplyToLen(); 294 295 bool inline_profileBoolean(); 296 bool inline_isCompileConstant(); 297 }; 298 299 300 //---------------------------make_vm_intrinsic---------------------------- 301 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { 302 vmIntrinsics::ID id = m->intrinsic_id(); 303 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); 304 305 ccstr disable_intr = NULL; 306 307 if ((DisableIntrinsic[0] != '\0' 308 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) || 309 (method_has_option_value("DisableIntrinsic", disable_intr) 310 && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) { 311 // disabled by a user request on the command line: 312 // example: -XX:DisableIntrinsic=_hashCode,_getClass 313 return NULL; 477 478 case vmIntrinsics::_getAndSetObject: 479 #ifdef _LP64 480 if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; 481 if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL; 482 break; 483 #else 484 if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; 485 break; 486 #endif 487 488 case vmIntrinsics::_aescrypt_encryptBlock: 489 case vmIntrinsics::_aescrypt_decryptBlock: 490 if (!UseAESIntrinsics) return NULL; 491 break; 492 493 case vmIntrinsics::_multiplyToLen: 494 if (!UseMultiplyToLenIntrinsic) return NULL; 495 break; 496 497 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 498 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 499 if (!UseAESIntrinsics) return NULL; 500 // these two require the predicated logic 501 predicates = 1; 502 break; 503 504 case vmIntrinsics::_sha_implCompress: 505 if (!UseSHA1Intrinsics) return NULL; 506 break; 507 508 case vmIntrinsics::_sha2_implCompress: 509 if (!UseSHA256Intrinsics) return NULL; 510 break; 511 512 case vmIntrinsics::_sha5_implCompress: 513 if (!UseSHA512Intrinsics) return NULL; 514 break; 515 516 case vmIntrinsics::_digestBase_implCompressMB: 896 case vmIntrinsics::_Class_cast: return inline_Class_cast(); 897 898 case vmIntrinsics::_aescrypt_encryptBlock: 899 case vmIntrinsics::_aescrypt_decryptBlock: return inline_aescrypt_Block(intrinsic_id()); 900 901 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 902 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 903 return inline_cipherBlockChaining_AESCrypt(intrinsic_id()); 904 905 case vmIntrinsics::_sha_implCompress: 906 case vmIntrinsics::_sha2_implCompress: 907 case vmIntrinsics::_sha5_implCompress: 908 return inline_sha_implCompress(intrinsic_id()); 909 910 case vmIntrinsics::_digestBase_implCompressMB: 911 return inline_digestBase_implCompressMB(predicate); 912 913 case vmIntrinsics::_multiplyToLen: 914 return inline_multiplyToLen(); 915 916 case vmIntrinsics::_encodeISOArray: 917 return inline_encodeISOArray(); 918 919 case vmIntrinsics::_updateCRC32: 920 return inline_updateCRC32(); 921 case vmIntrinsics::_updateBytesCRC32: 922 return inline_updateBytesCRC32(); 923 case vmIntrinsics::_updateByteBufferCRC32: 924 return inline_updateByteBufferCRC32(); 925 926 case vmIntrinsics::_profileBoolean: 927 return inline_profileBoolean(); 928 case vmIntrinsics::_isCompileConstant: 929 return inline_isCompileConstant(); 930 931 default: 932 // If you get here, it may be that someone has added a new intrinsic 933 // to the list in vmSymbols.hpp without implementing it here. 934 #ifndef PRODUCT 935 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) { 5287 z = __ value(z_alloc); 5288 // Can't use TypeAryPtr::INTS which uses Bottom offset. 5289 _gvn.set_type(z, TypeOopPtr::make_from_klass(klass)); 5290 // Final sync IdealKit and GraphKit. 5291 final_sync(ideal); 5292 #undef __ 5293 5294 Node* z_start = array_element_address(z, intcon(0), T_INT); 5295 5296 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, 5297 OptoRuntime::multiplyToLen_Type(), 5298 stubAddr, stubName, TypePtr::BOTTOM, 5299 x_start, xlen, y_start, ylen, z_start, zlen); 5300 } // original reexecute is set back here 5301 5302 C->set_has_split_ifs(true); // Has chance for split-if optimization 5303 set_result(z); 5304 return true; 5305 } 5306 5307 5308 /** 5309 * Calculate CRC32 for byte. 5310 * int java.util.zip.CRC32.update(int crc, int b) 5311 */ 5312 bool LibraryCallKit::inline_updateCRC32() { 5313 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support"); 5314 assert(callee()->signature()->size() == 2, "update has 2 parameters"); 5315 // no receiver since it is static method 5316 Node* crc = argument(0); // type: int 5317 Node* b = argument(1); // type: int 5318 5319 /* 5320 * int c = ~ crc; 5321 * b = timesXtoThe32[(b ^ c) & 0xFF]; 5322 * b = b ^ (c >>> 8); 5323 * crc = ~b; 5324 */ 5325 5326 Node* M1 = intcon(-1); | 274 bool inline_reference_get(); 275 bool inline_Class_cast(); 276 bool inline_aescrypt_Block(vmIntrinsics::ID id); 277 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id); 278 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); 279 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); 280 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); 281 bool inline_sha_implCompress(vmIntrinsics::ID id); 282 bool inline_digestBase_implCompressMB(int predicate); 283 bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, 284 bool long_state, address stubAddr, const char *stubName, 285 Node* src_start, Node* ofs, Node* limit); 286 Node* get_state_from_sha_object(Node *sha_object); 287 Node* get_state_from_sha5_object(Node *sha_object); 288 Node* inline_digestBase_implCompressMB_predicate(int predicate); 289 bool inline_encodeISOArray(); 290 bool inline_updateCRC32(); 291 bool inline_updateBytesCRC32(); 292 bool inline_updateByteBufferCRC32(); 293 bool inline_multiplyToLen(); 294 bool inline_squareToLen(); 295 bool inline_mulAdd(); 296 297 bool inline_profileBoolean(); 298 bool inline_isCompileConstant(); 299 }; 300 301 302 //---------------------------make_vm_intrinsic---------------------------- 303 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { 304 vmIntrinsics::ID id = m->intrinsic_id(); 305 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); 306 307 ccstr disable_intr = NULL; 308 309 if ((DisableIntrinsic[0] != '\0' 310 && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) || 311 (method_has_option_value("DisableIntrinsic", disable_intr) 312 && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) { 313 // disabled by a user request on the command line: 314 // example: -XX:DisableIntrinsic=_hashCode,_getClass 315 return NULL; 479 480 case vmIntrinsics::_getAndSetObject: 481 #ifdef _LP64 482 if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; 483 if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL; 484 break; 485 #else 486 if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL; 487 break; 488 #endif 489 490 case vmIntrinsics::_aescrypt_encryptBlock: 491 case vmIntrinsics::_aescrypt_decryptBlock: 492 if (!UseAESIntrinsics) return NULL; 493 break; 494 495 case vmIntrinsics::_multiplyToLen: 496 if (!UseMultiplyToLenIntrinsic) return NULL; 497 break; 498 499 case vmIntrinsics::_squareToLen: 500 if (!UseSquareToLenIntrinsic) return NULL; 501 break; 502 503 case vmIntrinsics::_mulAdd: 504 if (!UseMulAddIntrinsic) return NULL; 505 break; 506 507 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 508 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 509 if (!UseAESIntrinsics) return NULL; 510 // these two require the predicated logic 511 predicates = 1; 512 break; 513 514 case vmIntrinsics::_sha_implCompress: 515 if (!UseSHA1Intrinsics) return NULL; 516 break; 517 518 case vmIntrinsics::_sha2_implCompress: 519 if (!UseSHA256Intrinsics) return NULL; 520 break; 521 522 case vmIntrinsics::_sha5_implCompress: 523 if (!UseSHA512Intrinsics) return NULL; 524 break; 525 526 case vmIntrinsics::_digestBase_implCompressMB: 906 case vmIntrinsics::_Class_cast: return inline_Class_cast(); 907 908 case vmIntrinsics::_aescrypt_encryptBlock: 909 case vmIntrinsics::_aescrypt_decryptBlock: return inline_aescrypt_Block(intrinsic_id()); 910 911 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 912 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 913 return inline_cipherBlockChaining_AESCrypt(intrinsic_id()); 914 915 case vmIntrinsics::_sha_implCompress: 916 case vmIntrinsics::_sha2_implCompress: 917 case vmIntrinsics::_sha5_implCompress: 918 return inline_sha_implCompress(intrinsic_id()); 919 920 case vmIntrinsics::_digestBase_implCompressMB: 921 return inline_digestBase_implCompressMB(predicate); 922 923 case vmIntrinsics::_multiplyToLen: 924 return inline_multiplyToLen(); 925 926 case vmIntrinsics::_squareToLen: 927 return inline_squareToLen(); 928 929 case vmIntrinsics::_mulAdd: 930 return inline_mulAdd(); 931 932 case vmIntrinsics::_encodeISOArray: 933 return inline_encodeISOArray(); 934 935 case vmIntrinsics::_updateCRC32: 936 return inline_updateCRC32(); 937 case vmIntrinsics::_updateBytesCRC32: 938 return inline_updateBytesCRC32(); 939 case vmIntrinsics::_updateByteBufferCRC32: 940 return inline_updateByteBufferCRC32(); 941 942 case vmIntrinsics::_profileBoolean: 943 return inline_profileBoolean(); 944 case vmIntrinsics::_isCompileConstant: 945 return inline_isCompileConstant(); 946 947 default: 948 // If you get here, it may be that someone has added a new intrinsic 949 // to the list in vmSymbols.hpp without implementing it here. 950 #ifndef PRODUCT 951 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) { 5303 z = __ value(z_alloc); 5304 // Can't use TypeAryPtr::INTS which uses Bottom offset. 5305 _gvn.set_type(z, TypeOopPtr::make_from_klass(klass)); 5306 // Final sync IdealKit and GraphKit. 5307 final_sync(ideal); 5308 #undef __ 5309 5310 Node* z_start = array_element_address(z, intcon(0), T_INT); 5311 5312 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, 5313 OptoRuntime::multiplyToLen_Type(), 5314 stubAddr, stubName, TypePtr::BOTTOM, 5315 x_start, xlen, y_start, ylen, z_start, zlen); 5316 } // original reexecute is set back here 5317 5318 C->set_has_split_ifs(true); // Has chance for split-if optimization 5319 set_result(z); 5320 return true; 5321 } 5322 5323 //-------------inline_squareToLen------------------------------------ 5324 bool LibraryCallKit::inline_squareToLen() { 5325 assert(UseSquareToLenIntrinsic, "not implementated on this platform"); 5326 5327 address stubAddr = StubRoutines::squareToLen(); 5328 if (stubAddr == NULL) { 5329 return false; // Intrinsic's stub is not implemented on this platform 5330 } 5331 const char* stubName = "squareToLen"; 5332 5333 assert(callee()->signature()->size() == 4, "implSquareToLen has 4 parameters"); 5334 5335 Node* x = argument(0); 5336 Node* len = argument(1); 5337 Node* z = argument(2); 5338 Node* zlen = argument(3); 5339 5340 const Type* x_type = x->Value(&_gvn); 5341 const Type* z_type = z->Value(&_gvn); 5342 const TypeAryPtr* top_x = x_type->isa_aryptr(); 5343 const TypeAryPtr* top_z = z_type->isa_aryptr(); 5344 if (top_x == NULL || top_x->klass() == NULL || 5345 top_z == NULL || top_z->klass() == NULL) { 5346 // failed array check 5347 return false; 5348 } 5349 5350 BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5351 BasicType z_elem = z_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5352 if (x_elem != T_INT || z_elem != T_INT) { 5353 return false; 5354 } 5355 5356 5357 Node* x_start = array_element_address(x, intcon(0), x_elem); 5358 Node* z_start = array_element_address(z, intcon(0), z_elem); 5359 5360 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, 5361 OptoRuntime::squareToLen_Type(), 5362 stubAddr, stubName, TypePtr::BOTTOM, 5363 x_start, len, z_start, zlen); 5364 5365 set_result(z); 5366 return true; 5367 } 5368 5369 //-------------inline_mulAdd------------------------------------------ 5370 bool LibraryCallKit::inline_mulAdd() { 5371 assert(UseMulAddIntrinsic, "not implementated on this platform"); 5372 5373 address stubAddr = StubRoutines::mulAdd(); 5374 if (stubAddr == NULL) { 5375 return false; // Intrinsic's stub is not implemented on this platform 5376 } 5377 const char* stubName = "mulAdd"; 5378 5379 assert(callee()->signature()->size() == 5, "mulAdd has 5 parameters"); 5380 5381 Node* out = argument(0); 5382 Node* in = argument(1); 5383 Node* offset = argument(2); 5384 Node* len = argument(3); 5385 Node* k = argument(4); 5386 5387 const Type* out_type = out->Value(&_gvn); 5388 const Type* in_type = in->Value(&_gvn); 5389 const TypeAryPtr* top_out = out_type->isa_aryptr(); 5390 const TypeAryPtr* top_in = in_type->isa_aryptr(); 5391 if (top_out == NULL || top_out->klass() == NULL || 5392 top_in == NULL || top_in->klass() == NULL) { 5393 // failed array check 5394 return false; 5395 } 5396 5397 BasicType out_elem = out_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5398 BasicType in_elem = in_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5399 if (out_elem != T_INT || in_elem != T_INT) { 5400 return false; 5401 } 5402 5403 Node* outlen = load_array_length(out); 5404 Node* new_offset = _gvn.transform(new SubINode(outlen, offset)); 5405 Node* out_start = array_element_address(out, intcon(0), out_elem); 5406 Node* in_start = array_element_address(in, intcon(0), in_elem); 5407 5408 Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, 5409 OptoRuntime::mulAdd_Type(), 5410 stubAddr, stubName, TypePtr::BOTTOM, 5411 out_start,in_start, new_offset, len, k); 5412 Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); 5413 set_result(result); 5414 return true; 5415 } 5416 5417 5418 /** 5419 * Calculate CRC32 for byte. 5420 * int java.util.zip.CRC32.update(int crc, int b) 5421 */ 5422 bool LibraryCallKit::inline_updateCRC32() { 5423 assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support"); 5424 assert(callee()->signature()->size() == 2, "update has 2 parameters"); 5425 // no receiver since it is static method 5426 Node* crc = argument(0); // type: int 5427 Node* b = argument(1); // type: int 5428 5429 /* 5430 * int c = ~ crc; 5431 * b = timesXtoThe32[(b ^ c) & 0xFF]; 5432 * b = b ^ (c >>> 8); 5433 * crc = ~b; 5434 */ 5435 5436 Node* M1 = intcon(-1); |