diff src/share/vm/opto/library_call.cpp @ 7637:b30b3c2a0cf2

6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86 Summary: Use SSE4.2 and AVX2 instructions for encodeArray intrinsic. Reviewed-by: roland
author kvn
date Tue, 22 Jan 2013 15:34:16 -0800
parents 6d1f5516534e
children 8b3da8d14c93
line wrap: on
line diff
--- a/src/share/vm/opto/library_call.cpp	Tue Jan 22 11:31:25 2013 -0800
+++ b/src/share/vm/opto/library_call.cpp	Tue Jan 22 15:34:16 2013 -0800
@@ -290,6 +290,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);
+  bool inline_encodeISOArray();
 };
 
 
@@ -381,6 +382,10 @@
     // These also use the arraycopy intrinsic mechanism:
     if (!InlineArrayCopy)  return NULL;
     break;
+  case vmIntrinsics::_encodeISOArray:
+    if (!SpecialEncodeISOArray)  return NULL;
+    if (!Matcher::match_rule_supported(Op_EncodeISOArray))  return NULL;
+    break;
   case vmIntrinsics::_checkIndex:
     // We do not intrinsify this.  The optimizer does fine with it.
     return NULL;
@@ -799,6 +804,9 @@
   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
     return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
 
+  case vmIntrinsics::_encodeISOArray:
+    return inline_encodeISOArray();
+
   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.
@@ -5368,6 +5376,47 @@
                     src_start, dest_start, copy_length XTOP);
 }
 
+//-------------inline_encodeISOArray-----------------------------------
+// encode char[] to byte[] in ISO_8859_1
+bool LibraryCallKit::inline_encodeISOArray() {
+  assert(callee()->signature()->size() == 5, "encodeISOArray has 5 parameters");
+  // no receiver since it is static method
+  Node *src         = argument(0);
+  Node *src_offset  = argument(1);
+  Node *dst         = argument(2);
+  Node *dst_offset  = argument(3);
+  Node *length      = argument(4);
+
+  const Type* src_type = src->Value(&_gvn);
+  const Type* dst_type = dst->Value(&_gvn);
+  const TypeAryPtr* top_src = src_type->isa_aryptr();
+  const TypeAryPtr* top_dest = dst_type->isa_aryptr();
+  if (top_src  == NULL || top_src->klass()  == NULL ||
+      top_dest == NULL || top_dest->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();
+  BasicType dst_elem = dst_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+  if (src_elem != T_CHAR || dst_elem != T_BYTE) {
+    return false;
+  }
+  Node* src_start = array_element_address(src, src_offset, src_elem);
+  Node* dst_start = array_element_address(dst, dst_offset, dst_elem);
+  // 'src_start' points to src array + scaled offset
+  // 'dst_start' points to dst array + scaled offset
+
+  const TypeAryPtr* mtype = TypeAryPtr::BYTES;
+  Node* enc = new (C) EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length);
+  enc = _gvn.transform(enc);
+  Node* res_mem = _gvn.transform(new (C) SCMemProjNode(enc));
+  set_memory(res_mem, mtype);
+  set_result(enc);
+  return true;
+}
+
 //----------------------------inline_reference_get----------------------------
 // public T java.lang.ref.Reference.get();
 bool LibraryCallKit::inline_reference_get() {