src/cpu/x86/vm/x86_64.ad
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/cpu/x86/vm/x86_64.ad Fri Mar 25 19:58:43 2011
--- new/src/cpu/x86/vm/x86_64.ad Fri Mar 25 19:58:43 2011
*** 572,587 ****
--- 572,586 ----
}
// In os_cpu .ad file
// int MachCallRuntimeNode::ret_addr_offset()
! // Indicate if the safepoint node needs the polling page as an input.
// Since amd64 does not have absolute addressing but RIP-relative
// addressing and the polling page is within 2G, it doesn't.
! // Indicate if the safepoint node needs the polling page as an input,
+ // it does if the polling page is more than disp32 away.
bool SafePointNode::needs_polling_address_input()
{
! return false;
! return Assembler::is_polling_page_far();
}
//
// Compute padding required for nodes which need alignment
//
*** 990,1008 ****
--- 989,1013 ----
// Remove word for return adr already pushed
// and RBP
framesize -= 2*wordSize;
if (framesize) {
! st->print_cr("addq\trsp, %d\t# Destroy frame", framesize);
! st->print_cr("addq rsp, %d\t# Destroy frame", framesize);
st->print("\t");
}
! st->print_cr("popq\trbp");
! st->print_cr("popq rbp");
if (do_polling() && C->is_method_compilation()) {
st->print_cr("\ttestl\trax, [rip + #offset_to_poll_page]\t"
"# Safepoint: poll for GC");
st->print("\t");
+ if (Assembler::is_polling_page_far()) {
+ st->print_cr("movq rscratch1, #polling_page_address\n\t"
+ "testl rax, [rscratch1]\t"
+ "# Safepoint: poll for GC");
+ } else {
+ st->print_cr("testl rax, [rip + #offset_to_poll_page]\t"
+ "# Safepoint: poll for GC");
+ }
}
}
#endif
void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
*** 1031,1079 ****
--- 1036,1061 ----
// popq rbp
emit_opcode(cbuf, 0x58 | RBP_enc);
if (do_polling() && C->is_method_compilation()) {
// testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
// XXX reg_mem doesn't support RIP-relative addressing yet
cbuf.set_insts_mark();
cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_return_type, 0); // XXX
emit_opcode(cbuf, 0x85); // testl
emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
// cbuf.insts_mark() is beginning of instruction
! emit_d32_reloc(cbuf, os::get_polling_page());
// relocInfo::poll_return_type,
+ MacroAssembler _masm(&cbuf);
+ AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
+ if (Assembler::is_polling_page_far()) {
+ __ lea(rscratch1, polling_page);
+ __ relocate(relocInfo::poll_return_type);
+ __ testl(rax, Address(rscratch1, 0));
+ } else {
! __ testl(rax, polling_page);
+ }
}
}
uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
{
Compile* C = ra_->C;
int framesize = C->frame_slots() << LogBytesPerInt;
assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
// Remove word for return adr already pushed
// and RBP
framesize -= 2*wordSize;
uint size = 0;
if (do_polling() && C->is_method_compilation()) {
size += 6;
}
// count popq rbp
size++;
if (framesize) {
if (framesize < 0x80) {
size += 4;
} else if (framesize) {
size += 7;
}
}
return size;
+ return MachNode::size(ra_); // too many variables; just compute it
+ // the hard way
}
int MachEpilogNode::reloc() const
{
return 2; // a large enough number
*** 3908,3933 ****
--- 3890,3899 ----
}
emit_opcode(cbuf, 0x58 | (dstenc & 7));
// done:
%}
// Safepoint Poll. This polls the safepoint page, and causes an
// exception if it is not readable. Unfortunately, it kills
// RFLAGS in the process.
enc_class enc_safepoint_poll
%{
// testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
// XXX reg_mem doesn't support RIP-relative addressing yet
cbuf.set_insts_mark();
cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0); // XXX
emit_opcode(cbuf, 0x85); // testl
emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
// cbuf.insts_mark() is beginning of instruction
emit_d32_reloc(cbuf, os::get_polling_page());
// relocInfo::poll_type,
%}
%}
//----------FRAME--------------------------------------------------------------
*** 4227,4236 ****
--- 4193,4211 ----
op_cost(5);
format %{ %}
interface(CONST_INTER);
%}
+ operand immP_poll() %{
+ predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
+ match(ConP);
+
+ // formats are generated automatically for constants and base registers
+ format %{ %}
+ interface(CONST_INTER);
+ %}
+
// Pointer Immediate
operand immN() %{
match(ConN);
op_cost(10);
*** 6562,6571 ****
--- 6537,6556 ----
opcode(0x33); /* + rd */
ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
ins_pipe(ialu_reg);
%}
+ instruct loadConP_poll(rRegP dst, immP_poll src) %{
+ match(Set dst src);
+ format %{ "movq $dst, $src\t!ptr" %}
+ ins_encode %{
+ AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
+ __ lea($dst$$Register, polling_page);
+ %}
+ ins_pipe(ialu_reg_fat);
+ %}
+
instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
%{
match(Set dst src);
effect(KILL cr);
*** 12467,12484 ****
--- 12452,12488 ----
// ============================================================================
// Safepoint Instructions
instruct safePoint_poll(rFlagsReg cr)
%{
+ predicate(!Assembler::is_polling_page_far());
match(SafePoint);
effect(KILL cr);
format %{ "testl rax, [rip + #offset_to_poll_page]\t"
"# Safepoint: poll for GC" %}
size(6); // Opcode + ModRM + Disp32 == 6 bytes
ins_cost(125);
! ins_encode(enc_safepoint_poll);
! ins_encode %{
+ AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type);
+ __ testl(rax, addr);
+ %}
+ ins_pipe(ialu_reg_mem);
+ %}
+
+ instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
+ %{
+ predicate(Assembler::is_polling_page_far());
+ match(SafePoint poll);
+ effect(KILL cr, USE poll);
+
+ format %{ "testl rax, [$poll]\t"
+ "# Safepoint: poll for GC" %}
+ ins_cost(125);
+ ins_encode %{
+ __ relocate(relocInfo::poll_type);
+ __ testl(rax, Address($poll$$Register, 0));
+ %}
ins_pipe(ialu_reg_mem);
%}
// ============================================================================
// Procedure Call/Return Instructions
src/cpu/x86/vm/x86_64.ad
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File