[aarch64-port-dev ] Improvements to safepoint polling

Edward Nevill ed at camswl.com
Wed May 7 16:13:08 UTC 2014


Hi,

The following patch makes some improvements to safepoint polling. The existing code uses adrp to get the address of the polling page in the case of a return poll as in the following output from C2:-

  0x00007f953905eb0c: adrp      xscratch1, 0x00007f9543e57000
                                                ;   {poll_return}
  0x00007f953905eb10: ldr       wzr, [xscratch1,#256]  ;   {poll_return}
  0x00007f953905eb14: ret

However for an inline poll it generates the following:-

  0x00007f953905eb30: movz      x12, #0x7000
  0x00007f953905eb34: movk      x12, #0x43e5, lsl #16
  0x00007f953905eb38: movk      x12, #0x7f95, lsl #32  ; OopMap{[0]=Oop off=156}
                                                ;*goto
                                                ; - MethodAtom::execute at 46 (line 35)

  0x00007f953905eb3c: ldr       wzr, [x12]      ;*goto
                                                ; - MethodAtom::execute at 46 (line 35)
                                                ;   {poll}

Note also that for the poll_return case it uses the SafepointPollOffset of 256, whereas for the inline poll it does not and uses an offset of 0.

The patch below causes it to generate adrp in all cases. I have set SafepointPollOffset to 0 as there is no reason for it to be 256. Having it set to 0 in all cases saves trashing a cache line.

Also I have removed references to SafepointPollOffset in aarch64.ad since SafepointPollOffset is a C1 concept (defined in c1_globals). No other arch references SafepointPollOffset in C2.

The patch involves some trickyness in the relocation code because the adrp may be subject to CSE / Loop invariance hoisting and therefore may be separated from the ldr.

OK to push?
Ed.


--- CUT HERE ---
# HG changeset patch
# User Edward Nevill edward.nevill at linaro.org
# Date 1399477316 -3600
#      Wed May 07 16:41:56 2014 +0100
# Node ID 8a569467b81b8589fb4daa87b6d4292bafc206f9
# Parent  f67f9b1b52ae8b1778dacb49df641bb5b6e48da1
Improvements to safepoint polling

diff -r f67f9b1b52ae -r 8a569467b81b src/cpu/aarch64/vm/aarch64.ad
--- a/src/cpu/aarch64/vm/aarch64.ad	Thu May 01 14:57:36 2014 +0100
+++ b/src/cpu/aarch64/vm/aarch64.ad	Wed May 07 16:41:56 2014 +0100
@@ -1011,7 +1011,7 @@
   }
 
   if (do_polling() && C->is_method_compilation()) {
-    address polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()));
+    address polling_page(os::get_polling_page());
     __ read_polling_page(rscratch1, polling_page, relocInfo::poll_return_type);
   }
 }
@@ -2557,6 +2557,15 @@
     __ mov(dst_reg, (u_int64_t)1);
   %}
 
+  enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{
+    MacroAssembler _masm(&cbuf);
+    address page = (address)$src$$constant;
+    Register dst_reg = as_Register($dst$$reg);
+    unsigned long off;
+    __ adrp(dst_reg, Address(page, relocInfo::poll_type), off);
+    assert(off == 0, "assumed offset == 0");
+  %}
+
   enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{
     MacroAssembler _masm(&cbuf);
     Register dst_reg = as_Register($dst$$reg);
@@ -3726,6 +3735,17 @@
   interface(CONST_INTER);
 %}
 
+// Polling Page Pointer Immediate
+operand immPollPage()
+%{
+  predicate((address)n->get_ptr() == os::get_polling_page());
+  match(ConP);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 // Pointer Immediate Minus One
 // this is used when we want to write the current PC to the thread anchor
 operand immP_M1()
@@ -5058,6 +5078,20 @@
   ins_pipe(pipe_class_default);
 %}
 
+// Load Poll Page Constant
+
+instruct loadConPollPage(iRegPNoSp dst, immPollPage con)
+%{
+  match(Set dst con);
+
+  ins_cost(INSN_COST);
+  format %{ "adr  $dst, $con\t# Poll Page Ptr" %}
+
+  ins_encode(aarch64_enc_mov_poll_page(dst, con));
+
+  ins_pipe(pipe_class_default);
+%}
+
 // Load Narrow Pointer Constant
 
 instruct loadConN(iRegNNoSp dst, immN con)
@@ -10815,7 +10849,7 @@
   match(SafePoint poll);
 
   format %{
-    "ldrw zr, [rscratch1, $poll]\t# Safepoint: poll for GC"
+    "ldrw zr, [$poll]\t# Safepoint: poll for GC"
   %}
   ins_encode %{
     __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type);
diff -r f67f9b1b52ae -r 8a569467b81b src/cpu/aarch64/vm/c1_globals_aarch64.hpp
--- a/src/cpu/aarch64/vm/c1_globals_aarch64.hpp	Thu May 01 14:57:36 2014 +0100
+++ b/src/cpu/aarch64/vm/c1_globals_aarch64.hpp	Wed May 07 16:41:56 2014 +0100
@@ -74,6 +74,6 @@
 define_pd_global(bool, CSEArrayLength,               false);
 define_pd_global(bool, TwoOperandLIRForm,            false );
 
-define_pd_global(intx, SafepointPollOffset,          256  );
+define_pd_global(intx, SafepointPollOffset,          0  );
 
 #endif // CPU_AARCH64_VM_C1_GLOBALS_AARCH64_HPP
diff -r f67f9b1b52ae -r 8a569467b81b src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu May 01 14:57:36 2014 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed May 07 16:41:56 2014 +0100
@@ -94,7 +94,9 @@
       offset = adr_page - pc_page;
 
       unsigned insn2 = ((unsigned*)branch)[1];
-      if (Instruction_aarch64::extract(insn2, 29, 24) == 0b111001) {
+      if ((address)target == os::get_polling_page()) {
+	assert(offset_lo == 0, "offset must be 0 for polling page");
+      } else if (Instruction_aarch64::extract(insn2, 29, 24) == 0b111001) {
 	// Load/store register (unsigned immediate)
 	unsigned size = Instruction_aarch64::extract(insn2, 31, 30);
 	Instruction_aarch64::patch(branch + sizeof (unsigned),
@@ -180,7 +182,9 @@
       uint64_t target_page = ((uint64_t)insn_addr) + offset;
       target_page &= ((uint64_t)-1) << shift;
       unsigned insn2 = ((unsigned*)insn_addr)[1];
-      if (Instruction_aarch64::extract(insn2, 29, 24) == 0b111001) {
+      if ((address)target_page == os::get_polling_page()) {
+	return (address)target_page;
+      } else if (Instruction_aarch64::extract(insn2, 29, 24) == 0b111001) {
 	// Load/store register (unsigned immediate)
 	unsigned int byte_offset = Instruction_aarch64::extract(insn2, 21, 10);
 	unsigned int size = Instruction_aarch64::extract(insn2, 31, 30);
--- CUT HERE ---




More information about the aarch64-port-dev mailing list