Unwinding The Stack

Unwinding the stack is the restoration/cleanup of ActivationRecords that must occur when control is transferred from one activation record to another; usually the caller's activation record. (When transferring control to a subroutine--this is winding the stack, but it usually isn't called that. When dealing with things like CoRoutines or FirstClassContinuations, this gets a lot more complicated; in this case ContinuationPassingStyle is often used).

In general, this applies to ActivationRecords regardless of what data structure(s) are used to store them; but it especially applies to languages that keep them on TheStack.

When one function calls another, several things must occur in the language implementation (this list includes both things that happen in the prologue of the called function, and in the call-site code in the caller):

When the function returns, the opposite things have to happen:

The latter set of operations is essentially what constitutes stack unwinding.

One longstanding issue with C/C++ and modern optimizing compilers is the interaction of setjmp/longjmp (and asynchronous signal handlers) with stack unwinding. Calling longjmp causes a "long distance" transfer of flow control, consuming many stack frames. Return values are a non-issue with longjmp(), but correct destructor semantics and register un-spilling are problems, as longjmp bypasses the compiler-emitted code to do this.

In C++, the presence of destructors especially complicates this. However, C++ has a feature--ExceptionHandling--that largely replaces setjmp/longjmp() (the one issue that remains is calling longjmp() in a signal handler); so use of setjmp/longjmp in C++ is generally discouraged. If you must use setjmp/longjmp in C++, you ought to avoid putting non-PlainOldData objects directly on TheStack.


EditText of this page (last edited August 25, 2006) or FindPage with title or text search