199 } |
199 } |
200 CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) { |
200 CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) { |
201 return generate_method_call(method_id, true, false); |
201 return generate_method_call(method_id, true, false); |
202 } |
202 } |
203 Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static, ciInstanceKlass * fromKls); |
203 Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static, ciInstanceKlass * fromKls); |
|
204 Node * field_address_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static, ciInstanceKlass * fromKls); |
204 |
205 |
205 Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2, StrIntrinsicNode::ArgEnc ae); |
206 Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2, StrIntrinsicNode::ArgEnc ae); |
206 bool inline_string_compareTo(StrIntrinsicNode::ArgEnc ae); |
207 bool inline_string_compareTo(StrIntrinsicNode::ArgEnc ae); |
207 bool inline_string_indexOf(StrIntrinsicNode::ArgEnc ae); |
208 bool inline_string_indexOf(StrIntrinsicNode::ArgEnc ae); |
208 bool inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae); |
209 bool inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae); |
281 bool inline_number_methods(vmIntrinsics::ID id); |
282 bool inline_number_methods(vmIntrinsics::ID id); |
282 bool inline_reference_get(); |
283 bool inline_reference_get(); |
283 bool inline_Class_cast(); |
284 bool inline_Class_cast(); |
284 bool inline_aescrypt_Block(vmIntrinsics::ID id); |
285 bool inline_aescrypt_Block(vmIntrinsics::ID id); |
285 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id); |
286 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id); |
|
287 bool inline_counterMode_AESCrypt(vmIntrinsics::ID id); |
286 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); |
288 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); |
|
289 Node* inline_counterMode_AESCrypt_predicate(); |
287 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); |
290 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); |
288 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); |
291 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); |
289 bool inline_ghash_processBlocks(); |
292 bool inline_ghash_processBlocks(); |
290 bool inline_sha_implCompress(vmIntrinsics::ID id); |
293 bool inline_sha_implCompress(vmIntrinsics::ID id); |
291 bool inline_digestBase_implCompressMB(int predicate); |
294 bool inline_digestBase_implCompressMB(int predicate); |
5776 insert_mem_bar(Op_MemBarAcquire, loadedField); |
5784 insert_mem_bar(Op_MemBarAcquire, loadedField); |
5777 } |
5785 } |
5778 return loadedField; |
5786 return loadedField; |
5779 } |
5787 } |
5780 |
5788 |
|
5789 Node * LibraryCallKit::field_address_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, |
|
5790 bool is_exact = true, bool is_static = false, |
|
5791 ciInstanceKlass * fromKls = NULL) { |
|
5792 if (fromKls == NULL) { |
|
5793 const TypeInstPtr* tinst = _gvn.type(fromObj)->isa_instptr(); |
|
5794 assert(tinst != NULL, "obj is null"); |
|
5795 assert(tinst->klass()->is_loaded(), "obj is not loaded"); |
|
5796 assert(!is_exact || tinst->klass_is_exact(), "klass not exact"); |
|
5797 fromKls = tinst->klass()->as_instance_klass(); |
|
5798 } |
|
5799 else { |
|
5800 assert(is_static, "only for static field access"); |
|
5801 } |
|
5802 ciField* field = fromKls->get_field_by_name(ciSymbol::make(fieldName), |
|
5803 ciSymbol::make(fieldTypeString), |
|
5804 is_static); |
|
5805 |
|
5806 assert(field != NULL, "undefined field"); |
|
5807 assert(!field->is_volatile(), "not defined for volatile fields"); |
|
5808 |
|
5809 if (is_static) { |
|
5810 const TypeInstPtr* tip = TypeInstPtr::make(fromKls->java_mirror()); |
|
5811 fromObj = makecon(tip); |
|
5812 } |
|
5813 |
|
5814 // Next code copied from Parse::do_get_xxx(): |
|
5815 |
|
5816 // Compute address and memory type. |
|
5817 int offset = field->offset_in_bytes(); |
|
5818 Node *adr = basic_plus_adr(fromObj, fromObj, offset); |
|
5819 |
|
5820 return adr; |
|
5821 } |
5781 |
5822 |
5782 //------------------------------inline_aescrypt_Block----------------------- |
5823 //------------------------------inline_aescrypt_Block----------------------- |
5783 bool LibraryCallKit::inline_aescrypt_Block(vmIntrinsics::ID id) { |
5824 bool LibraryCallKit::inline_aescrypt_Block(vmIntrinsics::ID id) { |
5784 address stubAddr = NULL; |
5825 address stubAddr = NULL; |
5785 const char *stubName; |
5826 const char *stubName; |
5938 src_start, dest_start, k_start, r_start, len); |
5979 src_start, dest_start, k_start, r_start, len); |
5939 } |
5980 } |
5940 |
5981 |
5941 // return cipher length (int) |
5982 // return cipher length (int) |
5942 Node* retvalue = _gvn.transform(new ProjNode(cbcCrypt, TypeFunc::Parms)); |
5983 Node* retvalue = _gvn.transform(new ProjNode(cbcCrypt, TypeFunc::Parms)); |
|
5984 set_result(retvalue); |
|
5985 return true; |
|
5986 } |
|
5987 |
|
5988 //------------------------------inline_counterMode_AESCrypt----------------------- |
|
5989 bool LibraryCallKit::inline_counterMode_AESCrypt(vmIntrinsics::ID id) { |
|
5990 assert(UseAES, "need AES instruction support"); |
|
5991 if (!UseAESCTRIntrinsics) return false; |
|
5992 |
|
5993 address stubAddr = NULL; |
|
5994 const char *stubName = NULL; |
|
5995 if (id == vmIntrinsics::_counterMode_AESCrypt) { |
|
5996 stubAddr = StubRoutines::counterMode_AESCrypt(); |
|
5997 stubName = "counterMode_AESCrypt"; |
|
5998 } |
|
5999 if (stubAddr == NULL) return false; |
|
6000 |
|
6001 Node* counterMode_object = argument(0); |
|
6002 Node* src = argument(1); |
|
6003 Node* src_offset = argument(2); |
|
6004 Node* len = argument(3); |
|
6005 Node* dest = argument(4); |
|
6006 Node* dest_offset = argument(5); |
|
6007 |
|
6008 // (1) src and dest are arrays. |
|
6009 const Type* src_type = src->Value(&_gvn); |
|
6010 const Type* dest_type = dest->Value(&_gvn); |
|
6011 const TypeAryPtr* top_src = src_type->isa_aryptr(); |
|
6012 const TypeAryPtr* top_dest = dest_type->isa_aryptr(); |
|
6013 assert(top_src != NULL && top_src->klass() != NULL && |
|
6014 top_dest != NULL && top_dest->klass() != NULL, "args are strange"); |
|
6015 |
|
6016 // checks are the responsibility of the caller |
|
6017 Node* src_start = src; |
|
6018 Node* dest_start = dest; |
|
6019 if (src_offset != NULL || dest_offset != NULL) { |
|
6020 assert(src_offset != NULL && dest_offset != NULL, ""); |
|
6021 src_start = array_element_address(src, src_offset, T_BYTE); |
|
6022 dest_start = array_element_address(dest, dest_offset, T_BYTE); |
|
6023 } |
|
6024 |
|
6025 // if we are in this set of code, we "know" the embeddedCipher is an AESCrypt object |
|
6026 // (because of the predicated logic executed earlier). |
|
6027 // so we cast it here safely. |
|
6028 // this requires a newer class file that has this array as littleEndian ints, otherwise we revert to java |
|
6029 Node* embeddedCipherObj = load_field_from_object(counterMode_object, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false); |
|
6030 if (embeddedCipherObj == NULL) return false; |
|
6031 // cast it to what we know it will be at runtime |
|
6032 const TypeInstPtr* tinst = _gvn.type(counterMode_object)->isa_instptr(); |
|
6033 assert(tinst != NULL, "CTR obj is null"); |
|
6034 assert(tinst->klass()->is_loaded(), "CTR obj is not loaded"); |
|
6035 ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt")); |
|
6036 assert(klass_AESCrypt->is_loaded(), "predicate checks that this class is loaded"); |
|
6037 ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass(); |
|
6038 const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt); |
|
6039 const TypeOopPtr* xtype = aklass->as_instance_type(); |
|
6040 Node* aescrypt_object = new CheckCastPPNode(control(), embeddedCipherObj, xtype); |
|
6041 aescrypt_object = _gvn.transform(aescrypt_object); |
|
6042 // we need to get the start of the aescrypt_object's expanded key array |
|
6043 Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object); |
|
6044 if (k_start == NULL) return false; |
|
6045 // similarly, get the start address of the r vector |
|
6046 Node* obj_counter = load_field_from_object(counterMode_object, "counter", "[B", /*is_exact*/ false); |
|
6047 if (obj_counter == NULL) return false; |
|
6048 Node* cnt_start = array_element_address(obj_counter, intcon(0), T_BYTE); |
|
6049 |
|
6050 Node* saved_encCounter = load_field_from_object(counterMode_object, "encryptedCounter", "[B", /*is_exact*/ false); |
|
6051 if (saved_encCounter == NULL) return false; |
|
6052 Node* saved_encCounter_start = array_element_address(saved_encCounter, intcon(0), T_BYTE); |
|
6053 Node* used = field_address_from_object(counterMode_object, "used", "I", /*is_exact*/ false); |
|
6054 |
|
6055 Node* ctrCrypt; |
|
6056 if (Matcher::pass_original_key_for_aes()) { |
|
6057 // no SPARC version for AES/CTR intrinsics now. |
|
6058 return false; |
|
6059 } |
|
6060 // Call the stub, passing src_start, dest_start, k_start, r_start and src_len |
|
6061 ctrCrypt = make_runtime_call(RC_LEAF|RC_NO_FP, |
|
6062 OptoRuntime::counterMode_aescrypt_Type(), |
|
6063 stubAddr, stubName, TypePtr::BOTTOM, |
|
6064 src_start, dest_start, k_start, cnt_start, len, saved_encCounter_start, used); |
|
6065 |
|
6066 // return cipher length (int) |
|
6067 Node* retvalue = _gvn.transform(new ProjNode(ctrCrypt, TypeFunc::Parms)); |
5943 set_result(retvalue); |
6068 set_result(retvalue); |
5944 return true; |
6069 return true; |
5945 } |
6070 } |
5946 |
6071 |
5947 //------------------------------get_key_start_from_aescrypt_object----------------------- |
6072 //------------------------------get_key_start_from_aescrypt_object----------------------- |
6021 Node* src_dest_conjoint = generate_guard(bool_src_dest, NULL, PROB_MIN); |
6146 Node* src_dest_conjoint = generate_guard(bool_src_dest, NULL, PROB_MIN); |
6022 region->init_req(2, src_dest_conjoint); |
6147 region->init_req(2, src_dest_conjoint); |
6023 |
6148 |
6024 record_for_igvn(region); |
6149 record_for_igvn(region); |
6025 return _gvn.transform(region); |
6150 return _gvn.transform(region); |
|
6151 } |
|
6152 |
|
6153 //----------------------------inline_counterMode_AESCrypt_predicate---------------------------- |
|
6154 // Return node representing slow path of predicate check. |
|
6155 // the pseudo code we want to emulate with this predicate is: |
|
6156 // for encryption: |
|
6157 // if (embeddedCipherObj instanceof AESCrypt) do_intrinsic, else do_javapath |
|
6158 // for decryption: |
|
6159 // if ((embeddedCipherObj instanceof AESCrypt) && (cipher!=plain)) do_intrinsic, else do_javapath |
|
6160 // note cipher==plain is more conservative than the original java code but that's OK |
|
6161 // |
|
6162 |
|
6163 Node* LibraryCallKit::inline_counterMode_AESCrypt_predicate() { |
|
6164 // The receiver was checked for NULL already. |
|
6165 Node* objCTR = argument(0); |
|
6166 |
|
6167 // Load embeddedCipher field of CipherBlockChaining object. |
|
6168 Node* embeddedCipherObj = load_field_from_object(objCTR, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false); |
|
6169 |
|
6170 // get AESCrypt klass for instanceOf check |
|
6171 // AESCrypt might not be loaded yet if some other SymmetricCipher got us to this compile point |
|
6172 // will have same classloader as CipherBlockChaining object |
|
6173 const TypeInstPtr* tinst = _gvn.type(objCTR)->isa_instptr(); |
|
6174 assert(tinst != NULL, "CTRobj is null"); |
|
6175 assert(tinst->klass()->is_loaded(), "CTRobj is not loaded"); |
|
6176 |
|
6177 // we want to do an instanceof comparison against the AESCrypt class |
|
6178 ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt")); |
|
6179 if (!klass_AESCrypt->is_loaded()) { |
|
6180 // if AESCrypt is not even loaded, we never take the intrinsic fast path |
|
6181 Node* ctrl = control(); |
|
6182 set_control(top()); // no regular fast path |
|
6183 return ctrl; |
|
6184 } |
|
6185 |
|
6186 ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass(); |
|
6187 Node* instof = gen_instanceof(embeddedCipherObj, makecon(TypeKlassPtr::make(instklass_AESCrypt))); |
|
6188 Node* cmp_instof = _gvn.transform(new CmpINode(instof, intcon(1))); |
|
6189 Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne)); |
|
6190 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN); |
|
6191 |
|
6192 return instof_false; // even if it is NULL |
6026 } |
6193 } |
6027 |
6194 |
6028 //------------------------------inline_ghash_processBlocks |
6195 //------------------------------inline_ghash_processBlocks |
6029 bool LibraryCallKit::inline_ghash_processBlocks() { |
6196 bool LibraryCallKit::inline_ghash_processBlocks() { |
6030 address stubAddr; |
6197 address stubAddr; |