< prev index next >
src/hotspot/cpu/x86/x86_64.ad
Print this page
rev 47591 : Add Thread Local handshakes and thread local polling
@@ -315,10 +315,22 @@
reg_class ptr_rsp_reg(RSP, RSP_H);
// Singleton class for TLS pointer
reg_class ptr_r15_reg(R15, R15_H);
+// The registers which can be used for
+// a thread local safepoint poll
+// * R12 is reserved for heap base
+// * R13 cannot be encoded for addressing without an offset byte
+// * R15 is reserved for the JavaThread
+reg_class ptr_rex_reg(R8, R8_H,
+ R9, R9_H,
+ R10, R10_H,
+ R11, R11_H,
+ R14, R14_H);
+
+
// Class for all long registers (excluding RSP)
reg_class long_reg_with_rbp(RAX, RAX_H,
RDX, RDX_H,
RBP, RBP_H,
RDI, RDI_H,
@@ -564,11 +576,11 @@
// 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 Assembler::is_polling_page_far();
+ return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far();
}
//
// Compute padding required for nodes which need alignment
//
@@ -936,11 +948,15 @@
}
st->print_cr("popq rbp");
if (do_polling() && C->is_method_compilation()) {
st->print("\t");
- if (Assembler::is_polling_page_far()) {
+ if (SafepointMechanism::uses_thread_local_poll()) {
+ st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t"
+ "testl rax, [rscratch1]\t"
+ "# Safepoint: poll for GC");
+ } else 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"
@@ -987,19 +1003,25 @@
__ reserved_stack_check();
}
if (do_polling() && C->is_method_compilation()) {
MacroAssembler _masm(&cbuf);
+ if (SafepointMechanism::uses_thread_local_poll()) {
+ __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset()));
+ __ relocate(relocInfo::poll_return_type);
+ __ testl(rax, Address(rscratch1, 0));
+ } else {
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
{
return MachNode::size(ra_); // too many variables; just compute it
@@ -3509,10 +3531,20 @@
format %{ %}
interface(REG_INTER);
%}
+operand rex_RegP()
+%{
+ constraint(ALLOC_IN_RC(ptr_rex_reg));
+ match(RegP);
+ match(rRegP);
+
+ format %{ %}
+ interface(REG_INTER);
+%}
+
operand rRegL()
%{
constraint(ALLOC_IN_RC(long_reg));
match(RegL);
match(rax_RegL);
@@ -12058,11 +12090,11 @@
// ============================================================================
// Safepoint Instructions
instruct safePoint_poll(rFlagsReg cr)
%{
- predicate(!Assembler::is_polling_page_far());
+ predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll());
match(SafePoint);
effect(KILL cr);
format %{ "testl rax, [rip + #offset_to_poll_page]\t"
"# Safepoint: poll for GC" %}
@@ -12074,20 +12106,40 @@
ins_pipe(ialu_reg_mem);
%}
instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
%{
- predicate(Assembler::is_polling_page_far());
+ predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll());
+ 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);
+%}
+
+instruct safePoint_poll_tls(rFlagsReg cr, rex_RegP poll)
+%{
+ predicate(SafepointMechanism::uses_thread_local_poll());
match(SafePoint poll);
effect(KILL cr, USE poll);
format %{ "testl rax, [$poll]\t"
"# Safepoint: poll for GC" %}
ins_cost(125);
+ size(3); /* setting an explicit size will cause debug builds to assert if size is incorrect */
ins_encode %{
__ relocate(relocInfo::poll_type);
+ address pre_pc = __ pc();
__ testl(rax, Address($poll$$Register, 0));
+ address post_pc = __ pc();
+ guarantee(pre_pc[0] == 0x41 && pre_pc[1] == 0x85, "must emit #rex test-ax [reg]");
%}
ins_pipe(ialu_reg_mem);
%}
// ============================================================================
< prev index next >