src/cpu/x86/vm/methodHandles_x86.hpp

changeset 3969
1d7922586cf6
parent 3451
5dbed2f542ff
child 4037
da91efe96a93
     1.1 --- a/src/cpu/x86/vm/methodHandles_x86.hpp	Mon Jul 23 13:04:59 2012 -0700
     1.2 +++ b/src/cpu/x86/vm/methodHandles_x86.hpp	Tue Jul 24 10:51:00 2012 -0700
     1.3 @@ -27,266 +27,12 @@
     1.4  
     1.5  // Adapters
     1.6  enum /* platform_dependent_constants */ {
     1.7 -  adapter_code_size = NOT_LP64(16000 DEBUG_ONLY(+ 15000)) LP64_ONLY(32000 DEBUG_ONLY(+ 120000))
     1.8 -};
     1.9 -
    1.10 -public:
    1.11 -
    1.12 -// The stack just after the recursive call from a ricochet frame
    1.13 -// looks something like this.  Offsets are marked in words, not bytes.
    1.14 -// rsi (r13 on LP64) is part of the interpreter calling sequence
    1.15 -// which tells the callee where is my real rsp (for frame walking).
    1.16 -// (...lower memory addresses)
    1.17 -// rsp:     [ return pc                 ]   always the global RicochetBlob::bounce_addr
    1.18 -// rsp+1:   [ recursive arg N           ]
    1.19 -// rsp+2:   [ recursive arg N-1         ]
    1.20 -// ...
    1.21 -// rsp+N:   [ recursive arg 1           ]
    1.22 -// rsp+N+1: [ recursive method handle   ]
    1.23 -// ...
    1.24 -// rbp-6:   [ cleanup continuation pc   ]   <-- (struct RicochetFrame)
    1.25 -// rbp-5:   [ saved target MH           ]   the MH we will call on the saved args
    1.26 -// rbp-4:   [ saved args layout oop     ]   an int[] array which describes argument layout
    1.27 -// rbp-3:   [ saved args pointer        ]   address of transformed adapter arg M (slot 0)
    1.28 -// rbp-2:   [ conversion                ]   information about how the return value is used
    1.29 -// rbp-1:   [ exact sender sp           ]   exact TOS (rsi/r13) of original sender frame
    1.30 -// rbp+0:   [ saved sender fp           ]   (for original sender of AMH)
    1.31 -// rbp+1:   [ saved sender pc           ]   (back to original sender of AMH)
    1.32 -// rbp+2:   [ transformed adapter arg M ]   <-- (extended TOS of original sender)
    1.33 -// rbp+3:   [ transformed adapter arg M-1]
    1.34 -// ...
    1.35 -// rbp+M+1: [ transformed adapter arg 1 ]
    1.36 -// rbp+M+2: [ padding                   ] <-- (rbp + saved args base offset)
    1.37 -// ...      [ optional padding]
    1.38 -// (higher memory addresses...)
    1.39 -//
    1.40 -// The arguments originally passed by the original sender
    1.41 -// are lost, and arbitrary amounts of stack motion might have
    1.42 -// happened due to argument transformation.
    1.43 -// (This is done by C2I/I2C adapters and non-direct method handles.)
    1.44 -// This is why there is an unpredictable amount of memory between
    1.45 -// the extended and exact TOS of the sender.
    1.46 -// The ricochet adapter itself will also (in general) perform
    1.47 -// transformations before the recursive call.
    1.48 -//
    1.49 -// The transformed and saved arguments, immediately above the saved
    1.50 -// return PC, are a well-formed method handle invocation ready to execute.
    1.51 -// When the GC needs to walk the stack, these arguments are described
    1.52 -// via the saved arg types oop, an int[] array with a private format.
    1.53 -// This array is derived from the type of the transformed adapter
    1.54 -// method handle, which also sits at the base of the saved argument
    1.55 -// bundle.  Since the GC may not be able to fish out the int[]
    1.56 -// array, so it is pushed explicitly on the stack.  This may be
    1.57 -// an unnecessary expense.
    1.58 -//
    1.59 -// The following register conventions are significant at this point:
    1.60 -// rsp       the thread stack, as always; preserved by caller
    1.61 -// rsi/r13   exact TOS of recursive frame (contents of [rbp-2])
    1.62 -// rcx       recursive method handle (contents of [rsp+N+1])
    1.63 -// rbp       preserved by caller (not used by caller)
    1.64 -// Unless otherwise specified, all registers can be blown by the call.
    1.65 -//
    1.66 -// If this frame must be walked, the transformed adapter arguments
    1.67 -// will be found with the help of the saved arguments descriptor.
    1.68 -//
    1.69 -// Therefore, the descriptor must match the referenced arguments.
    1.70 -// The arguments must be followed by at least one word of padding,
    1.71 -// which will be necessary to complete the final method handle call.
    1.72 -// That word is not treated as holding an oop.  Neither is the word
    1.73 -//
    1.74 -// The word pointed to by the return argument pointer is not
    1.75 -// treated as an oop, even if points to a saved argument.
    1.76 -// This allows the saved argument list to have a "hole" in it
    1.77 -// to receive an oop from the recursive call.
    1.78 -// (The hole might temporarily contain RETURN_VALUE_PLACEHOLDER.)
    1.79 -//
    1.80 -// When the recursive callee returns, RicochetBlob::bounce_addr will
    1.81 -// immediately jump to the continuation stored in the RF.
    1.82 -// This continuation will merge the recursive return value
    1.83 -// into the saved argument list.  At that point, the original
    1.84 -// rsi, rbp, and rsp will be reloaded, the ricochet frame will
    1.85 -// disappear, and the final target of the adapter method handle
    1.86 -// will be invoked on the transformed argument list.
    1.87 -
    1.88 -class RicochetFrame {
    1.89 -  friend class MethodHandles;
    1.90 -  friend class VMStructs;
    1.91 -
    1.92 - private:
    1.93 -  intptr_t* _continuation;          // what to do when control gets back here
    1.94 -  oopDesc*  _saved_target;          // target method handle to invoke on saved_args
    1.95 -  oopDesc*  _saved_args_layout;     // caching point for MethodTypeForm.vmlayout cookie
    1.96 -  intptr_t* _saved_args_base;       // base of pushed arguments (slot 0, arg N) (-3)
    1.97 -  intptr_t  _conversion;            // misc. information from original AdapterMethodHandle (-2)
    1.98 -  intptr_t* _exact_sender_sp;       // parallel to interpreter_frame_sender_sp (-1)
    1.99 -  intptr_t* _sender_link;           // *must* coincide with frame::link_offset (0)
   1.100 -  address   _sender_pc;             // *must* coincide with frame::return_addr_offset (1)
   1.101 -
   1.102 - public:
   1.103 -  intptr_t* continuation() const        { return _continuation; }
   1.104 -  oop       saved_target() const        { return _saved_target; }
   1.105 -  oop       saved_args_layout() const   { return _saved_args_layout; }
   1.106 -  intptr_t* saved_args_base() const     { return _saved_args_base; }
   1.107 -  intptr_t  conversion() const          { return _conversion; }
   1.108 -  intptr_t* exact_sender_sp() const     { return _exact_sender_sp; }
   1.109 -  intptr_t* sender_link() const         { return _sender_link; }
   1.110 -  address   sender_pc() const           { return _sender_pc; }
   1.111 -
   1.112 -  intptr_t* extended_sender_sp() const {
   1.113 -    // The extended sender SP is above the current RicochetFrame.
   1.114 -    return (intptr_t*) (((address) this) + sizeof(RicochetFrame));
   1.115 -  }
   1.116 -
   1.117 -  intptr_t  return_value_slot_number() const {
   1.118 -    return adapter_conversion_vminfo(conversion());
   1.119 -  }
   1.120 -  BasicType return_value_type() const {
   1.121 -    return adapter_conversion_dest_type(conversion());
   1.122 -  }
   1.123 -  bool has_return_value_slot() const {
   1.124 -    return return_value_type() != T_VOID;
   1.125 -  }
   1.126 -  intptr_t* return_value_slot_addr() const {
   1.127 -    assert(has_return_value_slot(), "");
   1.128 -    return saved_arg_slot_addr(return_value_slot_number());
   1.129 -  }
   1.130 -  intptr_t* saved_target_slot_addr() const {
   1.131 -    return saved_arg_slot_addr(saved_args_length());
   1.132 -  }
   1.133 -  intptr_t* saved_arg_slot_addr(int slot) const {
   1.134 -    assert(slot >= 0, "");
   1.135 -    return (intptr_t*)( (address)saved_args_base() + (slot * Interpreter::stackElementSize) );
   1.136 -  }
   1.137 -
   1.138 -  jint      saved_args_length() const;
   1.139 -  jint      saved_arg_offset(int arg) const;
   1.140 -
   1.141 -  // GC interface
   1.142 -  oop*  saved_target_addr()                     { return (oop*)&_saved_target; }
   1.143 -  oop*  saved_args_layout_addr()                { return (oop*)&_saved_args_layout; }
   1.144 -
   1.145 -  oop  compute_saved_args_layout(bool read_cache, bool write_cache);
   1.146 -
   1.147 -  // Compiler/assembler interface.
   1.148 -  static int continuation_offset_in_bytes()     { return offset_of(RicochetFrame, _continuation); }
   1.149 -  static int saved_target_offset_in_bytes()     { return offset_of(RicochetFrame, _saved_target); }
   1.150 -  static int saved_args_layout_offset_in_bytes(){ return offset_of(RicochetFrame, _saved_args_layout); }
   1.151 -  static int saved_args_base_offset_in_bytes()  { return offset_of(RicochetFrame, _saved_args_base); }
   1.152 -  static int conversion_offset_in_bytes()       { return offset_of(RicochetFrame, _conversion); }
   1.153 -  static int exact_sender_sp_offset_in_bytes()  { return offset_of(RicochetFrame, _exact_sender_sp); }
   1.154 -  static int sender_link_offset_in_bytes()      { return offset_of(RicochetFrame, _sender_link); }
   1.155 -  static int sender_pc_offset_in_bytes()        { return offset_of(RicochetFrame, _sender_pc); }
   1.156 -
   1.157 -  // This value is not used for much, but it apparently must be nonzero.
   1.158 -  static int frame_size_in_bytes()              { return sender_link_offset_in_bytes(); }
   1.159 -
   1.160 -#ifdef ASSERT
   1.161 -  // The magic number is supposed to help find ricochet frames within the bytes of stack dumps.
   1.162 -  enum { MAGIC_NUMBER_1 = 0xFEED03E, MAGIC_NUMBER_2 = 0xBEEF03E };
   1.163 -  static int magic_number_1_offset_in_bytes()   { return -wordSize; }
   1.164 -  static int magic_number_2_offset_in_bytes()   { return sizeof(RicochetFrame); }
   1.165 -  intptr_t magic_number_1() const               { return *(intptr_t*)((address)this + magic_number_1_offset_in_bytes()); };
   1.166 -  intptr_t magic_number_2() const               { return *(intptr_t*)((address)this + magic_number_2_offset_in_bytes()); };
   1.167 -#endif //ASSERT
   1.168 -
   1.169 -  enum { RETURN_VALUE_PLACEHOLDER = (NOT_DEBUG(0) DEBUG_ONLY(42)) };
   1.170 -
   1.171 -  static void verify_offsets() NOT_DEBUG_RETURN;
   1.172 -  void verify() const NOT_DEBUG_RETURN; // check for MAGIC_NUMBER, etc.
   1.173 -  void zap_arguments() NOT_DEBUG_RETURN;
   1.174 -
   1.175 -  static void generate_ricochet_blob(MacroAssembler* _masm,
   1.176 -                                     // output params:
   1.177 -                                     int* bounce_offset,
   1.178 -                                     int* exception_offset,
   1.179 -                                     int* frame_size_in_words);
   1.180 -
   1.181 -  static void enter_ricochet_frame(MacroAssembler* _masm,
   1.182 -                                   Register rcx_recv,
   1.183 -                                   Register rax_argv,
   1.184 -                                   address return_handler,
   1.185 -                                   Register rbx_temp);
   1.186 -  static void leave_ricochet_frame(MacroAssembler* _masm,
   1.187 -                                   Register rcx_recv,
   1.188 -                                   Register new_sp_reg,
   1.189 -                                   Register sender_pc_reg);
   1.190 -
   1.191 -  static Address frame_address(int offset = 0) {
   1.192 -    // The RicochetFrame is found by subtracting a constant offset from rbp.
   1.193 -    return Address(rbp, - sender_link_offset_in_bytes() + offset);
   1.194 -  }
   1.195 -
   1.196 -  static RicochetFrame* from_frame(const frame& fr) {
   1.197 -    address bp = (address) fr.fp();
   1.198 -    RicochetFrame* rf = (RicochetFrame*)(bp - sender_link_offset_in_bytes());
   1.199 -    rf->verify();
   1.200 -    return rf;
   1.201 -  }
   1.202 -
   1.203 -  static void verify_clean(MacroAssembler* _masm) NOT_DEBUG_RETURN;
   1.204 -
   1.205 -  static void describe(const frame* fr, FrameValues& values, int frame_no) PRODUCT_RETURN;
   1.206 +  adapter_code_size = NOT_LP64(16000 DEBUG_ONLY(+ 25000)) LP64_ONLY(32000 DEBUG_ONLY(+ 150000))
   1.207  };
   1.208  
   1.209  // Additional helper methods for MethodHandles code generation:
   1.210  public:
   1.211    static void load_klass_from_Class(MacroAssembler* _masm, Register klass_reg);
   1.212 -  static void load_conversion_vminfo(MacroAssembler* _masm, Register reg, Address conversion_field_addr);
   1.213 -  static void load_conversion_dest_type(MacroAssembler* _masm, Register reg, Address conversion_field_addr);
   1.214 -
   1.215 -  static void load_stack_move(MacroAssembler* _masm,
   1.216 -                              Register rdi_stack_move,
   1.217 -                              Register rcx_amh,
   1.218 -                              bool might_be_negative);
   1.219 -
   1.220 -  static void insert_arg_slots(MacroAssembler* _masm,
   1.221 -                               RegisterOrConstant arg_slots,
   1.222 -                               Register rax_argslot,
   1.223 -                               Register rbx_temp, Register rdx_temp);
   1.224 -
   1.225 -  static void remove_arg_slots(MacroAssembler* _masm,
   1.226 -                               RegisterOrConstant arg_slots,
   1.227 -                               Register rax_argslot,
   1.228 -                               Register rbx_temp, Register rdx_temp);
   1.229 -
   1.230 -  static void push_arg_slots(MacroAssembler* _masm,
   1.231 -                                   Register rax_argslot,
   1.232 -                                   RegisterOrConstant slot_count,
   1.233 -                                   int skip_words_count,
   1.234 -                                   Register rbx_temp, Register rdx_temp);
   1.235 -
   1.236 -  static void move_arg_slots_up(MacroAssembler* _masm,
   1.237 -                                Register rbx_bottom,  // invariant
   1.238 -                                Address  top_addr,    // can use rax_temp
   1.239 -                                RegisterOrConstant positive_distance_in_slots,
   1.240 -                                Register rax_temp, Register rdx_temp);
   1.241 -
   1.242 -  static void move_arg_slots_down(MacroAssembler* _masm,
   1.243 -                                  Address  bottom_addr,  // can use rax_temp
   1.244 -                                  Register rbx_top,      // invariant
   1.245 -                                  RegisterOrConstant negative_distance_in_slots,
   1.246 -                                  Register rax_temp, Register rdx_temp);
   1.247 -
   1.248 -  static void move_typed_arg(MacroAssembler* _masm,
   1.249 -                             BasicType type, bool is_element,
   1.250 -                             Address slot_dest, Address value_src,
   1.251 -                             Register rbx_temp, Register rdx_temp);
   1.252 -
   1.253 -  static void move_return_value(MacroAssembler* _masm, BasicType type,
   1.254 -                                Address return_slot);
   1.255 -
   1.256 -  static void verify_argslot(MacroAssembler* _masm, Register argslot_reg,
   1.257 -                             const char* error_message) NOT_DEBUG_RETURN;
   1.258 -
   1.259 -  static void verify_argslots(MacroAssembler* _masm,
   1.260 -                              RegisterOrConstant argslot_count,
   1.261 -                              Register argslot_reg,
   1.262 -                              bool negate_argslot,
   1.263 -                              const char* error_message) NOT_DEBUG_RETURN;
   1.264 -
   1.265 -  static void verify_stack_move(MacroAssembler* _masm,
   1.266 -                                RegisterOrConstant arg_slots,
   1.267 -                                int direction) NOT_DEBUG_RETURN;
   1.268  
   1.269    static void verify_klass(MacroAssembler* _masm,
   1.270                             Register obj, KlassHandle klass,
   1.271 @@ -297,9 +43,17 @@
   1.272                   "reference is a MH");
   1.273    }
   1.274  
   1.275 +  static void verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) NOT_DEBUG_RETURN;
   1.276 +
   1.277    // Similar to InterpreterMacroAssembler::jump_from_interpreted.
   1.278    // Takes care of special dispatch from single stepping too.
   1.279 -  static void jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp);
   1.280 +  static void jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
   1.281 +                                      bool for_compiler_entry);
   1.282 +
   1.283 +  static void jump_to_lambda_form(MacroAssembler* _masm,
   1.284 +                                  Register recv, Register method_temp,
   1.285 +                                  Register temp2,
   1.286 +                                  bool for_compiler_entry);
   1.287  
   1.288    static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;
   1.289  

mercurial