--- old/src/share/vm/opto/library_call.cpp 2015-02-13 08:28:07.335543642 -0800 +++ new/src/share/vm/opto/library_call.cpp 2015-02-13 08:28:07.231544307 -0800 @@ -274,6 +274,8 @@ 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_ghash_processBlocks(vmIntrinsics::ID id); + Node* get_vars_from_ghash_object(Node *ghash_object, const char *var_name); bool inline_sha_implCompress(vmIntrinsics::ID id); bool inline_digestBase_implCompressMB(int predicate); bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, @@ -511,6 +513,10 @@ predicates = 3; break; + case vmIntrinsics::_ghash_processBlocks: + if (!UseGHASHIntrinsics) return NULL; + break; + case vmIntrinsics::_updateCRC32: case vmIntrinsics::_updateBytesCRC32: case vmIntrinsics::_updateByteBufferCRC32: @@ -699,7 +705,6 @@ } assert(merged_memory(), ""); - switch (intrinsic_id()) { case vmIntrinsics::_hashCode: return inline_native_hashcode(intrinsic()->is_virtual(), !is_static); case vmIntrinsics::_identityHashCode: return inline_native_hashcode(/*!virtual*/ false, is_static); @@ -890,6 +895,9 @@ case vmIntrinsics::_multiplyToLen: return inline_multiplyToLen(); + case vmIntrinsics::_ghash_processBlocks: + return inline_ghash_processBlocks(intrinsic_id()); + case vmIntrinsics::_encodeISOArray: return inline_encodeISOArray(); @@ -5613,6 +5621,45 @@ return _gvn.transform(region); } +//------------------------------get_vars_from_ghash_object----------------------- +Node * LibraryCallKit::get_vars_from_ghash_object(Node *ghash_object, const char *var_name) { + Node* ghash_var = load_field_from_object(ghash_object, var_name, "[J", /*is_exact*/ false); + assert (ghash_var != NULL, "wrong version of sun.security.provider.GHASH"); + if (ghash_var == NULL) return (Node *) NULL; + + // now have the array, need to get the start address of the array + Node* var = array_element_address(ghash_var, intcon(0), T_LONG); + return var; +} + +//------------------------------inline_ghash_processBlocks +bool LibraryCallKit::inline_ghash_processBlocks(vmIntrinsics::ID id) { + address stubAddr; + const char *stubName; + assert(UseGHASHIntrinsics, "need GHASH intrinsics support"); + + stubAddr = StubRoutines::ghash_processBlocks(); + stubName = "ghash_processBlocks"; + + Node* ghash_object = argument(0); + Node* data = argument(1); + Node* offset = argument(2); + Node* len = argument(3); + + Node* state_start = get_vars_from_ghash_object(ghash_object, "state"); + assert(state_start, "Unable to load GHASH state"); + Node* subkeyH_start = get_vars_from_ghash_object(ghash_object, "subkeyH"); + assert(subkeyH_start, "Unable to load GHASH subkeyH"); + Node* data_start = array_element_address(data, offset, T_BYTE); + assert(data_start, "data is NULL"); + + Node* ghash = make_runtime_call(RC_LEAF|RC_NO_FP, + OptoRuntime::ghash_processBlocks_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + state_start, subkeyH_start, data_start, len); + return true; +} + //------------------------------inline_sha_implCompress----------------------- // // Calculate SHA (i.e., SHA-1) for single-block byte[] array.