src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/library_call.cpp Tue Jun 10 17:34:41 2014
--- new/src/share/vm/opto/library_call.cpp Tue Jun 10 17:34:41 2014
*** 314,323 ****
--- 314,331 ----
bool inline_aescrypt_Block(vmIntrinsics::ID id);
bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
+ bool inline_sha_implCompress(vmIntrinsics::ID id);
+ bool inline_digestBase_implCompressMB(int predicate);
+ bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
+ bool long_state, address stubAddr, const char *stubName,
+ Node* src_start, Node* ofs, Node* limit);
+ Node* get_state_from_sha_object(Node *sha_object);
+ Node* get_state_from_sha5_object(Node *sha_object);
+ Node* inline_digestBase_implCompressMB_predicate(int predicate);
bool inline_encodeISOArray();
bool inline_updateCRC32();
bool inline_updateBytesCRC32();
bool inline_updateByteBufferCRC32();
};
*** 517,526 ****
--- 525,551 ----
if (!UseAESIntrinsics) return NULL;
// these two require the predicated logic
predicates = 1;
break;
+ case vmIntrinsics::_sha_implCompress:
+ if (!UseSHA1Intrinsics) return NULL;
+ break;
+
+ case vmIntrinsics::_sha2_implCompress:
+ if (!UseSHA256Intrinsics) return NULL;
+ break;
+
+ case vmIntrinsics::_sha5_implCompress:
+ if (!UseSHA512Intrinsics) return NULL;
+ break;
+
+ case vmIntrinsics::_digestBase_implCompressMB:
+ if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return NULL;
+ predicates = 3;
+ break;
+
case vmIntrinsics::_updateCRC32:
case vmIntrinsics::_updateBytesCRC32:
case vmIntrinsics::_updateByteBufferCRC32:
if (!UseCRC32Intrinsics) return NULL;
break;
*** 884,893 ****
--- 909,926 ----
case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
+ case vmIntrinsics::_sha_implCompress:
+ case vmIntrinsics::_sha2_implCompress:
+ case vmIntrinsics::_sha5_implCompress:
+ return inline_sha_implCompress(intrinsic_id());
+
+ case vmIntrinsics::_digestBase_implCompressMB:
+ return inline_digestBase_implCompressMB(predicate);
+
case vmIntrinsics::_encodeISOArray:
return inline_encodeISOArray();
case vmIntrinsics::_updateCRC32:
return inline_updateCRC32();
*** 921,930 ****
--- 954,965 ----
switch (intrinsic_id()) {
case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
return inline_cipherBlockChaining_AESCrypt_predicate(false);
case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
return inline_cipherBlockChaining_AESCrypt_predicate(true);
+ case vmIntrinsics::_digestBase_implCompressMB:
+ return inline_digestBase_implCompressMB_predicate(predicate);
default:
// If you get here, it may be that someone has added a new intrinsic
// to the list in vmSymbols.hpp without implementing it here.
#ifndef PRODUCT
*** 6128,6132 ****
--- 6163,6422 ----
region->init_req(2, src_dest_conjoint);
record_for_igvn(region);
return _gvn.transform(region);
}
+
+ //------------------------------inline_sha_implCompress-----------------------
+ //
+ // Calculate SHA (i.e., SHA-1) for single-block byte[] array.
+ // void com.sun.security.provider.SHA.implCompress(byte[] buf, int ofs)
+ //
+ // Calculate SHA2 (i.e., SHA-244 or SHA-256) for single-block byte[] array.
+ // void com.sun.security.provider.SHA2.implCompress(byte[] buf, int ofs)
+ //
+ // Calculate SHA5 (i.e., SHA-384 or SHA-512) for single-block byte[] array.
+ // void com.sun.security.provider.SHA5.implCompress(byte[] buf, int ofs)
+ //
+ bool LibraryCallKit::inline_sha_implCompress(vmIntrinsics::ID id) {
+ assert(callee()->signature()->size() == 2, "sha_implCompress has 2 parameters");
+
+ Node* sha_obj = argument(0);
+ Node* src = argument(1); // type oop
+ Node* ofs = argument(2); // type int
+
+ const Type* src_type = src->Value(&_gvn);
+ const TypeAryPtr* top_src = src_type->isa_aryptr();
+ if (top_src == NULL || top_src->klass() == NULL) {
+ // failed array check
+ return false;
+ }
+ // Figure out the size and type of the elements we will be copying.
+ BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ if (src_elem != T_BYTE) {
+ return false;
+ }
+ // 'src_start' points to src array + offset
+ Node* src_start = array_element_address(src, ofs, src_elem);
+ Node* state = NULL;
+ address stubAddr;
+ const char *stubName;
+
+ switch(id) {
+ case vmIntrinsics::_sha_implCompress:
+ assert(UseSHA1Intrinsics, "need SHA1 instruction support");
+ state = get_state_from_sha_object(sha_obj);
+ stubAddr = StubRoutines::sha1_implCompress();
+ stubName = "sha1_implCompress";
+ break;
+ case vmIntrinsics::_sha2_implCompress:
+ assert(UseSHA256Intrinsics, "need SHA256 instruction support");
+ state = get_state_from_sha_object(sha_obj);
+ stubAddr = StubRoutines::sha256_implCompress();
+ stubName = "sha256_implCompress";
+ break;
+ case vmIntrinsics::_sha5_implCompress:
+ assert(UseSHA512Intrinsics, "need SHA512 instruction support");
+ state = get_state_from_sha5_object(sha_obj);
+ stubAddr = StubRoutines::sha512_implCompress();
+ stubName = "sha512_implCompress";
+ break;
+ default:
+ fatal_unexpected_iid(id);
+ return false;
+ }
+ if (state == NULL) return false;
+
+ // Call the stub.
+ Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::sha_implCompress_Type(),
+ stubAddr, stubName, TypePtr::BOTTOM,
+ src_start, state);
+
+ return true;
+ }
+
+ //------------------------------inline_digestBase_implCompressMB-----------------------
+ //
+ // Calculate SHA/SHA2/SHA5 for multi-block byte[] array.
+ // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit)
+ //
+ bool LibraryCallKit::inline_digestBase_implCompressMB(int predicate) {
+ assert(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics,
+ "need SHA1/SHA256/SHA512 instruction support");
+ assert((uint)predicate < 3, "sanity");
+ assert(callee()->signature()->size() == 3, "digestBase_implCompressMB has 3 parameters");
+
+ Node* digestBase_obj = argument(0); // The receiver was checked for NULL already.
+ Node* src = argument(1); // byte[] array
+ Node* ofs = argument(2); // type int
+ Node* limit = argument(3); // type int
+
+ const Type* src_type = src->Value(&_gvn);
+ const TypeAryPtr* top_src = src_type->isa_aryptr();
+ if (top_src == NULL || top_src->klass() == NULL) {
+ // failed array check
+ return false;
+ }
+ // Figure out the size and type of the elements we will be copying.
+ BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ if (src_elem != T_BYTE) {
+ return false;
+ }
+ // 'src_start' points to src array + offset
+ Node* src_start = array_element_address(src, ofs, src_elem);
+
+ const char* klass_SHA_name = NULL;
+ const char* stub_name = NULL;
+ address stub_addr = NULL;
+ bool long_state = false;
+
+ switch (predicate) {
+ case 0:
+ if (UseSHA1Intrinsics) {
+ klass_SHA_name = "sun/security/provider/SHA";
+ stub_name = "sha1_implCompressMB";
+ stub_addr = StubRoutines::sha1_implCompressMB();
+ }
+ break;
+ case 1:
+ if (UseSHA256Intrinsics) {
+ klass_SHA_name = "sun/security/provider/SHA2";
+ stub_name = "sha256_implCompressMB";
+ stub_addr = StubRoutines::sha256_implCompressMB();
+ }
+ break;
+ case 2:
+ if (UseSHA512Intrinsics) {
+ klass_SHA_name = "sun/security/provider/SHA5";
+ stub_name = "sha512_implCompressMB";
+ stub_addr = StubRoutines::sha512_implCompressMB();
+ long_state = true;
+ }
+ break;
+ default:
+ fatal(err_msg_res("unknown SHA intrinsic predicate: %d", predicate));
+ }
+ if (klass_SHA_name != NULL) {
+ // get DigestBase klass to lookup for SHA klass
+ const TypeInstPtr* tinst = _gvn.type(digestBase_obj)->isa_instptr();
+ assert(tinst != NULL, "digestBase_obj is not instance???");
+ assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
+
+ ciKlass* klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name));
+ assert(klass_SHA->is_loaded(), "predicate checks that this class is loaded");
+ ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass();
+ return inline_sha_implCompressMB(digestBase_obj, instklass_SHA, long_state, stub_addr, stub_name, src_start, ofs, limit);
+ }
+ return false;
+ }
+ //------------------------------inline_sha_implCompressMB-----------------------
+ bool LibraryCallKit::inline_sha_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_SHA,
+ bool long_state, address stubAddr, const char *stubName,
+ Node* src_start, Node* ofs, Node* limit) {
+ const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_SHA);
+ const TypeOopPtr* xtype = aklass->as_instance_type();
+ Node* sha_obj = new CheckCastPPNode(control(), digestBase_obj, xtype);
+ sha_obj = _gvn.transform(sha_obj);
+
+ Node* state;
+ if (long_state) {
+ state = get_state_from_sha5_object(sha_obj);
+ } else {
+ state = get_state_from_sha_object(sha_obj);
+ }
+ if (state == NULL) return false;
+
+ // Call the stub.
+ Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
+ OptoRuntime::digestBase_implCompressMB_Type(),
+ stubAddr, stubName, TypePtr::BOTTOM,
+ src_start, state, ofs, limit);
+ // return ofs (int)
+ Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
+ set_result(result);
+
+ return true;
+ }
+
+ //------------------------------get_state_from_sha_object-----------------------
+ Node * LibraryCallKit::get_state_from_sha_object(Node *sha_object) {
+ Node* sha_state = load_field_from_object(sha_object, "state", "[I", /*is_exact*/ false);
+ assert (sha_state != NULL, "wrong version of sun.security.provider.SHA/SHA2");
+ if (sha_state == NULL) return (Node *) NULL;
+
+ // now have the array, need to get the start address of the state array
+ Node* state = array_element_address(sha_state, intcon(0), T_INT);
+ return state;
+ }
+
+ //------------------------------get_state_from_sha5_object-----------------------
+ Node * LibraryCallKit::get_state_from_sha5_object(Node *sha_object) {
+ Node* sha_state = load_field_from_object(sha_object, "state", "[J", /*is_exact*/ false);
+ assert (sha_state != NULL, "wrong version of sun.security.provider.SHA5");
+ if (sha_state == NULL) return (Node *) NULL;
+
+ // now have the array, need to get the start address of the state array
+ Node* state = array_element_address(sha_state, intcon(0), T_LONG);
+ return state;
+ }
+
+ //----------------------------inline_digestBase_implCompressMB_predicate----------------------------
+ // Return node representing slow path of predicate check.
+ // the pseudo code we want to emulate with this predicate is:
+ // if (digestBaseObj instanceof SHA/SHA2/SHA5) do_intrinsic, else do_javapath
+ //
+ Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate) {
+ assert(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics,
+ "need SHA1/SHA256/SHA512 instruction support");
+ assert((uint)predicate < 3, "sanity");
+
+ // The receiver was checked for NULL already.
+ Node* digestBaseObj = argument(0);
+
+ // get DigestBase klass for instanceOf check
+ const TypeInstPtr* tinst = _gvn.type(digestBaseObj)->isa_instptr();
+ assert(tinst != NULL, "digestBaseObj is null");
+ assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
+
+ const char* klass_SHA_name = NULL;
+ switch (predicate) {
+ case 0:
+ if (UseSHA1Intrinsics) {
+ // we want to do an instanceof comparison against the SHA class
+ klass_SHA_name = "sun/security/provider/SHA";
+ }
+ break;
+ case 1:
+ if (UseSHA256Intrinsics) {
+ // we want to do an instanceof comparison against the SHA2 class
+ klass_SHA_name = "sun/security/provider/SHA2";
+ }
+ break;
+ case 2:
+ if (UseSHA512Intrinsics) {
+ // we want to do an instanceof comparison against the SHA5 class
+ klass_SHA_name = "sun/security/provider/SHA5";
+ }
+ break;
+ default:
+ fatal(err_msg_res("unknown SHA intrinsic predicate: %d", predicate));
+ }
+
+ ciKlass* klass_SHA = NULL;
+ if (klass_SHA_name != NULL) {
+ klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name));
+ }
+ if ((klass_SHA == NULL) || !klass_SHA->is_loaded()) {
+ // if none of SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path
+ Node* ctrl = control();
+ set_control(top()); // no intrinsic path
+ return ctrl;
+ }
+ ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass();
+
+ Node* instofSHA = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass_SHA)));
+ Node* cmp_instof = _gvn.transform(new CmpINode(instofSHA, intcon(1)));
+ Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne));
+ Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
+
+ return instof_false; // even if it is NULL
+ }
src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File