6829192: JSR 292 needs to support 64-bit x86

Wed, 16 Dec 2009 12:48:04 +0100

author
twisti
date
Wed, 16 Dec 2009 12:48:04 +0100
changeset 1543
85f13cdfbc1d
parent 1537
6dc5471e0f66
child 1544
032260830071

6829192: JSR 292 needs to support 64-bit x86
Summary: changes for method handles and invokedynamic
Reviewed-by: kvn

src/cpu/x86/vm/assembler_x86.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/interp_masm_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/interp_masm_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/interp_masm_x86_64.hpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/interpreter_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/methodHandles_x86.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/stubGenerator_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/templateInterpreter_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/templateTable_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/templateTable_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/templateTable_x86_64.hpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/classFileParser.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/x86/vm/assembler_x86.cpp	Tue Dec 15 17:19:40 2009 -0800
     1.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Wed Dec 16 12:48:04 2009 +0100
     1.3 @@ -7666,7 +7666,7 @@
     1.4  
     1.5  #ifdef ASSERT
     1.6    Label L;
     1.7 -  testl(tmp, tmp);
     1.8 +  testptr(tmp, tmp);
     1.9    jccb(Assembler::notZero, L);
    1.10    hlt();
    1.11    bind(L);
     2.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp	Tue Dec 15 17:19:40 2009 -0800
     2.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp	Wed Dec 16 12:48:04 2009 +0100
     2.3 @@ -196,6 +196,9 @@
     2.4    } else {
     2.5      assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
     2.6      movl(reg, Address(rsi, bcp_offset));
     2.7 +    // Check if the secondary index definition is still ~x, otherwise
     2.8 +    // we have to change the following assembler code to calculate the
     2.9 +    // plain index.
    2.10      assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
    2.11      notl(reg);  // convert to plain index
    2.12    }
     3.1 --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp	Tue Dec 15 17:19:40 2009 -0800
     3.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp	Wed Dec 16 12:48:04 2009 +0100
     3.3 @@ -185,12 +185,30 @@
     3.4  }
     3.5  
     3.6  
     3.7 +void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
     3.8 +                                                       int bcp_offset,
     3.9 +                                                       bool giant_index) {
    3.10 +  assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
    3.11 +  if (!giant_index) {
    3.12 +    load_unsigned_short(index, Address(r13, bcp_offset));
    3.13 +  } else {
    3.14 +    assert(EnableInvokeDynamic, "giant index used only for EnableInvokeDynamic");
    3.15 +    movl(index, Address(r13, bcp_offset));
    3.16 +    // Check if the secondary index definition is still ~x, otherwise
    3.17 +    // we have to change the following assembler code to calculate the
    3.18 +    // plain index.
    3.19 +    assert(constantPoolCacheOopDesc::decode_secondary_index(~123) == 123, "else change next line");
    3.20 +    notl(index);  // convert to plain index
    3.21 +  }
    3.22 +}
    3.23 +
    3.24 +
    3.25  void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
    3.26                                                             Register index,
    3.27 -                                                           int bcp_offset) {
    3.28 -  assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
    3.29 +                                                           int bcp_offset,
    3.30 +                                                           bool giant_index) {
    3.31    assert(cache != index, "must use different registers");
    3.32 -  load_unsigned_short(index, Address(r13, bcp_offset));
    3.33 +  get_cache_index_at_bcp(index, bcp_offset, giant_index);
    3.34    movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
    3.35    assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
    3.36    // convert from field index to ConstantPoolCacheEntry index
    3.37 @@ -200,10 +218,10 @@
    3.38  
    3.39  void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
    3.40                                                                 Register tmp,
    3.41 -                                                               int bcp_offset) {
    3.42 -  assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
    3.43 +                                                               int bcp_offset,
    3.44 +                                                               bool giant_index) {
    3.45    assert(cache != tmp, "must use different register");
    3.46 -  load_unsigned_short(tmp, Address(r13, bcp_offset));
    3.47 +  get_cache_index_at_bcp(tmp, bcp_offset, giant_index);
    3.48    assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
    3.49    // convert from field index to ConstantPoolCacheEntry index
    3.50    // and from word offset to byte offset
    3.51 @@ -1236,7 +1254,8 @@
    3.52  
    3.53  void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
    3.54                                                       Register mdp,
    3.55 -                                                     Register reg2) {
    3.56 +                                                     Register reg2,
    3.57 +                                                     bool receiver_can_be_null) {
    3.58    if (ProfileInterpreter) {
    3.59      Label profile_continue;
    3.60  
    3.61 @@ -1246,8 +1265,15 @@
    3.62      // We are making a call.  Increment the count.
    3.63      increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
    3.64  
    3.65 +    Label skip_receiver_profile;
    3.66 +    if (receiver_can_be_null) {
    3.67 +      testptr(receiver, receiver);
    3.68 +      jcc(Assembler::zero, skip_receiver_profile);
    3.69 +    }
    3.70 +
    3.71      // Record the receiver type.
    3.72      record_klass_in_profile(receiver, mdp, reg2);
    3.73 +    bind(skip_receiver_profile);
    3.74  
    3.75      // The method data pointer needs to be updated to reflect the new target.
    3.76      update_mdp_by_constant(mdp,
     4.1 --- a/src/cpu/x86/vm/interp_masm_x86_64.hpp	Tue Dec 15 17:19:40 2009 -0800
     4.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.hpp	Wed Dec 16 12:48:04 2009 +0100
     4.3 @@ -95,9 +95,10 @@
     4.4  
     4.5    void get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset);
     4.6    void get_cache_and_index_at_bcp(Register cache, Register index,
     4.7 -                                  int bcp_offset);
     4.8 +                                  int bcp_offset, bool giant_index = false);
     4.9    void get_cache_entry_pointer_at_bcp(Register cache, Register tmp,
    4.10 -                                      int bcp_offset);
    4.11 +                                      int bcp_offset, bool giant_index = false);
    4.12 +  void get_cache_index_at_bcp(Register index, int bcp_offset, bool giant_index = false);
    4.13  
    4.14  
    4.15    void pop_ptr(Register r = rax);
    4.16 @@ -236,7 +237,8 @@
    4.17    void profile_call(Register mdp);
    4.18    void profile_final_call(Register mdp);
    4.19    void profile_virtual_call(Register receiver, Register mdp,
    4.20 -                            Register scratch2);
    4.21 +                            Register scratch2,
    4.22 +                            bool receiver_can_be_null = false);
    4.23    void profile_ret(Register return_bci, Register mdp);
    4.24    void profile_null_seen(Register mdp);
    4.25    void profile_typecheck(Register mdp, Register klass, Register scratch);
     5.1 --- a/src/cpu/x86/vm/interpreter_x86_64.cpp	Tue Dec 15 17:19:40 2009 -0800
     5.2 +++ b/src/cpu/x86/vm/interpreter_x86_64.cpp	Wed Dec 16 12:48:04 2009 +0100
     5.3 @@ -277,12 +277,11 @@
     5.4    address entry_point = __ pc();
     5.5  
     5.6    // abstract method entry
     5.7 -  // remove return address. Not really needed, since exception
     5.8 -  // handling throws away expression stack
     5.9 -  __ pop(rbx);
    5.10  
    5.11 -  // adjust stack to what a normal return would do
    5.12 -  __ mov(rsp, r13);
    5.13 +  //  pop return address, reset last_sp to NULL
    5.14 +  __ empty_expression_stack();
    5.15 +  __ restore_bcp();      // rsi must be correct for exception handler   (was destroyed)
    5.16 +  __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
    5.17  
    5.18    // throw exception
    5.19    __ call_VM(noreg, CAST_FROM_FN_PTR(address,
    5.20 @@ -300,7 +299,10 @@
    5.21    if (!EnableMethodHandles) {
    5.22      return generate_abstract_entry();
    5.23    }
    5.24 -  return generate_abstract_entry(); //6815692//
    5.25 +
    5.26 +  address entry_point = MethodHandles::generate_method_handle_interpreter_entry(_masm);
    5.27 +
    5.28 +  return entry_point;
    5.29  }
    5.30  
    5.31  
     6.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp	Tue Dec 15 17:19:40 2009 -0800
     6.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Wed Dec 16 12:48:04 2009 +0100
     6.3 @@ -448,7 +448,7 @@
     6.4                                  rbx_index, Address::times_ptr,
     6.5                                  base + vtableEntry::method_offset_in_bytes());
     6.6        Register rbx_method = rbx_temp;
     6.7 -      __ movl(rbx_method, vtable_entry_addr);
     6.8 +      __ movptr(rbx_method, vtable_entry_addr);
     6.9  
    6.10        __ verify_oop(rbx_method);
    6.11        __ jmp(rbx_method_fie);
     7.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Tue Dec 15 17:19:40 2009 -0800
     7.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Dec 16 12:48:04 2009 +0100
     7.3 @@ -2935,6 +2935,16 @@
     7.4  
     7.5      // arraycopy stubs used by compilers
     7.6      generate_arraycopy_stubs();
     7.7 +
     7.8 +    // generic method handle stubs
     7.9 +    if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) {
    7.10 +      for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
    7.11 +           ek < MethodHandles::_EK_LIMIT;
    7.12 +           ek = MethodHandles::EntryKind(1 + (int)ek)) {
    7.13 +        StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
    7.14 +        MethodHandles::generate_method_handle_stub(_masm, ek);
    7.15 +      }
    7.16 +    }
    7.17    }
    7.18  
    7.19   public:
     8.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Tue Dec 15 17:19:40 2009 -0800
     8.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Wed Dec 16 12:48:04 2009 +0100
     8.3 @@ -100,21 +100,26 @@
     8.4    return entry;
     8.5  }
     8.6  
     8.7 -// Arguments are: required type in rarg1, failing object (or NULL) in rarg2
     8.8 +// Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4.
     8.9  address TemplateInterpreterGenerator::generate_WrongMethodType_handler() {
    8.10    address entry = __ pc();
    8.11  
    8.12    __ pop(c_rarg2);              // failing object is at TOS
    8.13    __ pop(c_rarg1);              // required type is at TOS+8
    8.14  
    8.15 -  // expression stack must be empty before entering the VM if an
    8.16 -  // exception happened
    8.17 +  __ verify_oop(c_rarg1);
    8.18 +  __ verify_oop(c_rarg2);
    8.19 +
    8.20 +  // Various method handle types use interpreter registers as temps.
    8.21 +  __ restore_bcp();
    8.22 +  __ restore_locals();
    8.23 +
    8.24 +  // Expression stack must be empty before entering the VM for an exception.
    8.25    __ empty_expression_stack();
    8.26  
    8.27    __ call_VM(noreg,
    8.28               CAST_FROM_FN_PTR(address,
    8.29 -                              InterpreterRuntime::
    8.30 -                              throw_WrongMethodTypeException),
    8.31 +                              InterpreterRuntime::throw_WrongMethodTypeException),
    8.32               // pass required type, failing object (or NULL)
    8.33               c_rarg1, c_rarg2);
    8.34    return entry;
    8.35 @@ -182,15 +187,29 @@
    8.36    __ restore_bcp();
    8.37    __ restore_locals();
    8.38  
    8.39 -  __ get_cache_and_index_at_bcp(rbx, rcx, 1);
    8.40 +  Label L_got_cache, L_giant_index;
    8.41 +  if (EnableInvokeDynamic) {
    8.42 +    __ cmpb(Address(r13, 0), Bytecodes::_invokedynamic);
    8.43 +    __ jcc(Assembler::equal, L_giant_index);
    8.44 +  }
    8.45 +  __ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
    8.46 +  __ bind(L_got_cache);
    8.47    __ movl(rbx, Address(rbx, rcx,
    8.48 -                       Address::times_8,
    8.49 +                       Address::times_ptr,
    8.50                         in_bytes(constantPoolCacheOopDesc::base_offset()) +
    8.51                         3 * wordSize));
    8.52    __ andl(rbx, 0xFF);
    8.53    if (TaggedStackInterpreter) __ shll(rbx, 1); // 2 slots per parameter.
    8.54    __ lea(rsp, Address(rsp, rbx, Address::times_8));
    8.55    __ dispatch_next(state, step);
    8.56 +
    8.57 +  // out of the main line of code...
    8.58 +  if (EnableInvokeDynamic) {
    8.59 +    __ bind(L_giant_index);
    8.60 +    __ get_cache_and_index_at_bcp(rbx, rcx, 1, true);
    8.61 +    __ jmp(L_got_cache);
    8.62 +  }
    8.63 +
    8.64    return entry;
    8.65  }
    8.66  
     9.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Tue Dec 15 17:19:40 2009 -0800
     9.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Wed Dec 16 12:48:04 2009 +0100
     9.3 @@ -3146,7 +3146,6 @@
     9.4      __ profile_call(rsi);
     9.5    }
     9.6  
     9.7 -  Label handle_unlinked_site;
     9.8    __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
     9.9    __ null_check(rcx);
    9.10    __ prepare_to_jump_from_interpreted();
    10.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Tue Dec 15 17:19:40 2009 -0800
    10.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Wed Dec 16 12:48:04 2009 +0100
    10.3 @@ -203,18 +203,15 @@
    10.4      __ jcc(Assembler::notEqual, fast_patch);
    10.5      __ get_method(scratch);
    10.6      // Let breakpoint table handling rewrite to quicker bytecode
    10.7 -    __ call_VM(noreg,
    10.8 -               CAST_FROM_FN_PTR(address,
    10.9 -                                InterpreterRuntime::set_original_bytecode_at),
   10.10 -               scratch, r13, bc);
   10.11 +    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, r13, bc);
   10.12  #ifndef ASSERT
   10.13      __ jmpb(patch_done);
   10.14 +#else
   10.15 +    __ jmp(patch_done);
   10.16 +#endif
   10.17      __ bind(fast_patch);
   10.18    }
   10.19 -#else
   10.20 -    __ jmp(patch_done);
   10.21 -    __ bind(fast_patch);
   10.22 -  }
   10.23 +#ifdef ASSERT
   10.24    Label okay;
   10.25    __ load_unsigned_byte(scratch, at_bcp(0));
   10.26    __ cmpl(scratch, (int) Bytecodes::java_code(bytecode));
   10.27 @@ -2054,26 +2051,28 @@
   10.28    }
   10.29  }
   10.30  
   10.31 -void TemplateTable::resolve_cache_and_index(int byte_no,
   10.32 -                                            Register Rcache,
   10.33 -                                            Register index) {
   10.34 +void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) {
   10.35    assert(byte_no == 1 || byte_no == 2, "byte_no out of range");
   10.36 +  bool is_invokedynamic = (bytecode() == Bytecodes::_invokedynamic);
   10.37  
   10.38    const Register temp = rbx;
   10.39    assert_different_registers(Rcache, index, temp);
   10.40  
   10.41    const int shift_count = (1 + byte_no) * BitsPerByte;
   10.42    Label resolved;
   10.43 -  __ get_cache_and_index_at_bcp(Rcache, index, 1);
   10.44 -  __ movl(temp, Address(Rcache,
   10.45 -                        index, Address::times_8,
   10.46 -                        constantPoolCacheOopDesc::base_offset() +
   10.47 -                        ConstantPoolCacheEntry::indices_offset()));
   10.48 -  __ shrl(temp, shift_count);
   10.49 -  // have we resolved this bytecode?
   10.50 -  __ andl(temp, 0xFF);
   10.51 -  __ cmpl(temp, (int) bytecode());
   10.52 -  __ jcc(Assembler::equal, resolved);
   10.53 +  __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
   10.54 +  if (is_invokedynamic) {
   10.55 +    // we are resolved if the f1 field contains a non-null CallSite object
   10.56 +    __ cmpptr(Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()), (int32_t) NULL_WORD);
   10.57 +    __ jcc(Assembler::notEqual, resolved);
   10.58 +  } else {
   10.59 +    __ movl(temp, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
   10.60 +    __ shrl(temp, shift_count);
   10.61 +    // have we resolved this bytecode?
   10.62 +    __ andl(temp, 0xFF);
   10.63 +    __ cmpl(temp, (int) bytecode());
   10.64 +    __ jcc(Assembler::equal, resolved);
   10.65 +  }
   10.66  
   10.67    // resolve first time through
   10.68    address entry;
   10.69 @@ -2090,6 +2089,9 @@
   10.70    case Bytecodes::_invokeinterface:
   10.71      entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
   10.72      break;
   10.73 +  case Bytecodes::_invokedynamic:
   10.74 +    entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
   10.75 +    break;
   10.76    default:
   10.77      ShouldNotReachHere();
   10.78      break;
   10.79 @@ -2098,7 +2100,7 @@
   10.80    __ call_VM(noreg, entry, temp);
   10.81  
   10.82    // Update registers with resolved info
   10.83 -  __ get_cache_and_index_at_bcp(Rcache, index, 1);
   10.84 +  __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
   10.85    __ bind(resolved);
   10.86  }
   10.87  
   10.88 @@ -2832,15 +2834,14 @@
   10.89    ShouldNotReachHere();
   10.90  }
   10.91  
   10.92 -void TemplateTable::prepare_invoke(Register method,
   10.93 -                                   Register index,
   10.94 -                                   int byte_no,
   10.95 -                                   Bytecodes::Code code) {
   10.96 +void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
   10.97    // determine flags
   10.98 +  Bytecodes::Code code = bytecode();
   10.99    const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
  10.100 +  const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
  10.101    const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
  10.102    const bool is_invokespecial    = code == Bytecodes::_invokespecial;
  10.103 -  const bool load_receiver       = code != Bytecodes::_invokestatic;
  10.104 +  const bool load_receiver      = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic);
  10.105    const bool receiver_null_check = is_invokespecial;
  10.106    const bool save_flags = is_invokeinterface || is_invokevirtual;
  10.107    // setup registers & access constant pool cache
  10.108 @@ -2858,9 +2859,13 @@
  10.109      __ movl(recv, flags);
  10.110      __ andl(recv, 0xFF);
  10.111      if (TaggedStackInterpreter) __ shll(recv, 1);  // index*2
  10.112 -    __ movptr(recv, Address(rsp, recv, Address::times_8,
  10.113 -                                 -Interpreter::expr_offset_in_bytes(1)));
  10.114 -    __ verify_oop(recv);
  10.115 +    Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1));
  10.116 +    if (is_invokedynamic) {
  10.117 +      __ lea(recv, recv_addr);
  10.118 +    } else {
  10.119 +      __ movptr(recv, recv_addr);
  10.120 +      __ verify_oop(recv);
  10.121 +    }
  10.122    }
  10.123  
  10.124    // do null check if needed
  10.125 @@ -2878,10 +2883,14 @@
  10.126    ConstantPoolCacheEntry::verify_tosBits();
  10.127    // load return address
  10.128    {
  10.129 -    ExternalAddress return_5((address)Interpreter::return_5_addrs_by_index_table());
  10.130 -    ExternalAddress return_3((address)Interpreter::return_3_addrs_by_index_table());
  10.131 -    __ lea(rscratch1, (is_invokeinterface ? return_5 : return_3));
  10.132 -    __ movptr(flags, Address(rscratch1, flags, Address::times_8));
  10.133 +    address table_addr;
  10.134 +    if (is_invokeinterface || is_invokedynamic)
  10.135 +      table_addr = (address)Interpreter::return_5_addrs_by_index_table();
  10.136 +    else
  10.137 +      table_addr = (address)Interpreter::return_3_addrs_by_index_table();
  10.138 +    ExternalAddress table(table_addr);
  10.139 +    __ lea(rscratch1, table);
  10.140 +    __ movptr(flags, Address(rscratch1, flags, Address::times_ptr));
  10.141    }
  10.142  
  10.143    // push return address
  10.144 @@ -2947,7 +2956,7 @@
  10.145  
  10.146  void TemplateTable::invokevirtual(int byte_no) {
  10.147    transition(vtos, vtos);
  10.148 -  prepare_invoke(rbx, noreg, byte_no, bytecode());
  10.149 +  prepare_invoke(rbx, noreg, byte_no);
  10.150  
  10.151    // rbx: index
  10.152    // rcx: receiver
  10.153 @@ -2959,7 +2968,7 @@
  10.154  
  10.155  void TemplateTable::invokespecial(int byte_no) {
  10.156    transition(vtos, vtos);
  10.157 -  prepare_invoke(rbx, noreg, byte_no, bytecode());
  10.158 +  prepare_invoke(rbx, noreg, byte_no);
  10.159    // do the call
  10.160    __ verify_oop(rbx);
  10.161    __ profile_call(rax);
  10.162 @@ -2969,7 +2978,7 @@
  10.163  
  10.164  void TemplateTable::invokestatic(int byte_no) {
  10.165    transition(vtos, vtos);
  10.166 -  prepare_invoke(rbx, noreg, byte_no, bytecode());
  10.167 +  prepare_invoke(rbx, noreg, byte_no);
  10.168    // do the call
  10.169    __ verify_oop(rbx);
  10.170    __ profile_call(rax);
  10.171 @@ -2983,7 +2992,7 @@
  10.172  
  10.173  void TemplateTable::invokeinterface(int byte_no) {
  10.174    transition(vtos, vtos);
  10.175 -  prepare_invoke(rax, rbx, byte_no, bytecode());
  10.176 +  prepare_invoke(rax, rbx, byte_no);
  10.177  
  10.178    // rax: Interface
  10.179    // rbx: index
  10.180 @@ -3072,7 +3081,24 @@
  10.181      return;
  10.182    }
  10.183  
  10.184 -  __ stop("invokedynamic NYI");//6815692//
  10.185 +  prepare_invoke(rax, rbx, byte_no);
  10.186 +
  10.187 +  // rax: CallSite object (f1)
  10.188 +  // rbx: unused (f2)
  10.189 +  // rcx: receiver address
  10.190 +  // rdx: flags (unused)
  10.191 +
  10.192 +  if (ProfileInterpreter) {
  10.193 +    Label L;
  10.194 +    // %%% should make a type profile for any invokedynamic that takes a ref argument
  10.195 +    // profile this call
  10.196 +    __ profile_call(r13);
  10.197 +  }
  10.198 +
  10.199 +  __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx)));
  10.200 +  __ null_check(rcx);
  10.201 +  __ prepare_to_jump_from_interpreted();
  10.202 +  __ jump_to_method_handle_entry(rcx, rdx);
  10.203  }
  10.204  
  10.205  
    11.1 --- a/src/cpu/x86/vm/templateTable_x86_64.hpp	Tue Dec 15 17:19:40 2009 -0800
    11.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.hpp	Wed Dec 16 12:48:04 2009 +0100
    11.3 @@ -22,8 +22,7 @@
    11.4   *
    11.5   */
    11.6  
    11.7 -  static void prepare_invoke(Register method, Register index, int byte_no,
    11.8 -                             Bytecodes::Code code);
    11.9 +  static void prepare_invoke(Register method, Register index, int byte_no);
   11.10    static void invokevirtual_helper(Register index, Register recv,
   11.11                                     Register flags);
   11.12    static void volatile_barrier(Assembler::Membar_mask_bits order_constraint);
    12.1 --- a/src/share/vm/classfile/classFileParser.cpp	Tue Dec 15 17:19:40 2009 -0800
    12.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Wed Dec 16 12:48:04 2009 +0100
    12.3 @@ -2511,23 +2511,12 @@
    12.4        fac_ptr->nonstatic_byte_count -= 1;
    12.5        (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset,
    12.6                                     word_sig_index);
    12.7 -      if (wordSize == jintSize) {
    12.8 -        fac_ptr->nonstatic_word_count += 1;
    12.9 -      } else {
   12.10 -        fac_ptr->nonstatic_double_count += 1;
   12.11 -      }
   12.12 -
   12.13 -      FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i+4);
   12.14 +      fac_ptr->nonstatic_word_count += 1;
   12.15 +
   12.16 +      FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i + instanceKlass::low_offset);
   12.17        assert(atype == NONSTATIC_BYTE, "");
   12.18        FieldAllocationType new_atype = NONSTATIC_WORD;
   12.19 -      if (wordSize > jintSize) {
   12.20 -        if (Universe::field_type_should_be_aligned(T_LONG)) {
   12.21 -          atype = NONSTATIC_ALIGNED_DOUBLE;
   12.22 -        } else {
   12.23 -          atype = NONSTATIC_DOUBLE;
   12.24 -        }
   12.25 -      }
   12.26 -      (*fields_ptr)->ushort_at_put(i+4, new_atype);
   12.27 +      (*fields_ptr)->ushort_at_put(i + instanceKlass::low_offset, new_atype);
   12.28  
   12.29        found_vmentry = true;
   12.30        break;
   12.31 @@ -3085,7 +3074,7 @@
   12.32      int len = fields->length();
   12.33      for (int i = 0; i < len; i += instanceKlass::next_offset) {
   12.34        int real_offset;
   12.35 -      FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i+4);
   12.36 +      FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset);
   12.37        switch (atype) {
   12.38          case STATIC_OOP:
   12.39            real_offset = next_static_oop_offset;
   12.40 @@ -3173,8 +3162,8 @@
   12.41          default:
   12.42            ShouldNotReachHere();
   12.43        }
   12.44 -      fields->short_at_put(i+4, extract_low_short_from_int(real_offset) );
   12.45 -      fields->short_at_put(i+5, extract_high_short_from_int(real_offset) );
   12.46 +      fields->short_at_put(i + instanceKlass::low_offset,  extract_low_short_from_int(real_offset));
   12.47 +      fields->short_at_put(i + instanceKlass::high_offset, extract_high_short_from_int(real_offset));
   12.48      }
   12.49  
   12.50      // Size of instances

mercurial