1.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Tue Jul 02 07:51:31 2013 +0200 1.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Tue Jul 02 20:42:12 2013 -0400 1.3 @@ -868,6 +868,120 @@ 1.4 return generate_accessor_entry(); 1.5 } 1.6 1.7 +/** 1.8 + * Method entry for static native methods: 1.9 + * int java.util.zip.CRC32.update(int crc, int b) 1.10 + */ 1.11 +address InterpreterGenerator::generate_CRC32_update_entry() { 1.12 + if (UseCRC32Intrinsics) { 1.13 + address entry = __ pc(); 1.14 + 1.15 + // rbx,: Method* 1.16 + // rsi: senderSP must preserved for slow path, set SP to it on fast path 1.17 + // rdx: scratch 1.18 + // rdi: scratch 1.19 + 1.20 + Label slow_path; 1.21 + // If we need a safepoint check, generate full interpreter entry. 1.22 + ExternalAddress state(SafepointSynchronize::address_of_state()); 1.23 + __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), 1.24 + SafepointSynchronize::_not_synchronized); 1.25 + __ jcc(Assembler::notEqual, slow_path); 1.26 + 1.27 + // We don't generate local frame and don't align stack because 1.28 + // we call stub code and there is no safepoint on this path. 1.29 + 1.30 + // Load parameters 1.31 + const Register crc = rax; // crc 1.32 + const Register val = rdx; // source java byte value 1.33 + const Register tbl = rdi; // scratch 1.34 + 1.35 + // Arguments are reversed on java expression stack 1.36 + __ movl(val, Address(rsp, wordSize)); // byte value 1.37 + __ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC 1.38 + 1.39 + __ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr())); 1.40 + __ notl(crc); // ~crc 1.41 + __ update_byte_crc32(crc, val, tbl); 1.42 + __ notl(crc); // ~crc 1.43 + // result in rax 1.44 + 1.45 + // _areturn 1.46 + __ pop(rdi); // get return address 1.47 + __ mov(rsp, rsi); // set sp to sender sp 1.48 + __ jmp(rdi); 1.49 + 1.50 + // generate a vanilla native entry as the slow path 1.51 + __ bind(slow_path); 1.52 + 1.53 + (void) generate_native_entry(false); 1.54 + 1.55 + return entry; 1.56 + } 1.57 + return generate_native_entry(false); 1.58 +} 1.59 + 1.60 +/** 1.61 + * Method entry for static native methods: 1.62 + * int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len) 1.63 + * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len) 1.64 + */ 1.65 +address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { 1.66 + if (UseCRC32Intrinsics) { 1.67 + address entry = __ pc(); 1.68 + 1.69 + // rbx,: Method* 1.70 + // rsi: senderSP must preserved for slow path, set SP to it on fast path 1.71 + // rdx: scratch 1.72 + // rdi: scratch 1.73 + 1.74 + Label slow_path; 1.75 + // If we need a safepoint check, generate full interpreter entry. 1.76 + ExternalAddress state(SafepointSynchronize::address_of_state()); 1.77 + __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), 1.78 + SafepointSynchronize::_not_synchronized); 1.79 + __ jcc(Assembler::notEqual, slow_path); 1.80 + 1.81 + // We don't generate local frame and don't align stack because 1.82 + // we call stub code and there is no safepoint on this path. 1.83 + 1.84 + // Load parameters 1.85 + const Register crc = rax; // crc 1.86 + const Register buf = rdx; // source java byte array address 1.87 + const Register len = rdi; // length 1.88 + 1.89 + // Arguments are reversed on java expression stack 1.90 + __ movl(len, Address(rsp, wordSize)); // Length 1.91 + // Calculate address of start element 1.92 + if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) { 1.93 + __ movptr(buf, Address(rsp, 3*wordSize)); // long buf 1.94 + __ addptr(buf, Address(rsp, 2*wordSize)); // + offset 1.95 + __ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC 1.96 + } else { 1.97 + __ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array 1.98 + __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size 1.99 + __ addptr(buf, Address(rsp, 2*wordSize)); // + offset 1.100 + __ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC 1.101 + } 1.102 + 1.103 + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len); 1.104 + // result in rax 1.105 + 1.106 + // _areturn 1.107 + __ pop(rdi); // get return address 1.108 + __ mov(rsp, rsi); // set sp to sender sp 1.109 + __ jmp(rdi); 1.110 + 1.111 + // generate a vanilla native entry as the slow path 1.112 + __ bind(slow_path); 1.113 + 1.114 + (void) generate_native_entry(false); 1.115 + 1.116 + return entry; 1.117 + } 1.118 + return generate_native_entry(false); 1.119 +} 1.120 + 1.121 // 1.122 // Interpreter stub for calling a native method. (asm interpreter) 1.123 // This sets up a somewhat different looking stack for calling the native method 1.124 @@ -1501,15 +1615,16 @@ 1.125 // determine code generation flags 1.126 bool synchronized = false; 1.127 address entry_point = NULL; 1.128 + InterpreterGenerator* ig_this = (InterpreterGenerator*)this; 1.129 1.130 switch (kind) { 1.131 - case Interpreter::zerolocals : break; 1.132 - case Interpreter::zerolocals_synchronized: synchronized = true; break; 1.133 - case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break; 1.134 - case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break; 1.135 - case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; 1.136 - case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; 1.137 - case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break; 1.138 + case Interpreter::zerolocals : break; 1.139 + case Interpreter::zerolocals_synchronized: synchronized = true; break; 1.140 + case Interpreter::native : entry_point = ig_this->generate_native_entry(false); break; 1.141 + case Interpreter::native_synchronized : entry_point = ig_this->generate_native_entry(true); break; 1.142 + case Interpreter::empty : entry_point = ig_this->generate_empty_entry(); break; 1.143 + case Interpreter::accessor : entry_point = ig_this->generate_accessor_entry(); break; 1.144 + case Interpreter::abstract : entry_point = ig_this->generate_abstract_entry(); break; 1.145 1.146 case Interpreter::java_lang_math_sin : // fall thru 1.147 case Interpreter::java_lang_math_cos : // fall thru 1.148 @@ -1519,9 +1634,15 @@ 1.149 case Interpreter::java_lang_math_log10 : // fall thru 1.150 case Interpreter::java_lang_math_sqrt : // fall thru 1.151 case Interpreter::java_lang_math_pow : // fall thru 1.152 - case Interpreter::java_lang_math_exp : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break; 1.153 + case Interpreter::java_lang_math_exp : entry_point = ig_this->generate_math_entry(kind); break; 1.154 case Interpreter::java_lang_ref_reference_get 1.155 - : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break; 1.156 + : entry_point = ig_this->generate_Reference_get_entry(); break; 1.157 + case Interpreter::java_util_zip_CRC32_update 1.158 + : entry_point = ig_this->generate_CRC32_update_entry(); break; 1.159 + case Interpreter::java_util_zip_CRC32_updateBytes 1.160 + : // fall thru 1.161 + case Interpreter::java_util_zip_CRC32_updateByteBuffer 1.162 + : entry_point = ig_this->generate_CRC32_updateBytes_entry(kind); break; 1.163 default: 1.164 fatal(err_msg("unexpected method kind: %d", kind)); 1.165 break; 1.166 @@ -1529,7 +1650,7 @@ 1.167 1.168 if (entry_point) return entry_point; 1.169 1.170 - return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized); 1.171 + return ig_this->generate_normal_entry(synchronized); 1.172 1.173 } 1.174