hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
changeset 10265 4c869854aebd
parent 10008 d84de97ad847
child 11430 718fc06da49a
child 11407 5399831730cd
equal deleted inserted replaced
10264:6879f93d268d 10265:4c869854aebd
   201 Address TemplateTable::at_bcp(int offset) {
   201 Address TemplateTable::at_bcp(int offset) {
   202   assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
   202   assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
   203   return Address(r13, offset);
   203   return Address(r13, offset);
   204 }
   204 }
   205 
   205 
   206 void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc,
   206 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
   207                                    Register scratch,
   207                                    Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
   208                                    bool load_bc_into_scratch/*=true*/) {
   208                                    int byte_no) {
   209   if (!RewriteBytecodes) {
   209   if (!RewriteBytecodes)  return;
   210     return;
   210   Label L_patch_done;
   211   }
   211 
   212   // the pair bytecodes have already done the load.
   212   switch (bc) {
   213   if (load_bc_into_scratch) {
   213   case Bytecodes::_fast_aputfield:
   214     __ movl(bc, bytecode);
   214   case Bytecodes::_fast_bputfield:
   215   }
   215   case Bytecodes::_fast_cputfield:
   216   Label patch_done;
   216   case Bytecodes::_fast_dputfield:
       
   217   case Bytecodes::_fast_fputfield:
       
   218   case Bytecodes::_fast_iputfield:
       
   219   case Bytecodes::_fast_lputfield:
       
   220   case Bytecodes::_fast_sputfield:
       
   221     {
       
   222       // We skip bytecode quickening for putfield instructions when
       
   223       // the put_code written to the constant pool cache is zero.
       
   224       // This is required so that every execution of this instruction
       
   225       // calls out to InterpreterRuntime::resolve_get_put to do
       
   226       // additional, required work.
       
   227       assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
       
   228       assert(load_bc_into_bc_reg, "we use bc_reg as temp");
       
   229       __ get_cache_and_index_and_bytecode_at_bcp(temp_reg, bc_reg, temp_reg, byte_no, 1);
       
   230       __ movl(bc_reg, bc);
       
   231       __ cmpl(temp_reg, (int) 0);
       
   232       __ jcc(Assembler::zero, L_patch_done);  // don't patch
       
   233     }
       
   234     break;
       
   235   default:
       
   236     assert(byte_no == -1, "sanity");
       
   237     // the pair bytecodes have already done the load.
       
   238     if (load_bc_into_bc_reg) {
       
   239       __ movl(bc_reg, bc);
       
   240     }
       
   241   }
       
   242 
   217   if (JvmtiExport::can_post_breakpoint()) {
   243   if (JvmtiExport::can_post_breakpoint()) {
   218     Label fast_patch;
   244     Label L_fast_patch;
   219     // if a breakpoint is present we can't rewrite the stream directly
   245     // if a breakpoint is present we can't rewrite the stream directly
   220     __ movzbl(scratch, at_bcp(0));
   246     __ movzbl(temp_reg, at_bcp(0));
   221     __ cmpl(scratch, Bytecodes::_breakpoint);
   247     __ cmpl(temp_reg, Bytecodes::_breakpoint);
   222     __ jcc(Assembler::notEqual, fast_patch);
   248     __ jcc(Assembler::notEqual, L_fast_patch);
   223     __ get_method(scratch);
   249     __ get_method(temp_reg);
   224     // Let breakpoint table handling rewrite to quicker bytecode
   250     // Let breakpoint table handling rewrite to quicker bytecode
   225     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, r13, bc);
   251     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), temp_reg, r13, bc_reg);
   226 #ifndef ASSERT
   252 #ifndef ASSERT
   227     __ jmpb(patch_done);
   253     __ jmpb(L_patch_done);
   228 #else
   254 #else
   229     __ jmp(patch_done);
   255     __ jmp(L_patch_done);
   230 #endif
   256 #endif
   231     __ bind(fast_patch);
   257     __ bind(L_fast_patch);
   232   }
   258   }
       
   259 
   233 #ifdef ASSERT
   260 #ifdef ASSERT
   234   Label okay;
   261   Label L_okay;
   235   __ load_unsigned_byte(scratch, at_bcp(0));
   262   __ load_unsigned_byte(temp_reg, at_bcp(0));
   236   __ cmpl(scratch, (int) Bytecodes::java_code(bytecode));
   263   __ cmpl(temp_reg, (int) Bytecodes::java_code(bc));
   237   __ jcc(Assembler::equal, okay);
   264   __ jcc(Assembler::equal, L_okay);
   238   __ cmpl(scratch, bc);
   265   __ cmpl(temp_reg, bc_reg);
   239   __ jcc(Assembler::equal, okay);
   266   __ jcc(Assembler::equal, L_okay);
   240   __ stop("patching the wrong bytecode");
   267   __ stop("patching the wrong bytecode");
   241   __ bind(okay);
   268   __ bind(L_okay);
   242 #endif
   269 #endif
       
   270 
   243   // patch bytecode
   271   // patch bytecode
   244   __ movb(at_bcp(0), bc);
   272   __ movb(at_bcp(0), bc_reg);
   245   __ bind(patch_done);
   273   __ bind(L_patch_done);
   246 }
   274 }
   247 
   275 
   248 
   276 
   249 // Individual instructions
   277 // Individual instructions
   250 
   278 
  2096                                             size_t index_size) {
  2124                                             size_t index_size) {
  2097   const Register temp = rbx;
  2125   const Register temp = rbx;
  2098   assert_different_registers(result, Rcache, index, temp);
  2126   assert_different_registers(result, Rcache, index, temp);
  2099 
  2127 
  2100   Label resolved;
  2128   Label resolved;
  2101   __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
       
  2102   if (byte_no == f1_oop) {
  2129   if (byte_no == f1_oop) {
  2103     // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
  2130     // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
  2104     // This kind of CP cache entry does not need to match the flags byte, because
  2131     // This kind of CP cache entry does not need to match the flags byte, because
  2105     // there is a 1-1 relation between bytecode type and CP entry type.
  2132     // there is a 1-1 relation between bytecode type and CP entry type.
  2106     assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD)
  2133     assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD)
       
  2134     __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
  2107     __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()));
  2135     __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()));
  2108     __ testptr(result, result);
  2136     __ testptr(result, result);
  2109     __ jcc(Assembler::notEqual, resolved);
  2137     __ jcc(Assembler::notEqual, resolved);
  2110   } else {
  2138   } else {
  2111     assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
  2139     assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
  2112     assert(result == noreg, "");  //else change code for setting result
  2140     assert(result == noreg, "");  //else change code for setting result
  2113     const int shift_count = (1 + byte_no) * BitsPerByte;
  2141     __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
  2114     __ movl(temp, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
  2142     __ cmpl(temp, (int) bytecode());  // have we resolved this bytecode?
  2115     __ shrl(temp, shift_count);
       
  2116     // have we resolved this bytecode?
       
  2117     __ andl(temp, 0xFF);
       
  2118     __ cmpl(temp, (int) bytecode());
       
  2119     __ jcc(Assembler::equal, resolved);
  2143     __ jcc(Assembler::equal, resolved);
  2120   }
  2144   }
  2121 
  2145 
  2122   // resolve first time through
  2146   // resolve first time through
  2123   address entry;
  2147   address entry;
  2505   __ shrl(flags, ConstantPoolCacheEntry::tosBits);
  2529   __ shrl(flags, ConstantPoolCacheEntry::tosBits);
  2506 
  2530 
  2507   assert(btos == 0, "change code, btos != 0");
  2531   assert(btos == 0, "change code, btos != 0");
  2508   __ andl(flags, 0x0f);
  2532   __ andl(flags, 0x0f);
  2509   __ jcc(Assembler::notZero, notByte);
  2533   __ jcc(Assembler::notZero, notByte);
       
  2534 
  2510   // btos
  2535   // btos
  2511   __ pop(btos);
  2536   {
  2512   if (!is_static) pop_and_check_object(obj);
  2537     __ pop(btos);
  2513   __ movb(field, rax);
  2538     if (!is_static) pop_and_check_object(obj);
  2514   if (!is_static) {
  2539     __ movb(field, rax);
  2515     patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx);
  2540     if (!is_static) {
  2516   }
  2541       patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx, true, byte_no);
  2517   __ jmp(Done);
  2542     }
       
  2543     __ jmp(Done);
       
  2544   }
  2518 
  2545 
  2519   __ bind(notByte);
  2546   __ bind(notByte);
  2520   __ cmpl(flags, atos);
  2547   __ cmpl(flags, atos);
  2521   __ jcc(Assembler::notEqual, notObj);
  2548   __ jcc(Assembler::notEqual, notObj);
       
  2549 
  2522   // atos
  2550   // atos
  2523   __ pop(atos);
  2551   {
  2524   if (!is_static) pop_and_check_object(obj);
  2552     __ pop(atos);
  2525 
  2553     if (!is_static) pop_and_check_object(obj);
  2526   // Store into the field
  2554     // Store into the field
  2527   do_oop_store(_masm, field, rax, _bs->kind(), false);
  2555     do_oop_store(_masm, field, rax, _bs->kind(), false);
  2528 
  2556     if (!is_static) {
  2529   if (!is_static) {
  2557       patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
  2530     patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx);
  2558     }
  2531   }
  2559     __ jmp(Done);
  2532   __ jmp(Done);
  2560   }
  2533 
  2561 
  2534   __ bind(notObj);
  2562   __ bind(notObj);
  2535   __ cmpl(flags, itos);
  2563   __ cmpl(flags, itos);
  2536   __ jcc(Assembler::notEqual, notInt);
  2564   __ jcc(Assembler::notEqual, notInt);
       
  2565 
  2537   // itos
  2566   // itos
  2538   __ pop(itos);
  2567   {
  2539   if (!is_static) pop_and_check_object(obj);
  2568     __ pop(itos);
  2540   __ movl(field, rax);
  2569     if (!is_static) pop_and_check_object(obj);
  2541   if (!is_static) {
  2570     __ movl(field, rax);
  2542     patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx);
  2571     if (!is_static) {
  2543   }
  2572       patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
  2544   __ jmp(Done);
  2573     }
       
  2574     __ jmp(Done);
       
  2575   }
  2545 
  2576 
  2546   __ bind(notInt);
  2577   __ bind(notInt);
  2547   __ cmpl(flags, ctos);
  2578   __ cmpl(flags, ctos);
  2548   __ jcc(Assembler::notEqual, notChar);
  2579   __ jcc(Assembler::notEqual, notChar);
       
  2580 
  2549   // ctos
  2581   // ctos
  2550   __ pop(ctos);
  2582   {
  2551   if (!is_static) pop_and_check_object(obj);
  2583     __ pop(ctos);
  2552   __ movw(field, rax);
  2584     if (!is_static) pop_and_check_object(obj);
  2553   if (!is_static) {
  2585     __ movw(field, rax);
  2554     patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx);
  2586     if (!is_static) {
  2555   }
  2587       patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx, true, byte_no);
  2556   __ jmp(Done);
  2588     }
       
  2589     __ jmp(Done);
       
  2590   }
  2557 
  2591 
  2558   __ bind(notChar);
  2592   __ bind(notChar);
  2559   __ cmpl(flags, stos);
  2593   __ cmpl(flags, stos);
  2560   __ jcc(Assembler::notEqual, notShort);
  2594   __ jcc(Assembler::notEqual, notShort);
       
  2595 
  2561   // stos
  2596   // stos
  2562   __ pop(stos);
  2597   {
  2563   if (!is_static) pop_and_check_object(obj);
  2598     __ pop(stos);
  2564   __ movw(field, rax);
  2599     if (!is_static) pop_and_check_object(obj);
  2565   if (!is_static) {
  2600     __ movw(field, rax);
  2566     patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx);
  2601     if (!is_static) {
  2567   }
  2602       patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx, true, byte_no);
  2568   __ jmp(Done);
  2603     }
       
  2604     __ jmp(Done);
       
  2605   }
  2569 
  2606 
  2570   __ bind(notShort);
  2607   __ bind(notShort);
  2571   __ cmpl(flags, ltos);
  2608   __ cmpl(flags, ltos);
  2572   __ jcc(Assembler::notEqual, notLong);
  2609   __ jcc(Assembler::notEqual, notLong);
       
  2610 
  2573   // ltos
  2611   // ltos
  2574   __ pop(ltos);
  2612   {
  2575   if (!is_static) pop_and_check_object(obj);
  2613     __ pop(ltos);
  2576   __ movq(field, rax);
  2614     if (!is_static) pop_and_check_object(obj);
  2577   if (!is_static) {
  2615     __ movq(field, rax);
  2578     patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx);
  2616     if (!is_static) {
  2579   }
  2617       patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx, true, byte_no);
  2580   __ jmp(Done);
  2618     }
       
  2619     __ jmp(Done);
       
  2620   }
  2581 
  2621 
  2582   __ bind(notLong);
  2622   __ bind(notLong);
  2583   __ cmpl(flags, ftos);
  2623   __ cmpl(flags, ftos);
  2584   __ jcc(Assembler::notEqual, notFloat);
  2624   __ jcc(Assembler::notEqual, notFloat);
       
  2625 
  2585   // ftos
  2626   // ftos
  2586   __ pop(ftos);
  2627   {
  2587   if (!is_static) pop_and_check_object(obj);
  2628     __ pop(ftos);
  2588   __ movflt(field, xmm0);
  2629     if (!is_static) pop_and_check_object(obj);
  2589   if (!is_static) {
  2630     __ movflt(field, xmm0);
  2590     patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx);
  2631     if (!is_static) {
  2591   }
  2632       patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx, true, byte_no);
  2592   __ jmp(Done);
  2633     }
       
  2634     __ jmp(Done);
       
  2635   }
  2593 
  2636 
  2594   __ bind(notFloat);
  2637   __ bind(notFloat);
  2595 #ifdef ASSERT
  2638 #ifdef ASSERT
  2596   __ cmpl(flags, dtos);
  2639   __ cmpl(flags, dtos);
  2597   __ jcc(Assembler::notEqual, notDouble);
  2640   __ jcc(Assembler::notEqual, notDouble);
  2598 #endif
  2641 #endif
       
  2642 
  2599   // dtos
  2643   // dtos
  2600   __ pop(dtos);
  2644   {
  2601   if (!is_static) pop_and_check_object(obj);
  2645     __ pop(dtos);
  2602   __ movdbl(field, xmm0);
  2646     if (!is_static) pop_and_check_object(obj);
  2603   if (!is_static) {
  2647     __ movdbl(field, xmm0);
  2604     patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx);
  2648     if (!is_static) {
       
  2649       patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no);
       
  2650     }
  2605   }
  2651   }
  2606 
  2652 
  2607 #ifdef ASSERT
  2653 #ifdef ASSERT
  2608   __ jmp(Done);
  2654   __ jmp(Done);
  2609 
  2655 
  2610   __ bind(notDouble);
  2656   __ bind(notDouble);
  2611   __ stop("Bad state");
  2657   __ stop("Bad state");
  2612 #endif
  2658 #endif
  2613 
  2659 
  2614   __ bind(Done);
  2660   __ bind(Done);
       
  2661 
  2615   // Check for volatile store
  2662   // Check for volatile store
  2616   __ testl(rdx, rdx);
  2663   __ testl(rdx, rdx);
  2617   __ jcc(Assembler::zero, notVolatile);
  2664   __ jcc(Assembler::zero, notVolatile);
  2618   volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
  2665   volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad |
  2619                                                Assembler::StoreStore));
  2666                                                Assembler::StoreStore));
  2620 
       
  2621   __ bind(notVolatile);
  2667   __ bind(notVolatile);
  2622 }
  2668 }
  2623 
  2669 
  2624 void TemplateTable::putfield(int byte_no) {
  2670 void TemplateTable::putfield(int byte_no) {
  2625   putfield_or_static(byte_no, false);
  2671   putfield_or_static(byte_no, false);