1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00
llvm-mirror/docs/SegmentedStacks.rst
Renato Golin dfb328c437 [docs] Fixing Sphinx warnings to unclog the buildbot
Lots of blocks had "llvm" or "nasm" syntax types but either weren't following
the syntax, or the syntax has changed (and sphinx hasn't keep up) or the type
doesn't even exist (nasm?).

Other documents had :options: what were invalid. I only removed those that had
warnings, and left the ones that didn't, in order to follow the principle of
least surprise.

This is like this for ages, but the buildbot is now failing on errors. It may
take a while to upgrade the buildbot's sphinx, if that's even possible, but
that shouldn't stop us from getting docs updates (which seem down for quite
a while).

Also, we're not losing any syntax highlight, since when it doesn't parse, it
doesn't colour. Ie. those blocks are not being highlighted anyway.

I'm trying to get all docs in one go, so that it's easy to revert later if we
do fix, or at least easy to know what's to fix.

llvm-svn: 276109
2016-07-20 12:16:38 +00:00

78 lines
3.1 KiB
ReStructuredText

========================
Segmented Stacks in LLVM
========================
.. contents::
:local:
Introduction
============
Segmented stack allows stack space to be allocated incrementally than as a
monolithic chunk (of some worst case size) at thread initialization. This is
done by allocating stack blocks (henceforth called *stacklets*) and linking them
into a doubly linked list. The function prologue is responsible for checking if
the current stacklet has enough space for the function to execute; and if not,
call into the libgcc runtime to allocate more stack space. Segmented stacks are
enabled with the ``"split-stack"`` attribute on LLVM functions.
The runtime functionality is `already there in libgcc
<http://gcc.gnu.org/wiki/SplitStacks>`_.
Implementation Details
======================
.. _allocating stacklets:
Allocating Stacklets
--------------------
As mentioned above, the function prologue checks if the current stacklet has
enough space. The current approach is to use a slot in the TCB to store the
current stack limit (minus the amount of space needed to allocate a new block) -
this slot's offset is again dictated by ``libgcc``. The generated
assembly looks like this on x86-64:
.. code-block:: text
leaq -8(%rsp), %r10
cmpq %fs:112, %r10
jg .LBB0_2
# More stack space needs to be allocated
movabsq $8, %r10 # The amount of space needed
movabsq $0, %r11 # The total size of arguments passed on stack
callq __morestack
ret # The reason for this extra return is explained below
.LBB0_2:
# Usual prologue continues here
The size of function arguments on the stack needs to be passed to
``__morestack`` (this function is implemented in ``libgcc``) since that number
of bytes has to be copied from the previous stacklet to the current one. This is
so that SP (and FP) relative addressing of function arguments work as expected.
The unusual ``ret`` is needed to have the function which made a call to
``__morestack`` return correctly. ``__morestack``, instead of returning, calls
into ``.LBB0_2``. This is possible since both, the size of the ``ret``
instruction and the PC of call to ``__morestack`` are known. When the function
body returns, control is transferred back to ``__morestack``. ``__morestack``
then de-allocates the new stacklet, restores the correct SP value, and does a
second return, which returns control to the correct caller.
Variable Sized Allocas
----------------------
The section on `allocating stacklets`_ automatically assumes that every stack
frame will be of fixed size. However, LLVM allows the use of the ``llvm.alloca``
intrinsic to allocate dynamically sized blocks of memory on the stack. When
faced with such a variable-sized alloca, code is generated to:
* Check if the current stacklet has enough space. If yes, just bump the SP, like
in the normal case.
* If not, generate a call to ``libgcc``, which allocates the memory from the
heap.
The memory allocated from the heap is linked into a list in the current
stacklet, and freed along with the same. This prevents a memory leak.