Print this page


Split Close
Expand all
Collapse all
          --- old/src/cpu/x86/vm/templateTable_x86_32.cpp
          +++ new/src/cpu/x86/vm/templateTable_x86_32.cpp
↓ open down ↓ 194 lines elided ↑ open up ↑
 195  195  
 196  196    }
 197  197  }
 198  198  
 199  199  Address TemplateTable::at_bcp(int offset) {
 200  200    assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
 201  201    return Address(rsi, offset);
 202  202  }
 203  203  
 204  204  
 205      -void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc,
 206      -                                   Register scratch,
 207      -                                   bool load_bc_into_scratch/*=true*/) {
 208      -
 209      -  if (!RewriteBytecodes) return;
 210      -  // the pair bytecodes have already done the load.
 211      -  if (load_bc_into_scratch) {
 212      -    __ movl(bc, bytecode);
      205 +void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
      206 +                                   Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
      207 +                                   int byte_no) {
      208 +  if (!RewriteBytecodes)  return;
      209 +  Label L_patch_done;
      210 +
      211 +  switch (bc) {
      212 +  case Bytecodes::_fast_aputfield:
      213 +  case Bytecodes::_fast_bputfield:
      214 +  case Bytecodes::_fast_cputfield:
      215 +  case Bytecodes::_fast_dputfield:
      216 +  case Bytecodes::_fast_fputfield:
      217 +  case Bytecodes::_fast_iputfield:
      218 +  case Bytecodes::_fast_lputfield:
      219 +  case Bytecodes::_fast_sputfield:
      220 +    {
      221 +      // We skip bytecode quickening for putfield instructions when
      222 +      // the put_code written to the constant pool cache is zero.
      223 +      // This is required so that every execution of this instruction
      224 +      // calls out to InterpreterRuntime::resolve_get_put to do
      225 +      // additional, required work.
      226 +      assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
      227 +      assert(load_bc_into_bc_reg, "we use bc_reg as temp");
      228 +      __ get_cache_and_index_and_bytecode_at_bcp(bc_reg, temp_reg, temp_reg, byte_no, 1);
      229 +      __ movl(bc_reg, bc);
      230 +      __ cmpl(temp_reg, (int) 0);
      231 +      __ jcc(Assembler::zero, L_patch_done);  // don't patch
      232 +    }
      233 +    break;
      234 +  default:
      235 +    assert(byte_no == -1, "sanity");
      236 +    // the pair bytecodes have already done the load.
      237 +    if (load_bc_into_bc_reg) {
      238 +      __ movl(bc_reg, bc);
      239 +    }
 213  240    }
 214      -  Label patch_done;
      241 +
 215  242    if (JvmtiExport::can_post_breakpoint()) {
 216      -    Label fast_patch;
      243 +    Label L_fast_patch;
 217  244      // if a breakpoint is present we can't rewrite the stream directly
 218      -    __ movzbl(scratch, at_bcp(0));
 219      -    __ cmpl(scratch, Bytecodes::_breakpoint);
 220      -    __ jcc(Assembler::notEqual, fast_patch);
 221      -    __ get_method(scratch);
      245 +    __ movzbl(temp_reg, at_bcp(0));
      246 +    __ cmpl(temp_reg, Bytecodes::_breakpoint);
      247 +    __ jcc(Assembler::notEqual, L_fast_patch);
      248 +    __ get_method(temp_reg);
 222  249      // Let breakpoint table handling rewrite to quicker bytecode
 223      -    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, rsi, bc);
      250 +    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), temp_reg, rsi, bc_reg);
 224  251  #ifndef ASSERT
 225      -    __ jmpb(patch_done);
      252 +    __ jmpb(L_patch_done);
 226  253  #else
 227      -    __ jmp(patch_done);
      254 +    __ jmp(L_patch_done);
 228  255  #endif
 229      -    __ bind(fast_patch);
      256 +    __ bind(L_fast_patch);
 230  257    }
      258 +
 231  259  #ifdef ASSERT
 232      -  Label okay;
 233      -  __ load_unsigned_byte(scratch, at_bcp(0));
 234      -  __ cmpl(scratch, (int)Bytecodes::java_code(bytecode));
 235      -  __ jccb(Assembler::equal, okay);
 236      -  __ cmpl(scratch, bc);
 237      -  __ jcc(Assembler::equal, okay);
      260 +  Label L_okay;
      261 +  __ load_unsigned_byte(temp_reg, at_bcp(0));
      262 +  __ cmpl(temp_reg, (int)Bytecodes::java_code(bc));
      263 +  __ jccb(Assembler::equal, L_okay);
      264 +  __ cmpl(temp_reg, bc_reg);
      265 +  __ jcc(Assembler::equal, L_okay);
 238  266    __ stop("patching the wrong bytecode");
 239      -  __ bind(okay);
      267 +  __ bind(L_okay);
 240  268  #endif
      269 +
 241  270    // patch bytecode
 242      -  __ movb(at_bcp(0), bc);
 243      -  __ bind(patch_done);
      271 +  __ movb(at_bcp(0), bc_reg);
      272 +  __ bind(L_patch_done);
 244  273  }
 245  274  
 246  275  //----------------------------------------------------------------------------------------------------
 247  276  // Individual instructions
 248  277  
 249  278  void TemplateTable::nop() {
 250  279    transition(vtos, vtos);
 251  280    // nothing to do
 252  281  }
 253  282  
↓ open down ↓ 1799 lines elided ↑ open up ↑
2053 2082  void TemplateTable::resolve_cache_and_index(int byte_no,
2054 2083                                              Register result,
2055 2084                                              Register Rcache,
2056 2085                                              Register index,
2057 2086                                              size_t index_size) {
2058 2087    Register temp = rbx;
2059 2088  
2060 2089    assert_different_registers(result, Rcache, index, temp);
2061 2090  
2062 2091    Label resolved;
2063      -  __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
2064 2092    if (byte_no == f1_oop) {
2065 2093      // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
2066 2094      // This kind of CP cache entry does not need to match the flags byte, because
2067 2095      // there is a 1-1 relation between bytecode type and CP entry type.
2068 2096      assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD)
     2097 +    __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
2069 2098      __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()));
2070 2099      __ testptr(result, result);
2071 2100      __ jcc(Assembler::notEqual, resolved);
2072 2101    } else {
2073 2102      assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
2074 2103      assert(result == noreg, "");  //else change code for setting result
2075      -    const int shift_count = (1 + byte_no)*BitsPerByte;
2076      -    __ movl(temp, Address(Rcache, index, Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
2077      -    __ shrl(temp, shift_count);
2078      -    // have we resolved this bytecode?
2079      -    __ andl(temp, 0xFF);
2080      -    __ cmpl(temp, (int)bytecode());
     2104 +    __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
     2105 +    __ cmpl(temp, (int) bytecode());  // have we resolved this bytecode?
2081 2106      __ jcc(Assembler::equal, resolved);
2082 2107    }
2083 2108  
2084 2109    // resolve first time through
2085 2110    address entry;
2086 2111    switch (bytecode()) {
2087 2112      case Bytecodes::_getstatic      : // fall through
2088 2113      case Bytecodes::_putstatic      : // fall through
2089 2114      case Bytecodes::_getfield       : // fall through
2090 2115      case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
↓ open down ↓ 355 lines elided ↑ open up ↑
2446 2471    __ andl(rdx, 0x1);
2447 2472  
2448 2473    // field addresses
2449 2474    const Address lo(obj, off, Address::times_1, 0*wordSize);
2450 2475    const Address hi(obj, off, Address::times_1, 1*wordSize);
2451 2476  
2452 2477    Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
2453 2478  
2454 2479    __ shrl(flags, ConstantPoolCacheEntry::tosBits);
2455 2480    assert(btos == 0, "change code, btos != 0");
2456      -  // btos
2457 2481    __ andl(flags, 0x0f);
2458 2482    __ jcc(Assembler::notZero, notByte);
2459 2483  
2460      -  __ pop(btos);
2461      -  if (!is_static) pop_and_check_object(obj);
2462      -  __ movb(lo, rax );
2463      -  if (!is_static) {
2464      -    patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx);
     2484 +  // btos
     2485 +  {
     2486 +    __ pop(btos);
     2487 +    if (!is_static) pop_and_check_object(obj);
     2488 +    __ movb(lo, rax);
     2489 +    if (!is_static) {
     2490 +      patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx, true, byte_no);
     2491 +    }
     2492 +    __ jmp(Done);
2465 2493    }
2466      -  __ jmp(Done);
2467 2494  
2468 2495    __ bind(notByte);
2469      -  // itos
2470      -  __ cmpl(flags, itos );
     2496 +  __ cmpl(flags, itos);
2471 2497    __ jcc(Assembler::notEqual, notInt);
2472 2498  
2473      -  __ pop(itos);
2474      -  if (!is_static) pop_and_check_object(obj);
2475      -
2476      -  __ movl(lo, rax );
2477      -  if (!is_static) {
2478      -    patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx);
     2499 +  // itos
     2500 +  {
     2501 +    __ pop(itos);
     2502 +    if (!is_static) pop_and_check_object(obj);
     2503 +    __ movl(lo, rax);
     2504 +    if (!is_static) {
     2505 +      patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx, true, byte_no);
     2506 +    }
     2507 +    __ jmp(Done);
2479 2508    }
2480      -  __ jmp(Done);
2481 2509  
2482 2510    __ bind(notInt);
2483      -  // atos
2484      -  __ cmpl(flags, atos );
     2511 +  __ cmpl(flags, atos);
2485 2512    __ jcc(Assembler::notEqual, notObj);
2486 2513  
2487      -  __ pop(atos);
2488      -  if (!is_static) pop_and_check_object(obj);
2489      -
2490      -  do_oop_store(_masm, lo, rax, _bs->kind(), false);
2491      -
2492      -  if (!is_static) {
2493      -    patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx);
     2514 +  // atos
     2515 +  {
     2516 +    __ pop(atos);
     2517 +    if (!is_static) pop_and_check_object(obj);
     2518 +    do_oop_store(_masm, lo, rax, _bs->kind(), false);
     2519 +    if (!is_static) {
     2520 +      patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx, true, byte_no);
     2521 +    }
     2522 +    __ jmp(Done);
2494 2523    }
2495 2524  
2496      -  __ jmp(Done);
2497      -
2498 2525    __ bind(notObj);
2499      -  // ctos
2500      -  __ cmpl(flags, ctos );
     2526 +  __ cmpl(flags, ctos);
2501 2527    __ jcc(Assembler::notEqual, notChar);
2502 2528  
2503      -  __ pop(ctos);
2504      -  if (!is_static) pop_and_check_object(obj);
2505      -  __ movw(lo, rax );
2506      -  if (!is_static) {
2507      -    patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx);
     2529 +  // ctos
     2530 +  {
     2531 +    __ pop(ctos);
     2532 +    if (!is_static) pop_and_check_object(obj);
     2533 +    __ movw(lo, rax);
     2534 +    if (!is_static) {
     2535 +      patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx, true, byte_no);
     2536 +    }
     2537 +    __ jmp(Done);
2508 2538    }
2509      -  __ jmp(Done);
2510 2539  
2511 2540    __ bind(notChar);
2512      -  // stos
2513      -  __ cmpl(flags, stos );
     2541 +  __ cmpl(flags, stos);
2514 2542    __ jcc(Assembler::notEqual, notShort);
2515 2543  
2516      -  __ pop(stos);
2517      -  if (!is_static) pop_and_check_object(obj);
2518      -  __ movw(lo, rax );
2519      -  if (!is_static) {
2520      -    patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx);
     2544 +  // stos
     2545 +  {
     2546 +    __ pop(stos);
     2547 +    if (!is_static) pop_and_check_object(obj);
     2548 +    __ movw(lo, rax);
     2549 +    if (!is_static) {
     2550 +      patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx, true, byte_no);
     2551 +    }
     2552 +    __ jmp(Done);
2521 2553    }
2522      -  __ jmp(Done);
2523 2554  
2524 2555    __ bind(notShort);
2525      -  // ltos
2526      -  __ cmpl(flags, ltos );
     2556 +  __ cmpl(flags, ltos);
2527 2557    __ jcc(Assembler::notEqual, notLong);
2528 2558  
2529      -  Label notVolatileLong;
2530      -  __ testl(rdx, rdx);
2531      -  __ jcc(Assembler::zero, notVolatileLong);
2532      -
2533      -  __ pop(ltos);  // overwrites rdx, do this after testing volatile.
2534      -  if (!is_static) pop_and_check_object(obj);
2535      -
2536      -  // Replace with real volatile test
2537      -  __ push(rdx);
2538      -  __ push(rax);                 // Must update atomically with FIST
2539      -  __ fild_d(Address(rsp,0));    // So load into FPU register
2540      -  __ fistp_d(lo);               // and put into memory atomically
2541      -  __ addptr(rsp, 2*wordSize);
2542      -  // volatile_barrier();
2543      -  volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
2544      -                                               Assembler::StoreStore));
2545      -  // Don't rewrite volatile version
2546      -  __ jmp(notVolatile);
2547      -
2548      -  __ bind(notVolatileLong);
2549      -
2550      -  __ pop(ltos);  // overwrites rdx
2551      -  if (!is_static) pop_and_check_object(obj);
2552      -  NOT_LP64(__ movptr(hi, rdx));
2553      -  __ movptr(lo, rax);
2554      -  if (!is_static) {
2555      -    patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx);
     2559 +  // ltos
     2560 +  {
     2561 +    Label notVolatileLong;
     2562 +    __ testl(rdx, rdx);
     2563 +    __ jcc(Assembler::zero, notVolatileLong);
     2564 +
     2565 +    __ pop(ltos);  // overwrites rdx, do this after testing volatile.
     2566 +    if (!is_static) pop_and_check_object(obj);
     2567 +
     2568 +    // Replace with real volatile test
     2569 +    __ push(rdx);
     2570 +    __ push(rax);                 // Must update atomically with FIST
     2571 +    __ fild_d(Address(rsp,0));    // So load into FPU register
     2572 +    __ fistp_d(lo);               // and put into memory atomically
     2573 +    __ addptr(rsp, 2*wordSize);
     2574 +    // volatile_barrier();
     2575 +    volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
     2576 +                                                 Assembler::StoreStore));
     2577 +    // Don't rewrite volatile version
     2578 +    __ jmp(notVolatile);
     2579 +
     2580 +    __ bind(notVolatileLong);
     2581 +
     2582 +    __ pop(ltos);  // overwrites rdx
     2583 +    if (!is_static) pop_and_check_object(obj);
     2584 +    NOT_LP64(__ movptr(hi, rdx));
     2585 +    __ movptr(lo, rax);
     2586 +    if (!is_static) {
     2587 +      patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx, true, byte_no);
     2588 +    }
     2589 +    __ jmp(notVolatile);
2556 2590    }
2557      -  __ jmp(notVolatile);
2558 2591  
2559 2592    __ bind(notLong);
2560      -  // ftos
2561      -  __ cmpl(flags, ftos );
     2593 +  __ cmpl(flags, ftos);
2562 2594    __ jcc(Assembler::notEqual, notFloat);
2563 2595  
2564      -  __ pop(ftos);
2565      -  if (!is_static) pop_and_check_object(obj);
2566      -  __ fstp_s(lo);
2567      -  if (!is_static) {
2568      -    patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx);
     2596 +  // ftos
     2597 +  {
     2598 +    __ pop(ftos);
     2599 +    if (!is_static) pop_and_check_object(obj);
     2600 +    __ fstp_s(lo);
     2601 +    if (!is_static) {
     2602 +      patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx, true, byte_no);
     2603 +    }
     2604 +    __ jmp(Done);
2569 2605    }
2570      -  __ jmp(Done);
2571 2606  
2572 2607    __ bind(notFloat);
2573      -  // dtos
2574      -  __ cmpl(flags, dtos );
     2608 +#ifdef ASSERT
     2609 +  __ cmpl(flags, dtos);
2575 2610    __ jcc(Assembler::notEqual, notDouble);
     2611 +#endif
2576 2612  
2577      -  __ pop(dtos);
2578      -  if (!is_static) pop_and_check_object(obj);
2579      -  __ fstp_d(lo);
2580      -  if (!is_static) {
2581      -    patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx);
     2613 +  // dtos
     2614 +  {
     2615 +    __ pop(dtos);
     2616 +    if (!is_static) pop_and_check_object(obj);
     2617 +    __ fstp_d(lo);
     2618 +    if (!is_static) {
     2619 +      patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx, true, byte_no);
     2620 +    }
     2621 +    __ jmp(Done);
2582 2622    }
2583      -  __ jmp(Done);
2584 2623  
     2624 +#ifdef ASSERT
2585 2625    __ bind(notDouble);
2586      -
2587 2626    __ stop("Bad state");
     2627 +#endif
2588 2628  
2589 2629    __ bind(Done);
2590 2630  
2591 2631    // Check for volatile store
2592 2632    __ testl(rdx, rdx);
2593 2633    __ jcc(Assembler::zero, notVolatile);
2594 2634    volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
2595 2635                                                 Assembler::StoreStore));
2596 2636    __ bind(notVolatile);
2597 2637  }
↓ open down ↓ 1015 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX