[PATCH] Segmented stack support ARM iOS
Valerii Hiora
valerii.hiora at gmail.com
Wed Apr 23 11:32:35 PDT 2014
Patch enables support of segmented stacks on armv7 iOS.
Although it seems to work fine, it relies on a couple of assumptions made about iOS internals which could be wrong so input from Apple engineers is really important.
To be precise, it uses Apple-specific implementation of _pthread_{get,set}specific_direct taken from http://www.opensource.apple.com/source/Libc/Libc-825.40.1/pthreads/pthread_machdep.h and uses static key #149. While it is not in Apple-reserved range (0..119 as of libc 825.40.1), it still unclear if it is smaller than total count of reserved slots.
http://reviews.llvm.org/D3473
Files:
lib/Target/ARM/ARMFrameLowering.cpp
Index: lib/Target/ARM/ARMFrameLowering.cpp
===================================================================
--- lib/Target/ARM/ARMFrameLowering.cpp
+++ lib/Target/ARM/ARMFrameLowering.cpp
@@ -1671,13 +1671,13 @@
bool Thumb = ST->isThumb();
// Sadly, this currently doesn't support varargs, platforms other than
- // android/linux. Note that thumb1/thumb2 are support for android/linux.
- if (MF.getFunction()->isVarArg())
- report_fatal_error("Segmented stacks do not support vararg functions.");
- if (!ST->isTargetAndroid() && !ST->isTargetLinux())
- report_fatal_error("Segmented stacks not supported on this platform.");
-
- MachineBasicBlock &prologueMBB = MF.front();
+ // android/linux. Note that thumb1/thumb2 are support for android/linux.
+ if (MF.getFunction()->isVarArg())
+ report_fatal_error("Segmented stacks do not support vararg functions.");
+ if (!ST->isTargetAndroid() && !ST->isTargetLinux() && !ST->isTargetIOS())
+ report_fatal_error("Segmented stacks not supported on this platform.");
+
+ MachineBasicBlock &prologueMBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineModuleInfo &MMI = MF.getMMI();
MCContext &Context = MMI.getContext();
@@ -1795,16 +1795,45 @@
.addImm(15)
.addImm(0)
.addImm(13)
- .addImm(0)
- .addImm(3));
-
- // Use the last tls slot on android and a private field of the TCP on linux.
- assert(ST->isTargetAndroid() || ST->isTargetLinux());
- unsigned TlsOffset = ST->isTargetAndroid() ? 63 : 1;
-
- // Get the stack limit from the right offset
- // ldr SR0, [sr0, #4 * TlsOffset]
- AddDefaultPred(BuildMI(GetMBB, DL, TII.get(ARM::LDRi12), ScratchReg0)
+ .addImm(0)
+ .addImm(3));
+
+ unsigned TlsOffset = 0;
+ if (ST->isTargetAndroid() || ST->isTargetLinux()) {
+ // Use the last tls slot on android and a private field of the TCP on linux.
+ TlsOffset = ST->isTargetAndroid() ? 63 : 1;
+ } else if (ST->isTargetIOS()) {
+ // Idea for iOS was taken from
+ // http://www.opensource.apple.com/source/Libc/Libc-825.40.1/pthreads/pthread_machdep.h
+ //
+ // In short: _pthread_{get,set}_specific_direct allows extremely fast
+ // access, exactly what is required for segmented stack
+ // There is a pool of reserved slots for Apple internal use (0..119)
+ // First dynamic allocated pthread key starts with 257 (on iOS7)
+ // So using slot 149 should be pretty safe ASSUMING space is reserved
+ // for every key < first dynamic key
+ // But it's just assumption...
+ //
+ // There is also an opportunity to steal keys reserved for Garbage Collection
+ // ranges 80..89 and 110..119, especially considering the fact Garbage Collection
+ // never supposed to work on iOS. But as everybody knows it - there is a chance
+ // that those slots will be re-used, like it happened with key 95 (moved from
+ // JavaScriptCore to CoreText)
+ //
+ // It will be great if slot for segmented stack will be officially reserved
+ // by Apple to avoid any clashes or misuse by other compilers.
+ // Good example is the key for SJ/LJ exceptions
+
+ // Bic SR0, SR0, #3
+ AddDefaultCC(AddDefaultPred(BuildMI(GetMBB, DL, TII.get(ARM::BICri), ScratchReg0)
+ .addReg(ScratchReg0, RegState::Kill)
+ .addImm(3)));
+ TlsOffset = 149;
+ }
+
+ // Get the stack limit from the right offset
+ // ldr SR0, [sr0, #4 * TlsOffset]
+ AddDefaultPred(BuildMI(GetMBB, DL, TII.get(ARM::LDRi12), ScratchReg0)
.addReg(ScratchReg0).addImm(4 * TlsOffset));
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3473.8779.patch
Type: text/x-patch
Size: 3885 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140423/b235e0fd/attachment.bin>
More information about the llvm-commits
mailing list