--- a/hotspot/src/share/vm/opto/library_call.cpp Tue Jan 14 14:51:47 2014 +0100
+++ b/hotspot/src/share/vm/opto/library_call.cpp Tue Jan 14 17:46:48 2014 -0800
@@ -304,6 +304,7 @@
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_encodeISOArray();
bool inline_updateCRC32();
bool inline_updateBytesCRC32();
@@ -5936,10 +5937,22 @@
Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object);
if (k_start == NULL) return false;
- // Call the stub.
- make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::aescrypt_block_Type(),
- stubAddr, stubName, TypePtr::BOTTOM,
- src_start, dest_start, k_start);
+ if (Matcher::pass_original_key_for_aes()) {
+ // on SPARC we need to pass the original key since key expansion needs to happen in intrinsics due to
+ // compatibility issues between Java key expansion and SPARC crypto instructions
+ Node* original_k_start = get_original_key_start_from_aescrypt_object(aescrypt_object);
+ if (original_k_start == NULL) return false;
+
+ // Call the stub.
+ make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::aescrypt_block_Type(),
+ stubAddr, stubName, TypePtr::BOTTOM,
+ src_start, dest_start, k_start, original_k_start);
+ } else {
+ // Call the stub.
+ make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::aescrypt_block_Type(),
+ stubAddr, stubName, TypePtr::BOTTOM,
+ src_start, dest_start, k_start);
+ }
return true;
}
@@ -6017,14 +6030,29 @@
if (objRvec == NULL) return false;
Node* r_start = array_element_address(objRvec, intcon(0), T_BYTE);
- // Call the stub, passing src_start, dest_start, k_start, r_start and src_len
- make_runtime_call(RC_LEAF|RC_NO_FP,
- OptoRuntime::cipherBlockChaining_aescrypt_Type(),
- stubAddr, stubName, TypePtr::BOTTOM,
- src_start, dest_start, k_start, r_start, len);
-
- // return is void so no result needs to be pushed
-
+ Node* cbcCrypt;
+ if (Matcher::pass_original_key_for_aes()) {
+ // on SPARC we need to pass the original key since key expansion needs to happen in intrinsics due to
+ // compatibility issues between Java key expansion and SPARC crypto instructions
+ Node* original_k_start = get_original_key_start_from_aescrypt_object(aescrypt_object);
+ if (original_k_start == NULL) return false;
+
+ // Call the stub, passing src_start, dest_start, k_start, r_start, src_len and original_k_start
+ cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
+ OptoRuntime::cipherBlockChaining_aescrypt_Type(),
+ stubAddr, stubName, TypePtr::BOTTOM,
+ src_start, dest_start, k_start, r_start, len, original_k_start);
+ } else {
+ // Call the stub, passing src_start, dest_start, k_start, r_start and src_len
+ cbcCrypt = make_runtime_call(RC_LEAF|RC_NO_FP,
+ OptoRuntime::cipherBlockChaining_aescrypt_Type(),
+ stubAddr, stubName, TypePtr::BOTTOM,
+ src_start, dest_start, k_start, r_start, len);
+ }
+
+ // return cipher length (int)
+ Node* retvalue = _gvn.transform(new (C) ProjNode(cbcCrypt, TypeFunc::Parms));
+ set_result(retvalue);
return true;
}
@@ -6039,6 +6067,17 @@
return k_start;
}
+//------------------------------get_original_key_start_from_aescrypt_object-----------------------
+Node * LibraryCallKit::get_original_key_start_from_aescrypt_object(Node *aescrypt_object) {
+ Node* objAESCryptKey = load_field_from_object(aescrypt_object, "lastKey", "[B", /*is_exact*/ false);
+ assert (objAESCryptKey != NULL, "wrong version of com.sun.crypto.provider.AESCrypt");
+ if (objAESCryptKey == NULL) return (Node *) NULL;
+
+ // now have the array, need to get the start address of the lastKey array
+ Node* original_k_start = array_element_address(objAESCryptKey, intcon(0), T_BYTE);
+ return original_k_start;
+}
+
//----------------------------inline_cipherBlockChaining_AESCrypt_predicate----------------------------
// Return node representing slow path of predicate check.
// the pseudo code we want to emulate with this predicate is: