<div dir="ltr">Ping<br><a href="http://reviews.llvm.org/D3473" target="_blank">http://reviews.llvm.org/D3473</a></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Apr 23, 2014 at 9:32 PM, Valerii Hiora <span dir="ltr"><<a href="mailto:valerii.hiora@gmail.com" target="_blank">valerii.hiora@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Patch enables support of segmented stacks on armv7 iOS.<br>
<br>
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.<br>
<br>
To be precise, it uses Apple-specific implementation of _pthread_{get,set}specific_direct taken from <a href="http://www.opensource.apple.com/source/Libc/Libc-825.40.1/pthreads/pthread_machdep.h" target="_blank">http://www.opensource.apple.com/source/Libc/Libc-825.40.1/pthreads/pthread_machdep.h</a> 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.<br>
<br>
<a href="http://reviews.llvm.org/D3473" target="_blank">http://reviews.llvm.org/D3473</a><br>
<br>
Files:<br>
lib/Target/ARM/ARMFrameLowering.cpp<br>
<br>
Index: lib/Target/ARM/ARMFrameLowering.cpp<br>
===================================================================<br>
--- lib/Target/ARM/ARMFrameLowering.cpp<br>
+++ lib/Target/ARM/ARMFrameLowering.cpp<br>
@@ -1671,13 +1671,13 @@<br>
bool Thumb = ST->isThumb();<br>
<br>
// Sadly, this currently doesn't support varargs, platforms other than<br>
- // android/linux. Note that thumb1/thumb2 are support for android/linux.<br>
- if (MF.getFunction()->isVarArg())<br>
- report_fatal_error("Segmented stacks do not support vararg functions.");<br>
- if (!ST->isTargetAndroid() && !ST->isTargetLinux())<br>
- report_fatal_error("Segmented stacks not supported on this platform.");<br>
-<br>
- MachineBasicBlock &prologueMBB = MF.front();<br>
+ // android/linux. Note that thumb1/thumb2 are support for android/linux.<br>
+ if (MF.getFunction()->isVarArg())<br>
+ report_fatal_error("Segmented stacks do not support vararg functions.");<br>
+ if (!ST->isTargetAndroid() && !ST->isTargetLinux() && !ST->isTargetIOS())<br>
+ report_fatal_error("Segmented stacks not supported on this platform.");<br>
+<br>
+ MachineBasicBlock &prologueMBB = MF.front();<br>
MachineFrameInfo *MFI = MF.getFrameInfo();<br>
MachineModuleInfo &MMI = MF.getMMI();<br>
MCContext &Context = MMI.getContext();<br>
@@ -1795,16 +1795,45 @@<br>
.addImm(15)<br>
.addImm(0)<br>
.addImm(13)<br>
- .addImm(0)<br>
- .addImm(3));<br>
-<br>
- // Use the last tls slot on android and a private field of the TCP on linux.<br>
- assert(ST->isTargetAndroid() || ST->isTargetLinux());<br>
- unsigned TlsOffset = ST->isTargetAndroid() ? 63 : 1;<br>
-<br>
- // Get the stack limit from the right offset<br>
- // ldr SR0, [sr0, #4 * TlsOffset]<br>
- AddDefaultPred(BuildMI(GetMBB, DL, TII.get(ARM::LDRi12), ScratchReg0)<br>
+ .addImm(0)<br>
+ .addImm(3));<br>
+<br>
+ unsigned TlsOffset = 0;<br>
+ if (ST->isTargetAndroid() || ST->isTargetLinux()) {<br>
+ // Use the last tls slot on android and a private field of the TCP on linux.<br>
+ TlsOffset = ST->isTargetAndroid() ? 63 : 1;<br>
+ } else if (ST->isTargetIOS()) {<br>
+ // Idea for iOS was taken from<br>
+ // <a href="http://www.opensource.apple.com/source/Libc/Libc-825.40.1/pthreads/pthread_machdep.h" target="_blank">http://www.opensource.apple.com/source/Libc/Libc-825.40.1/pthreads/pthread_machdep.h</a><br>
+ //<br>
+ // In short: _pthread_{get,set}_specific_direct allows extremely fast<br>
+ // access, exactly what is required for segmented stack<br>
+ // There is a pool of reserved slots for Apple internal use (0..119)<br>
+ // First dynamic allocated pthread key starts with 257 (on iOS7)<br>
+ // So using slot 149 should be pretty safe ASSUMING space is reserved<br>
+ // for every key < first dynamic key<br>
+ // But it's just assumption...<br>
+ //<br>
+ // There is also an opportunity to steal keys reserved for Garbage Collection<br>
+ // ranges 80..89 and 110..119, especially considering the fact Garbage Collection<br>
+ // never supposed to work on iOS. But as everybody knows it - there is a chance<br>
+ // that those slots will be re-used, like it happened with key 95 (moved from<br>
+ // JavaScriptCore to CoreText)<br>
+ //<br>
+ // It will be great if slot for segmented stack will be officially reserved<br>
+ // by Apple to avoid any clashes or misuse by other compilers.<br>
+ // Good example is the key for SJ/LJ exceptions<br>
+<br>
+ // Bic SR0, SR0, #3<br>
+ AddDefaultCC(AddDefaultPred(BuildMI(GetMBB, DL, TII.get(ARM::BICri), ScratchReg0)<br>
+ .addReg(ScratchReg0, RegState::Kill)<br>
+ .addImm(3)));<br>
+ TlsOffset = 149;<br>
+ }<br>
+<br>
+ // Get the stack limit from the right offset<br>
+ // ldr SR0, [sr0, #4 * TlsOffset]<br>
+ AddDefaultPred(BuildMI(GetMBB, DL, TII.get(ARM::LDRi12), ScratchReg0)<br>
.addReg(ScratchReg0).addImm(4 * TlsOffset));<br>
}<br>
</blockquote></div><br></div>