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