View
230
Download
3
Embed Size (px)
Citation preview
Chapter 6
Activation Records
Local Variables, Instantiations
int f(int x) {
int y = x+x;
if (y<10)
return f(y);
else
return y-1;
}
Many (recursive) f calls -> Many x’s and y’s Runtime Stack
Higher-order Function
In Pseudo-C
int (*)() f(int x) { int g(int y) {return x+y;} return g; }
int (*h)() = f(3); -> x=3 int (*j)() = f(4); -> x=4
int z = h(5) ; <- y = 5 but no x int w = j(7) ; <- no x
nested function (where inner functions may use variables defined in the outer functions)
+functions returned as results
-> not in stack-mode
C -> no nested function
runtime stack
Stack Frames
incomingargs
locallocalvariablesvariables
return addressreturn address
tempstemps
saved saved registersregisters
arg narg n....
arg 1arg 1Static linkStatic link
arg narg n....
arg 1arg 1static linkstatic link
outgoingargs
currentframe
prevframe
nextframe
stackpointer
framepointer
low
er m
em
ory
ad
dre
sses
h
igh
er a
dd
ress
es
• Push/pop frames• Access variables in deeper
frames -> nonlocal variables• Stack frame
– Local variables– Parameters– Return address– Temporaries– Register save area
• Usually has “standard” frame layout for several languages
• Depends on architecture
arg narg n....
arg 1arg 1stackpointer
framepointer
arg narg n....
arg 1arg 1stackpointer
framepointer
: frame sizeeither fixed or varies => Can be determined very late
Frame PointerFrame Pointer
g(…) calls f(a1, a2, ………, an)
Registers
register : local vars, temporary results… Can save load/store instructions
general purpose vs. special purpose registers caller save vs. callee save register
Ex: MIPS r16 - r23 are preserved across procedure calls (callee-save) r0 - r15 not preserved (caller-save)
If we do interprocedure analysis, we can do fine register save scheduling
If x is not needed after the call caller-save but not save If x is need before and after the call callee-save In general, register allocator (chapter 11)
Parameter Passing
passing with stack passing some in registers and others in stack
k=6 or 4 Need to save register when call another function
To reduce memory traffic, need not to save “argument registers”, when
Leaf procedure – procedure does not call other procedures
Interprocedural register allocation – analyze all functions
Arguments become dead variables at the point where another function is called
Register windows - each function call allocates a fresh set of registers
Parameter Passing (cont’d)
argument passing in reg + stack
Sometimes formal parameters are at consecutive addresses: register save area by callee
call-by-reference Code for dereferencing formal
parameter access no dangling referenceint *f(int x) {return &x;}void f(int &y);
arg karg k....
arg 1arg 1
arg narg n....
arg k+arg k+11
registersavearea
framepointer
Return Address
g calls f : f returns Need g’s address (resume point) -> return address Call instruction at address a
-> return to a+1 (the next instruction) Can be saved
On stack In special register In special memory location
Hardware “call” instruction dependent Usually in designated registers Need to save (non-leaf proc) No need to save (leaf proc)
Frame-resident Variables
Variables are written to memory only when necessary Variable will be passed by reference or & (address of)
operator is applied Variable is accessed by a procedure nested inside the
current one Value is too big to fit into a single register Variable is an array Register holding variable is needed for special purpose
(parameter passing) Too many local variables (“spilled” into frame)
Escaped Variable
A variable “escape”s if it is passed by reference, its address is taken, or it is accessed from a nested function.
Variables are bound to register or memory in later phase in compiling. declarations vs. uses
Static Linksprettyprint output
write --output
show
n
ident
i,s
--output
--n
-- i,s
Inner functions may use variables declared in outer functions
Variable References• Static Links• Lambda lifting (passing all nonlocals as arguments)• Display
Procedure Calls
prettyprint show ident
show,,
Static Link
activation record contains a static link (pointer) that points to outer scope
int aap(int i) {
int noot() {return i+7;}
int mies(int i) {return i+noot();}
return mies(2)- 3;
}
static link
dynamic link
return address
parameter i
aap
static link
dynamic link
return address
parameter i
mies
parameter i
nootstatic link
dynamic link
return address
Example
Given the GNU C routine:
void A(int a) {
void B(int b) {
void C(void) {
printf(“C called, a = %d\n”, a);
}
if (b == 0) C() else B(b-1);
}
B(a);
}
a) draw the stack that results from the call A(2)b) how does C access the parameter (a) from A?
Answers
dynamic
linksstatic
links
A 2
B 2
B 1
B 0
CFP->static_link->static_link->param[#i]
Lambda lifting
outer-scope variables referencing: pass additional pointers
int f() {
int k = 5;
int g(int t) {
return k + t
}
return g(2);
}
nested
int g(int k, int t) { return k + t }
int f() {
int k = 5;
return g(k, 2);
}
lifted
Lambda lifting
out-of-scope variables referencing: pass additional pointers creating: heap (dynamic) allocation
typedef int (*fptr)();
fptr mies(int i) {
int aap() {return i+7;}
return aap;
}
nested
int aap(int *i) {return *i+7;}
fptr mies(int i) {
int *_i = malloc(sizeof(i));
*_i = i;
return closure(aap,_i);
}
lifted
Frames in MiniJava
Package Frame Frame.java Access.java AccessList.java
Package Temp Temp.java, TempList.java, Label.java, LabelList.java
Package Util BoolList.java
Package T(Mips, Sparcs) T(Mips/Sparcs) Frame.java
Inframe(), InReg(), newFrame(), allocLocal()
Package Frame
Abstraction of Actual Frames
package Frame;import Temp.Temp import Temp.Label;
Public abstract class Access{ … }public class AccessList { public Access head; public AccessList tail; public AccessList(Access h, AccessList t) { head=h; tail=t;}}
Frame.java
public abstract class Frame { public abstract Frame newFrame(Temp.Label name,
Util.BoolList formals); public Temp.Label name; //Function name public AccessList formals; //Parameters public abstract Access allocLocal(boolean escape);
public abstract Temp.Temp FP(); //Frame Pointer public abstract Temp.Temp RV(); //Return Value /* ..other stuff, eventually … */
// public abstract int wordSize(); //Size of Word// public abstract Tree.Exp externalCall(String func,
Tree.ExpList args);}
Hold information for parameters & local variables allocated in this frame
TFrame : specific to Target Machine
For T machine… package T; class Frame extends Frame.Frame { /* real definitions of Frame */ …. }
In machine independent part of compiler // in class Main.Main: Frame.Frame frame = new T.Frame(…);
To hide the identity of the target machine
Making new Frames
Frame for function f with k formals
newFrame(f, l) where f : Label l: BoolList
Ex: a three-argument function named g with 1st argument escaped, i.e., needs to stay in memory
frame,newFrame(g,
new BoolList(true,
new BoolList(false,
new BoolList(false,null))))
(No parameters will be escapes in MiniJava.)
Class Access
Access formal & local variables in the frame or in registers
Abstract data type whose implementation is visible only inside the Frame module:
package T class InFrame extends Frame.Access { int offset; InFrame (int o) {offset = o; } } class InReg extends Frame.Access { Temp.Temp temp; InReg(Temp.Temp t) {temp = t; }
Access and Allocate the Variables
InFrame(X) : a memory location at offset X from the FP(frame pointer)
InReg(t84) : in register t84
formals in Frame.java A list of k “accesses” denoting locations where the formal
parameters will be kept at runtime , as seen from inside the callee
May be seen differently by the caller and callee : “shift of view”
View shift must be handled by “newFrame()”
Representation of Frame Descriptions
Implementation of frame is an object holding: the location of all the formals instructions required to implement the “view shift” the number of locals allocated so far the “label” at which the function’s machine code is to
begin See Table 6.4 on page 129
Local Variables
To allocate a new local variable in a frame f
f.allocLocal(true) // allocate in memory (stack)
will return InFrame() access with an offset from FPex) two local variables in Sparcs => InFrame(-4), InFrame(-8)
f.allocLocal(false) // allocate in register will return InReg()
ex) on register-allocated vars => InReg(t481)
allocLocal(bool) Called when frame is create Called when nested block is entered
Allocating Local Storage in frame with the Same Name v
function f() {
var v1 := 6
print(v1);
{
var v2 := 7
print(v2);
}
print(v1);
{ var v3 := 8
print(v3);
} }
allocLocal()
allocLocal()
allocLocal()
v1
v2
v3
v3 mightuse the same space of v1 or v2
framepointer
stackpointer
Escape Variables
No variables escape in MiniJava, because there is no nesting of classes and methods it is not possible to take the address of a variable integers and booleans are passed by value object, including integer arrays, can be represented as
pointers that are passed by value
Temporaries and Labels
Temps are virtual registers May not be enough registers available to store all
temporaries in a register Delay decision until later
Labels are like labels in assembler, a location of a machine language instruction
processing the declaration m(…) new Temp.Label(“C”+”$”+”m”)
Classes Temp and Label in package Temp Packages Frame and Temp provide machine
independent views of variables
Managing Static Links
Static Link management is somewhat tedious? MiniJava does not have nested function declarations:
thus Frame should not know anything about static links.
It will be handled in the Translation phase. Static links may be passed to the callee by the 1st
formal parameter.