src/cpu/x86/vm/templateTable_x86_32.cpp

changeset 3969
1d7922586cf6
parent 3698
19e197e2a1af
child 4037
da91efe96a93
     1.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Mon Jul 23 13:04:59 2012 -0700
     1.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Tue Jul 24 10:51:00 2012 -0700
     1.3 @@ -446,13 +446,13 @@
     1.4    const Register cache = rcx;
     1.5    const Register index = rdx;
     1.6  
     1.7 -  resolve_cache_and_index(f1_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1));
     1.8 +  resolve_cache_and_index(f12_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1));
     1.9    if (VerifyOops) {
    1.10      __ verify_oop(rax);
    1.11    }
    1.12  
    1.13    Label L_done, L_throw_exception;
    1.14 -  const Register con_klass_temp = rcx;  // same as Rcache
    1.15 +  const Register con_klass_temp = rcx;  // same as cache
    1.16    __ load_klass(con_klass_temp, rax);
    1.17    __ cmpptr(con_klass_temp, ExternalAddress((address)Universe::systemObjArrayKlassObj_addr()));
    1.18    __ jcc(Assembler::notEqual, L_done);
    1.19 @@ -2084,15 +2084,15 @@
    1.20                                              Register Rcache,
    1.21                                              Register index,
    1.22                                              size_t index_size) {
    1.23 -  Register temp = rbx;
    1.24 -
    1.25 +  const Register temp = rbx;
    1.26    assert_different_registers(result, Rcache, index, temp);
    1.27  
    1.28    Label resolved;
    1.29 -  if (byte_no == f1_oop) {
    1.30 -    // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
    1.31 -    // This kind of CP cache entry does not need to match the flags byte, because
    1.32 +  if (byte_no == f12_oop) {
    1.33 +    // We are resolved if the f1 field contains a non-null object (CallSite, MethodType, etc.)
    1.34 +    // This kind of CP cache entry does not need to match bytecode_1 or bytecode_2, because
    1.35      // there is a 1-1 relation between bytecode type and CP entry type.
    1.36 +    // The caller will also load a methodOop from f2.
    1.37      assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD)
    1.38      __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
    1.39      __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()));
    1.40 @@ -2112,15 +2112,18 @@
    1.41      case Bytecodes::_getstatic      : // fall through
    1.42      case Bytecodes::_putstatic      : // fall through
    1.43      case Bytecodes::_getfield       : // fall through
    1.44 -    case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
    1.45 +    case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put);        break;
    1.46      case Bytecodes::_invokevirtual  : // fall through
    1.47      case Bytecodes::_invokespecial  : // fall through
    1.48      case Bytecodes::_invokestatic   : // fall through
    1.49 -    case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);  break;
    1.50 -    case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
    1.51 -    case Bytecodes::_fast_aldc      : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
    1.52 -    case Bytecodes::_fast_aldc_w    : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
    1.53 -    default                         : ShouldNotReachHere();                                 break;
    1.54 +    case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);         break;
    1.55 +    case Bytecodes::_invokehandle   : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);   break;
    1.56 +    case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);  break;
    1.57 +    case Bytecodes::_fast_aldc      : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);            break;
    1.58 +    case Bytecodes::_fast_aldc_w    : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);            break;
    1.59 +    default:
    1.60 +      fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
    1.61 +      break;
    1.62    }
    1.63    __ movl(temp, (int)bytecode());
    1.64    __ call_VM(noreg, entry, temp);
    1.65 @@ -2149,7 +2152,7 @@
    1.66    __ movl(flags, Address(cache, index, Address::times_ptr,
    1.67             in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset())));
    1.68  
    1.69 -  // klass     overwrite register
    1.70 +  // klass overwrite register
    1.71    if (is_static) {
    1.72      __ movptr(obj, Address(cache, index, Address::times_ptr,
    1.73                             in_bytes(cp_base_offset + ConstantPoolCacheEntry::f1_offset())));
    1.74 @@ -2161,7 +2164,7 @@
    1.75                                                 Register itable_index,
    1.76                                                 Register flags,
    1.77                                                 bool is_invokevirtual,
    1.78 -                                               bool is_invokevfinal /*unused*/,
    1.79 +                                               bool is_invokevfinal, /*unused*/
    1.80                                                 bool is_invokedynamic) {
    1.81    // setup registers
    1.82    const Register cache = rcx;
    1.83 @@ -2171,28 +2174,33 @@
    1.84    assert_different_registers(itable_index, flags);
    1.85    assert_different_registers(itable_index, cache, index);
    1.86    // determine constant pool cache field offsets
    1.87 +  assert(is_invokevirtual == (byte_no == f2_byte), "is_invokevirtual flag redundant");
    1.88    const int method_offset = in_bytes(
    1.89      constantPoolCacheOopDesc::base_offset() +
    1.90 -      (is_invokevirtual
    1.91 +      ((byte_no == f2_byte)
    1.92         ? ConstantPoolCacheEntry::f2_offset()
    1.93 -       : ConstantPoolCacheEntry::f1_offset()
    1.94 -      )
    1.95 -    );
    1.96 +       : ConstantPoolCacheEntry::f1_offset()));
    1.97    const int flags_offset = in_bytes(constantPoolCacheOopDesc::base_offset() +
    1.98                                      ConstantPoolCacheEntry::flags_offset());
    1.99    // access constant pool cache fields
   1.100    const int index_offset = in_bytes(constantPoolCacheOopDesc::base_offset() +
   1.101                                      ConstantPoolCacheEntry::f2_offset());
   1.102  
   1.103 -  if (byte_no == f1_oop) {
   1.104 -    // Resolved f1_oop goes directly into 'method' register.
   1.105 -    assert(is_invokedynamic, "");
   1.106 -    resolve_cache_and_index(byte_no, method, cache, index, sizeof(u4));
   1.107 +  if (byte_no == f12_oop) {
   1.108 +    // Resolved f1_oop (CallSite, MethodType, etc.) goes into 'itable_index'.
   1.109 +    // Resolved f2_oop (methodOop invoker) will go into 'method' (at index_offset).
   1.110 +    // See ConstantPoolCacheEntry::set_dynamic_call and set_method_handle.
   1.111 +    size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2));
   1.112 +    resolve_cache_and_index(byte_no, itable_index, cache, index, index_size);
   1.113 +    __ movptr(method, Address(cache, index, Address::times_ptr, index_offset));
   1.114 +    itable_index = noreg;  // hack to disable load below
   1.115    } else {
   1.116      resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
   1.117      __ movptr(method, Address(cache, index, Address::times_ptr, method_offset));
   1.118    }
   1.119    if (itable_index != noreg) {
   1.120 +    // pick up itable index from f2 also:
   1.121 +    assert(byte_no == f1_byte, "already picked up f1");
   1.122      __ movptr(itable_index, Address(cache, index, Address::times_ptr, index_offset));
   1.123    }
   1.124    __ movl(flags, Address(cache, index, Address::times_ptr, flags_offset));
   1.125 @@ -2260,10 +2268,10 @@
   1.126  
   1.127    Label Done, notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
   1.128  
   1.129 -  __ shrl(flags, ConstantPoolCacheEntry::tosBits);
   1.130 +  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
   1.131    assert(btos == 0, "change code, btos != 0");
   1.132    // btos
   1.133 -  __ andptr(flags, 0x0f);
   1.134 +  __ andptr(flags, ConstantPoolCacheEntry::tos_state_mask);
   1.135    __ jcc(Assembler::notZero, notByte);
   1.136  
   1.137    __ load_signed_byte(rax, lo );
   1.138 @@ -2415,9 +2423,9 @@
   1.139        __ movl(rcx, Address(rax, rdx, Address::times_ptr, in_bytes(cp_base_offset +
   1.140                                     ConstantPoolCacheEntry::flags_offset())));
   1.141        __ mov(rbx, rsp);
   1.142 -      __ shrl(rcx, ConstantPoolCacheEntry::tosBits);
   1.143 -      // Make sure we don't need to mask rcx for tosBits after the above shift
   1.144 -      ConstantPoolCacheEntry::verify_tosBits();
   1.145 +      __ shrl(rcx, ConstantPoolCacheEntry::tos_state_shift);
   1.146 +      // Make sure we don't need to mask rcx after the above shift
   1.147 +      ConstantPoolCacheEntry::verify_tos_state_shift();
   1.148        __ cmpl(rcx, ltos);
   1.149        __ jccb(Assembler::equal, two_word);
   1.150        __ cmpl(rcx, dtos);
   1.151 @@ -2467,7 +2475,7 @@
   1.152  
   1.153    Label notVolatile, Done;
   1.154    __ movl(rdx, flags);
   1.155 -  __ shrl(rdx, ConstantPoolCacheEntry::volatileField);
   1.156 +  __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
   1.157    __ andl(rdx, 0x1);
   1.158  
   1.159    // field addresses
   1.160 @@ -2476,9 +2484,9 @@
   1.161  
   1.162    Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
   1.163  
   1.164 -  __ shrl(flags, ConstantPoolCacheEntry::tosBits);
   1.165 +  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
   1.166    assert(btos == 0, "change code, btos != 0");
   1.167 -  __ andl(flags, 0x0f);
   1.168 +  __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);
   1.169    __ jcc(Assembler::notZero, notByte);
   1.170  
   1.171    // btos
   1.172 @@ -2719,7 +2727,7 @@
   1.173    // volatile_barrier( );
   1.174  
   1.175    Label notVolatile, Done;
   1.176 -  __ shrl(rdx, ConstantPoolCacheEntry::volatileField);
   1.177 +  __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
   1.178    __ andl(rdx, 0x1);
   1.179    // Check for volatile store
   1.180    __ testl(rdx, rdx);
   1.181 @@ -2885,19 +2893,29 @@
   1.182  }
   1.183  
   1.184  
   1.185 -void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
   1.186 +void TemplateTable::prepare_invoke(int byte_no,
   1.187 +                                   Register method,  // linked method (or i-klass)
   1.188 +                                   Register index,   // itable index, MethodType, etc.
   1.189 +                                   Register recv,    // if caller wants to see it
   1.190 +                                   Register flags    // if caller wants to test it
   1.191 +                                   ) {
   1.192    // determine flags
   1.193 -  Bytecodes::Code code = bytecode();
   1.194 +  const Bytecodes::Code code = bytecode();
   1.195    const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
   1.196    const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
   1.197 +  const bool is_invokehandle     = code == Bytecodes::_invokehandle;
   1.198    const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
   1.199    const bool is_invokespecial    = code == Bytecodes::_invokespecial;
   1.200 -  const bool load_receiver      = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic);
   1.201 -  const bool receiver_null_check = is_invokespecial;
   1.202 -  const bool save_flags = is_invokeinterface || is_invokevirtual;
   1.203 +  const bool load_receiver       = (recv  != noreg);
   1.204 +  const bool save_flags          = (flags != noreg);
   1.205 +  assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), "");
   1.206 +  assert(save_flags    == (is_invokeinterface || is_invokevirtual), "need flags for vfinal");
   1.207 +  assert(flags == noreg || flags == rdx, "");
   1.208 +  assert(recv  == noreg || recv  == rcx, "");
   1.209 +
   1.210    // setup registers & access constant pool cache
   1.211 -  const Register recv   = rcx;
   1.212 -  const Register flags  = rdx;
   1.213 +  if (recv  == noreg)  recv  = rcx;
   1.214 +  if (flags == noreg)  flags = rdx;
   1.215    assert_different_registers(method, index, recv, flags);
   1.216  
   1.217    // save 'interpreter return address'
   1.218 @@ -2905,37 +2923,43 @@
   1.219  
   1.220    load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic);
   1.221  
   1.222 +  // maybe push appendix to arguments (just before return address)
   1.223 +  if (is_invokedynamic || is_invokehandle) {
   1.224 +    Label L_no_push;
   1.225 +    __ verify_oop(index);
   1.226 +    __ testl(flags, (1 << ConstantPoolCacheEntry::has_appendix_shift));
   1.227 +    __ jccb(Assembler::zero, L_no_push);
   1.228 +    // Push the appendix as a trailing parameter.
   1.229 +    // This must be done before we get the receiver,
   1.230 +    // since the parameter_size includes it.
   1.231 +    __ push(index);  // push appendix (MethodType, CallSite, etc.)
   1.232 +    __ bind(L_no_push);
   1.233 +  }
   1.234 +
   1.235    // load receiver if needed (note: no return address pushed yet)
   1.236    if (load_receiver) {
   1.237 -    assert(!is_invokedynamic, "");
   1.238      __ movl(recv, flags);
   1.239 -    __ andl(recv, 0xFF);
   1.240 -    // recv count is 0 based?
   1.241 -    Address recv_addr(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1));
   1.242 +    __ andl(recv, ConstantPoolCacheEntry::parameter_size_mask);
   1.243 +    const int no_return_pc_pushed_yet = -1;  // argument slot correction before we push return address
   1.244 +    const int receiver_is_at_end      = -1;  // back off one slot to get receiver
   1.245 +    Address recv_addr = __ argument_address(recv, no_return_pc_pushed_yet + receiver_is_at_end);
   1.246      __ movptr(recv, recv_addr);
   1.247      __ verify_oop(recv);
   1.248    }
   1.249  
   1.250 -  // do null check if needed
   1.251 -  if (receiver_null_check) {
   1.252 -    __ null_check(recv);
   1.253 -  }
   1.254 -
   1.255    if (save_flags) {
   1.256      __ mov(rsi, flags);
   1.257    }
   1.258  
   1.259    // compute return type
   1.260 -  __ shrl(flags, ConstantPoolCacheEntry::tosBits);
   1.261 -  // Make sure we don't need to mask flags for tosBits after the above shift
   1.262 -  ConstantPoolCacheEntry::verify_tosBits();
   1.263 +  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
   1.264 +  // Make sure we don't need to mask flags after the above shift
   1.265 +  ConstantPoolCacheEntry::verify_tos_state_shift();
   1.266    // load return address
   1.267    {
   1.268 -    address table_addr;
   1.269 -    if (is_invokeinterface || is_invokedynamic)
   1.270 -      table_addr = (address)Interpreter::return_5_addrs_by_index_table();
   1.271 -    else
   1.272 -      table_addr = (address)Interpreter::return_3_addrs_by_index_table();
   1.273 +    const address table_addr = (is_invokeinterface || is_invokedynamic) ?
   1.274 +        (address)Interpreter::return_5_addrs_by_index_table() :
   1.275 +        (address)Interpreter::return_3_addrs_by_index_table();
   1.276      ExternalAddress table(table_addr);
   1.277      __ movptr(flags, ArrayAddress(table, Address(noreg, flags, Address::times_ptr)));
   1.278    }
   1.279 @@ -2943,7 +2967,7 @@
   1.280    // push return address
   1.281    __ push(flags);
   1.282  
   1.283 -  // Restore flag value from the constant pool cache, and restore rsi
   1.284 +  // Restore flags value from the constant pool cache, and restore rsi
   1.285    // for later null checks.  rsi is the bytecode pointer
   1.286    if (save_flags) {
   1.287      __ mov(flags, rsi);
   1.288 @@ -2952,22 +2976,26 @@
   1.289  }
   1.290  
   1.291  
   1.292 -void TemplateTable::invokevirtual_helper(Register index, Register recv,
   1.293 -                        Register flags) {
   1.294 -
   1.295 +void TemplateTable::invokevirtual_helper(Register index,
   1.296 +                                         Register recv,
   1.297 +                                         Register flags) {
   1.298    // Uses temporary registers rax, rdx
   1.299    assert_different_registers(index, recv, rax, rdx);
   1.300 +  assert(index == rbx, "");
   1.301 +  assert(recv  == rcx, "");
   1.302  
   1.303    // Test for an invoke of a final method
   1.304    Label notFinal;
   1.305    __ movl(rax, flags);
   1.306 -  __ andl(rax, (1 << ConstantPoolCacheEntry::vfinalMethod));
   1.307 +  __ andl(rax, (1 << ConstantPoolCacheEntry::is_vfinal_shift));
   1.308    __ jcc(Assembler::zero, notFinal);
   1.309  
   1.310 -  Register method = index;  // method must be rbx,
   1.311 -  assert(method == rbx, "methodOop must be rbx, for interpreter calling convention");
   1.312 +  const Register method = index;  // method must be rbx
   1.313 +  assert(method == rbx,
   1.314 +         "methodOop must be rbx for interpreter calling convention");
   1.315  
   1.316    // do the call - the index is actually the method to call
   1.317 +  // that is, f2 is a vtable index if !is_vfinal, else f2 is a methodOop
   1.318    __ verify_oop(method);
   1.319  
   1.320    // It's final, need a null check here!
   1.321 @@ -2982,7 +3010,6 @@
   1.322  
   1.323    // get receiver klass
   1.324    __ null_check(recv, oopDesc::klass_offset_in_bytes());
   1.325 -  // Keep recv in rcx for callee expects it there
   1.326    __ load_klass(rax, recv);
   1.327    __ verify_oop(rax);
   1.328  
   1.329 @@ -2990,9 +3017,7 @@
   1.330    __ profile_virtual_call(rax, rdi, rdx);
   1.331  
   1.332    // get target methodOop & entry point
   1.333 -  const int base = instanceKlass::vtable_start_offset() * wordSize;
   1.334 -  assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below");
   1.335 -  __ movptr(method, Address(rax, index, Address::times_ptr, base + vtableEntry::method_offset_in_bytes()));
   1.336 +  __ lookup_virtual_method(rax, index, method);
   1.337    __ jump_from_interpreted(method, rdx);
   1.338  }
   1.339  
   1.340 @@ -3000,9 +3025,12 @@
   1.341  void TemplateTable::invokevirtual(int byte_no) {
   1.342    transition(vtos, vtos);
   1.343    assert(byte_no == f2_byte, "use this argument");
   1.344 -  prepare_invoke(rbx, noreg, byte_no);
   1.345 -
   1.346 -  // rbx,: index
   1.347 +  prepare_invoke(byte_no,
   1.348 +                 rbx,    // method or vtable index
   1.349 +                 noreg,  // unused itable index
   1.350 +                 rcx, rdx); // recv, flags
   1.351 +
   1.352 +  // rbx: index
   1.353    // rcx: receiver
   1.354    // rdx: flags
   1.355  
   1.356 @@ -3013,7 +3041,10 @@
   1.357  void TemplateTable::invokespecial(int byte_no) {
   1.358    transition(vtos, vtos);
   1.359    assert(byte_no == f1_byte, "use this argument");
   1.360 -  prepare_invoke(rbx, noreg, byte_no);
   1.361 +  prepare_invoke(byte_no, rbx, noreg,  // get f1 methodOop
   1.362 +                 rcx);  // get receiver also for null check
   1.363 +  __ verify_oop(rcx);
   1.364 +  __ null_check(rcx);
   1.365    // do the call
   1.366    __ verify_oop(rbx);
   1.367    __ profile_call(rax);
   1.368 @@ -3024,7 +3055,7 @@
   1.369  void TemplateTable::invokestatic(int byte_no) {
   1.370    transition(vtos, vtos);
   1.371    assert(byte_no == f1_byte, "use this argument");
   1.372 -  prepare_invoke(rbx, noreg, byte_no);
   1.373 +  prepare_invoke(byte_no, rbx);  // get f1 methodOop
   1.374    // do the call
   1.375    __ verify_oop(rbx);
   1.376    __ profile_call(rax);
   1.377 @@ -3042,10 +3073,11 @@
   1.378  void TemplateTable::invokeinterface(int byte_no) {
   1.379    transition(vtos, vtos);
   1.380    assert(byte_no == f1_byte, "use this argument");
   1.381 -  prepare_invoke(rax, rbx, byte_no);
   1.382 -
   1.383 -  // rax,: Interface
   1.384 -  // rbx,: index
   1.385 +  prepare_invoke(byte_no, rax, rbx,  // get f1 klassOop, f2 itable index
   1.386 +                 rcx, rdx); // recv, flags
   1.387 +
   1.388 +  // rax: interface klass (from f1)
   1.389 +  // rbx: itable index (from f2)
   1.390    // rcx: receiver
   1.391    // rdx: flags
   1.392  
   1.393 @@ -3055,7 +3087,7 @@
   1.394    // another compliant java compiler.
   1.395    Label notMethod;
   1.396    __ movl(rdi, rdx);
   1.397 -  __ andl(rdi, (1 << ConstantPoolCacheEntry::methodInterface));
   1.398 +  __ andl(rdi, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
   1.399    __ jcc(Assembler::zero, notMethod);
   1.400  
   1.401    invokevirtual_helper(rbx, rcx, rdx);
   1.402 @@ -3063,6 +3095,7 @@
   1.403  
   1.404    // Get receiver klass into rdx - also a null check
   1.405    __ restore_locals();  // restore rdi
   1.406 +  __ null_check(rcx, oopDesc::klass_offset_in_bytes());
   1.407    __ load_klass(rdx, rcx);
   1.408    __ verify_oop(rdx);
   1.409  
   1.410 @@ -3077,7 +3110,7 @@
   1.411                               rbx, rsi,
   1.412                               no_such_interface);
   1.413  
   1.414 -  // rbx,: methodOop to call
   1.415 +  // rbx: methodOop to call
   1.416    // rcx: receiver
   1.417    // Check for abstract method error
   1.418    // Note: This should be done more efficiently via a throw_abstract_method_error
   1.419 @@ -3116,9 +3149,39 @@
   1.420    __ should_not_reach_here();
   1.421  }
   1.422  
   1.423 +void TemplateTable::invokehandle(int byte_no) {
   1.424 +  transition(vtos, vtos);
   1.425 +  assert(byte_no == f12_oop, "use this argument");
   1.426 +  const Register rbx_method = rbx;  // (from f2)
   1.427 +  const Register rax_mtype  = rax;  // (from f1)
   1.428 +  const Register rcx_recv   = rcx;
   1.429 +  const Register rdx_flags  = rdx;
   1.430 +
   1.431 +  if (!EnableInvokeDynamic) {
   1.432 +    // rewriter does not generate this bytecode
   1.433 +    __ should_not_reach_here();
   1.434 +    return;
   1.435 +  }
   1.436 +
   1.437 +  prepare_invoke(byte_no,
   1.438 +                 rbx_method, rax_mtype,  // get f2 methodOop, f1 MethodType
   1.439 +                 rcx_recv);
   1.440 +  __ verify_oop(rbx_method);
   1.441 +  __ verify_oop(rcx_recv);
   1.442 +  __ null_check(rcx_recv);
   1.443 +
   1.444 +  // Note:  rax_mtype is already pushed (if necessary) by prepare_invoke
   1.445 +
   1.446 +  // FIXME: profile the LambdaForm also
   1.447 +  __ profile_final_call(rax);
   1.448 +
   1.449 +  __ jump_from_interpreted(rbx_method, rdx);
   1.450 +}
   1.451 +
   1.452 +
   1.453  void TemplateTable::invokedynamic(int byte_no) {
   1.454    transition(vtos, vtos);
   1.455 -  assert(byte_no == f1_oop, "use this argument");
   1.456 +  assert(byte_no == f12_oop, "use this argument");
   1.457  
   1.458    if (!EnableInvokeDynamic) {
   1.459      // We should not encounter this bytecode if !EnableInvokeDynamic.
   1.460 @@ -3131,26 +3194,23 @@
   1.461      return;
   1.462    }
   1.463  
   1.464 -  prepare_invoke(rax, rbx, byte_no);
   1.465 -
   1.466 -  // rax: CallSite object (f1)
   1.467 -  // rbx: unused (f2)
   1.468 -  // rcx: receiver address
   1.469 -  // rdx: flags (unused)
   1.470 -
   1.471 -  Register rax_callsite      = rax;
   1.472 -  Register rcx_method_handle = rcx;
   1.473 +  const Register rbx_method   = rbx;
   1.474 +  const Register rax_callsite = rax;
   1.475 +
   1.476 +  prepare_invoke(byte_no, rbx_method, rax_callsite);
   1.477 +
   1.478 +  // rax: CallSite object (from f1)
   1.479 +  // rbx: MH.linkToCallSite method (from f2)
   1.480 +
   1.481 +  // Note:  rax_callsite is already pushed by prepare_invoke
   1.482  
   1.483    // %%% should make a type profile for any invokedynamic that takes a ref argument
   1.484    // profile this call
   1.485    __ profile_call(rsi);
   1.486  
   1.487    __ verify_oop(rax_callsite);
   1.488 -  __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rdx)));
   1.489 -  __ null_check(rcx_method_handle);
   1.490 -  __ verify_oop(rcx_method_handle);
   1.491 -  __ prepare_to_jump_from_interpreted();
   1.492 -  __ jump_to_method_handle_entry(rcx_method_handle, rdx);
   1.493 +
   1.494 +  __ jump_from_interpreted(rbx_method, rdx);
   1.495  }
   1.496  
   1.497  //----------------------------------------------------------------------------------------------------

mercurial