comparison src/cpu/x86/vm/templateInterpreter_x86_32.cpp @ 11080:b800986664f4

7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32 Summary: add intrinsics using new instruction to interpreter, C1, C2, for suitable x86; add test Reviewed-by: kvn, twisti
author drchase
date Tue, 02 Jul 2013 20:42:12 -0400
parents 603ca7e51354
children ca0165daa6ec
comparison
equal deleted inserted replaced
11079:738e04fb1232 11080:b800986664f4
866 // If G1 is not enabled then attempt to go through the accessor entry point 866 // If G1 is not enabled then attempt to go through the accessor entry point
867 // Reference.get is an accessor 867 // Reference.get is an accessor
868 return generate_accessor_entry(); 868 return generate_accessor_entry();
869 } 869 }
870 870
871 /**
872 * Method entry for static native methods:
873 * int java.util.zip.CRC32.update(int crc, int b)
874 */
875 address InterpreterGenerator::generate_CRC32_update_entry() {
876 if (UseCRC32Intrinsics) {
877 address entry = __ pc();
878
879 // rbx,: Method*
880 // rsi: senderSP must preserved for slow path, set SP to it on fast path
881 // rdx: scratch
882 // rdi: scratch
883
884 Label slow_path;
885 // If we need a safepoint check, generate full interpreter entry.
886 ExternalAddress state(SafepointSynchronize::address_of_state());
887 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
888 SafepointSynchronize::_not_synchronized);
889 __ jcc(Assembler::notEqual, slow_path);
890
891 // We don't generate local frame and don't align stack because
892 // we call stub code and there is no safepoint on this path.
893
894 // Load parameters
895 const Register crc = rax; // crc
896 const Register val = rdx; // source java byte value
897 const Register tbl = rdi; // scratch
898
899 // Arguments are reversed on java expression stack
900 __ movl(val, Address(rsp, wordSize)); // byte value
901 __ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
902
903 __ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
904 __ notl(crc); // ~crc
905 __ update_byte_crc32(crc, val, tbl);
906 __ notl(crc); // ~crc
907 // result in rax
908
909 // _areturn
910 __ pop(rdi); // get return address
911 __ mov(rsp, rsi); // set sp to sender sp
912 __ jmp(rdi);
913
914 // generate a vanilla native entry as the slow path
915 __ bind(slow_path);
916
917 (void) generate_native_entry(false);
918
919 return entry;
920 }
921 return generate_native_entry(false);
922 }
923
924 /**
925 * Method entry for static native methods:
926 * int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
927 * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
928 */
929 address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
930 if (UseCRC32Intrinsics) {
931 address entry = __ pc();
932
933 // rbx,: Method*
934 // rsi: senderSP must preserved for slow path, set SP to it on fast path
935 // rdx: scratch
936 // rdi: scratch
937
938 Label slow_path;
939 // If we need a safepoint check, generate full interpreter entry.
940 ExternalAddress state(SafepointSynchronize::address_of_state());
941 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
942 SafepointSynchronize::_not_synchronized);
943 __ jcc(Assembler::notEqual, slow_path);
944
945 // We don't generate local frame and don't align stack because
946 // we call stub code and there is no safepoint on this path.
947
948 // Load parameters
949 const Register crc = rax; // crc
950 const Register buf = rdx; // source java byte array address
951 const Register len = rdi; // length
952
953 // Arguments are reversed on java expression stack
954 __ movl(len, Address(rsp, wordSize)); // Length
955 // Calculate address of start element
956 if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
957 __ movptr(buf, Address(rsp, 3*wordSize)); // long buf
958 __ addptr(buf, Address(rsp, 2*wordSize)); // + offset
959 __ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC
960 } else {
961 __ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array
962 __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
963 __ addptr(buf, Address(rsp, 2*wordSize)); // + offset
964 __ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC
965 }
966
967 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
968 // result in rax
969
970 // _areturn
971 __ pop(rdi); // get return address
972 __ mov(rsp, rsi); // set sp to sender sp
973 __ jmp(rdi);
974
975 // generate a vanilla native entry as the slow path
976 __ bind(slow_path);
977
978 (void) generate_native_entry(false);
979
980 return entry;
981 }
982 return generate_native_entry(false);
983 }
984
871 // 985 //
872 // Interpreter stub for calling a native method. (asm interpreter) 986 // Interpreter stub for calling a native method. (asm interpreter)
873 // This sets up a somewhat different looking stack for calling the native method 987 // This sets up a somewhat different looking stack for calling the native method
874 // than the typical interpreter frame setup. 988 // than the typical interpreter frame setup.
875 // 989 //
1499 1613
1500 address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) { 1614 address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter::MethodKind kind) {
1501 // determine code generation flags 1615 // determine code generation flags
1502 bool synchronized = false; 1616 bool synchronized = false;
1503 address entry_point = NULL; 1617 address entry_point = NULL;
1618 InterpreterGenerator* ig_this = (InterpreterGenerator*)this;
1504 1619
1505 switch (kind) { 1620 switch (kind) {
1506 case Interpreter::zerolocals : break; 1621 case Interpreter::zerolocals : break;
1507 case Interpreter::zerolocals_synchronized: synchronized = true; break; 1622 case Interpreter::zerolocals_synchronized: synchronized = true; break;
1508 case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break; 1623 case Interpreter::native : entry_point = ig_this->generate_native_entry(false); break;
1509 case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break; 1624 case Interpreter::native_synchronized : entry_point = ig_this->generate_native_entry(true); break;
1510 case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; 1625 case Interpreter::empty : entry_point = ig_this->generate_empty_entry(); break;
1511 case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; 1626 case Interpreter::accessor : entry_point = ig_this->generate_accessor_entry(); break;
1512 case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break; 1627 case Interpreter::abstract : entry_point = ig_this->generate_abstract_entry(); break;
1513 1628
1514 case Interpreter::java_lang_math_sin : // fall thru 1629 case Interpreter::java_lang_math_sin : // fall thru
1515 case Interpreter::java_lang_math_cos : // fall thru 1630 case Interpreter::java_lang_math_cos : // fall thru
1516 case Interpreter::java_lang_math_tan : // fall thru 1631 case Interpreter::java_lang_math_tan : // fall thru
1517 case Interpreter::java_lang_math_abs : // fall thru 1632 case Interpreter::java_lang_math_abs : // fall thru
1518 case Interpreter::java_lang_math_log : // fall thru 1633 case Interpreter::java_lang_math_log : // fall thru
1519 case Interpreter::java_lang_math_log10 : // fall thru 1634 case Interpreter::java_lang_math_log10 : // fall thru
1520 case Interpreter::java_lang_math_sqrt : // fall thru 1635 case Interpreter::java_lang_math_sqrt : // fall thru
1521 case Interpreter::java_lang_math_pow : // fall thru 1636 case Interpreter::java_lang_math_pow : // fall thru
1522 case Interpreter::java_lang_math_exp : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break; 1637 case Interpreter::java_lang_math_exp : entry_point = ig_this->generate_math_entry(kind); break;
1523 case Interpreter::java_lang_ref_reference_get 1638 case Interpreter::java_lang_ref_reference_get
1524 : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break; 1639 : entry_point = ig_this->generate_Reference_get_entry(); break;
1640 case Interpreter::java_util_zip_CRC32_update
1641 : entry_point = ig_this->generate_CRC32_update_entry(); break;
1642 case Interpreter::java_util_zip_CRC32_updateBytes
1643 : // fall thru
1644 case Interpreter::java_util_zip_CRC32_updateByteBuffer
1645 : entry_point = ig_this->generate_CRC32_updateBytes_entry(kind); break;
1525 default: 1646 default:
1526 fatal(err_msg("unexpected method kind: %d", kind)); 1647 fatal(err_msg("unexpected method kind: %d", kind));
1527 break; 1648 break;
1528 } 1649 }
1529 1650
1530 if (entry_point) return entry_point; 1651 if (entry_point) return entry_point;
1531 1652
1532 return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized); 1653 return ig_this->generate_normal_entry(synchronized);
1533 1654
1534 } 1655 }
1535 1656
1536 // These should never be compiled since the interpreter will prefer 1657 // These should never be compiled since the interpreter will prefer
1537 // the compiled version to the intrinsic version. 1658 // the compiled version to the intrinsic version.