1.1 --- a/src/cpu/x86/vm/x86_32.ad Mon Jan 04 15:21:09 2010 -0800 1.2 +++ b/src/cpu/x86/vm/x86_32.ad Tue Jan 05 13:05:58 2010 +0100 1.3 @@ -268,22 +268,36 @@ 1.4 static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000)); 1.5 static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000)); 1.6 1.7 +// Offset hacking within calls. 1.8 +static int pre_call_FPU_size() { 1.9 + if (Compile::current()->in_24_bit_fp_mode()) 1.10 + return 6; // fldcw 1.11 + return 0; 1.12 +} 1.13 + 1.14 +static int preserve_SP_size() { 1.15 + return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg) 1.16 +} 1.17 + 1.18 // !!!!! Special hack to get all type of calls to specify the byte offset 1.19 // from the start of the call to the point where the return address 1.20 // will point. 1.21 int MachCallStaticJavaNode::ret_addr_offset() { 1.22 - return 5 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0); // 5 bytes from start of call to where return address points 1.23 + int offset = 5 + pre_call_FPU_size(); // 5 bytes from start of call to where return address points 1.24 + if (_method_handle_invoke) 1.25 + offset += preserve_SP_size(); 1.26 + return offset; 1.27 } 1.28 1.29 int MachCallDynamicJavaNode::ret_addr_offset() { 1.30 - return 10 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0); // 10 bytes from start of call to where return address points 1.31 + return 10 + pre_call_FPU_size(); // 10 bytes from start of call to where return address points 1.32 } 1.33 1.34 static int sizeof_FFree_Float_Stack_All = -1; 1.35 1.36 int MachCallRuntimeNode::ret_addr_offset() { 1.37 assert(sizeof_FFree_Float_Stack_All != -1, "must have been emitted already"); 1.38 - return sizeof_FFree_Float_Stack_All + 5 + (Compile::current()->in_24_bit_fp_mode() ? 6 : 0); 1.39 + return sizeof_FFree_Float_Stack_All + 5 + pre_call_FPU_size(); 1.40 } 1.41 1.42 // Indicate if the safepoint node needs the polling page as an input. 1.43 @@ -299,8 +313,16 @@ 1.44 // The address of the call instruction needs to be 4-byte aligned to 1.45 // ensure that it does not span a cache line so that it can be patched. 1.46 int CallStaticJavaDirectNode::compute_padding(int current_offset) const { 1.47 - if (Compile::current()->in_24_bit_fp_mode()) 1.48 - current_offset += 6; // skip fldcw in pre_call_FPU, if any 1.49 + current_offset += pre_call_FPU_size(); // skip fldcw, if any 1.50 + current_offset += 1; // skip call opcode byte 1.51 + return round_to(current_offset, alignment_required()) - current_offset; 1.52 +} 1.53 + 1.54 +// The address of the call instruction needs to be 4-byte aligned to 1.55 +// ensure that it does not span a cache line so that it can be patched. 1.56 +int CallStaticJavaHandleNode::compute_padding(int current_offset) const { 1.57 + current_offset += pre_call_FPU_size(); // skip fldcw, if any 1.58 + current_offset += preserve_SP_size(); // skip mov rbp, rsp 1.59 current_offset += 1; // skip call opcode byte 1.60 return round_to(current_offset, alignment_required()) - current_offset; 1.61 } 1.62 @@ -308,8 +330,7 @@ 1.63 // The address of the call instruction needs to be 4-byte aligned to 1.64 // ensure that it does not span a cache line so that it can be patched. 1.65 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const { 1.66 - if (Compile::current()->in_24_bit_fp_mode()) 1.67 - current_offset += 6; // skip fldcw in pre_call_FPU, if any 1.68 + current_offset += pre_call_FPU_size(); // skip fldcw, if any 1.69 current_offset += 5; // skip MOV instruction 1.70 current_offset += 1; // skip call opcode byte 1.71 return round_to(current_offset, alignment_required()) - current_offset; 1.72 @@ -1460,6 +1481,10 @@ 1.73 return RegMask(); 1.74 } 1.75 1.76 +const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1.77 + return EBP_REG_mask; 1.78 +} 1.79 + 1.80 %} 1.81 1.82 //----------ENCODING BLOCK----------------------------------------------------- 1.83 @@ -1772,10 +1797,13 @@ 1.84 1.85 enc_class pre_call_FPU %{ 1.86 // If method sets FPU control word restore it here 1.87 + debug_only(int off0 = cbuf.code_size()); 1.88 if( Compile::current()->in_24_bit_fp_mode() ) { 1.89 MacroAssembler masm(&cbuf); 1.90 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); 1.91 } 1.92 + debug_only(int off1 = cbuf.code_size()); 1.93 + assert(off1 - off0 == pre_call_FPU_size(), "correct size prediction"); 1.94 %} 1.95 1.96 enc_class post_call_FPU %{ 1.97 @@ -1786,6 +1814,21 @@ 1.98 } 1.99 %} 1.100 1.101 + enc_class preserve_SP %{ 1.102 + debug_only(int off0 = cbuf.code_size()); 1.103 + MacroAssembler _masm(&cbuf); 1.104 + // RBP is preserved across all calls, even compiled calls. 1.105 + // Use it to preserve RSP in places where the callee might change the SP. 1.106 + __ movptr(rbp, rsp); 1.107 + debug_only(int off1 = cbuf.code_size()); 1.108 + assert(off1 - off0 == preserve_SP_size(), "correct size prediction"); 1.109 + %} 1.110 + 1.111 + enc_class restore_SP %{ 1.112 + MacroAssembler _masm(&cbuf); 1.113 + __ movptr(rsp, rbp); 1.114 + %} 1.115 + 1.116 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL 1.117 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 1.118 // who we intended to call. 1.119 @@ -13406,6 +13449,7 @@ 1.120 // compute_padding() functions will have to be adjusted. 1.121 instruct CallStaticJavaDirect(method meth) %{ 1.122 match(CallStaticJava); 1.123 + predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke()); 1.124 effect(USE meth); 1.125 1.126 ins_cost(300); 1.127 @@ -13420,6 +13464,30 @@ 1.128 ins_alignment(4); 1.129 %} 1.130 1.131 +// Call Java Static Instruction (method handle version) 1.132 +// Note: If this code changes, the corresponding ret_addr_offset() and 1.133 +// compute_padding() functions will have to be adjusted. 1.134 +instruct CallStaticJavaHandle(method meth, eBPRegP ebp) %{ 1.135 + match(CallStaticJava); 1.136 + predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke()); 1.137 + effect(USE meth); 1.138 + // EBP is saved by all callees (for interpreter stack correction). 1.139 + // We use it here for a similar purpose, in {preserve,restore}_SP. 1.140 + 1.141 + ins_cost(300); 1.142 + format %{ "CALL,static/MethodHandle " %} 1.143 + opcode(0xE8); /* E8 cd */ 1.144 + ins_encode( pre_call_FPU, 1.145 + preserve_SP, 1.146 + Java_Static_Call( meth ), 1.147 + restore_SP, 1.148 + call_epilog, 1.149 + post_call_FPU ); 1.150 + ins_pipe( pipe_slow ); 1.151 + ins_pc_relative(1); 1.152 + ins_alignment(4); 1.153 +%} 1.154 + 1.155 // Call Java Dynamic Instruction 1.156 // Note: If this code changes, the corresponding ret_addr_offset() and 1.157 // compute_padding() functions will have to be adjusted.