300 likes | 375 Views
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) {
E N D
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
next frame prev frame Stack Frames arg n . . arg 1 Static link incoming args • 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 frame pointer local variables return address temps saved registers lower memory addresses higher addresses current frame arg n . . arg 1 static link outgoing args stack pointer
Frame Pointer frame pointer g(…) calls f(a1, a2, ………, an) arg n . . arg 1 stack pointer : frame size either fixed or varies => Can be determined very late frame pointer arg n . . arg 1 stack pointer
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
arg n . . arg k+1 arg k . . arg 1 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 reference int *f(int x) {return &x;} void f(int &y); frame pointer register save area
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
prettyprint output write --output show n ident i,s --output --n -- i,s prettyprint show ident show , , Static Links • Inner functions may use variables declared in outer functions • Variable References • Static Links • Lambda lifting (passing all nonlocals as arguments) • Display • Procedure Calls
aap mies parameter i parameter i static link dynamic link return address static link dynamic link return address noot parameter i static link dynamic link return address Static Link • activation record contains astatic 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; }
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); } • draw the stack that results from the call A(2) • how does C access the parameter (a) from A?
dynamic links static links A 2 B 2 B 1 B 0 C Answers FP->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); } int g(int k, int t) { return k + t } int f() { int k = 5; return g(k, 2); } nested lifted
Lambda lifting • out-of-scope variables • referencing: pass additional pointers • creating: heap (dynamic) allocation int aap(int *i) {return *i+7;} fptr mies(int i) { int *_i = malloc(sizeof(i)); *_i = i; return closure(aap,_i); } typedef int (*fptr)(); fptr mies(int i) { int aap(){return i+7;} return aap; } nested 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 FP ex) 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
allocLocal() allocLocal() allocLocal() function f() { var v1 := 6 print(v1); { var v2 := 7 print(v2); } print(v1); { var v3 := 8 print(v3); } } Allocating Local Storage in frame with the Same Name v frame pointer v3might use the same space of v1orv2 v1 v2 v3 stack pointer
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 Tempand Labelin packageTemp • Packages Frameand 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.