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