Download Activation Records and Frames in Compiler Design and more Slides Compilers in PDF only on Docsity!
COMPILERS
Activation Records
Subprogram Invocation Mechanics
Save status of caller.
Process parameters.
Save return address.
Jump to called subprogram.
… do stuff ...
Process value-result/result parameters and
function return value(s).
Restore status of caller.
Jump back to caller’s saved position.
Stack-based Recursion
When recursion is implemented using a
stack, activation records are pushed onto
the stack at invocation and popped upon
return.
Example:
int sum ( int x )
if (x==0) return 0;
else return (x + sum (x-1));
void main ()
{ sum (2); }
Recursion Activation Records
mainARI
retvalue (?) parm (x=0) dynamiclink staticlink return (sum) retvalue (?) parm (x=1) dynamiclink staticlink return (sum) retvalue (?) parm (x=2) dynamiclink staticlink return (main) mainARI
retvalue (?) parm (x=1) dynamiclink staticlink return (sum) retvalue (?) parm (x=2) dynamiclink staticlink return (main) mainARI
retvalue (?) parm (x=2) dynamiclink staticlink return (main)
sum(2)
main
sum(2)
main
sum(1)
sum(2)
main
sum(1)
sum(0)
Non-local Reference Example
Example:
main { int x; sub SUBA { sub SUBB { x = 1; } SUBB; } sub SUBC { int x; int y; SUBA; } SUBC; }
breakpoint
breakpoint
breakpoint
breakpoint
Static Chains
local (x)
dynamiclink staticlink return (A) dynamiclink staticlink return (C) local (x) local (y) dynamiclink staticlink return (main) local (x)
dynamiclink staticlink return (C) local (x) local (y) dynamiclink staticlink return (main) local (x)
local (x) local (y) dynamiclink staticlink return (main)
SUBC
main
SUBC
main
SUBA
SUBC
main
SUBA
SUBB
breakpoint1 breakpoint2 breakpoint
Static Chains vs. Displays
Static chains require more indirect
addressing – displays require a fixed
amount of work.
Displays require pointer maintenance on
return – static chains do not.
Displays require “backing up” of display
pointer – static chains require static links
in each activation record.
Dynamic Scoping
Dynamically scoped languages can be
implemented using:
Deep Access
Follow the dynamic chains to find most recent
non-local name definition.
Shallow Access
Maintain a separate stack for each name.
Frame Pointers
Stack frames are usually supported by:
stack pointer - points to top of stack
frame pointer - points to top of previous frame
frame
pointer
stack
pointer
AR g
AR h
frame
pointer
stack
pointer
AR g
AR f AR f
After call to h()
View Shifts
On a Pentium machine,
M[SP + 0] <-- FP
(^) save old frame pointer
FP <-- SP
(^) move frame pointer to top of stack
SP <-- SP - K
(^) move stack pointer to end of new frame
On machines which use registers for frame
optimisation, remember to save registers
in temporary variables.
Parameter Passing
Registers are more efficient than copying
every parameter to the stack frame.
Registers are limited so pass first k parameters
in registers and rest in frame.
Nested subprogram calls require saving
and restoring so there is dubious cost
savings!
leaf procedures, different registers, done with
variables, register windows
How does C support varargs?
Return Addresses
Traditionally a stack frame entry.
More efficient to simply use a register.
Same saving procedure necessary as before for
non-leaf subprograms.
Frame Implementation 1/
A Frame class corresponds to the frame
for each subprogram.
During translation, frames are created to track
variables and generate prologue/epilogue
code.
Frame can be an abstract class with
instantiations for different machine
architectures.
Each instantiation must know how to
implement a “view shift” from one frame to
another.
Frame Implementation 2/
Each time a local variable is defined, a
method of Frame can be called to allocate
space appropriately (on stack frame or in
registers).
f.allocLocal (false)
Parameter indicates if variable requires
memory (escapes) or not - should we allocate
stack space or temporary?
Allocating a temporary for each variable
can be slow - future stages will optimise by
reusing both registers and space.