src/cpu/x86/vm/templateInterpreter_x86_32.cpp

changeset 5353
b800986664f4
parent 5225
603ca7e51354
child 5496
ca0165daa6ec
     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  

mercurial