< 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 >