src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 8055494 Sdiff src/share/vm/opto

src/share/vm/opto/library_call.cpp

Print this page




 268   bool inline_fp_conversions(vmIntrinsics::ID id);
 269   bool inline_number_methods(vmIntrinsics::ID id);
 270   bool inline_reference_get();
 271   bool inline_aescrypt_Block(vmIntrinsics::ID id);
 272   bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
 273   Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
 274   Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
 275   Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
 276   bool inline_sha_implCompress(vmIntrinsics::ID id);
 277   bool inline_digestBase_implCompressMB(int predicate);
 278   bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
 279                                  bool long_state, address stubAddr, const char *stubName,
 280                                  Node* src_start, Node* ofs, Node* limit);
 281   Node* get_state_from_sha_object(Node *sha_object);
 282   Node* get_state_from_sha5_object(Node *sha_object);
 283   Node* inline_digestBase_implCompressMB_predicate(int predicate);
 284   bool inline_encodeISOArray();
 285   bool inline_updateCRC32();
 286   bool inline_updateBytesCRC32();
 287   bool inline_updateByteBufferCRC32();

 288 };
 289 
 290 
 291 //---------------------------make_vm_intrinsic----------------------------
 292 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
 293   vmIntrinsics::ID id = m->intrinsic_id();
 294   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 295 
 296   if (DisableIntrinsic[0] != '\0'
 297       && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) {




 298     // disabled by a user request on the command line:
 299     // example: -XX:DisableIntrinsic=_hashCode,_getClass
 300     return NULL;
 301   }
 302 
 303   if (!m->is_loaded()) {
 304     // do not attempt to inline unloaded methods
 305     return NULL;
 306   }
 307 
 308   // Only a few intrinsics implement a virtual dispatch.
 309   // They are expensive calls which are also frequently overridden.
 310   if (is_virtual) {
 311     switch (id) {
 312     case vmIntrinsics::_hashCode:
 313     case vmIntrinsics::_clone:
 314       // OK, Object.hashCode and Object.clone intrinsics come in both flavors
 315       break;
 316     default:
 317       return NULL;


 460 
 461   case vmIntrinsics::_getAndSetLong:
 462     if (!Matcher::match_rule_supported(Op_GetAndSetL)) return NULL;
 463     break;
 464 
 465   case vmIntrinsics::_getAndSetObject:
 466 #ifdef _LP64
 467     if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
 468     if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL;
 469     break;
 470 #else
 471     if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
 472     break;
 473 #endif
 474 
 475   case vmIntrinsics::_aescrypt_encryptBlock:
 476   case vmIntrinsics::_aescrypt_decryptBlock:
 477     if (!UseAESIntrinsics) return NULL;
 478     break;
 479 




 480   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
 481   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
 482     if (!UseAESIntrinsics) return NULL;
 483     // these two require the predicated logic
 484     predicates = 1;
 485     break;
 486 
 487   case vmIntrinsics::_sha_implCompress:
 488     if (!UseSHA1Intrinsics) return NULL;
 489     break;
 490 
 491   case vmIntrinsics::_sha2_implCompress:
 492     if (!UseSHA256Intrinsics) return NULL;
 493     break;
 494 
 495   case vmIntrinsics::_sha5_implCompress:
 496     if (!UseSHA512Intrinsics) return NULL;
 497     break;
 498 
 499   case vmIntrinsics::_digestBase_implCompressMB:


 859 
 860   case vmIntrinsics::_getCallerClass:           return inline_native_Reflection_getCallerClass();
 861 
 862   case vmIntrinsics::_Reference_get:            return inline_reference_get();
 863 
 864   case vmIntrinsics::_aescrypt_encryptBlock:
 865   case vmIntrinsics::_aescrypt_decryptBlock:    return inline_aescrypt_Block(intrinsic_id());
 866 
 867   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
 868   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
 869     return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
 870 
 871   case vmIntrinsics::_sha_implCompress:
 872   case vmIntrinsics::_sha2_implCompress:
 873   case vmIntrinsics::_sha5_implCompress:
 874     return inline_sha_implCompress(intrinsic_id());
 875 
 876   case vmIntrinsics::_digestBase_implCompressMB:
 877     return inline_digestBase_implCompressMB(predicate);
 878 



 879   case vmIntrinsics::_encodeISOArray:
 880     return inline_encodeISOArray();
 881 
 882   case vmIntrinsics::_updateCRC32:
 883     return inline_updateCRC32();
 884   case vmIntrinsics::_updateBytesCRC32:
 885     return inline_updateBytesCRC32();
 886   case vmIntrinsics::_updateByteBufferCRC32:
 887     return inline_updateByteBufferCRC32();
 888 
 889   default:
 890     // If you get here, it may be that someone has added a new intrinsic
 891     // to the list in vmSymbols.hpp without implementing it here.
 892 #ifndef PRODUCT
 893     if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
 894       tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
 895                     vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
 896     }
 897 #endif
 898     return false;


4907   // Figure out the size and type of the elements we will be copying.
4908   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
4909   BasicType dst_elem = dst_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
4910   if (src_elem != T_CHAR || dst_elem != T_BYTE) {
4911     return false;
4912   }
4913   Node* src_start = array_element_address(src, src_offset, src_elem);
4914   Node* dst_start = array_element_address(dst, dst_offset, dst_elem);
4915   // 'src_start' points to src array + scaled offset
4916   // 'dst_start' points to dst array + scaled offset
4917 
4918   const TypeAryPtr* mtype = TypeAryPtr::BYTES;
4919   Node* enc = new EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length);
4920   enc = _gvn.transform(enc);
4921   Node* res_mem = _gvn.transform(new SCMemProjNode(enc));
4922   set_memory(res_mem, mtype);
4923   set_result(enc);
4924   return true;
4925 }
4926 




































































































4927 /**
4928  * Calculate CRC32 for byte.
4929  * int java.util.zip.CRC32.update(int crc, int b)
4930  */
4931 bool LibraryCallKit::inline_updateCRC32() {
4932   assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
4933   assert(callee()->signature()->size() == 2, "update has 2 parameters");
4934   // no receiver since it is static method
4935   Node* crc  = argument(0); // type: int
4936   Node* b    = argument(1); // type: int
4937 
4938   /*
4939    *    int c = ~ crc;
4940    *    b = timesXtoThe32[(b ^ c) & 0xFF];
4941    *    b = b ^ (c >>> 8);
4942    *    crc = ~b;
4943    */
4944 
4945   Node* M1 = intcon(-1);
4946   crc = _gvn.transform(new XorINode(crc, M1));




 268   bool inline_fp_conversions(vmIntrinsics::ID id);
 269   bool inline_number_methods(vmIntrinsics::ID id);
 270   bool inline_reference_get();
 271   bool inline_aescrypt_Block(vmIntrinsics::ID id);
 272   bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
 273   Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
 274   Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
 275   Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
 276   bool inline_sha_implCompress(vmIntrinsics::ID id);
 277   bool inline_digestBase_implCompressMB(int predicate);
 278   bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
 279                                  bool long_state, address stubAddr, const char *stubName,
 280                                  Node* src_start, Node* ofs, Node* limit);
 281   Node* get_state_from_sha_object(Node *sha_object);
 282   Node* get_state_from_sha5_object(Node *sha_object);
 283   Node* inline_digestBase_implCompressMB_predicate(int predicate);
 284   bool inline_encodeISOArray();
 285   bool inline_updateCRC32();
 286   bool inline_updateBytesCRC32();
 287   bool inline_updateByteBufferCRC32();
 288   bool inline_multiplyToLen();
 289 };
 290 
 291 
 292 //---------------------------make_vm_intrinsic----------------------------
 293 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
 294   vmIntrinsics::ID id = m->intrinsic_id();
 295   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 296 
 297   ccstr disable_intr = NULL;
 298 
 299   if ((DisableIntrinsic[0] != '\0'
 300        && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
 301       (method_has_option_value("DisableIntrinsic", disable_intr)
 302        && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
 303     // disabled by a user request on the command line:
 304     // example: -XX:DisableIntrinsic=_hashCode,_getClass
 305     return NULL;
 306   }
 307 
 308   if (!m->is_loaded()) {
 309     // do not attempt to inline unloaded methods
 310     return NULL;
 311   }
 312 
 313   // Only a few intrinsics implement a virtual dispatch.
 314   // They are expensive calls which are also frequently overridden.
 315   if (is_virtual) {
 316     switch (id) {
 317     case vmIntrinsics::_hashCode:
 318     case vmIntrinsics::_clone:
 319       // OK, Object.hashCode and Object.clone intrinsics come in both flavors
 320       break;
 321     default:
 322       return NULL;


 465 
 466   case vmIntrinsics::_getAndSetLong:
 467     if (!Matcher::match_rule_supported(Op_GetAndSetL)) return NULL;
 468     break;
 469 
 470   case vmIntrinsics::_getAndSetObject:
 471 #ifdef _LP64
 472     if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
 473     if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL;
 474     break;
 475 #else
 476     if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
 477     break;
 478 #endif
 479 
 480   case vmIntrinsics::_aescrypt_encryptBlock:
 481   case vmIntrinsics::_aescrypt_decryptBlock:
 482     if (!UseAESIntrinsics) return NULL;
 483     break;
 484 
 485   case vmIntrinsics::_multiplyToLen:
 486     if (!UseMultiplyToLenIntrinsic) return NULL;
 487     break;
 488 
 489   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
 490   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
 491     if (!UseAESIntrinsics) return NULL;
 492     // these two require the predicated logic
 493     predicates = 1;
 494     break;
 495 
 496   case vmIntrinsics::_sha_implCompress:
 497     if (!UseSHA1Intrinsics) return NULL;
 498     break;
 499 
 500   case vmIntrinsics::_sha2_implCompress:
 501     if (!UseSHA256Intrinsics) return NULL;
 502     break;
 503 
 504   case vmIntrinsics::_sha5_implCompress:
 505     if (!UseSHA512Intrinsics) return NULL;
 506     break;
 507 
 508   case vmIntrinsics::_digestBase_implCompressMB:


 868 
 869   case vmIntrinsics::_getCallerClass:           return inline_native_Reflection_getCallerClass();
 870 
 871   case vmIntrinsics::_Reference_get:            return inline_reference_get();
 872 
 873   case vmIntrinsics::_aescrypt_encryptBlock:
 874   case vmIntrinsics::_aescrypt_decryptBlock:    return inline_aescrypt_Block(intrinsic_id());
 875 
 876   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
 877   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
 878     return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
 879 
 880   case vmIntrinsics::_sha_implCompress:
 881   case vmIntrinsics::_sha2_implCompress:
 882   case vmIntrinsics::_sha5_implCompress:
 883     return inline_sha_implCompress(intrinsic_id());
 884 
 885   case vmIntrinsics::_digestBase_implCompressMB:
 886     return inline_digestBase_implCompressMB(predicate);
 887 
 888   case vmIntrinsics::_multiplyToLen:
 889     return inline_multiplyToLen();
 890 
 891   case vmIntrinsics::_encodeISOArray:
 892     return inline_encodeISOArray();
 893 
 894   case vmIntrinsics::_updateCRC32:
 895     return inline_updateCRC32();
 896   case vmIntrinsics::_updateBytesCRC32:
 897     return inline_updateBytesCRC32();
 898   case vmIntrinsics::_updateByteBufferCRC32:
 899     return inline_updateByteBufferCRC32();
 900 
 901   default:
 902     // If you get here, it may be that someone has added a new intrinsic
 903     // to the list in vmSymbols.hpp without implementing it here.
 904 #ifndef PRODUCT
 905     if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
 906       tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
 907                     vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
 908     }
 909 #endif
 910     return false;


4919   // Figure out the size and type of the elements we will be copying.
4920   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
4921   BasicType dst_elem = dst_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
4922   if (src_elem != T_CHAR || dst_elem != T_BYTE) {
4923     return false;
4924   }
4925   Node* src_start = array_element_address(src, src_offset, src_elem);
4926   Node* dst_start = array_element_address(dst, dst_offset, dst_elem);
4927   // 'src_start' points to src array + scaled offset
4928   // 'dst_start' points to dst array + scaled offset
4929 
4930   const TypeAryPtr* mtype = TypeAryPtr::BYTES;
4931   Node* enc = new EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length);
4932   enc = _gvn.transform(enc);
4933   Node* res_mem = _gvn.transform(new SCMemProjNode(enc));
4934   set_memory(res_mem, mtype);
4935   set_result(enc);
4936   return true;
4937 }
4938 
4939 //-------------inline_multiplyToLen-----------------------------------
4940 bool LibraryCallKit::inline_multiplyToLen() {
4941   assert(UseMultiplyToLenIntrinsic, "not implementated on this platform");
4942 
4943   address stubAddr = StubRoutines::multiplyToLen();
4944   if (stubAddr == NULL) {
4945     return false; // Intrinsic's stub is not implemented on this platform
4946   }
4947   const char* stubName = "multiplyToLen";
4948 
4949   assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters");
4950 
4951   Node* x    = argument(1);
4952   Node* xlen = argument(2);
4953   Node* y    = argument(3);
4954   Node* ylen = argument(4);
4955   Node* z    = argument(5);
4956 
4957   const Type* x_type = x->Value(&_gvn);
4958   const Type* y_type = y->Value(&_gvn);
4959   const TypeAryPtr* top_x = x_type->isa_aryptr();
4960   const TypeAryPtr* top_y = y_type->isa_aryptr();
4961   if (top_x  == NULL || top_x->klass()  == NULL ||
4962       top_y == NULL || top_y->klass() == NULL) {
4963     // failed array check
4964     return false;
4965   }
4966 
4967   BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
4968   BasicType y_elem = y_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
4969   if (x_elem != T_INT || y_elem != T_INT) {
4970     return false;
4971   }
4972 
4973   // Set the original stack and the reexecute bit for the interpreter to reexecute
4974   // the bytecode that invokes BigInteger.multiplyToLen() if deoptimization happens
4975   // on the return from z array allocation in runtime.
4976   { PreserveReexecuteState preexecs(this);
4977     jvms()->set_should_reexecute(true);
4978 
4979     Node* x_start = array_element_address(x, intcon(0), x_elem);
4980     Node* y_start = array_element_address(y, intcon(0), y_elem);
4981     // 'x_start' points to x array + scaled xlen
4982     // 'y_start' points to y array + scaled ylen
4983 
4984     // Allocate the result array
4985     Node* zlen = _gvn.transform(new AddINode(xlen, ylen));
4986     Node* klass_node = makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_INT)));
4987 
4988     IdealKit ideal(this);
4989 
4990 #define __ ideal.
4991      Node* one = __ ConI(1);
4992      Node* zero = __ ConI(0);
4993      IdealVariable need_alloc(ideal), z_alloc(ideal);  __ declarations_done();
4994      __ set(need_alloc, zero);
4995      __ set(z_alloc, z);
4996      __ if_then(z, BoolTest::eq, null()); {
4997        __ increment (need_alloc, one);
4998      } __ else_(); {
4999        // Update graphKit memory and control from IdealKit.
5000        sync_kit(ideal);
5001        Node* zlen_arg = load_array_length(z);
5002        // Update IdealKit memory and control from graphKit.
5003        __ sync_kit(this);
5004        __ if_then(zlen_arg, BoolTest::lt, zlen); {
5005          __ increment (need_alloc, one);
5006        } __ end_if();
5007      } __ end_if();
5008 
5009      __ if_then(__ value(need_alloc), BoolTest::ne, zero); {
5010        // Update graphKit memory and control from IdealKit.
5011        sync_kit(ideal);
5012        Node * narr = new_array(klass_node, zlen, 1);
5013        // Update IdealKit memory and control from graphKit.
5014        __ sync_kit(this);
5015        __ set(z_alloc, narr);
5016      } __ end_if();
5017 
5018      sync_kit(ideal);
5019      z = __ value(z_alloc);
5020      _gvn.set_type(z, TypeAryPtr::INTS);
5021      // Final sync IdealKit and GraphKit.
5022      final_sync(ideal);
5023 #undef __
5024 
5025     Node* z_start = array_element_address(z, intcon(0), T_INT);
5026 
5027     Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
5028                                    OptoRuntime::multiplyToLen_Type(),
5029                                    stubAddr, stubName, TypePtr::BOTTOM,
5030                                    x_start, xlen, y_start, ylen, z_start, zlen);
5031   } // original reexecute is set back here
5032 
5033   C->set_has_split_ifs(true); // Has chance for split-if optimization
5034   set_result(z);
5035   return true;
5036 }
5037 
5038 
5039 /**
5040  * Calculate CRC32 for byte.
5041  * int java.util.zip.CRC32.update(int crc, int b)
5042  */
5043 bool LibraryCallKit::inline_updateCRC32() {
5044   assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
5045   assert(callee()->signature()->size() == 2, "update has 2 parameters");
5046   // no receiver since it is static method
5047   Node* crc  = argument(0); // type: int
5048   Node* b    = argument(1); // type: int
5049 
5050   /*
5051    *    int c = ~ crc;
5052    *    b = timesXtoThe32[(b ^ c) & 0xFF];
5053    *    b = b ^ (c >>> 8);
5054    *    crc = ~b;
5055    */
5056 
5057   Node* M1 = intcon(-1);
5058   crc = _gvn.transform(new XorINode(crc, M1));


src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File