1.1 --- a/src/cpu/x86/vm/interpreter_x86_64.cpp Tue Aug 26 15:49:40 2008 -0700 1.2 +++ b/src/cpu/x86/vm/interpreter_x86_64.cpp Wed Aug 27 00:21:55 2008 -0700 1.3 @@ -35,9 +35,9 @@ 1.4 // rbx: method 1.5 // r14: pointer to locals 1.6 // c_rarg3: first stack arg - wordSize 1.7 - __ movq(c_rarg3, rsp); 1.8 + __ mov(c_rarg3, rsp); 1.9 // adjust rsp 1.10 - __ subq(rsp, 4 * wordSize); 1.11 + __ subptr(rsp, 4 * wordSize); 1.12 __ call_VM(noreg, 1.13 CAST_FROM_FN_PTR(address, 1.14 InterpreterRuntime::slow_signature_handler), 1.15 @@ -70,13 +70,13 @@ 1.16 case 0: 1.17 __ movl(rscratch1, Address(rbx, methodOopDesc::access_flags_offset())); 1.18 __ testl(rscratch1, JVM_ACC_STATIC); 1.19 - __ cmovq(Assembler::zero, c_rarg1, Address(rsp, 0)); 1.20 + __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); 1.21 break; 1.22 case 1: 1.23 - __ movq(c_rarg2, Address(rsp, wordSize)); 1.24 + __ movptr(c_rarg2, Address(rsp, wordSize)); 1.25 break; 1.26 case 2: 1.27 - __ movq(c_rarg3, Address(rsp, 2 * wordSize)); 1.28 + __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); 1.29 break; 1.30 default: 1.31 break; 1.32 @@ -101,7 +101,7 @@ 1.33 1.34 1.35 // restore rsp 1.36 - __ addq(rsp, 4 * wordSize); 1.37 + __ addptr(rsp, 4 * wordSize); 1.38 1.39 __ ret(0); 1.40 1.41 @@ -114,9 +114,9 @@ 1.42 // rbx: method 1.43 // r14: pointer to locals 1.44 // c_rarg3: first stack arg - wordSize 1.45 - __ movq(c_rarg3, rsp); 1.46 + __ mov(c_rarg3, rsp); 1.47 // adjust rsp 1.48 - __ subq(rsp, 14 * wordSize); 1.49 + __ subptr(rsp, 14 * wordSize); 1.50 __ call_VM(noreg, 1.51 CAST_FROM_FN_PTR(address, 1.52 InterpreterRuntime::slow_signature_handler), 1.53 @@ -155,15 +155,15 @@ 1.54 // Now handle integrals. Only do c_rarg1 if not static. 1.55 __ movl(c_rarg3, Address(rbx, methodOopDesc::access_flags_offset())); 1.56 __ testl(c_rarg3, JVM_ACC_STATIC); 1.57 - __ cmovq(Assembler::zero, c_rarg1, Address(rsp, 0)); 1.58 + __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); 1.59 1.60 - __ movq(c_rarg2, Address(rsp, wordSize)); 1.61 - __ movq(c_rarg3, Address(rsp, 2 * wordSize)); 1.62 - __ movq(c_rarg4, Address(rsp, 3 * wordSize)); 1.63 - __ movq(c_rarg5, Address(rsp, 4 * wordSize)); 1.64 + __ movptr(c_rarg2, Address(rsp, wordSize)); 1.65 + __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); 1.66 + __ movptr(c_rarg4, Address(rsp, 3 * wordSize)); 1.67 + __ movptr(c_rarg5, Address(rsp, 4 * wordSize)); 1.68 1.69 // restore rsp 1.70 - __ addq(rsp, 14 * wordSize); 1.71 + __ addptr(rsp, 14 * wordSize); 1.72 1.73 __ ret(0); 1.74 1.75 @@ -176,15 +176,14 @@ 1.76 // Various method entries 1.77 // 1.78 1.79 -address InterpreterGenerator::generate_math_entry( 1.80 - AbstractInterpreter::MethodKind kind) { 1.81 - // rbx: methodOop 1.82 +address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { 1.83 + 1.84 + // rbx,: methodOop 1.85 + // rcx: scratrch 1.86 + // r13: sender sp 1.87 1.88 if (!InlineIntrinsics) return NULL; // Generate a vanilla entry 1.89 1.90 - assert(kind == Interpreter::java_lang_math_sqrt, 1.91 - "Other intrinsics are not special"); 1.92 - 1.93 address entry_point = __ pc(); 1.94 1.95 // These don't need a safepoint check because they aren't virtually 1.96 @@ -197,6 +196,11 @@ 1.97 // in order to avoid monotonicity bugs when switching 1.98 // from interpreter to compiler in the middle of some 1.99 // computation) 1.100 + // 1.101 + // stack: [ ret adr ] <-- rsp 1.102 + // [ lo(arg) ] 1.103 + // [ hi(arg) ] 1.104 + // 1.105 1.106 // Note: For JDK 1.2 StrictMath doesn't exist and Math.sin/cos/sqrt are 1.107 // native methods. Interpreter::method_kind(...) does a check for 1.108 @@ -218,10 +222,46 @@ 1.109 // Note: For JDK 1.3 StrictMath exists and Math.sin/cos/sqrt are 1.110 // java methods. Interpreter::method_kind(...) will select 1.111 // this entry point for the corresponding methods in JDK 1.3. 1.112 - __ sqrtsd(xmm0, Address(rsp, wordSize)); 1.113 + // get argument 1.114 1.115 - __ popq(rax); 1.116 - __ movq(rsp, r13); 1.117 + if (kind == Interpreter::java_lang_math_sqrt) { 1.118 + __ sqrtsd(xmm0, Address(rsp, wordSize)); 1.119 + } else { 1.120 + __ fld_d(Address(rsp, wordSize)); 1.121 + switch (kind) { 1.122 + case Interpreter::java_lang_math_sin : 1.123 + __ trigfunc('s'); 1.124 + break; 1.125 + case Interpreter::java_lang_math_cos : 1.126 + __ trigfunc('c'); 1.127 + break; 1.128 + case Interpreter::java_lang_math_tan : 1.129 + __ trigfunc('t'); 1.130 + break; 1.131 + case Interpreter::java_lang_math_abs: 1.132 + __ fabs(); 1.133 + break; 1.134 + case Interpreter::java_lang_math_log: 1.135 + __ flog(); 1.136 + break; 1.137 + case Interpreter::java_lang_math_log10: 1.138 + __ flog10(); 1.139 + break; 1.140 + default : 1.141 + ShouldNotReachHere(); 1.142 + } 1.143 + 1.144 + // return double result in xmm0 for interpreter and compilers. 1.145 + __ subptr(rsp, 2*wordSize); 1.146 + // Round to 64bit precision 1.147 + __ fstp_d(Address(rsp, 0)); 1.148 + __ movdbl(xmm0, Address(rsp, 0)); 1.149 + __ addptr(rsp, 2*wordSize); 1.150 + } 1.151 + 1.152 + 1.153 + __ pop(rax); 1.154 + __ mov(rsp, r13); 1.155 __ jmp(rax); 1.156 1.157 return entry_point; 1.158 @@ -239,10 +279,10 @@ 1.159 // abstract method entry 1.160 // remove return address. Not really needed, since exception 1.161 // handling throws away expression stack 1.162 - __ popq(rbx); 1.163 + __ pop(rbx); 1.164 1.165 // adjust stack to what a normal return would do 1.166 - __ movq(rsp, r13); 1.167 + __ mov(rsp, r13); 1.168 1.169 // throw exception 1.170 __ call_VM(noreg, CAST_FROM_FN_PTR(address, 1.171 @@ -276,8 +316,8 @@ 1.172 // Code: _return 1.173 // _return 1.174 // return w/o popping parameters 1.175 - __ popq(rax); 1.176 - __ movq(rsp, r13); 1.177 + __ pop(rax); 1.178 + __ mov(rsp, r13); 1.179 __ jmp(rax); 1.180 1.181 __ bind(slow_path); 1.182 @@ -286,148 +326,6 @@ 1.183 1.184 } 1.185 1.186 -// Call an accessor method (assuming it is resolved, otherwise drop 1.187 -// into vanilla (slow path) entry 1.188 -address InterpreterGenerator::generate_accessor_entry(void) { 1.189 - // rbx: methodOop 1.190 - 1.191 - // r13: senderSP must preserver for slow path, set SP to it on fast path 1.192 - 1.193 - address entry_point = __ pc(); 1.194 - Label xreturn_path; 1.195 - 1.196 - // do fastpath for resolved accessor methods 1.197 - if (UseFastAccessorMethods) { 1.198 - // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites 1.199 - // thereof; parameter size = 1 1.200 - // Note: We can only use this code if the getfield has been resolved 1.201 - // and if we don't have a null-pointer exception => check for 1.202 - // these conditions first and use slow path if necessary. 1.203 - Label slow_path; 1.204 - // If we need a safepoint check, generate full interpreter entry. 1.205 - __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), 1.206 - SafepointSynchronize::_not_synchronized); 1.207 - 1.208 - __ jcc(Assembler::notEqual, slow_path); 1.209 - // rbx: method 1.210 - __ movq(rax, Address(rsp, wordSize)); 1.211 - 1.212 - // check if local 0 != NULL and read field 1.213 - __ testq(rax, rax); 1.214 - __ jcc(Assembler::zero, slow_path); 1.215 - 1.216 - __ movq(rdi, Address(rbx, methodOopDesc::constants_offset())); 1.217 - // read first instruction word and extract bytecode @ 1 and index @ 2 1.218 - __ movq(rdx, Address(rbx, methodOopDesc::const_offset())); 1.219 - __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset())); 1.220 - // Shift codes right to get the index on the right. 1.221 - // The bytecode fetched looks like <index><0xb4><0x2a> 1.222 - __ shrl(rdx, 2 * BitsPerByte); 1.223 - __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); 1.224 - __ movq(rdi, Address(rdi, constantPoolOopDesc::cache_offset_in_bytes())); 1.225 - 1.226 - // rax: local 0 1.227 - // rbx: method 1.228 - // rdx: constant pool cache index 1.229 - // rdi: constant pool cache 1.230 - 1.231 - // check if getfield has been resolved and read constant pool cache entry 1.232 - // check the validity of the cache entry by testing whether _indices field 1.233 - // contains Bytecode::_getfield in b1 byte. 1.234 - assert(in_words(ConstantPoolCacheEntry::size()) == 4, 1.235 - "adjust shift below"); 1.236 - __ movl(rcx, 1.237 - Address(rdi, 1.238 - rdx, 1.239 - Address::times_8, 1.240 - constantPoolCacheOopDesc::base_offset() + 1.241 - ConstantPoolCacheEntry::indices_offset())); 1.242 - __ shrl(rcx, 2 * BitsPerByte); 1.243 - __ andl(rcx, 0xFF); 1.244 - __ cmpl(rcx, Bytecodes::_getfield); 1.245 - __ jcc(Assembler::notEqual, slow_path); 1.246 - 1.247 - // Note: constant pool entry is not valid before bytecode is resolved 1.248 - __ movq(rcx, 1.249 - Address(rdi, 1.250 - rdx, 1.251 - Address::times_8, 1.252 - constantPoolCacheOopDesc::base_offset() + 1.253 - ConstantPoolCacheEntry::f2_offset())); 1.254 - // edx: flags 1.255 - __ movl(rdx, 1.256 - Address(rdi, 1.257 - rdx, 1.258 - Address::times_8, 1.259 - constantPoolCacheOopDesc::base_offset() + 1.260 - ConstantPoolCacheEntry::flags_offset())); 1.261 - 1.262 - Label notObj, notInt, notByte, notShort; 1.263 - const Address field_address(rax, rcx, Address::times_1); 1.264 - 1.265 - // Need to differentiate between igetfield, agetfield, bgetfield etc. 1.266 - // because they are different sizes. 1.267 - // Use the type from the constant pool cache 1.268 - __ shrl(rdx, ConstantPoolCacheEntry::tosBits); 1.269 - // Make sure we don't need to mask edx for tosBits after the above shift 1.270 - ConstantPoolCacheEntry::verify_tosBits(); 1.271 - 1.272 - __ cmpl(rdx, atos); 1.273 - __ jcc(Assembler::notEqual, notObj); 1.274 - // atos 1.275 - __ load_heap_oop(rax, field_address); 1.276 - __ jmp(xreturn_path); 1.277 - 1.278 - __ bind(notObj); 1.279 - __ cmpl(rdx, itos); 1.280 - __ jcc(Assembler::notEqual, notInt); 1.281 - // itos 1.282 - __ movl(rax, field_address); 1.283 - __ jmp(xreturn_path); 1.284 - 1.285 - __ bind(notInt); 1.286 - __ cmpl(rdx, btos); 1.287 - __ jcc(Assembler::notEqual, notByte); 1.288 - // btos 1.289 - __ load_signed_byte(rax, field_address); 1.290 - __ jmp(xreturn_path); 1.291 - 1.292 - __ bind(notByte); 1.293 - __ cmpl(rdx, stos); 1.294 - __ jcc(Assembler::notEqual, notShort); 1.295 - // stos 1.296 - __ load_signed_word(rax, field_address); 1.297 - __ jmp(xreturn_path); 1.298 - 1.299 - __ bind(notShort); 1.300 -#ifdef ASSERT 1.301 - Label okay; 1.302 - __ cmpl(rdx, ctos); 1.303 - __ jcc(Assembler::equal, okay); 1.304 - __ stop("what type is this?"); 1.305 - __ bind(okay); 1.306 -#endif 1.307 - // ctos 1.308 - __ load_unsigned_word(rax, field_address); 1.309 - 1.310 - __ bind(xreturn_path); 1.311 - 1.312 - // _ireturn/_areturn 1.313 - __ popq(rdi); 1.314 - __ movq(rsp, r13); 1.315 - __ jmp(rdi); 1.316 - __ ret(0); 1.317 - 1.318 - // generate a vanilla interpreter entry as the slow path 1.319 - __ bind(slow_path); 1.320 - (void) generate_normal_entry(false); 1.321 - } else { 1.322 - (void) generate_normal_entry(false); 1.323 - } 1.324 - 1.325 - return entry_point; 1.326 -} 1.327 - 1.328 // This method tells the deoptimizer how big an interpreted frame must be: 1.329 int AbstractInterpreter::size_activation(methodOop method, 1.330 int tempcount,