Thu, 18 Mar 2010 09:56:51 +0100
6932091: JSR 292 x86 code cleanup
Summary: Some code cleanups found during the JSR 292 SPARC port.
Reviewed-by: kvn, never
1.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp Wed Mar 17 16:40:25 2010 -0700 1.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Thu Mar 18 09:56:51 2010 +0100 1.3 @@ -60,13 +60,13 @@ 1.4 } 1.5 1.6 #ifdef ASSERT 1.7 -static void verify_argslot(MacroAssembler* _masm, Register rax_argslot, 1.8 +static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, 1.9 const char* error_message) { 1.10 // Verify that argslot lies within (rsp, rbp]. 1.11 Label L_ok, L_bad; 1.12 - __ cmpptr(rax_argslot, rbp); 1.13 + __ cmpptr(argslot_reg, rbp); 1.14 __ jccb(Assembler::above, L_bad); 1.15 - __ cmpptr(rsp, rax_argslot); 1.16 + __ cmpptr(rsp, argslot_reg); 1.17 __ jccb(Assembler::below, L_ok); 1.18 __ bind(L_bad); 1.19 __ stop(error_message); 1.20 @@ -178,22 +178,6 @@ 1.21 1.22 // Now move the argslot down, to point to the opened-up space. 1.23 __ lea(rax_argslot, Address(rax_argslot, arg_slots, Address::times_ptr)); 1.24 - 1.25 - if (TaggedStackInterpreter && arg_mask != _INSERT_NO_MASK) { 1.26 - // The caller has specified a bitmask of tags to put into the opened space. 1.27 - // This only works when the arg_slots value is an assembly-time constant. 1.28 - int constant_arg_slots = arg_slots.as_constant() / stack_move_unit(); 1.29 - int tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes(); 1.30 - for (int slot = 0; slot < constant_arg_slots; slot++) { 1.31 - BasicType slot_type = ((arg_mask & (1 << slot)) == 0 ? T_OBJECT : T_INT); 1.32 - int slot_offset = Interpreter::stackElementSize() * slot; 1.33 - Address tag_addr(rax_argslot, slot_offset + tag_offset); 1.34 - __ movptr(tag_addr, frame::tag_for_basic_type(slot_type)); 1.35 - } 1.36 - // Note that the new argument slots are tagged properly but contain 1.37 - // garbage at this point. The value portions must be initialized 1.38 - // by the caller. (Especially references!) 1.39 - } 1.40 } 1.41 1.42 // Helper to remove argument slots from the stack. 1.43 @@ -206,18 +190,9 @@ 1.44 (!arg_slots.is_register() ? rsp : arg_slots.as_register())); 1.45 1.46 #ifdef ASSERT 1.47 - { 1.48 - // Verify that [argslot..argslot+size) lies within (rsp, rbp). 1.49 - Label L_ok, L_bad; 1.50 - __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr)); 1.51 - __ cmpptr(rbx_temp, rbp); 1.52 - __ jccb(Assembler::above, L_bad); 1.53 - __ cmpptr(rsp, rax_argslot); 1.54 - __ jccb(Assembler::below, L_ok); 1.55 - __ bind(L_bad); 1.56 - __ stop("deleted argument(s) must fall within current frame"); 1.57 - __ bind(L_ok); 1.58 - } 1.59 + // Verify that [argslot..argslot+size) lies within (rsp, rbp). 1.60 + __ lea(rbx_temp, Address(rax_argslot, arg_slots, Address::times_ptr)); 1.61 + verify_argslot(_masm, rbx_temp, "deleted argument(s) must fall within current frame"); 1.62 if (arg_slots.is_register()) { 1.63 Label L_ok, L_bad; 1.64 __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD); 1.65 @@ -321,12 +296,6 @@ 1.66 Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() ); 1.67 Address vmarg; // __ argument_address(vmargslot) 1.68 1.69 - int tag_offset = -1; 1.70 - if (TaggedStackInterpreter) { 1.71 - tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes(); 1.72 - assert(tag_offset = wordSize, "stack grows as expected"); 1.73 - } 1.74 - 1.75 const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); 1.76 1.77 if (have_entry(ek)) { 1.78 @@ -372,11 +341,8 @@ 1.79 __ mov(rsp, rsi); // cut the stack back to where the caller started 1.80 1.81 // Repush the arguments as if coming from the interpreter. 1.82 - if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_INT)); 1.83 __ push(rdx_code); 1.84 - if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT)); 1.85 __ push(rcx_fail); 1.86 - if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT)); 1.87 __ push(rax_want); 1.88 1.89 Register rbx_method = rbx_temp; 1.90 @@ -397,7 +363,6 @@ 1.91 // Do something that is at least causes a valid throw from the interpreter. 1.92 __ bind(no_method); 1.93 __ pop(rax_want); 1.94 - if (TaggedStackInterpreter) __ pop(rcx_fail); 1.95 __ pop(rcx_fail); 1.96 __ push(rax_want); 1.97 __ push(rcx_fail); 1.98 @@ -510,18 +475,10 @@ 1.99 case _bound_long_direct_mh: 1.100 { 1.101 bool direct_to_method = (ek >= _bound_ref_direct_mh); 1.102 - BasicType arg_type = T_ILLEGAL; 1.103 - if (ek == _bound_long_mh || ek == _bound_long_direct_mh) { 1.104 - arg_type = T_LONG; 1.105 - } else if (ek == _bound_int_mh || ek == _bound_int_direct_mh) { 1.106 - arg_type = T_INT; 1.107 - } else { 1.108 - assert(ek == _bound_ref_mh || ek == _bound_ref_direct_mh, "must be ref"); 1.109 - arg_type = T_OBJECT; 1.110 - } 1.111 - int arg_slots = type2size[arg_type]; 1.112 - int arg_mask = (arg_type == T_OBJECT ? _INSERT_REF_MASK : 1.113 - arg_slots == 1 ? _INSERT_INT_MASK : _INSERT_LONG_MASK); 1.114 + BasicType arg_type = T_ILLEGAL; 1.115 + int arg_mask = _INSERT_NO_MASK; 1.116 + int arg_slots = -1; 1.117 + get_ek_bound_mh_info(ek, arg_type, arg_mask, arg_slots); 1.118 1.119 // make room for the new argument: 1.120 __ movl(rax_argslot, rcx_bmh_vmargslot); 1.121 @@ -660,13 +617,10 @@ 1.122 } 1.123 break; 1.124 default: 1.125 - assert(false, ""); 1.126 + ShouldNotReachHere(); 1.127 } 1.128 - goto finish_int_conversion; 1.129 - } 1.130 1.131 - finish_int_conversion: 1.132 - { 1.133 + // Do the requested conversion and store the value. 1.134 Register rbx_vminfo = rbx_temp; 1.135 __ movl(rbx_vminfo, rcx_amh_conversion); 1.136 assert(CONV_VMINFO_SHIFT == 0, "preshifted"); 1.137 @@ -692,7 +646,7 @@ 1.138 __ shrl(rdx_temp /*, rcx*/); 1.139 1.140 __ bind(done); 1.141 - __ movl(vmarg, rdx_temp); 1.142 + __ movl(vmarg, rdx_temp); // Store the value. 1.143 __ xchgptr(rcx, rbx_vminfo); // restore rcx_recv 1.144 1.145 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 1.146 @@ -744,7 +698,7 @@ 1.147 } 1.148 break; 1.149 default: 1.150 - assert(false, ""); 1.151 + ShouldNotReachHere(); 1.152 } 1.153 1.154 __ movptr(rcx_recv, rcx_mh_vmtarget); 1.155 @@ -778,20 +732,9 @@ 1.156 if (ek == _adapter_opt_f2d) { 1.157 __ fld_s(vmarg); // load float to ST0 1.158 __ fstp_s(vmarg); // store single 1.159 - } else if (!TaggedStackInterpreter) { 1.160 + } else { 1.161 __ fld_d(vmarg); // load double to ST0 1.162 __ fstp_s(vmarg); // store single 1.163 - } else { 1.164 - Address vmarg_tag = vmarg.plus_disp(tag_offset); 1.165 - Address vmarg2 = vmarg.plus_disp(Interpreter::stackElementSize()); 1.166 - // vmarg2_tag does not participate in this code 1.167 - Register rbx_tag = rbx_temp; 1.168 - __ movl(rbx_tag, vmarg_tag); // preserve tag 1.169 - __ movl(rdx_temp, vmarg2); // get second word of double 1.170 - __ movl(vmarg_tag, rdx_temp); // align with first word 1.171 - __ fld_d(vmarg); // load double to ST0 1.172 - __ movl(vmarg_tag, rbx_tag); // restore tag 1.173 - __ fstp_s(vmarg); // store single 1.174 } 1.175 #endif //_LP64 1.176 1.177 @@ -822,19 +765,8 @@ 1.178 case _adapter_opt_rot_2_up: 1.179 case _adapter_opt_rot_2_down: 1.180 { 1.181 - int rotate = 0, swap_slots = 0; 1.182 - switch ((int)ek) { 1.183 - case _adapter_opt_swap_1: swap_slots = 1; break; 1.184 - case _adapter_opt_swap_2: swap_slots = 2; break; 1.185 - case _adapter_opt_rot_1_up: swap_slots = 1; rotate++; break; 1.186 - case _adapter_opt_rot_1_down: swap_slots = 1; rotate--; break; 1.187 - case _adapter_opt_rot_2_up: swap_slots = 2; rotate++; break; 1.188 - case _adapter_opt_rot_2_down: swap_slots = 2; rotate--; break; 1.189 - default: assert(false, ""); 1.190 - } 1.191 - 1.192 - // the real size of the move must be doubled if TaggedStackInterpreter: 1.193 - int swap_bytes = (int)( swap_slots * Interpreter::stackElementWords() * wordSize ); 1.194 + int swap_bytes = 0, rotate = 0; 1.195 + get_ek_adapter_opt_swap_rot_info(ek, swap_bytes, rotate); 1.196 1.197 // 'argslot' is the position of the first argument to swap 1.198 __ movl(rax_argslot, rcx_amh_vmargslot); 1.199 @@ -1024,11 +956,7 @@ 1.200 case _adapter_opt_spread_more: 1.201 { 1.202 // spread an array out into a group of arguments 1.203 - int length_constant = -1; 1.204 - switch (ek) { 1.205 - case _adapter_opt_spread_0: length_constant = 0; break; 1.206 - case _adapter_opt_spread_1: length_constant = 1; break; 1.207 - } 1.208 + int length_constant = get_ek_adapter_opt_spread_info(ek); 1.209 1.210 // find the address of the array argument 1.211 __ movl(rax_argslot, rcx_amh_vmargslot); 1.212 @@ -1124,10 +1052,6 @@ 1.213 __ movptr(rbx_temp, Address(rsi_source, 0)); 1.214 __ movptr(Address(rax_argslot, 0), rbx_temp); 1.215 __ addptr(rsi_source, type2aelembytes(elem_type)); 1.216 - if (TaggedStackInterpreter) { 1.217 - __ movptr(Address(rax_argslot, tag_offset), 1.218 - frame::tag_for_basic_type(elem_type)); 1.219 - } 1.220 __ addptr(rax_argslot, Interpreter::stackElementSize()); 1.221 __ cmpptr(rax_argslot, rdx_argslot_limit); 1.222 __ jccb(Assembler::less, loop); 1.223 @@ -1141,10 +1065,6 @@ 1.224 __ movptr(rbx_temp, Address(rsi_array, elem_offset)); 1.225 __ movptr(Address(rax_argslot, slot_offset), rbx_temp); 1.226 elem_offset += type2aelembytes(elem_type); 1.227 - if (TaggedStackInterpreter) { 1.228 - __ movptr(Address(rax_argslot, slot_offset + tag_offset), 1.229 - frame::tag_for_basic_type(elem_type)); 1.230 - } 1.231 slot_offset += Interpreter::stackElementSize(); 1.232 } 1.233 }
2.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Mar 17 16:40:25 2010 -0700 2.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Mar 18 09:56:51 2010 +0100 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 2.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -2915,12 +2915,8 @@ 2.11 __ andl(recv, 0xFF); 2.12 // recv count is 0 based? 2.13 Address recv_addr(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1)); 2.14 - if (is_invokedynamic) { 2.15 - __ lea(recv, recv_addr); 2.16 - } else { 2.17 - __ movptr(recv, recv_addr); 2.18 - __ verify_oop(recv); 2.19 - } 2.20 + __ movptr(recv, recv_addr); 2.21 + __ verify_oop(recv); 2.22 } 2.23 2.24 // do null check if needed
3.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Mar 17 16:40:25 2010 -0700 3.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Mar 18 09:56:51 2010 +0100 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. 3.6 + * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -2860,12 +2860,8 @@ 3.11 __ andl(recv, 0xFF); 3.12 if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 3.13 Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1)); 3.14 - if (is_invokedynamic) { 3.15 - __ lea(recv, recv_addr); 3.16 - } else { 3.17 - __ movptr(recv, recv_addr); 3.18 - __ verify_oop(recv); 3.19 - } 3.20 + __ movptr(recv, recv_addr); 3.21 + __ verify_oop(recv); 3.22 } 3.23 3.24 // do null check if needed
4.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp Wed Mar 17 16:40:25 2010 -0700 4.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Thu Mar 18 09:56:51 2010 +0100 4.3 @@ -2376,8 +2376,7 @@ 4.4 CodeEmitInfo* info = state_for(x, x->state()); 4.5 4.6 // invokedynamics can deoptimize. 4.7 - bool is_invokedynamic = x->code() == Bytecodes::_invokedynamic; 4.8 - CodeEmitInfo* deopt_info = is_invokedynamic ? state_for(x, x->state_before()) : NULL; 4.9 + CodeEmitInfo* deopt_info = x->is_invokedynamic() ? state_for(x, x->state_before()) : NULL; 4.10 4.11 invoke_load_arguments(x, args, arg_list); 4.12
5.1 --- a/src/share/vm/prims/methodHandles.hpp Wed Mar 17 16:40:25 2010 -0700 5.2 +++ b/src/share/vm/prims/methodHandles.hpp Thu Mar 18 09:56:51 2010 +0100 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved. 5.6 + * Copyright 2008-2010 Sun Microsystems, Inc. All Rights Reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -137,6 +137,43 @@ 5.11 _entries[ek] = me; 5.12 } 5.13 5.14 + // Some adapter helper functions. 5.15 + static void get_ek_bound_mh_info(EntryKind ek, BasicType& arg_type, int& arg_mask, int& arg_slots) { 5.16 + switch (ek) { 5.17 + case _bound_int_mh : // fall-thru 5.18 + case _bound_int_direct_mh : arg_type = T_INT; arg_mask = _INSERT_INT_MASK; break; 5.19 + case _bound_long_mh : // fall-thru 5.20 + case _bound_long_direct_mh: arg_type = T_LONG; arg_mask = _INSERT_LONG_MASK; break; 5.21 + case _bound_ref_mh : // fall-thru 5.22 + case _bound_ref_direct_mh : arg_type = T_OBJECT; arg_mask = _INSERT_REF_MASK; break; 5.23 + default: ShouldNotReachHere(); 5.24 + } 5.25 + arg_slots = type2size[arg_type]; 5.26 + } 5.27 + 5.28 + static void get_ek_adapter_opt_swap_rot_info(EntryKind ek, int& swap_bytes, int& rotate) { 5.29 + int swap_slots = 0; 5.30 + switch (ek) { 5.31 + case _adapter_opt_swap_1: swap_slots = 1; rotate = 0; break; 5.32 + case _adapter_opt_swap_2: swap_slots = 2; rotate = 0; break; 5.33 + case _adapter_opt_rot_1_up: swap_slots = 1; rotate = 1; break; 5.34 + case _adapter_opt_rot_1_down: swap_slots = 1; rotate = -1; break; 5.35 + case _adapter_opt_rot_2_up: swap_slots = 2; rotate = 1; break; 5.36 + case _adapter_opt_rot_2_down: swap_slots = 2; rotate = -1; break; 5.37 + default: ShouldNotReachHere(); 5.38 + } 5.39 + // Return the size of the stack slots to move in bytes. 5.40 + swap_bytes = swap_slots * Interpreter::stackElementSize(); 5.41 + } 5.42 + 5.43 + static int get_ek_adapter_opt_spread_info(EntryKind ek) { 5.44 + switch (ek) { 5.45 + case _adapter_opt_spread_0: return 0; 5.46 + case _adapter_opt_spread_1: return 1; 5.47 + default : return -1; 5.48 + } 5.49 + } 5.50 + 5.51 static methodOop raise_exception_method() { 5.52 oop rem = JNIHandles::resolve(_raise_exception_method); 5.53 assert(rem == NULL || rem->is_method(), ""); 5.54 @@ -392,13 +429,13 @@ 5.55 static void insert_arg_slots(MacroAssembler* _masm, 5.56 RegisterOrConstant arg_slots, 5.57 int arg_mask, 5.58 - Register rax_argslot, 5.59 - Register rbx_temp, Register rdx_temp); 5.60 + Register argslot_reg, 5.61 + Register temp_reg, Register temp2_reg); 5.62 5.63 static void remove_arg_slots(MacroAssembler* _masm, 5.64 RegisterOrConstant arg_slots, 5.65 - Register rax_argslot, 5.66 - Register rbx_temp, Register rdx_temp); 5.67 + Register argslot_reg, 5.68 + Register temp_reg, Register temp2_reg); 5.69 }; 5.70 5.71
6.1 --- a/src/share/vm/runtime/arguments.cpp Wed Mar 17 16:40:25 2010 -0700 6.2 +++ b/src/share/vm/runtime/arguments.cpp Thu Mar 18 09:56:51 2010 +0100 6.3 @@ -2859,6 +2859,12 @@ 6.4 } 6.5 #endif // _LP64 6.6 6.7 + // MethodHandles code does not support TaggedStackInterpreter. 6.8 + if (EnableMethodHandles && TaggedStackInterpreter) { 6.9 + warning("TaggedStackInterpreter is not supported by MethodHandles code. Disabling TaggedStackInterpreter."); 6.10 + TaggedStackInterpreter = false; 6.11 + } 6.12 + 6.13 // Check the GC selections again. 6.14 if (!check_gc_consistency()) { 6.15 return JNI_EINVAL;