src/cpu/x86/vm/interpreter_x86_64.cpp

changeset 739
dc7f315e41f7
parent 631
d1605aabd0a1
child 1145
e5b0439ef4ae
     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,

mercurial