1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

Update "Stack Layout"

* doc/ref/vm.texi (Stack Layout): Update.
This commit is contained in:
Andy Wingo 2018-09-28 12:15:58 +02:00
parent 7e623d1014
commit 5e671cea02

View file

@ -167,20 +167,22 @@ course is the tail call case, @pxref{Tail Calls}.)
The structure of the top stack frame is as follows: The structure of the top stack frame is as follows:
@example @example
| ... | | ...previous frame locals... |
+==================+ <- fp + 2 = SCM_FRAME_PREVIOUS_SP (fp) +==============================+ <- fp + 3
| Dynamic link | | Dynamic link |
+------------------+ +------------------------------+
| Return address | | Virtual return address (vRA) |
+==================+ <- fp +------------------------------+
| Machine return address (mRA) |
+==============================+ <- fp
| Local 0 | | Local 0 |
+------------------+ +------------------------------+
| Local 1 | | Local 1 |
+------------------+ +------------------------------+
| ... | | ... |
+------------------+ +------------------------------+
| Local N-1 | | Local N-1 |
\------------------/ <- sp \------------------------------/ <- sp
@end example @end example
In the above drawing, the stack grows downward. At the beginning of a In the above drawing, the stack grows downward. At the beginning of a
@ -196,18 +198,25 @@ backtraces in Guile aren't always able to show all of the arguments: it
could be that the slot corresponding to that argument was re-used by could be that the slot corresponding to that argument was re-used by
some other variable. some other variable.
The @dfn{return address} is the @code{ip} that was in effect before this The @dfn{virtual return address} is the @code{ip} that was in effect
program was applied. When we return from this activation frame, we will before this program was applied. When we return from this activation
jump back to this @code{ip}. Likewise, the @dfn{dynamic link} is the frame, we will jump back to this @code{ip}. Likewise, the @dfn{dynamic
offset of the @code{fp} that was in effect before this program was link} is the offset of the @code{fp} that was in effect before this
applied, relative to the current @code{fp}. program was applied, relative to the current @code{fp}.
There are two return addresses: the virtual return address (vRA), and
the machine return address (mRA). The vRA is always present and
indicates a bytecode address. The mRA is only present when a call is
made from a function with machine code (e.g. a function that has been
JIT-compiled).
To prepare for a non-tail application, Guile's VM will emit code that To prepare for a non-tail application, Guile's VM will emit code that
shuffles the function to apply and its arguments into appropriate stack shuffles the function to apply and its arguments into appropriate stack
slots, with two free slots below them. The call then initializes those slots, with three free slots below them. The call then initializes
free slots with the current @code{ip} and @code{fp}, and updates those free slots to hold the machine return address (or NULL), the
@code{ip} to point to the function entry, and @code{fp} to point to the virtual return address, and the offset to the previous frame pointer
new call frame. (@code{fp}). It then gets the @code{ip} for the function being called
and adjusts @code{fp} to point to the new call frame.
In this way, the dynamic link links the current frame to the previous In this way, the dynamic link links the current frame to the previous
frame. Computing a stack trace involves traversing these frames. frame. Computing a stack trace involves traversing these frames.