< prev index next >

src/share/vm/opto/library_call.cpp

Print this page
rev 8499 : 8086069: Adapt runtime calls to recent intrinsics to pass ints as long


5294 
5295      __ if_then(__ value(need_alloc), BoolTest::ne, zero); {
5296        // Update graphKit memory and control from IdealKit.
5297        sync_kit(ideal);
5298        Node * narr = new_array(klass_node, zlen, 1);
5299        // Update IdealKit memory and control from graphKit.
5300        __ sync_kit(this);
5301        __ set(z_alloc, narr);
5302      } __ end_if();
5303 
5304      sync_kit(ideal);
5305      z = __ value(z_alloc);
5306      // Can't use TypeAryPtr::INTS which uses Bottom offset.
5307      _gvn.set_type(z, TypeOopPtr::make_from_klass(klass));
5308      // Final sync IdealKit and GraphKit.
5309      final_sync(ideal);
5310 #undef __
5311 
5312     Node* z_start = array_element_address(z, intcon(0), T_INT);
5313 
5314     Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,










5315                                    OptoRuntime::multiplyToLen_Type(),
5316                                    stubAddr, stubName, TypePtr::BOTTOM,
5317                                    x_start, xlen, y_start, ylen, z_start, zlen);

5318   } // original reexecute is set back here
5319 
5320   C->set_has_split_ifs(true); // Has chance for split-if optimization
5321   set_result(z);
5322   return true;
5323 }
5324 
5325 //-------------inline_squareToLen------------------------------------
5326 bool LibraryCallKit::inline_squareToLen() {
5327   assert(UseSquareToLenIntrinsic, "not implementated on this platform");
5328 
5329   address stubAddr = StubRoutines::squareToLen();
5330   if (stubAddr == NULL) {
5331     return false; // Intrinsic's stub is not implemented on this platform
5332   }
5333   const char* stubName = "squareToLen";
5334 
5335   assert(callee()->signature()->size() == 4, "implSquareToLen has 4 parameters");
5336 
5337   Node* x    = argument(0);


5471     // failed array check
5472     return false;
5473   }
5474 
5475   // Figure out the size and type of the elements we will be copying.
5476   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5477   if (src_elem != T_BYTE) {
5478     return false;
5479   }
5480 
5481   // 'src_start' points to src array + scaled offset
5482   Node* src_start = array_element_address(src, offset, src_elem);
5483 
5484   // We assume that range check is done by caller.
5485   // TODO: generate range check (offset+length < src.length) in debug VM.
5486 
5487   // Call the stub.
5488   address stubAddr = StubRoutines::updateBytesCRC32();
5489   const char *stubName = "updateBytesCRC32";
5490 
5491   Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(),








5492                                  stubAddr, stubName, TypePtr::BOTTOM,
5493                                  crc, src_start, length);

5494   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
5495   set_result(result);
5496   return true;
5497 }
5498 
5499 /**
5500  * Calculate CRC32 for ByteBuffer.
5501  * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
5502  */
5503 bool LibraryCallKit::inline_updateByteBufferCRC32() {
5504   assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
5505   assert(callee()->signature()->size() == 5, "updateByteBuffer has 4 parameters and one is long");
5506   // no receiver since it is static method
5507   Node* crc     = argument(0); // type: int
5508   Node* src     = argument(1); // type: long
5509   Node* offset  = argument(3); // type: int
5510   Node* length  = argument(4); // type: int
5511 
5512   src = ConvL2X(src);  // adjust Java long to machine word
5513   Node* base = _gvn.transform(new CastX2PNode(src));
5514   offset = ConvI2X(offset);
5515 
5516   // 'src_start' points to src array + scaled offset
5517   Node* src_start = basic_plus_adr(top(), base, offset);
5518 
5519   // Call the stub.
5520   address stubAddr = StubRoutines::updateBytesCRC32();
5521   const char *stubName = "updateBytesCRC32";
5522 
5523   Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(),








5524                                  stubAddr, stubName, TypePtr::BOTTOM,
5525                                  crc, src_start, length);

5526   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
5527   set_result(result);
5528   return true;
5529 }
5530 
5531 //----------------------------inline_reference_get----------------------------
5532 // public T java.lang.ref.Reference.get();
5533 bool LibraryCallKit::inline_reference_get() {
5534   const int referent_offset = java_lang_ref_Reference::referent_offset;
5535   guarantee(referent_offset > 0, "should have already been set");
5536 
5537   // Get the argument:
5538   Node* reference_obj = null_check_receiver();
5539   if (stopped()) return true;
5540 
5541   Node* adr = basic_plus_adr(reference_obj, reference_obj, referent_offset);
5542 
5543   ciInstanceKlass* klass = env()->Object_klass();
5544   const TypeOopPtr* object_type = TypeOopPtr::make_from_klass(klass);
5545 


5742   Node* aescrypt_object = new CheckCastPPNode(control(), embeddedCipherObj, xtype);
5743   aescrypt_object = _gvn.transform(aescrypt_object);
5744 
5745   // we need to get the start of the aescrypt_object's expanded key array
5746   Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object);
5747   if (k_start == NULL) return false;
5748 
5749   // similarly, get the start address of the r vector
5750   Node* objRvec = load_field_from_object(cipherBlockChaining_object, "r", "[B", /*is_exact*/ false);
5751   if (objRvec == NULL) return false;
5752   Node* r_start = array_element_address(objRvec, intcon(0), T_BYTE);
5753 
5754   Node* cbcCrypt;
5755   if (Matcher::pass_original_key_for_aes()) {
5756     // on SPARC we need to pass the original key since key expansion needs to happen in intrinsics due to
5757     // compatibility issues between Java key expansion and SPARC crypto instructions
5758     Node* original_k_start = get_original_key_start_from_aescrypt_object(aescrypt_object);
5759     if (original_k_start == NULL) return false;
5760 
5761     // Call the stub, passing src_start, dest_start, k_start, r_start, src_len and original_k_start







5762     cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
5763                                  OptoRuntime::cipherBlockChaining_aescrypt_Type(),
5764                                  stubAddr, stubName, TypePtr::BOTTOM,
5765                                  src_start, dest_start, k_start, r_start, len, original_k_start);

5766   } else {
5767     // Call the stub, passing src_start, dest_start, k_start, r_start and src_len







5768     cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
5769                                  OptoRuntime::cipherBlockChaining_aescrypt_Type(),
5770                                  stubAddr, stubName, TypePtr::BOTTOM,
5771                                  src_start, dest_start, k_start, r_start, len);
5772   }

5773 
5774   // return cipher length (int)
5775   Node* retvalue = _gvn.transform(new ProjNode(cbcCrypt, TypeFunc::Parms));
5776   set_result(retvalue);
5777   return true;
5778 }
5779 
5780 //------------------------------get_key_start_from_aescrypt_object-----------------------
5781 Node * LibraryCallKit::get_key_start_from_aescrypt_object(Node *aescrypt_object) {
5782   Node* objAESCryptKey = load_field_from_object(aescrypt_object, "K", "[I", /*is_exact*/ false);
5783   assert (objAESCryptKey != NULL, "wrong version of com.sun.crypto.provider.AESCrypt");
5784   if (objAESCryptKey == NULL) return (Node *) NULL;
5785 
5786   // now have the array, need to get the start address of the K array
5787   Node* k_start = array_element_address(objAESCryptKey, intcon(0), T_INT);
5788   return k_start;
5789 }
5790 
5791 //------------------------------get_original_key_start_from_aescrypt_object-----------------------
5792 Node * LibraryCallKit::get_original_key_start_from_aescrypt_object(Node *aescrypt_object) {


6001   return false;
6002 }
6003 //------------------------------inline_sha_implCompressMB-----------------------
6004 bool LibraryCallKit::inline_sha_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_SHA,
6005                                                bool long_state, address stubAddr, const char *stubName,
6006                                                Node* src_start, Node* ofs, Node* limit) {
6007   const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_SHA);
6008   const TypeOopPtr* xtype = aklass->as_instance_type();
6009   Node* sha_obj = new CheckCastPPNode(control(), digestBase_obj, xtype);
6010   sha_obj = _gvn.transform(sha_obj);
6011 
6012   Node* state;
6013   if (long_state) {
6014     state = get_state_from_sha5_object(sha_obj);
6015   } else {
6016     state = get_state_from_sha_object(sha_obj);
6017   }
6018   if (state == NULL) return false;
6019 
6020   // Call the stub.
6021   Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,









6022                                  OptoRuntime::digestBase_implCompressMB_Type(),
6023                                  stubAddr, stubName, TypePtr::BOTTOM,
6024                                  src_start, state, ofs, limit);

6025   // return ofs (int)
6026   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
6027   set_result(result);
6028 
6029   return true;
6030 }
6031 
6032 //------------------------------get_state_from_sha_object-----------------------
6033 Node * LibraryCallKit::get_state_from_sha_object(Node *sha_object) {
6034   Node* sha_state = load_field_from_object(sha_object, "state", "[I", /*is_exact*/ false);
6035   assert (sha_state != NULL, "wrong version of sun.security.provider.SHA/SHA2");
6036   if (sha_state == NULL) return (Node *) NULL;
6037 
6038   // now have the array, need to get the start address of the state array
6039   Node* state = array_element_address(sha_state, intcon(0), T_INT);
6040   return state;
6041 }
6042 
6043 //------------------------------get_state_from_sha5_object-----------------------
6044 Node * LibraryCallKit::get_state_from_sha5_object(Node *sha_object) {




5294 
5295      __ if_then(__ value(need_alloc), BoolTest::ne, zero); {
5296        // Update graphKit memory and control from IdealKit.
5297        sync_kit(ideal);
5298        Node * narr = new_array(klass_node, zlen, 1);
5299        // Update IdealKit memory and control from graphKit.
5300        __ sync_kit(this);
5301        __ set(z_alloc, narr);
5302      } __ end_if();
5303 
5304      sync_kit(ideal);
5305      z = __ value(z_alloc);
5306      // Can't use TypeAryPtr::INTS which uses Bottom offset.
5307      _gvn.set_type(z, TypeOopPtr::make_from_klass(klass));
5308      // Final sync IdealKit and GraphKit.
5309      final_sync(ideal);
5310 #undef __
5311 
5312     Node* z_start = array_element_address(z, intcon(0), T_INT);
5313 
5314     Node* call = NULL;
5315     if (CCallingConventionRequiresIntsAsLongs) {
5316       Node* xlen_I2L = ConvI2L(xlen);
5317       Node* ylen_I2L = ConvI2L(ylen);
5318       Node* zlen_I2L = ConvI2L(zlen);
5319       call = make_runtime_call(RC_LEAF|RC_NO_FP,
5320                                OptoRuntime::multiplyToLen_Type(),
5321                                stubAddr, stubName, TypePtr::BOTTOM,
5322                                x_start, xlen_I2L XTOP, y_start, ylen_I2L XTOP, z_start, zlen_I2L XTOP);
5323     } else {
5324       call = make_runtime_call(RC_LEAF|RC_NO_FP,
5325                                OptoRuntime::multiplyToLen_Type(),
5326                                stubAddr, stubName, TypePtr::BOTTOM,
5327                                x_start, xlen, y_start, ylen, z_start, zlen);
5328     }
5329   } // original reexecute is set back here
5330 
5331   C->set_has_split_ifs(true); // Has chance for split-if optimization
5332   set_result(z);
5333   return true;
5334 }
5335 
5336 //-------------inline_squareToLen------------------------------------
5337 bool LibraryCallKit::inline_squareToLen() {
5338   assert(UseSquareToLenIntrinsic, "not implementated on this platform");
5339 
5340   address stubAddr = StubRoutines::squareToLen();
5341   if (stubAddr == NULL) {
5342     return false; // Intrinsic's stub is not implemented on this platform
5343   }
5344   const char* stubName = "squareToLen";
5345 
5346   assert(callee()->signature()->size() == 4, "implSquareToLen has 4 parameters");
5347 
5348   Node* x    = argument(0);


5482     // failed array check
5483     return false;
5484   }
5485 
5486   // Figure out the size and type of the elements we will be copying.
5487   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
5488   if (src_elem != T_BYTE) {
5489     return false;
5490   }
5491 
5492   // 'src_start' points to src array + scaled offset
5493   Node* src_start = array_element_address(src, offset, src_elem);
5494 
5495   // We assume that range check is done by caller.
5496   // TODO: generate range check (offset+length < src.length) in debug VM.
5497 
5498   // Call the stub.
5499   address stubAddr = StubRoutines::updateBytesCRC32();
5500   const char *stubName = "updateBytesCRC32";
5501 
5502   Node* call = NULL;
5503   if (CCallingConventionRequiresIntsAsLongs) {
5504     Node* crc_I2L    = ConvI2L(crc);
5505     Node* length_I2L = ConvI2L(length);
5506     call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(),
5507                              stubAddr, stubName, TypePtr::BOTTOM,
5508                              crc_I2L XTOP, src_start, length_I2L XTOP);
5509   } else {
5510     call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(),
5511                              stubAddr, stubName, TypePtr::BOTTOM,
5512                              crc, src_start, length);
5513   }
5514   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
5515   set_result(result);
5516   return true;
5517 }
5518 
5519 /**
5520  * Calculate CRC32 for ByteBuffer.
5521  * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
5522  */
5523 bool LibraryCallKit::inline_updateByteBufferCRC32() {
5524   assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
5525   assert(callee()->signature()->size() == 5, "updateByteBuffer has 4 parameters and one is long");
5526   // no receiver since it is static method
5527   Node* crc     = argument(0); // type: int
5528   Node* src     = argument(1); // type: long
5529   Node* offset  = argument(3); // type: int
5530   Node* length  = argument(4); // type: int
5531 
5532   src = ConvL2X(src);  // adjust Java long to machine word
5533   Node* base = _gvn.transform(new CastX2PNode(src));
5534   offset = ConvI2X(offset);
5535 
5536   // 'src_start' points to src array + scaled offset
5537   Node* src_start = basic_plus_adr(top(), base, offset);
5538 
5539   // Call the stub.
5540   address stubAddr = StubRoutines::updateBytesCRC32();
5541   const char *stubName = "updateBytesCRC32";
5542 
5543   Node* call = NULL;
5544   if (CCallingConventionRequiresIntsAsLongs) {
5545     Node* crc_I2L    = ConvI2L(crc);
5546     Node* length_I2L = ConvI2L(length);
5547     call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(),
5548                              stubAddr, stubName, TypePtr::BOTTOM,
5549                              crc_I2L XTOP, src_start, length_I2L XTOP);
5550   } else {
5551     call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(),
5552                              stubAddr, stubName, TypePtr::BOTTOM,
5553                              crc, src_start, length);
5554   }
5555   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
5556   set_result(result);
5557   return true;
5558 }
5559 
5560 //----------------------------inline_reference_get----------------------------
5561 // public T java.lang.ref.Reference.get();
5562 bool LibraryCallKit::inline_reference_get() {
5563   const int referent_offset = java_lang_ref_Reference::referent_offset;
5564   guarantee(referent_offset > 0, "should have already been set");
5565 
5566   // Get the argument:
5567   Node* reference_obj = null_check_receiver();
5568   if (stopped()) return true;
5569 
5570   Node* adr = basic_plus_adr(reference_obj, reference_obj, referent_offset);
5571 
5572   ciInstanceKlass* klass = env()->Object_klass();
5573   const TypeOopPtr* object_type = TypeOopPtr::make_from_klass(klass);
5574 


5771   Node* aescrypt_object = new CheckCastPPNode(control(), embeddedCipherObj, xtype);
5772   aescrypt_object = _gvn.transform(aescrypt_object);
5773 
5774   // we need to get the start of the aescrypt_object's expanded key array
5775   Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object);
5776   if (k_start == NULL) return false;
5777 
5778   // similarly, get the start address of the r vector
5779   Node* objRvec = load_field_from_object(cipherBlockChaining_object, "r", "[B", /*is_exact*/ false);
5780   if (objRvec == NULL) return false;
5781   Node* r_start = array_element_address(objRvec, intcon(0), T_BYTE);
5782 
5783   Node* cbcCrypt;
5784   if (Matcher::pass_original_key_for_aes()) {
5785     // on SPARC we need to pass the original key since key expansion needs to happen in intrinsics due to
5786     // compatibility issues between Java key expansion and SPARC crypto instructions
5787     Node* original_k_start = get_original_key_start_from_aescrypt_object(aescrypt_object);
5788     if (original_k_start == NULL) return false;
5789 
5790     // Call the stub, passing src_start, dest_start, k_start, r_start, src_len and original_k_start
5791     if (CCallingConventionRequiresIntsAsLongs) {
5792       Node* len_I2L    = ConvI2L(len);
5793       cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
5794                                    OptoRuntime::cipherBlockChaining_aescrypt_Type(),
5795                                    stubAddr, stubName, TypePtr::BOTTOM,
5796                                    src_start, dest_start, k_start, r_start, len_I2L XTOP, original_k_start);
5797     } else {
5798       cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
5799                                    OptoRuntime::cipherBlockChaining_aescrypt_Type(),
5800                                    stubAddr, stubName, TypePtr::BOTTOM,
5801                                    src_start, dest_start, k_start, r_start, len, original_k_start);
5802     }
5803   } else {
5804     // Call the stub, passing src_start, dest_start, k_start, r_start and src_len
5805     if (CCallingConventionRequiresIntsAsLongs) {
5806       Node* len_I2L    = ConvI2L(len);
5807       cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
5808                                    OptoRuntime::cipherBlockChaining_aescrypt_Type(),
5809                                    stubAddr, stubName, TypePtr::BOTTOM,
5810                                    src_start, dest_start, k_start, r_start, len_I2L XTOP);
5811     } else {
5812       cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
5813                                    OptoRuntime::cipherBlockChaining_aescrypt_Type(),
5814                                    stubAddr, stubName, TypePtr::BOTTOM,
5815                                    src_start, dest_start, k_start, r_start, len);
5816     }
5817   }
5818 
5819   // return cipher length (int)
5820   Node* retvalue = _gvn.transform(new ProjNode(cbcCrypt, TypeFunc::Parms));
5821   set_result(retvalue);
5822   return true;
5823 }
5824 
5825 //------------------------------get_key_start_from_aescrypt_object-----------------------
5826 Node * LibraryCallKit::get_key_start_from_aescrypt_object(Node *aescrypt_object) {
5827   Node* objAESCryptKey = load_field_from_object(aescrypt_object, "K", "[I", /*is_exact*/ false);
5828   assert (objAESCryptKey != NULL, "wrong version of com.sun.crypto.provider.AESCrypt");
5829   if (objAESCryptKey == NULL) return (Node *) NULL;
5830 
5831   // now have the array, need to get the start address of the K array
5832   Node* k_start = array_element_address(objAESCryptKey, intcon(0), T_INT);
5833   return k_start;
5834 }
5835 
5836 //------------------------------get_original_key_start_from_aescrypt_object-----------------------
5837 Node * LibraryCallKit::get_original_key_start_from_aescrypt_object(Node *aescrypt_object) {


6046   return false;
6047 }
6048 //------------------------------inline_sha_implCompressMB-----------------------
6049 bool LibraryCallKit::inline_sha_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_SHA,
6050                                                bool long_state, address stubAddr, const char *stubName,
6051                                                Node* src_start, Node* ofs, Node* limit) {
6052   const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_SHA);
6053   const TypeOopPtr* xtype = aklass->as_instance_type();
6054   Node* sha_obj = new CheckCastPPNode(control(), digestBase_obj, xtype);
6055   sha_obj = _gvn.transform(sha_obj);
6056 
6057   Node* state;
6058   if (long_state) {
6059     state = get_state_from_sha5_object(sha_obj);
6060   } else {
6061     state = get_state_from_sha_object(sha_obj);
6062   }
6063   if (state == NULL) return false;
6064 
6065   // Call the stub.
6066   Node* call = NULL;
6067   if (CCallingConventionRequiresIntsAsLongs) {
6068     Node* ofs_I2L   = ConvI2L(ofs);
6069     Node* limit_I2L = ConvI2L(limit);
6070     call = make_runtime_call(RC_LEAF|RC_NO_FP,
6071                              OptoRuntime::digestBase_implCompressMB_Type(),
6072                              stubAddr, stubName, TypePtr::BOTTOM,
6073                              src_start, state, ofs_I2L XTOP, limit_I2L XTOP);
6074   } else {
6075     call = make_runtime_call(RC_LEAF|RC_NO_FP,
6076                              OptoRuntime::digestBase_implCompressMB_Type(),
6077                              stubAddr, stubName, TypePtr::BOTTOM,
6078                              src_start, state, ofs, limit);
6079   }
6080   // return ofs (int)
6081   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
6082   set_result(result);
6083 
6084   return true;
6085 }
6086 
6087 //------------------------------get_state_from_sha_object-----------------------
6088 Node * LibraryCallKit::get_state_from_sha_object(Node *sha_object) {
6089   Node* sha_state = load_field_from_object(sha_object, "state", "[I", /*is_exact*/ false);
6090   assert (sha_state != NULL, "wrong version of sun.security.provider.SHA/SHA2");
6091   if (sha_state == NULL) return (Node *) NULL;
6092 
6093   // now have the array, need to get the start address of the state array
6094   Node* state = array_element_address(sha_state, intcon(0), T_INT);
6095   return state;
6096 }
6097 
6098 //------------------------------get_state_from_sha5_object-----------------------
6099 Node * LibraryCallKit::get_state_from_sha5_object(Node *sha_object) {


< prev index next >