--- old/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp 2017-03-14 08:56:52.010159000 +0100 +++ new/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp 2017-03-14 08:56:51.827134000 +0100 @@ -1433,9 +1433,19 @@ LIRItem crc(x->argument_at(0), this); LIRItem buf(x->argument_at(1), this); LIRItem off(x->argument_at(2), this); - LIRItem len(x->argument_at(3), 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(); int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0; @@ -1467,9 +1477,9 @@ arg2 = cc->at(1), arg3 = cc->at(2); - crc.load_item_force(arg1); // We skip int->long conversion here, because CRC32 stub doesn't care about high bits. + crc.load_item_force(arg1); // We skip int->long conversion here, because CRC32C stub doesn't care about high bits. __ leal(LIR_OprFact::address(a), arg2); - len.load_item_force(arg3); // We skip int->long conversion here, , because CRC32 stub expects int. + __ move(len, cc->at(2)); // We skip int->long conversion here, because CRC32C stub expects int. __ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), LIR_OprFact::illegalOpr, result_reg, cc->args()); __ move(result_reg, result); --- old/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp 2017-03-14 08:56:52.743215000 +0100 +++ new/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp 2017-03-14 08:56:52.610207000 +0100 @@ -1911,11 +1911,7 @@ return NULL; } -// TODO: generate_CRC32_updateBytes_entry and generate_CRC32C_updateBytes_entry are identical -// except for using different crc tables and some block comment strings. -// We should provide a common implementation. -// CRC32 Intrinsics. /** * Method entry for static native methods: * int java.util.zip.CRC32.updateBytes( int crc, byte[] b, int off, int len) @@ -2007,11 +2003,13 @@ return NULL; } -// CRC32C Intrinsics. + /** - * Method entry for static native methods: - * int java.util.zip.CRC32C.updateBytes( int crc, byte[] b, int off, int len) - * int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long* buf, int off, int len) + * 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 (UseCRC32CIntrinsics) { @@ -2055,6 +2053,7 @@ __ lwa( dataLen, 1*wordSize, argP); // #bytes to process __ lwz( crc, 5*wordSize, argP); // current crc state __ add( data, data, tmp); // Add byte buffer offset. + __ sub( dataLen, dataLen, tmp); // (end_index - offset) } else { // Used for "updateBytes update". BLOCK_COMMENT("CRC32C_updateBytes {"); // crc @ (SP + 4W) (32bit) @@ -2066,6 +2065,7 @@ __ lwa( tmp, 2*wordSize, argP); // byte buffer offset __ lwa( dataLen, 1*wordSize, argP); // #bytes to process __ add( data, data, tmp); // add byte buffer offset + __ sub( dataLen, dataLen, tmp); // (end_index - offset) __ lwz( crc, 4*wordSize, argP); // current crc state __ addi(data, data, arrayOopDesc::base_offset_in_bytes(T_BYTE)); } --- old/src/cpu/s390/vm/c1_LIRGenerator_s390.cpp 2017-03-14 08:56:53.488274000 +0100 +++ new/src/cpu/s390/vm/c1_LIRGenerator_s390.cpp 2017-03-14 08:56:53.364247000 +0100 @@ -1229,9 +1229,19 @@ LIRItem crc(x->argument_at(0), this); LIRItem buf(x->argument_at(1), this); LIRItem off(x->argument_at(2), this); - LIRItem len(x->argument_at(3), 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(); int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0; @@ -1262,7 +1272,7 @@ crc.load_item_force(arg1); // We skip int->long conversion here, because CRC32C stub doesn't care about high bits. __ leal(LIR_OprFact::address(a), arg2); - len.load_item_force(arg3); // We skip int->long conversion here, because CRC32C stub expects int. + __ move(len, cc->at(2)); // We skip int->long conversion here, because CRC32C stub expects int. __ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), LIR_OprFact::illegalOpr, result_reg, cc->args()); __ move(result_reg, result); --- old/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp 2017-03-14 08:56:54.008313000 +0100 +++ new/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp 2017-03-14 08:56:53.882313000 +0100 @@ -1933,8 +1933,11 @@ return entry_point; } -// Method entry for static native methods: -// int java.util.zip.CRC32.update(int crc, int b) + +/** + * Method entry for static native methods: + * int java.util.zip.CRC32.update(int crc, int b) + */ address TemplateInterpreterGenerator::generate_CRC32_update_entry() { if (UseCRC32Intrinsics) { @@ -1983,9 +1986,11 @@ } -// Method entry for static native methods: -// int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len) -// int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len) +/** + * Method entry for static native methods: + * int java.util.zip.CRC32.updateBytes( int crc, byte[] b, int off, int len) + * int java.util.zip.CRC32.updateByteBuffer(int crc, long* buf, int off, int len) + */ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { if (UseCRC32Intrinsics) { @@ -2061,9 +2066,13 @@ } -// Method entry for static native methods: -// int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int len) -// int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long buf, int off, int len) +/** + * 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 (UseCRC32CIntrinsics) { @@ -2096,7 +2105,8 @@ __ z_llgf(crc, 5*wordSize, argP); // current crc state __ z_lg(data, 3*wordSize, argP); // start of byte buffer __ z_agf(data, 2*wordSize, argP); // Add byte buffer offset. - __ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process + __ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process, calculated as + __ z_sgf(dataLen, Address(argP, 2*wordSize)); // (end_index - offset) } else { // Used for "updateBytes update". // crc @ (SP + 4W) (32bit) // buf @ (SP + 3W) (64bit ptr to byte array) @@ -2107,7 +2117,8 @@ __ z_llgf(crc, 4*wordSize, argP); // current crc state __ z_lg(data, 3*wordSize, argP); // start of byte buffer __ z_agf(data, 2*wordSize, argP); // Add byte buffer offset. - __ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process + __ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process, calculated as + __ z_sgf(dataLen, Address(argP, 2*wordSize)); // (end_index - offset) __ z_aghi(data, arrayOopDesc::base_offset_in_bytes(T_BYTE)); }