diff -r 4b84186a8248 -r 97125851f396 src/cpu/x86/vm/x86_64.ad --- a/src/cpu/x86/vm/x86_64.ad Mon Jan 04 15:21:09 2010 -0800 +++ b/src/cpu/x86/vm/x86_64.ad Tue Jan 05 13:05:58 2010 +0100 @@ -551,12 +551,19 @@ #define __ _masm. +static int preserve_SP_size() { + return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg) +} + // !!!!! Special hack to get all types of calls to specify the byte offset // from the start of the call to the point where the return address // will point. int MachCallStaticJavaNode::ret_addr_offset() { - return 5; // 5 bytes from start of call to where return address points + int offset = 5; // 5 bytes from start of call to where return address points + if (_method_handle_invoke) + offset += preserve_SP_size(); + return offset; } int MachCallDynamicJavaNode::ret_addr_offset() @@ -589,6 +596,15 @@ // The address of the call instruction needs to be 4-byte aligned to // ensure that it does not span a cache line so that it can be patched. +int CallStaticJavaHandleNode::compute_padding(int current_offset) const +{ + current_offset += preserve_SP_size(); // skip mov rbp, rsp + current_offset += 1; // skip call opcode byte + return round_to(current_offset, alignment_required()) - current_offset; +} + +// The address of the call instruction needs to be 4-byte aligned to +// ensure that it does not span a cache line so that it can be patched. int CallDynamicJavaDirectNode::compute_padding(int current_offset) const { current_offset += 11; // skip movq instruction + call opcode byte @@ -2113,6 +2129,10 @@ return LONG_RDX_REG_mask; } +const RegMask Matcher::method_handle_invoke_SP_save_mask() { + return PTR_RBP_REG_mask; +} + static Address build_address(int b, int i, int s, int d) { Register index = as_Register(i); Address::ScaleFactor scale = (Address::ScaleFactor)s; @@ -2608,6 +2628,21 @@ RELOC_DISP32); %} + enc_class preserve_SP %{ + debug_only(int off0 = cbuf.code_size()); + MacroAssembler _masm(&cbuf); + // RBP is preserved across all calls, even compiled calls. + // Use it to preserve RSP in places where the callee might change the SP. + __ movptr(rbp, rsp); + debug_only(int off1 = cbuf.code_size()); + assert(off1 - off0 == preserve_SP_size(), "correct size prediction"); + %} + + enc_class restore_SP %{ + MacroAssembler _masm(&cbuf); + __ movptr(rsp, rbp); + %} + enc_class Java_Static_Call(method meth) %{ // JAVA STATIC CALL @@ -12526,9 +12561,9 @@ // Call Java Static Instruction // Note: If this code changes, the corresponding ret_addr_offset() and // compute_padding() functions will have to be adjusted. -instruct CallStaticJavaDirect(method meth) -%{ +instruct CallStaticJavaDirect(method meth) %{ match(CallStaticJava); + predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); effect(USE meth); ins_cost(300); @@ -12540,6 +12575,28 @@ ins_alignment(4); %} +// Call Java Static Instruction (method handle version) +// Note: If this code changes, the corresponding ret_addr_offset() and +// compute_padding() functions will have to be adjusted. +instruct CallStaticJavaHandle(method meth, rbp_RegP rbp) %{ + match(CallStaticJava); + predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); + effect(USE meth); + // RBP is saved by all callees (for interpreter stack correction). + // We use it here for a similar purpose, in {preserve,restore}_SP. + + ins_cost(300); + format %{ "call,static/MethodHandle " %} + opcode(0xE8); /* E8 cd */ + ins_encode(preserve_SP, + Java_Static_Call(meth), + restore_SP, + call_epilog); + ins_pipe(pipe_slow); + ins_pc_relative(1); + ins_alignment(4); +%} + // Call Java Dynamic Instruction // Note: If this code changes, the corresponding ret_addr_offset() and // compute_padding() functions will have to be adjusted.