< prev index next >

src/hotspot/cpu/x86/x86_64.ad

Print this page
rev 47415 : 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 >