diff src/cpu/x86/vm/methodHandles_x86.hpp @ 6275:957c266d8bc5

Merge with http://hg.openjdk.java.net/hsx/hsx24/hotspot/
author Doug Simon <doug.simon@oracle.com>
date Tue, 21 Aug 2012 10:39:19 +0200
parents 1d7922586cf6
children da91efe96a93
line wrap: on
line diff
--- a/src/cpu/x86/vm/methodHandles_x86.hpp	Mon Aug 20 15:21:31 2012 +0200
+++ b/src/cpu/x86/vm/methodHandles_x86.hpp	Tue Aug 21 10:39:19 2012 +0200
@@ -27,266 +27,12 @@
 
 // Adapters
 enum /* platform_dependent_constants */ {
-  adapter_code_size = NOT_LP64(16000 DEBUG_ONLY(+ 15000)) LP64_ONLY(32000 DEBUG_ONLY(+ 120000))
-};
-
-public:
-
-// The stack just after the recursive call from a ricochet frame
-// looks something like this.  Offsets are marked in words, not bytes.
-// rsi (r13 on LP64) is part of the interpreter calling sequence
-// which tells the callee where is my real rsp (for frame walking).
-// (...lower memory addresses)
-// rsp:     [ return pc                 ]   always the global RicochetBlob::bounce_addr
-// rsp+1:   [ recursive arg N           ]
-// rsp+2:   [ recursive arg N-1         ]
-// ...
-// rsp+N:   [ recursive arg 1           ]
-// rsp+N+1: [ recursive method handle   ]
-// ...
-// rbp-6:   [ cleanup continuation pc   ]   <-- (struct RicochetFrame)
-// rbp-5:   [ saved target MH           ]   the MH we will call on the saved args
-// rbp-4:   [ saved args layout oop     ]   an int[] array which describes argument layout
-// rbp-3:   [ saved args pointer        ]   address of transformed adapter arg M (slot 0)
-// rbp-2:   [ conversion                ]   information about how the return value is used
-// rbp-1:   [ exact sender sp           ]   exact TOS (rsi/r13) of original sender frame
-// rbp+0:   [ saved sender fp           ]   (for original sender of AMH)
-// rbp+1:   [ saved sender pc           ]   (back to original sender of AMH)
-// rbp+2:   [ transformed adapter arg M ]   <-- (extended TOS of original sender)
-// rbp+3:   [ transformed adapter arg M-1]
-// ...
-// rbp+M+1: [ transformed adapter arg 1 ]
-// rbp+M+2: [ padding                   ] <-- (rbp + saved args base offset)
-// ...      [ optional padding]
-// (higher memory addresses...)
-//
-// The arguments originally passed by the original sender
-// are lost, and arbitrary amounts of stack motion might have
-// happened due to argument transformation.
-// (This is done by C2I/I2C adapters and non-direct method handles.)
-// This is why there is an unpredictable amount of memory between
-// the extended and exact TOS of the sender.
-// The ricochet adapter itself will also (in general) perform
-// transformations before the recursive call.
-//
-// The transformed and saved arguments, immediately above the saved
-// return PC, are a well-formed method handle invocation ready to execute.
-// When the GC needs to walk the stack, these arguments are described
-// via the saved arg types oop, an int[] array with a private format.
-// This array is derived from the type of the transformed adapter
-// method handle, which also sits at the base of the saved argument
-// bundle.  Since the GC may not be able to fish out the int[]
-// array, so it is pushed explicitly on the stack.  This may be
-// an unnecessary expense.
-//
-// The following register conventions are significant at this point:
-// rsp       the thread stack, as always; preserved by caller
-// rsi/r13   exact TOS of recursive frame (contents of [rbp-2])
-// rcx       recursive method handle (contents of [rsp+N+1])
-// rbp       preserved by caller (not used by caller)
-// Unless otherwise specified, all registers can be blown by the call.
-//
-// If this frame must be walked, the transformed adapter arguments
-// will be found with the help of the saved arguments descriptor.
-//
-// Therefore, the descriptor must match the referenced arguments.
-// The arguments must be followed by at least one word of padding,
-// which will be necessary to complete the final method handle call.
-// That word is not treated as holding an oop.  Neither is the word
-//
-// The word pointed to by the return argument pointer is not
-// treated as an oop, even if points to a saved argument.
-// This allows the saved argument list to have a "hole" in it
-// to receive an oop from the recursive call.
-// (The hole might temporarily contain RETURN_VALUE_PLACEHOLDER.)
-//
-// When the recursive callee returns, RicochetBlob::bounce_addr will
-// immediately jump to the continuation stored in the RF.
-// This continuation will merge the recursive return value
-// into the saved argument list.  At that point, the original
-// rsi, rbp, and rsp will be reloaded, the ricochet frame will
-// disappear, and the final target of the adapter method handle
-// will be invoked on the transformed argument list.
-
-class RicochetFrame {
-  friend class MethodHandles;
-  friend class VMStructs;
-
- private:
-  intptr_t* _continuation;          // what to do when control gets back here
-  oopDesc*  _saved_target;          // target method handle to invoke on saved_args
-  oopDesc*  _saved_args_layout;     // caching point for MethodTypeForm.vmlayout cookie
-  intptr_t* _saved_args_base;       // base of pushed arguments (slot 0, arg N) (-3)
-  intptr_t  _conversion;            // misc. information from original AdapterMethodHandle (-2)
-  intptr_t* _exact_sender_sp;       // parallel to interpreter_frame_sender_sp (-1)
-  intptr_t* _sender_link;           // *must* coincide with frame::link_offset (0)
-  address   _sender_pc;             // *must* coincide with frame::return_addr_offset (1)
-
- public:
-  intptr_t* continuation() const        { return _continuation; }
-  oop       saved_target() const        { return _saved_target; }
-  oop       saved_args_layout() const   { return _saved_args_layout; }
-  intptr_t* saved_args_base() const     { return _saved_args_base; }
-  intptr_t  conversion() const          { return _conversion; }
-  intptr_t* exact_sender_sp() const     { return _exact_sender_sp; }
-  intptr_t* sender_link() const         { return _sender_link; }
-  address   sender_pc() const           { return _sender_pc; }
-
-  intptr_t* extended_sender_sp() const {
-    // The extended sender SP is above the current RicochetFrame.
-    return (intptr_t*) (((address) this) + sizeof(RicochetFrame));
-  }
-
-  intptr_t  return_value_slot_number() const {
-    return adapter_conversion_vminfo(conversion());
-  }
-  BasicType return_value_type() const {
-    return adapter_conversion_dest_type(conversion());
-  }
-  bool has_return_value_slot() const {
-    return return_value_type() != T_VOID;
-  }
-  intptr_t* return_value_slot_addr() const {
-    assert(has_return_value_slot(), "");
-    return saved_arg_slot_addr(return_value_slot_number());
-  }
-  intptr_t* saved_target_slot_addr() const {
-    return saved_arg_slot_addr(saved_args_length());
-  }
-  intptr_t* saved_arg_slot_addr(int slot) const {
-    assert(slot >= 0, "");
-    return (intptr_t*)( (address)saved_args_base() + (slot * Interpreter::stackElementSize) );
-  }
-
-  jint      saved_args_length() const;
-  jint      saved_arg_offset(int arg) const;
-
-  // GC interface
-  oop*  saved_target_addr()                     { return (oop*)&_saved_target; }
-  oop*  saved_args_layout_addr()                { return (oop*)&_saved_args_layout; }
-
-  oop  compute_saved_args_layout(bool read_cache, bool write_cache);
-
-  // Compiler/assembler interface.
-  static int continuation_offset_in_bytes()     { return offset_of(RicochetFrame, _continuation); }
-  static int saved_target_offset_in_bytes()     { return offset_of(RicochetFrame, _saved_target); }
-  static int saved_args_layout_offset_in_bytes(){ return offset_of(RicochetFrame, _saved_args_layout); }
-  static int saved_args_base_offset_in_bytes()  { return offset_of(RicochetFrame, _saved_args_base); }
-  static int conversion_offset_in_bytes()       { return offset_of(RicochetFrame, _conversion); }
-  static int exact_sender_sp_offset_in_bytes()  { return offset_of(RicochetFrame, _exact_sender_sp); }
-  static int sender_link_offset_in_bytes()      { return offset_of(RicochetFrame, _sender_link); }
-  static int sender_pc_offset_in_bytes()        { return offset_of(RicochetFrame, _sender_pc); }
-
-  // This value is not used for much, but it apparently must be nonzero.
-  static int frame_size_in_bytes()              { return sender_link_offset_in_bytes(); }
-
-#ifdef ASSERT
-  // The magic number is supposed to help find ricochet frames within the bytes of stack dumps.
-  enum { MAGIC_NUMBER_1 = 0xFEED03E, MAGIC_NUMBER_2 = 0xBEEF03E };
-  static int magic_number_1_offset_in_bytes()   { return -wordSize; }
-  static int magic_number_2_offset_in_bytes()   { return sizeof(RicochetFrame); }
-  intptr_t magic_number_1() const               { return *(intptr_t*)((address)this + magic_number_1_offset_in_bytes()); };
-  intptr_t magic_number_2() const               { return *(intptr_t*)((address)this + magic_number_2_offset_in_bytes()); };
-#endif //ASSERT
-
-  enum { RETURN_VALUE_PLACEHOLDER = (NOT_DEBUG(0) DEBUG_ONLY(42)) };
-
-  static void verify_offsets() NOT_DEBUG_RETURN;
-  void verify() const NOT_DEBUG_RETURN; // check for MAGIC_NUMBER, etc.
-  void zap_arguments() NOT_DEBUG_RETURN;
-
-  static void generate_ricochet_blob(MacroAssembler* _masm,
-                                     // output params:
-                                     int* bounce_offset,
-                                     int* exception_offset,
-                                     int* frame_size_in_words);
-
-  static void enter_ricochet_frame(MacroAssembler* _masm,
-                                   Register rcx_recv,
-                                   Register rax_argv,
-                                   address return_handler,
-                                   Register rbx_temp);
-  static void leave_ricochet_frame(MacroAssembler* _masm,
-                                   Register rcx_recv,
-                                   Register new_sp_reg,
-                                   Register sender_pc_reg);
-
-  static Address frame_address(int offset = 0) {
-    // The RicochetFrame is found by subtracting a constant offset from rbp.
-    return Address(rbp, - sender_link_offset_in_bytes() + offset);
-  }
-
-  static RicochetFrame* from_frame(const frame& fr) {
-    address bp = (address) fr.fp();
-    RicochetFrame* rf = (RicochetFrame*)(bp - sender_link_offset_in_bytes());
-    rf->verify();
-    return rf;
-  }
-
-  static void verify_clean(MacroAssembler* _masm) NOT_DEBUG_RETURN;
-
-  static void describe(const frame* fr, FrameValues& values, int frame_no) PRODUCT_RETURN;
+  adapter_code_size = NOT_LP64(16000 DEBUG_ONLY(+ 25000)) LP64_ONLY(32000 DEBUG_ONLY(+ 150000))
 };
 
 // Additional helper methods for MethodHandles code generation:
 public:
   static void load_klass_from_Class(MacroAssembler* _masm, Register klass_reg);
-  static void load_conversion_vminfo(MacroAssembler* _masm, Register reg, Address conversion_field_addr);
-  static void load_conversion_dest_type(MacroAssembler* _masm, Register reg, Address conversion_field_addr);
-
-  static void load_stack_move(MacroAssembler* _masm,
-                              Register rdi_stack_move,
-                              Register rcx_amh,
-                              bool might_be_negative);
-
-  static void insert_arg_slots(MacroAssembler* _masm,
-                               RegisterOrConstant arg_slots,
-                               Register rax_argslot,
-                               Register rbx_temp, Register rdx_temp);
-
-  static void remove_arg_slots(MacroAssembler* _masm,
-                               RegisterOrConstant arg_slots,
-                               Register rax_argslot,
-                               Register rbx_temp, Register rdx_temp);
-
-  static void push_arg_slots(MacroAssembler* _masm,
-                                   Register rax_argslot,
-                                   RegisterOrConstant slot_count,
-                                   int skip_words_count,
-                                   Register rbx_temp, Register rdx_temp);
-
-  static void move_arg_slots_up(MacroAssembler* _masm,
-                                Register rbx_bottom,  // invariant
-                                Address  top_addr,    // can use rax_temp
-                                RegisterOrConstant positive_distance_in_slots,
-                                Register rax_temp, Register rdx_temp);
-
-  static void move_arg_slots_down(MacroAssembler* _masm,
-                                  Address  bottom_addr,  // can use rax_temp
-                                  Register rbx_top,      // invariant
-                                  RegisterOrConstant negative_distance_in_slots,
-                                  Register rax_temp, Register rdx_temp);
-
-  static void move_typed_arg(MacroAssembler* _masm,
-                             BasicType type, bool is_element,
-                             Address slot_dest, Address value_src,
-                             Register rbx_temp, Register rdx_temp);
-
-  static void move_return_value(MacroAssembler* _masm, BasicType type,
-                                Address return_slot);
-
-  static void verify_argslot(MacroAssembler* _masm, Register argslot_reg,
-                             const char* error_message) NOT_DEBUG_RETURN;
-
-  static void verify_argslots(MacroAssembler* _masm,
-                              RegisterOrConstant argslot_count,
-                              Register argslot_reg,
-                              bool negate_argslot,
-                              const char* error_message) NOT_DEBUG_RETURN;
-
-  static void verify_stack_move(MacroAssembler* _masm,
-                                RegisterOrConstant arg_slots,
-                                int direction) NOT_DEBUG_RETURN;
 
   static void verify_klass(MacroAssembler* _masm,
                            Register obj, KlassHandle klass,
@@ -297,9 +43,17 @@
                  "reference is a MH");
   }
 
+  static void verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) NOT_DEBUG_RETURN;
+
   // Similar to InterpreterMacroAssembler::jump_from_interpreted.
   // Takes care of special dispatch from single stepping too.
-  static void jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp);
+  static void jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
+                                      bool for_compiler_entry);
+
+  static void jump_to_lambda_form(MacroAssembler* _masm,
+                                  Register recv, Register method_temp,
+                                  Register temp2,
+                                  bool for_compiler_entry);
 
   static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;