src/hotspot/cpu/x86/x86_64.ad
changeset 47881 0ce0ac68ace7
parent 47216 71c04702a3d5
child 48371 291020144f22
--- a/src/hotspot/cpu/x86/x86_64.ad	Sat Nov 11 01:21:09 2017 +0100
+++ b/src/hotspot/cpu/x86/x86_64.ad	Thu Aug 31 10:00:28 2017 +0200
@@ -317,6 +317,18 @@
 // 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,
@@ -566,7 +578,7 @@
 // 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();
 }
 
 //
@@ -938,7 +950,11 @@
   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");
@@ -989,13 +1005,19 @@
 
   if (do_polling() && C->is_method_compilation()) {
     MacroAssembler _masm(&cbuf);
-    AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
-    if (Assembler::is_polling_page_far()) {
-      __ lea(rscratch1, polling_page);
+    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 {
-      __ testl(rax, polling_page);
+      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);
+      }
     }
   }
 }
@@ -3511,6 +3533,16 @@
   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));
@@ -12060,7 +12092,7 @@
 // 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);
 
@@ -12076,7 +12108,7 @@
 
 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);
 
@@ -12090,6 +12122,26 @@
   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);
+%}
+
 // ============================================================================
 // Procedure Call/Return Instructions
 // Call Java Static Instruction