< prev index next >

src/hotspot/cpu/aarch64/register_aarch64.hpp

Print this page
rev 60623 : 8248500: AArch64: Remove the r18 dependency on Windows AArch64
Reviewed-by:
Contributed-by: mbeckwit, luhenry, burban

@@ -89,11 +89,22 @@
 CONSTANT_REGISTER_DECLARATION(Register, r13,  (13));
 CONSTANT_REGISTER_DECLARATION(Register, r14,  (14));
 CONSTANT_REGISTER_DECLARATION(Register, r15,  (15));
 CONSTANT_REGISTER_DECLARATION(Register, r16,  (16));
 CONSTANT_REGISTER_DECLARATION(Register, r17,  (17));
-CONSTANT_REGISTER_DECLARATION(Register, r18,  (18));
+
+// In the ABI for Windows+AArch64 the register r18 is used to store the pointer
+// to the current thread's TEB (where TLS variables are stored). We could
+// carefully save and restore r18 at key places, however Win32 Structured
+// Exception Handling (SEH) is using TLS to unwind the stack. If r18 is used
+// for any other purpose at the time of an exception happening, SEH would not
+// be able to unwind the stack properly and most likely crash.
+//
+// It's easier to avoid allocating r18 altogether.
+//
+// See https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019#integer-registers
+CONSTANT_REGISTER_DECLARATION(Register, r18_tls,  (18));
 CONSTANT_REGISTER_DECLARATION(Register, r19,  (19));
 CONSTANT_REGISTER_DECLARATION(Register, r20,  (20));
 CONSTANT_REGISTER_DECLARATION(Register, r21,  (21));
 CONSTANT_REGISTER_DECLARATION(Register, r22,  (22));
 CONSTANT_REGISTER_DECLARATION(Register, r23,  (23));

@@ -205,10 +216,12 @@
   // added to make it compile
   static const int max_gpr;
   static const int max_fpr;
 };
 
+class RegSetIterator;
+
 // A set of registers
 class RegSet {
   uint32_t _bitset;
 
   RegSet(uint32_t bitset) : _bitset(bitset) { }

@@ -263,8 +276,51 @@
 
     return RegSet(bits);
   }
 
   uint32_t bits() const { return _bitset; }
+
+private:
+
+  Register first() {
+    uint32_t first = _bitset & -_bitset;
+    return first ? as_Register(exact_log2(first)) : noreg;
+  }
+
+public:
+
+  friend class RegSetIterator;
+
+  RegSetIterator begin();
 };
 
+class RegSetIterator {
+  RegSet _regs;
+
+public:
+  RegSetIterator(RegSet x): _regs(x) {}
+  RegSetIterator(const RegSetIterator& mit) : _regs(mit._regs) {}
+
+  RegSetIterator& operator++() {
+    Register r = _regs.first();
+    if (r != noreg)
+      _regs -= r;
+    return *this;
+  }
+
+  bool operator==(const RegSetIterator& rhs) const {
+    return _regs.bits() == rhs._regs.bits();
+  }
+  bool operator!=(const RegSetIterator& rhs) const {
+    return ! (rhs == *this);
+  }
+
+  Register operator*() {
+    return _regs.first();
+  }
+};
+
+inline RegSetIterator RegSet::begin() {
+  return RegSetIterator(*this);
+}
+
 #endif // CPU_AARCH64_REGISTER_AARCH64_HPP
< prev index next >