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)); }