src/cpu/x86/vm/templateTable_x86_32.cpp

changeset 3050
fdb992d83a87
parent 2982
ddd894528dbc
child 3368
52b5d32fbfaf
child 3391
069ab3f976d3
     1.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Thu Aug 11 12:08:11 2011 -0700
     1.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Tue Aug 16 04:14:05 2011 -0700
     1.3 @@ -202,45 +202,74 @@
     1.4  }
     1.5  
     1.6  
     1.7 -void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc,
     1.8 -                                   Register scratch,
     1.9 -                                   bool load_bc_into_scratch/*=true*/) {
    1.10 -
    1.11 -  if (!RewriteBytecodes) return;
    1.12 -  // the pair bytecodes have already done the load.
    1.13 -  if (load_bc_into_scratch) {
    1.14 -    __ movl(bc, bytecode);
    1.15 +void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
    1.16 +                                   Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
    1.17 +                                   int byte_no) {
    1.18 +  if (!RewriteBytecodes)  return;
    1.19 +  Label L_patch_done;
    1.20 +
    1.21 +  switch (bc) {
    1.22 +  case Bytecodes::_fast_aputfield:
    1.23 +  case Bytecodes::_fast_bputfield:
    1.24 +  case Bytecodes::_fast_cputfield:
    1.25 +  case Bytecodes::_fast_dputfield:
    1.26 +  case Bytecodes::_fast_fputfield:
    1.27 +  case Bytecodes::_fast_iputfield:
    1.28 +  case Bytecodes::_fast_lputfield:
    1.29 +  case Bytecodes::_fast_sputfield:
    1.30 +    {
    1.31 +      // We skip bytecode quickening for putfield instructions when
    1.32 +      // the put_code written to the constant pool cache is zero.
    1.33 +      // This is required so that every execution of this instruction
    1.34 +      // calls out to InterpreterRuntime::resolve_get_put to do
    1.35 +      // additional, required work.
    1.36 +      assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
    1.37 +      assert(load_bc_into_bc_reg, "we use bc_reg as temp");
    1.38 +      __ get_cache_and_index_and_bytecode_at_bcp(bc_reg, temp_reg, temp_reg, byte_no, 1);
    1.39 +      __ movl(bc_reg, bc);
    1.40 +      __ cmpl(temp_reg, (int) 0);
    1.41 +      __ jcc(Assembler::zero, L_patch_done);  // don't patch
    1.42 +    }
    1.43 +    break;
    1.44 +  default:
    1.45 +    assert(byte_no == -1, "sanity");
    1.46 +    // the pair bytecodes have already done the load.
    1.47 +    if (load_bc_into_bc_reg) {
    1.48 +      __ movl(bc_reg, bc);
    1.49 +    }
    1.50    }
    1.51 -  Label patch_done;
    1.52 +
    1.53    if (JvmtiExport::can_post_breakpoint()) {
    1.54 -    Label fast_patch;
    1.55 +    Label L_fast_patch;
    1.56      // if a breakpoint is present we can't rewrite the stream directly
    1.57 -    __ movzbl(scratch, at_bcp(0));
    1.58 -    __ cmpl(scratch, Bytecodes::_breakpoint);
    1.59 -    __ jcc(Assembler::notEqual, fast_patch);
    1.60 -    __ get_method(scratch);
    1.61 +    __ movzbl(temp_reg, at_bcp(0));
    1.62 +    __ cmpl(temp_reg, Bytecodes::_breakpoint);
    1.63 +    __ jcc(Assembler::notEqual, L_fast_patch);
    1.64 +    __ get_method(temp_reg);
    1.65      // Let breakpoint table handling rewrite to quicker bytecode
    1.66 -    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, rsi, bc);
    1.67 +    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), temp_reg, rsi, bc_reg);
    1.68  #ifndef ASSERT
    1.69 -    __ jmpb(patch_done);
    1.70 +    __ jmpb(L_patch_done);
    1.71  #else
    1.72 -    __ jmp(patch_done);
    1.73 +    __ jmp(L_patch_done);
    1.74  #endif
    1.75 -    __ bind(fast_patch);
    1.76 +    __ bind(L_fast_patch);
    1.77    }
    1.78 +
    1.79  #ifdef ASSERT
    1.80 -  Label okay;
    1.81 -  __ load_unsigned_byte(scratch, at_bcp(0));
    1.82 -  __ cmpl(scratch, (int)Bytecodes::java_code(bytecode));
    1.83 -  __ jccb(Assembler::equal, okay);
    1.84 -  __ cmpl(scratch, bc);
    1.85 -  __ jcc(Assembler::equal, okay);
    1.86 +  Label L_okay;
    1.87 +  __ load_unsigned_byte(temp_reg, at_bcp(0));
    1.88 +  __ cmpl(temp_reg, (int)Bytecodes::java_code(bc));
    1.89 +  __ jccb(Assembler::equal, L_okay);
    1.90 +  __ cmpl(temp_reg, bc_reg);
    1.91 +  __ jcc(Assembler::equal, L_okay);
    1.92    __ stop("patching the wrong bytecode");
    1.93 -  __ bind(okay);
    1.94 +  __ bind(L_okay);
    1.95  #endif
    1.96 +
    1.97    // patch bytecode
    1.98 -  __ movb(at_bcp(0), bc);
    1.99 -  __ bind(patch_done);
   1.100 +  __ movb(at_bcp(0), bc_reg);
   1.101 +  __ bind(L_patch_done);
   1.102  }
   1.103  
   1.104  //----------------------------------------------------------------------------------------------------
   1.105 @@ -2060,24 +2089,20 @@
   1.106    assert_different_registers(result, Rcache, index, temp);
   1.107  
   1.108    Label resolved;
   1.109 -  __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
   1.110    if (byte_no == f1_oop) {
   1.111      // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
   1.112      // This kind of CP cache entry does not need to match the flags byte, because
   1.113      // there is a 1-1 relation between bytecode type and CP entry type.
   1.114      assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD)
   1.115 +    __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
   1.116      __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()));
   1.117      __ testptr(result, result);
   1.118      __ jcc(Assembler::notEqual, resolved);
   1.119    } else {
   1.120      assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
   1.121      assert(result == noreg, "");  //else change code for setting result
   1.122 -    const int shift_count = (1 + byte_no)*BitsPerByte;
   1.123 -    __ movl(temp, Address(Rcache, index, Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
   1.124 -    __ shrl(temp, shift_count);
   1.125 -    // have we resolved this bytecode?
   1.126 -    __ andl(temp, 0xFF);
   1.127 -    __ cmpl(temp, (int)bytecode());
   1.128 +    __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
   1.129 +    __ cmpl(temp, (int) bytecode());  // have we resolved this bytecode?
   1.130      __ jcc(Assembler::equal, resolved);
   1.131    }
   1.132  
   1.133 @@ -2453,138 +2478,153 @@
   1.134  
   1.135    __ shrl(flags, ConstantPoolCacheEntry::tosBits);
   1.136    assert(btos == 0, "change code, btos != 0");
   1.137 -  // btos
   1.138    __ andl(flags, 0x0f);
   1.139    __ jcc(Assembler::notZero, notByte);
   1.140  
   1.141 -  __ pop(btos);
   1.142 -  if (!is_static) pop_and_check_object(obj);
   1.143 -  __ movb(lo, rax );
   1.144 -  if (!is_static) {
   1.145 -    patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx);
   1.146 +  // btos
   1.147 +  {
   1.148 +    __ pop(btos);
   1.149 +    if (!is_static) pop_and_check_object(obj);
   1.150 +    __ movb(lo, rax);
   1.151 +    if (!is_static) {
   1.152 +      patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx, true, byte_no);
   1.153 +    }
   1.154 +    __ jmp(Done);
   1.155    }
   1.156 -  __ jmp(Done);
   1.157  
   1.158    __ bind(notByte);
   1.159 +  __ cmpl(flags, itos);
   1.160 +  __ jcc(Assembler::notEqual, notInt);
   1.161 +
   1.162    // itos
   1.163 -  __ cmpl(flags, itos );
   1.164 -  __ jcc(Assembler::notEqual, notInt);
   1.165 -
   1.166 -  __ pop(itos);
   1.167 -  if (!is_static) pop_and_check_object(obj);
   1.168 -
   1.169 -  __ movl(lo, rax );
   1.170 -  if (!is_static) {
   1.171 -    patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx);
   1.172 +  {
   1.173 +    __ pop(itos);
   1.174 +    if (!is_static) pop_and_check_object(obj);
   1.175 +    __ movl(lo, rax);
   1.176 +    if (!is_static) {
   1.177 +      patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx, true, byte_no);
   1.178 +    }
   1.179 +    __ jmp(Done);
   1.180    }
   1.181 -  __ jmp(Done);
   1.182  
   1.183    __ bind(notInt);
   1.184 +  __ cmpl(flags, atos);
   1.185 +  __ jcc(Assembler::notEqual, notObj);
   1.186 +
   1.187    // atos
   1.188 -  __ cmpl(flags, atos );
   1.189 -  __ jcc(Assembler::notEqual, notObj);
   1.190 -
   1.191 -  __ pop(atos);
   1.192 -  if (!is_static) pop_and_check_object(obj);
   1.193 -
   1.194 -  do_oop_store(_masm, lo, rax, _bs->kind(), false);
   1.195 -
   1.196 -  if (!is_static) {
   1.197 -    patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx);
   1.198 +  {
   1.199 +    __ pop(atos);
   1.200 +    if (!is_static) pop_and_check_object(obj);
   1.201 +    do_oop_store(_masm, lo, rax, _bs->kind(), false);
   1.202 +    if (!is_static) {
   1.203 +      patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx, true, byte_no);
   1.204 +    }
   1.205 +    __ jmp(Done);
   1.206    }
   1.207  
   1.208 -  __ jmp(Done);
   1.209 -
   1.210    __ bind(notObj);
   1.211 +  __ cmpl(flags, ctos);
   1.212 +  __ jcc(Assembler::notEqual, notChar);
   1.213 +
   1.214    // ctos
   1.215 -  __ cmpl(flags, ctos );
   1.216 -  __ jcc(Assembler::notEqual, notChar);
   1.217 -
   1.218 -  __ pop(ctos);
   1.219 -  if (!is_static) pop_and_check_object(obj);
   1.220 -  __ movw(lo, rax );
   1.221 -  if (!is_static) {
   1.222 -    patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx);
   1.223 +  {
   1.224 +    __ pop(ctos);
   1.225 +    if (!is_static) pop_and_check_object(obj);
   1.226 +    __ movw(lo, rax);
   1.227 +    if (!is_static) {
   1.228 +      patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx, true, byte_no);
   1.229 +    }
   1.230 +    __ jmp(Done);
   1.231    }
   1.232 -  __ jmp(Done);
   1.233  
   1.234    __ bind(notChar);
   1.235 +  __ cmpl(flags, stos);
   1.236 +  __ jcc(Assembler::notEqual, notShort);
   1.237 +
   1.238    // stos
   1.239 -  __ cmpl(flags, stos );
   1.240 -  __ jcc(Assembler::notEqual, notShort);
   1.241 -
   1.242 -  __ pop(stos);
   1.243 -  if (!is_static) pop_and_check_object(obj);
   1.244 -  __ movw(lo, rax );
   1.245 -  if (!is_static) {
   1.246 -    patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx);
   1.247 +  {
   1.248 +    __ pop(stos);
   1.249 +    if (!is_static) pop_and_check_object(obj);
   1.250 +    __ movw(lo, rax);
   1.251 +    if (!is_static) {
   1.252 +      patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx, true, byte_no);
   1.253 +    }
   1.254 +    __ jmp(Done);
   1.255    }
   1.256 -  __ jmp(Done);
   1.257  
   1.258    __ bind(notShort);
   1.259 +  __ cmpl(flags, ltos);
   1.260 +  __ jcc(Assembler::notEqual, notLong);
   1.261 +
   1.262    // ltos
   1.263 -  __ cmpl(flags, ltos );
   1.264 -  __ jcc(Assembler::notEqual, notLong);
   1.265 -
   1.266 -  Label notVolatileLong;
   1.267 -  __ testl(rdx, rdx);
   1.268 -  __ jcc(Assembler::zero, notVolatileLong);
   1.269 -
   1.270 -  __ pop(ltos);  // overwrites rdx, do this after testing volatile.
   1.271 -  if (!is_static) pop_and_check_object(obj);
   1.272 -
   1.273 -  // Replace with real volatile test
   1.274 -  __ push(rdx);
   1.275 -  __ push(rax);                 // Must update atomically with FIST
   1.276 -  __ fild_d(Address(rsp,0));    // So load into FPU register
   1.277 -  __ fistp_d(lo);               // and put into memory atomically
   1.278 -  __ addptr(rsp, 2*wordSize);
   1.279 -  // volatile_barrier();
   1.280 -  volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
   1.281 -                                               Assembler::StoreStore));
   1.282 -  // Don't rewrite volatile version
   1.283 -  __ jmp(notVolatile);
   1.284 -
   1.285 -  __ bind(notVolatileLong);
   1.286 -
   1.287 -  __ pop(ltos);  // overwrites rdx
   1.288 -  if (!is_static) pop_and_check_object(obj);
   1.289 -  NOT_LP64(__ movptr(hi, rdx));
   1.290 -  __ movptr(lo, rax);
   1.291 -  if (!is_static) {
   1.292 -    patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx);
   1.293 +  {
   1.294 +    Label notVolatileLong;
   1.295 +    __ testl(rdx, rdx);
   1.296 +    __ jcc(Assembler::zero, notVolatileLong);
   1.297 +
   1.298 +    __ pop(ltos);  // overwrites rdx, do this after testing volatile.
   1.299 +    if (!is_static) pop_and_check_object(obj);
   1.300 +
   1.301 +    // Replace with real volatile test
   1.302 +    __ push(rdx);
   1.303 +    __ push(rax);                 // Must update atomically with FIST
   1.304 +    __ fild_d(Address(rsp,0));    // So load into FPU register
   1.305 +    __ fistp_d(lo);               // and put into memory atomically
   1.306 +    __ addptr(rsp, 2*wordSize);
   1.307 +    // volatile_barrier();
   1.308 +    volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
   1.309 +                                                 Assembler::StoreStore));
   1.310 +    // Don't rewrite volatile version
   1.311 +    __ jmp(notVolatile);
   1.312 +
   1.313 +    __ bind(notVolatileLong);
   1.314 +
   1.315 +    __ pop(ltos);  // overwrites rdx
   1.316 +    if (!is_static) pop_and_check_object(obj);
   1.317 +    NOT_LP64(__ movptr(hi, rdx));
   1.318 +    __ movptr(lo, rax);
   1.319 +    if (!is_static) {
   1.320 +      patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx, true, byte_no);
   1.321 +    }
   1.322 +    __ jmp(notVolatile);
   1.323    }
   1.324 -  __ jmp(notVolatile);
   1.325  
   1.326    __ bind(notLong);
   1.327 +  __ cmpl(flags, ftos);
   1.328 +  __ jcc(Assembler::notEqual, notFloat);
   1.329 +
   1.330    // ftos
   1.331 -  __ cmpl(flags, ftos );
   1.332 -  __ jcc(Assembler::notEqual, notFloat);
   1.333 -
   1.334 -  __ pop(ftos);
   1.335 -  if (!is_static) pop_and_check_object(obj);
   1.336 -  __ fstp_s(lo);
   1.337 -  if (!is_static) {
   1.338 -    patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx);
   1.339 +  {
   1.340 +    __ pop(ftos);
   1.341 +    if (!is_static) pop_and_check_object(obj);
   1.342 +    __ fstp_s(lo);
   1.343 +    if (!is_static) {
   1.344 +      patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx, true, byte_no);
   1.345 +    }
   1.346 +    __ jmp(Done);
   1.347    }
   1.348 -  __ jmp(Done);
   1.349  
   1.350    __ bind(notFloat);
   1.351 +#ifdef ASSERT
   1.352 +  __ cmpl(flags, dtos);
   1.353 +  __ jcc(Assembler::notEqual, notDouble);
   1.354 +#endif
   1.355 +
   1.356    // dtos
   1.357 -  __ cmpl(flags, dtos );
   1.358 -  __ jcc(Assembler::notEqual, notDouble);
   1.359 -
   1.360 -  __ pop(dtos);
   1.361 -  if (!is_static) pop_and_check_object(obj);
   1.362 -  __ fstp_d(lo);
   1.363 -  if (!is_static) {
   1.364 -    patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx);
   1.365 +  {
   1.366 +    __ pop(dtos);
   1.367 +    if (!is_static) pop_and_check_object(obj);
   1.368 +    __ fstp_d(lo);
   1.369 +    if (!is_static) {
   1.370 +      patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx, true, byte_no);
   1.371 +    }
   1.372 +    __ jmp(Done);
   1.373    }
   1.374 -  __ jmp(Done);
   1.375 -
   1.376 +
   1.377 +#ifdef ASSERT
   1.378    __ bind(notDouble);
   1.379 -
   1.380    __ stop("Bad state");
   1.381 +#endif
   1.382  
   1.383    __ bind(Done);
   1.384  

mercurial