Mercurial > hg > graal-compiler
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. |