--- old/src/cpu/x86/vm/x86_64.ad Wed Feb 15 11:46:30 2012 +++ new/src/cpu/x86/vm/x86_64.ad Wed Feb 15 11:46:30 2012 @@ -853,121 +853,53 @@ //============================================================================= #ifndef PRODUCT -void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const -{ +void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { Compile* C = ra_->C; int framesize = C->frame_slots() << LogBytesPerInt; assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); - // Remove wordSize for return adr already pushed - // and another for the RBP we are going to save - framesize -= 2*wordSize; - bool need_nop = true; + // Remove wordSize for return addr which is already pushed. + framesize -= wordSize; - // Calls to C2R adapters often do not accept exceptional returns. - // We require that their callers must bang for them. But be - // careful, because some VM calls (such as call site linkage) can - // use several kilobytes of stack. But the stack safety zone should - // account for that. See bugs 4446381, 4468289, 4497237. if (C->need_stack_bang(framesize)) { - st->print_cr("# stack bang"); st->print("\t"); - need_nop = false; + framesize -= wordSize; + st->print("# stack bang"); + st->print("\n\t"); + st->print("pushq rbp\t# Save rbp"); + if (framesize) { + st->print("\n\t"); + st->print("subq rsp, #%d\t# Create frame",framesize); + } + } else { + st->print("subq rsp, #%d\t# Create frame",framesize); + st->print("\n\t"); + framesize -= wordSize; + st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); } - st->print_cr("pushq rbp"); st->print("\t"); if (VerifyStackAtCalls) { - // Majik cookie to verify stack depth - st->print_cr("pushq 0xffffffffbadb100d" - "\t# Majik cookie for stack depth check"); - st->print("\t"); - framesize -= wordSize; // Remove 2 for cookie - need_nop = false; + st->print("\n\t"); + framesize -= wordSize; + st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); +#ifdef ASSERT + st->print("\n\t"); + st->print("# stack alignment check"); +#endif } - - if (framesize) { - st->print("subq rsp, #%d\t# Create frame", framesize); - if (framesize < 0x80 && need_nop) { - st->print("\n\tnop\t# nop for patch_verified_entry"); - } - } + st->cr(); } #endif -void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const -{ +void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { Compile* C = ra_->C; + MacroAssembler _masm(&cbuf); - // WARNING: Initial instruction MUST be 5 bytes or longer so that - // NativeJump::patch_verified_entry will be able to patch out the entry - // code safely. The fldcw is ok at 6 bytes, the push to verify stack - // depth is ok at 5 bytes, the frame allocation can be either 3 or - // 6 bytes. So if we don't do the fldcw or the push then we must - // use the 6 byte frame allocation even if we have no frame. :-( - // If method sets FPU control word do it now - int framesize = C->frame_slots() << LogBytesPerInt; - assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); - // Remove wordSize for return adr already pushed - // and another for the RBP we are going to save - framesize -= 2*wordSize; - bool need_nop = true; - // Calls to C2R adapters often do not accept exceptional returns. - // We require that their callers must bang for them. But be - // careful, because some VM calls (such as call site linkage) can - // use several kilobytes of stack. But the stack safety zone should - // account for that. See bugs 4446381, 4468289, 4497237. - if (C->need_stack_bang(framesize)) { - MacroAssembler masm(&cbuf); - masm.generate_stack_overflow_check(framesize); - need_nop = false; - } + __ verified_entry(framesize, C->need_stack_bang(framesize), false); - // We always push rbp so that on return to interpreter rbp will be - // restored correctly and we can correct the stack. - emit_opcode(cbuf, 0x50 | RBP_enc); - - if (VerifyStackAtCalls) { - // Majik cookie to verify stack depth - emit_opcode(cbuf, 0x68); // pushq (sign-extended) 0xbadb100d - emit_d32(cbuf, 0xbadb100d); - framesize -= wordSize; // Remove 2 for cookie - need_nop = false; - } - - if (framesize) { - emit_opcode(cbuf, Assembler::REX_W); - if (framesize < 0x80) { - emit_opcode(cbuf, 0x83); // sub SP,#framesize - emit_rm(cbuf, 0x3, 0x05, RSP_enc); - emit_d8(cbuf, framesize); - if (need_nop) { - emit_opcode(cbuf, 0x90); // nop - } - } else { - emit_opcode(cbuf, 0x81); // sub SP,#framesize - emit_rm(cbuf, 0x3, 0x05, RSP_enc); - emit_d32(cbuf, framesize); - } - } - C->set_frame_complete(cbuf.insts_size()); -#ifdef ASSERT - if (VerifyStackAtCalls) { - Label L; - MacroAssembler masm(&cbuf); - masm.push(rax); - masm.mov(rax, rsp); - masm.andptr(rax, StackAlignmentInBytes-1); - masm.cmpptr(rax, StackAlignmentInBytes-wordSize); - masm.pop(rax); - masm.jcc(Assembler::equal, L); - masm.stop("Stack is not properly aligned!"); - masm.bind(L); - } -#endif - if (C->has_mach_constant_base_node()) { // NOTE: We set the table base offset here because users might be // emitted before MachConstantBaseNode.