SegmentedStacks.rst 3.1 KB

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