brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · b1c588c Raw
78 lines · plain
1========================2Segmented Stacks in LLVM3========================4 5.. contents::6   :local:7 8Introduction9============10 11Segmented stack allows stack space to be allocated incrementally than as a12monolithic chunk (of some worst case size) at thread initialization. This is13done by allocating stack blocks (henceforth called *stacklets*) and linking them14into a doubly linked list. The function prologue is responsible for checking if15the current stacklet has enough space for the function to execute; and if not,16call into the libgcc runtime to allocate more stack space. Segmented stacks are17enabled with the ``"split-stack"`` attribute on LLVM functions.18 19The runtime functionality is `already there in libgcc20<http://gcc.gnu.org/wiki/SplitStacks>`_.21 22Implementation Details23======================24 25.. _allocating stacklets:26 27Allocating Stacklets28--------------------29 30As mentioned above, the function prologue checks if the current stacklet has31enough space. The current approach is to use a slot in the TCB to store the32current stack limit (minus the amount of space needed to allocate a new block) -33this slot's offset is again dictated by ``libgcc``. The generated34assembly looks like this on x86-64:35 36.. code-block:: text37 38    leaq     -8(%rsp), %r1039    cmpq     %fs:112,  %r1040    jg       .LBB0_241 42    # More stack space needs to be allocated43    movabsq  $8, %r10   # The amount of space needed44    movabsq  $0, %r11   # The total size of arguments passed on stack45    callq    __morestack46    ret                 # The reason for this extra return is explained below47  .LBB0_2:48    # Usual prologue continues here49 50The size of function arguments on the stack needs to be passed to51``__morestack`` (this function is implemented in ``libgcc``) since that number52of bytes has to be copied from the previous stacklet to the current one. This is53so that SP (and FP) relative addressing of function arguments work as expected.54 55The unusual ``ret`` is needed to have the function which made a call to56``__morestack`` return correctly. ``__morestack``, instead of returning, calls57into ``.LBB0_2``. This is possible since both, the size of the ``ret``58instruction and the PC of call to ``__morestack`` are known. When the function59body returns, control is transferred back to ``__morestack``. ``__morestack``60then de-allocates the new stacklet, restores the correct SP value, and does a61second return, which returns control to the correct caller.62 63Variable Sized Allocas64----------------------65 66The section on `allocating stacklets`_ automatically assumes that every stack67frame will be of fixed size. However, LLVM allows the use of the ``llvm.alloca``68intrinsic to allocate dynamically sized blocks of memory on the stack. When69faced with such a variable-sized alloca, code is generated to:70 71* Check if the current stacklet has enough space. If yes, just bump the SP, like72  in the normal case.73* If not, generate a call to ``libgcc``, which allocates the memory from the74  heap.75 76The memory allocated from the heap is linked into a list in the current77stacklet, and freed along with the same. This prevents a memory leak.78