8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1
authordchuyko
Wed, 01 Nov 2017 16:48:12 +0300
changeset 47767 107622f2695c
parent 47766 bfba73a06c8c
child 47768 3d1d05c9b6cd
8189745: AARCH64: Use CRC32C intrinsic code in interpreter and C1 Reviewed-by: aph
src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp
src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp
src/hotspot/share/c1/c1_Compiler.cpp
--- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp	Tue Oct 31 16:31:39 2017 -0700
+++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp	Wed Nov 01 16:48:12 2017 +0300
@@ -1030,7 +1030,81 @@
 }
 
 void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
-  Unimplemented();
+  assert(UseCRC32CIntrinsics, "why are we here?");
+  // Make all state_for calls early since they can emit code
+  LIR_Opr result = rlock_result(x);
+  int flags = 0;
+  switch (x->id()) {
+    case vmIntrinsics::_updateBytesCRC32C:
+    case vmIntrinsics::_updateDirectByteBufferCRC32C: {
+      bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32C);
+      int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0;
+
+      LIRItem crc(x->argument_at(0), this);
+      LIRItem buf(x->argument_at(1), this);
+      LIRItem off(x->argument_at(2), this);
+      LIRItem end(x->argument_at(3), this);
+
+      buf.load_item();
+      off.load_nonconstant();
+      end.load_nonconstant();
+
+      // len = end - off
+      LIR_Opr len  = end.result();
+      LIR_Opr tmpA = new_register(T_INT);
+      LIR_Opr tmpB = new_register(T_INT);
+      __ move(end.result(), tmpA);
+      __ move(off.result(), tmpB);
+      __ sub(tmpA, tmpB, tmpA);
+      len = tmpA;
+
+      LIR_Opr index = off.result();
+      if(off.result()->is_constant()) {
+        index = LIR_OprFact::illegalOpr;
+        offset += off.result()->as_jint();
+      }
+      LIR_Opr base_op = buf.result();
+
+      if (index->is_valid()) {
+        LIR_Opr tmp = new_register(T_LONG);
+        __ convert(Bytecodes::_i2l, index, tmp);
+        index = tmp;
+      }
+
+      if (offset) {
+        LIR_Opr tmp = new_pointer_register();
+        __ add(base_op, LIR_OprFact::intConst(offset), tmp);
+        base_op = tmp;
+        offset = 0;
+      }
+
+      LIR_Address* a = new LIR_Address(base_op,
+                                       index,
+                                       offset,
+                                       T_BYTE);
+      BasicTypeList signature(3);
+      signature.append(T_INT);
+      signature.append(T_ADDRESS);
+      signature.append(T_INT);
+      CallingConvention* cc = frame_map()->c_calling_convention(&signature);
+      const LIR_Opr result_reg = result_register_for(x->type());
+
+      LIR_Opr addr = new_pointer_register();
+      __ leal(LIR_OprFact::address(a), addr);
+
+      crc.load_item_force(cc->at(0));
+      __ move(addr, cc->at(1));
+      __ move(len, cc->at(2));
+
+      __ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), getThreadTemp(), result_reg, cc->args());
+      __ move(result_reg, result);
+
+      break;
+    }
+    default: {
+      ShouldNotReachHere();
+    }
+  }
 }
 
 void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Tue Oct 31 16:31:39 2017 -0700
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Wed Nov 01 16:48:12 2017 +0300
@@ -4937,6 +4937,10 @@
       StubRoutines::_crc_table_adr = (address)StubRoutines::aarch64::_crc_table;
       StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
     }
+
+    if (UseCRC32CIntrinsics) {
+      StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
+    }
   }
 
   void generate_all() {
@@ -5014,10 +5018,6 @@
       StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true,  "sha256_implCompressMB");
     }
 
-    if (UseCRC32CIntrinsics) {
-      StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
-    }
-
     // generate Adler32 intrinsics code
     if (UseAdler32Intrinsics) {
       StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32();
--- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Tue Oct 31 16:31:39 2017 -0700
+++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Wed Nov 01 16:48:12 2017 +0300
@@ -1061,8 +1061,44 @@
   return NULL;
 }
 
-// Not supported
+/**
+ * Method entry for intrinsic-candidate (non-native) methods:
+ *   int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
+ *   int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long buf, int off, int end)
+ * Unlike CRC32, CRC32C does not have any methods marked as native
+ * CRC32C also uses an "end" variable instead of the length variable CRC32 uses
+ */
 address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
+  if (UseCRC32Intrinsics) {
+    address entry = __ pc();
+
+    // Prepare jump to stub using parameters from the stack
+    const Register crc = c_rarg0; // initial crc
+    const Register buf = c_rarg1; // source java byte array address
+    const Register len = c_rarg2; // len argument to the kernel
+
+    const Register end = len; // index of last element to process
+    const Register off = crc; // offset
+
+    __ ldrw(end, Address(esp)); // int end
+    __ ldrw(off, Address(esp, wordSize)); // int offset
+    __ sub(len, end, off);
+    __ ldr(buf, Address(esp, 2*wordSize)); // byte[] buf | long buf
+    __ add(buf, buf, off); // + offset
+    if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
+      __ ldrw(crc, Address(esp, 4*wordSize)); // long crc
+    } else {
+      __ add(buf, buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
+      __ ldrw(crc, Address(esp, 3*wordSize)); // long crc
+    }
+
+    __ andr(sp, r13, -16); // Restore the caller's SP
+
+    // Jump to the stub.
+    __ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()));
+
+    return entry;
+  }
   return NULL;
 }
 
--- a/src/hotspot/share/c1/c1_Compiler.cpp	Tue Oct 31 16:31:39 2017 -0700
+++ b/src/hotspot/share/c1/c1_Compiler.cpp	Wed Nov 01 16:48:12 2017 +0300
@@ -213,7 +213,7 @@
   case vmIntrinsics::_updateCRC32:
   case vmIntrinsics::_updateBytesCRC32:
   case vmIntrinsics::_updateByteBufferCRC32:
-#if defined(SPARC) || defined(S390) || defined(PPC64)
+#if defined(SPARC) || defined(S390) || defined(PPC64) || defined(AARCH64)
   case vmIntrinsics::_updateBytesCRC32C:
   case vmIntrinsics::_updateDirectByteBufferCRC32C:
 #endif