changeset 13512:8085ce95b6f5

reloc info for safepoint polls includes whether the poison page is far or near
author Doug Simon <doug.simon@oracle.com>
date Mon, 06 Jan 2014 13:41:59 +0100
parents 51e16c7a5685
children 64a23ce736a0
files src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp src/cpu/sparc/vm/relocInfo_sparc.cpp src/cpu/x86/vm/assembler_x86.cpp src/cpu/x86/vm/graalCodeInstaller_x86.hpp src/cpu/x86/vm/relocInfo_x86.cpp src/share/vm/code/relocInfo.cpp src/share/vm/code/relocInfo.hpp
diffstat 8 files changed, 87 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Sat Jan 04 02:08:33 2014 +0200
+++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Mon Jan 06 13:41:59 2014 +0100
@@ -1601,7 +1601,7 @@
   }
 #endif // TIERED
   __ set((intptr_t)os::get_polling_page(), L0);
-  __ relocate(relocInfo::poll_return_type);
+  __ relocate(poll_return_Relocation::spec(poll_Relocation::far));
   __ ld_ptr(L0, 0, G0);
   __ ret();
   __ delayed()->restore();
@@ -1613,7 +1613,7 @@
   if (info != NULL) {
     add_debug_info_for_branch(info);
   } else {
-    __ relocate(relocInfo::poll_type);
+    __ relocate(poll_Relocation::spec(poll_Relocation::far));
   }
 
   int offset = __ offset();
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Sat Jan 04 02:08:33 2014 +0200
+++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Mon Jan 06 13:41:59 2014 +0100
@@ -188,13 +188,13 @@
       fatal("unimplemented");
     }
     case MARK_POLL_FAR:
-      _instructions->relocate(pc, relocInfo::poll_type);
+      _instructions->relocate(pc, poll_Relocation::spec(poll_Relocation::far));
       break;
     case MARK_POLL_RETURN_NEAR: {
       fatal("unimplemented");
     }
     case MARK_POLL_RETURN_FAR:
-      _instructions->relocate(pc, relocInfo::poll_return_type);
+      _instructions->relocate(pc, poll_return_Relocation::spec(poll_Relocation::far));
       break;
     default:
       fatal("invalid mark value");
--- a/src/cpu/sparc/vm/relocInfo_sparc.cpp	Sat Jan 04 02:08:33 2014 +0200
+++ b/src/cpu/sparc/vm/relocInfo_sparc.cpp	Mon Jan 06 13:41:59 2014 +0100
@@ -196,8 +196,5 @@
 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
 }
 
-void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
-}
-
 void metadata_Relocation::pd_fix_value(address x) {
 }
--- a/src/cpu/x86/vm/assembler_x86.cpp	Sat Jan 04 02:08:33 2014 +0200
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Mon Jan 06 13:41:59 2014 +0100
@@ -81,8 +81,10 @@
     _rspec = runtime_call_Relocation::spec();
     break;
   case relocInfo::poll_type:
+    _rspec = poll_Relocation::spec(Assembler::is_polling_page_far() ? poll_Relocation::far : poll_Relocation::near);
+    break;
   case relocInfo::poll_return_type:
-    _rspec = Relocation::spec_simple(rtype);
+    _rspec = poll_return_Relocation::spec(Assembler::is_polling_page_far() ? poll_Relocation::far : poll_Relocation::near);
     break;
   case relocInfo::none:
     break;
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Sat Jan 04 02:08:33 2014 +0200
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Mon Jan 06 13:41:59 2014 +0100
@@ -232,15 +232,19 @@
   switch (mark) {
     case MARK_POLL_NEAR: {
       relocate_poll_near(pc);
+      _instructions->relocate(pc, poll_Relocation::spec(poll_Relocation::near));
+      break;
     }
     case MARK_POLL_FAR:
-      _instructions->relocate(pc, relocInfo::poll_type);
+      _instructions->relocate(pc, poll_Relocation::spec(poll_Relocation::far));
       break;
     case MARK_POLL_RETURN_NEAR: {
       relocate_poll_near(pc);
+      _instructions->relocate(pc, poll_return_Relocation::spec(poll_Relocation::near));
+      break;
     }
     case MARK_POLL_RETURN_FAR:
-      _instructions->relocate(pc, relocInfo::poll_return_type);
+      _instructions->relocate(pc, poll_return_Relocation::spec(poll_Relocation::far));
       break;
     default:
       fatal("invalid mark value");
--- a/src/cpu/x86/vm/relocInfo_x86.cpp	Sat Jan 04 02:08:33 2014 +0200
+++ b/src/cpu/x86/vm/relocInfo_x86.cpp	Mon Jan 06 13:41:59 2014 +0100
@@ -179,29 +179,7 @@
 
 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
 #ifdef _LP64
-  if (!Assembler::is_polling_page_far()) {
-    typedef Assembler::WhichOperand WhichOperand;
-    WhichOperand which = (WhichOperand) format();
-    // This format is imm but it is really disp32
-    which = Assembler::disp32_operand;
-    address orig_addr = old_addr_for(addr(), src, dest);
-    NativeInstruction* oni = nativeInstruction_at(orig_addr);
-    int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
-    // This poll_addr is incorrect by the size of the instruction it is irrelevant
-    intptr_t poll_addr = (intptr_t)oni + *orig_disp;
-
-    NativeInstruction* ni = nativeInstruction_at(addr());
-    intptr_t new_disp = poll_addr - (intptr_t) ni;
-
-    int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
-    * disp = (int32_t)new_disp;
-  }
-#endif // _LP64
-}
-
-void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
-#ifdef _LP64
-  if (!Assembler::is_polling_page_far()) {
+  if (_distance == near) {
     typedef Assembler::WhichOperand WhichOperand;
     WhichOperand which = (WhichOperand) format();
     // This format is imm but it is really disp32
--- a/src/share/vm/code/relocInfo.cpp	Sat Jan 04 02:08:33 2014 +0200
+++ b/src/share/vm/code/relocInfo.cpp	Mon Jan 06 13:41:59 2014 +0100
@@ -679,6 +679,16 @@
   _target  = address_from_scaled_offset(offset, base);
 }
 
+void poll_Relocation::pack_data_to(CodeSection* dest) {
+  short* p = (short*) dest->locs_end();
+  p = pack_1_int_to(p, _distance);
+  dest->set_locs_end((relocInfo*) p);
+}
+
+void poll_Relocation::unpack_data() {
+  _distance = (poll_Relocation::pollingPageDistance) unpack_1_int();
+}
+
 //// miscellaneous methods
 oop* oop_Relocation::oop_addr() {
   int n = _oop_index;
@@ -975,6 +985,22 @@
       tty->print(" | [static_call=" INTPTR_FORMAT "]", r->static_call());
       break;
     }
+  case relocInfo::poll_type:
+  case relocInfo::poll_return_type:
+    {
+      poll_Relocation* r = (poll_Relocation*) reloc();
+      const char *distanceName = "unknown";
+      switch (r->distance()) {
+        case poll_Relocation::near:
+          distanceName = "near";
+          break;
+        case poll_Relocation::far:
+          distanceName = "far";
+          break;
+      }
+      tty->print(" | [distance=%d(%s)]", r->distance(), distanceName);
+      break;
+    }
   }
   tty->cr();
 }
--- a/src/share/vm/code/relocInfo.hpp	Sat Jan 04 02:08:33 2014 +0200
+++ b/src/share/vm/code/relocInfo.hpp	Mon Jan 06 13:41:59 2014 +0100
@@ -210,6 +210,12 @@
 //   See [About Offsets] below.
 //   //%note reloc_2
 //
+// relocInfo::poll_[return_]type -- a safepoint poll
+//   Value:  none
+//   Instruction types: memory load or test
+//   Data:  []       the associated set-oops are adjacent to the call
+//          [n]      n is a poll_Relocation::pollingPageDistance value
+//
 // For example:
 //
 //   INSTRUCTIONS                        RELOC: TYPE    PREFIX DATA
@@ -1271,17 +1277,53 @@
   section_word_Relocation() { }
 };
 
-
 class poll_Relocation : public Relocation {
+ public:
+  enum pollingPageDistance {
+    near,
+    far
+  };
+  relocInfo::relocType type() { return relocInfo::poll_type; }
   bool          is_data()                      { return true; }
-  relocInfo::relocType type() { return relocInfo::poll_type; }
   void     fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
+ private:
+  pollingPageDistance     _distance;
+ public:
+
+  static RelocationHolder spec(poll_Relocation::pollingPageDistance distance) {
+    RelocationHolder rh = newHolder();
+    new(rh) poll_Relocation(distance);
+    return rh;
+  }
+
+  poll_Relocation(poll_Relocation::pollingPageDistance distance) {
+    _distance = distance;
+  }
+  poll_Relocation::pollingPageDistance distance() { return _distance; }
+
+  void pack_data_to(CodeSection* dest);
+  void unpack_data();
+
+ protected:
+  friend class RelocIterator;
+  poll_Relocation() { }
 };
 
-class poll_return_Relocation : public Relocation {
-  bool          is_data()                      { return true; }
+class poll_return_Relocation : public poll_Relocation {
+ public:
   relocInfo::relocType type() { return relocInfo::poll_return_type; }
-  void     fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
+
+  static RelocationHolder spec(poll_Relocation::pollingPageDistance distance) {
+    RelocationHolder rh = newHolder();
+    new(rh) poll_return_Relocation(distance);
+    return rh;
+  }
+
+  poll_return_Relocation(poll_Relocation::pollingPageDistance distance) : poll_Relocation(distance) { }
+
+ private:
+  friend class RelocIterator;
+  poll_return_Relocation() { }
 };
 
 // We know all the xxx_Relocation classes, so now we can define these: