1*9880d681SAndroid Build Coastguard Worker======================== 2*9880d681SAndroid Build Coastguard WorkerSegmented Stacks in LLVM 3*9880d681SAndroid Build Coastguard Worker======================== 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker.. contents:: 6*9880d681SAndroid Build Coastguard Worker :local: 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard WorkerIntroduction 9*9880d681SAndroid Build Coastguard Worker============ 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard WorkerSegmented stack allows stack space to be allocated incrementally than as a 12*9880d681SAndroid Build Coastguard Workermonolithic chunk (of some worst case size) at thread initialization. This is 13*9880d681SAndroid Build Coastguard Workerdone by allocating stack blocks (henceforth called *stacklets*) and linking them 14*9880d681SAndroid Build Coastguard Workerinto a doubly linked list. The function prologue is responsible for checking if 15*9880d681SAndroid Build Coastguard Workerthe current stacklet has enough space for the function to execute; and if not, 16*9880d681SAndroid Build Coastguard Workercall into the libgcc runtime to allocate more stack space. Segmented stacks are 17*9880d681SAndroid Build Coastguard Workerenabled with the ``"split-stack"`` attribute on LLVM functions. 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard WorkerThe runtime functionality is `already there in libgcc 20*9880d681SAndroid Build Coastguard Worker<http://gcc.gnu.org/wiki/SplitStacks>`_. 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard WorkerImplementation Details 23*9880d681SAndroid Build Coastguard Worker====================== 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker.. _allocating stacklets: 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard WorkerAllocating Stacklets 28*9880d681SAndroid Build Coastguard Worker-------------------- 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard WorkerAs mentioned above, the function prologue checks if the current stacklet has 31*9880d681SAndroid Build Coastguard Workerenough space. The current approach is to use a slot in the TCB to store the 32*9880d681SAndroid Build Coastguard Workercurrent stack limit (minus the amount of space needed to allocate a new block) - 33*9880d681SAndroid Build Coastguard Workerthis slot's offset is again dictated by ``libgcc``. The generated 34*9880d681SAndroid Build Coastguard Workerassembly looks like this on x86-64: 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker.. code-block:: nasm 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker leaq -8(%rsp), %r10 39*9880d681SAndroid Build Coastguard Worker cmpq %fs:112, %r10 40*9880d681SAndroid Build Coastguard Worker jg .LBB0_2 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Worker # More stack space needs to be allocated 43*9880d681SAndroid Build Coastguard Worker movabsq $8, %r10 # The amount of space needed 44*9880d681SAndroid Build Coastguard Worker movabsq $0, %r11 # The total size of arguments passed on stack 45*9880d681SAndroid Build Coastguard Worker callq __morestack 46*9880d681SAndroid Build Coastguard Worker ret # The reason for this extra return is explained below 47*9880d681SAndroid Build Coastguard Worker .LBB0_2: 48*9880d681SAndroid Build Coastguard Worker # Usual prologue continues here 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard WorkerThe size of function arguments on the stack needs to be passed to 51*9880d681SAndroid Build Coastguard Worker``__morestack`` (this function is implemented in ``libgcc``) since that number 52*9880d681SAndroid Build Coastguard Workerof bytes has to be copied from the previous stacklet to the current one. This is 53*9880d681SAndroid Build Coastguard Workerso that SP (and FP) relative addressing of function arguments work as expected. 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard WorkerThe unusual ``ret`` is needed to have the function which made a call to 56*9880d681SAndroid Build Coastguard Worker``__morestack`` return correctly. ``__morestack``, instead of returning, calls 57*9880d681SAndroid Build Coastguard Workerinto ``.LBB0_2``. This is possible since both, the size of the ``ret`` 58*9880d681SAndroid Build Coastguard Workerinstruction and the PC of call to ``__morestack`` are known. When the function 59*9880d681SAndroid Build Coastguard Workerbody returns, control is transferred back to ``__morestack``. ``__morestack`` 60*9880d681SAndroid Build Coastguard Workerthen de-allocates the new stacklet, restores the correct SP value, and does a 61*9880d681SAndroid Build Coastguard Workersecond return, which returns control to the correct caller. 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard WorkerVariable Sized Allocas 64*9880d681SAndroid Build Coastguard Worker---------------------- 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard WorkerThe section on `allocating stacklets`_ automatically assumes that every stack 67*9880d681SAndroid Build Coastguard Workerframe will be of fixed size. However, LLVM allows the use of the ``llvm.alloca`` 68*9880d681SAndroid Build Coastguard Workerintrinsic to allocate dynamically sized blocks of memory on the stack. When 69*9880d681SAndroid Build Coastguard Workerfaced with such a variable-sized alloca, code is generated to: 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker* Check if the current stacklet has enough space. If yes, just bump the SP, like 72*9880d681SAndroid Build Coastguard Worker in the normal case. 73*9880d681SAndroid Build Coastguard Worker* If not, generate a call to ``libgcc``, which allocates the memory from the 74*9880d681SAndroid Build Coastguard Worker heap. 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard WorkerThe memory allocated from the heap is linked into a list in the current 77*9880d681SAndroid Build Coastguard Workerstacklet, and freed along with the same. This prevents a memory leak. 78