xref: /aosp_15_r20/external/llvm/docs/SegmentedStacks.rst (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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