590 likes | 764 Views
A Brief Recap. Subprogram benefits, basic characteristics from names to their values names can be occurrences in text scope issues: static vs dynamic subprogram calls parameters as basic mechanism for communicating runtime values to subprograms
E N D
A Brief Recap • Subprogram • benefits, basic characteristics • from names to their values • names can be occurrences in text • scope issues: static vs dynamic • subprogram calls • parameters as basic mechanism for communicating runtime values to subprograms • information exchange between caller and subprogram requires conventions or methods • different methods: pass by value, pass by reference, pass by result, pass by value-result, and pass by name CSCI337 Organization of Prog. Lang
Today: Continue the Question with how names get their values • in statically scoped language, binding of names to value are divided into 3 stages: • compile time: have seen name as occurrences in text governed by scope rules • activation time: how a variable declaration can be bound to different storage location each time a subprogram is used (today’s focus) • run time: binding locations to values as done dynamically by changing assignments CSCI337 Organization of Prog. Lang
Activation Records • Activation Record (AR) – storage associated with an activation of a subprogram for variables declared in the subprogram. • Lifetime of a subprogram begins when control enters activation and ends when control returns from activation • control flows between activations in a LIFO manner: if P calls Q and then Q calls R, then R returns to Q before Q returns to P CSCI337 Organization of Prog. Lang
Activation Tree • show the flow of control between activations • root: main program • edge/branch: call from one subprogram to another ordered from left to right according to temporal ordering • leaves: subprogram that calls no other subprogram CSCI337 Organization of Prog. Lang
Example: Activation Tree • P is the main program • P calls Q, so Q is P’s child • Q is called by P before R is called by P, so Q is left of R P Q R CSCI337 Organization of Prog. Lang
Another example: recursive subprogram program activations; function pred(m: integer): integer; begin pred := m – 1 end; function f(n: integer): integer; begin if n =0 then f := 1 else f := n * f(pred(n)) end; CSCI337 Organization of Prog. Lang
f(3) f(2) pred(3) f(1) pred(2) f(0) pred(1) continue main program: f(3) CSCI337 Organization of Prog. Lang
Recursive vs Non-Recursive Subprograms • non-recursive subprogram can only have single activation at a given time, so only one AR exists per call – so easy to implement (e.g. Fortran) • in recursive subprogram multiple activations are possible, so different ARs are required (e.g. C, Pascal) – more difficult to implement, management is required. • management of different ARs involve linkages – call actions and return actions CSCI337 Organization of Prog. Lang
Call Actions/Operations • binding of actuals to formals • allocation of local variable storage (for runtime variables) • save any execution state of the calling program unit • transfer control to the code in the subprogram • enable access to non-local variables • ensures that control can return to the proper place CSCI337 Organization of Prog. Lang
Return Actions/Operations • provide calling program unit with return value (or values if using out mode) • move local values of formals to corresponding actuals • deallocate allocated local variable storage • restore any saved execution state • disable access to non-local variables • return to the access configuration that was in place prior to the call • return control to the calling program unit CSCI337 Organization of Prog. Lang
Implementation of ARs • varies from different languages, traditionally ARs were implemented as stacks, e.g. Pascal and C, but other possibility has been used, e.g. Modula-3 uses heap allocation • the main difference: stack is LIFO (last in first out) – note that although control behave in a LIFO manner, this is insufficient to justify the use of stack. A main reason to favor stack is that storage for a variable declared within a subprogram should be local to the subprogram activation, I.e. the lifetime of the locals should coincide with the lifetime of the AR. CSCI337 Organization of Prog. Lang
Elements of an AR stack frame • pointer to stack of the caller (control/dynamic link) • return address (within caller) • mechanism to find non-local variables (access/static link) • stroage for parameters • storage for local variables • storage for temporary and final values Again, this is a general description of an AR stack frame, details differ from language to language, machine to machine. CSCI337 Organization of Prog. Lang
program L; var n : char; procedure W; begin writeln(n) end; procedure D; begin n := ‘D’; W end; begin { L } n := ‘L’; W; D end have both dynamic and static reading of scopes under dynamic scope control links are used to keep track of callers’ ARs under static scope access links are used to find the binding of non-local n in W Control – Access Links and Scopes CSCI337 Organization of Prog. Lang
P control links Q frame pointer R top of stack Control Link • P calls Q, Q calls R • R returns to Q, Q returns to P • when a subprogram finished control passed back to caller • the sequence of control links is called a dynamic chain. It connects all the current active subprograms CSCI337 Organization of Prog. Lang
In addition • the AR must contain an instruction pointer (Program Counter) • points to the next instruction to be executed after exiting the subprogram • when Q calls R, the caller Q saves the next instruction into its AR CSCI337 Organization of Prog. Lang
How does it work? R: … Q: x := x+y R(x) y :=y+1 Q calls R: • save IP in Q’s AR • create R’s AR • creates control link in R’s AR • current AR (frame/stack pointer) is R’s AR Q R: … Q: x := x+y R(x) y :=y+1 Q R top of stack CSCI337 Organization of Prog. Lang
When R returns… • FP is set to Q’s AR using R’s control link • R’s AR is popped off the stack • the code pointed to by the IP in Q’s AR is executed CSCI337 Organization of Prog. Lang
Variables Reference Again • local variables: no problem, stored in the current frame • referenced via offsets from the frame pointer within the current frame procedure P( … ) var x, y : integer; begin x := 5; y := 6; … end; return address control link set contents(FP-4) to 5 set contents(FP-8) to 6 x y memory layout 4 bytes CSCI337 Organization of Prog. Lang
Parameters • parameters are treated as local variables • passing modes • pass by value: copies written in the frame • pass by reference: frame holds pointer to the actual CSCI337 Organization of Prog. Lang
Pass by Reference Example procedure R(var x : integer) var z : integer; begin … end; procedure Q( … ) var y : integer; begin … R(y); … end; z control link R return address x y control link Q return address … CSCI337 Organization of Prog. Lang
Non-Local Variables … procedure Q( … ) var x : integer; procedure R( … ) begin x := 7; end; begin … R( … ); … end; How to access Q’s x from internal R? control link R return address … x control link Q return address … CSCI337 Organization of Prog. Lang
Can R use control link to find Q’s AR? ‘No’ because the caller may not be the defining subprogram in this case Q calls P and P calls R but R needs Q’s AR procedure Q( … ) var x : integer; procedure R( … ) begin x := 7; end; procedure P( … ) var x : integer; begin …; R( … ); … end; begin …; P( … ); … end; Control Link Doesn’t Work CSCI337 Organization of Prog. Lang
Access Link for Non-Local Variables • The solution is for each frame for subprogram P to contain a pointer to the most recent frame of the subprogram that define P • The pointer is the access link • For a non-local variable that was defined in the defining subprogram just follow the access link • If the variable was non-local to the defining subprogram, just follow the access link! CSCI337 Organization of Prog. Lang
Q control links P R top of stack Example Again procedure Q( … ) var x : integer; procedure R( … ) begin x := 7; end; procedure P( … ) var x : integer; begin …; R( … ); … end; begin …; P( … ); … end; CSCI337 Organization of Prog. Lang
Chasing Links or Casting Nests? • A sequence of access links is called a access chain • every non-local variable required by a subprogram call can be found in the access chain of the frame (the outer subprogram must be active) • How to find the non-local variable? • search through the access chain for the name of the variable? No!!! • Answer: need to compute access nesting level CSCI337 Organization of Prog. Lang
the access nesting level ANL is the number of surrounding scopes of a definition program main(…); ANL0 var n: integer; procedure P (…); ANL1 procedure Q (…); ANL2 begin ( *Q* ) n := 9; end; ( *Q* ) ANL1 begin ( *P* ) n := 7; R(…); end; ( *P* ) ANL0 begin; n := 5; P(…); end Nesting Level CSCI337 Organization of Prog. Lang
Access Distance • access distance between two constructs is the difference of their nesting levels – the traversal between them, the number of links they have to pass through to reach each other • generally we want access distance between a variable definition and a variable reference • the number of access links to follow to find the value of a non-local variable is the access distance between the definition and the reference CSCI337 Organization of Prog. Lang
Computing Access Distance • can be determined at compile time • if access distance is 0, the variable is local, so access by offset into the current frame • otherwise, follow the access chain for the corresponding number of links to find the frame and access by offset into this frame CSCI337 Organization of Prog. Lang
Example x is 2 access links away P … procedure P (…) var x : integer; procedure Q (…) procedure R(…) …; x := 7;… control links Q … R top of stack CSCI337 Organization of Prog. Lang
How to Create Access Links? When a subprogram is called • the defining subprogram must be active (its frame must be on the stack at least once) • the defining subprogram must be in the access chain of the calling subprogram CSCI337 Organization of Prog. Lang
(2a) if the calling subprogram is the defining subprogram, then access link = control link. So the calling subprogram sets up the access link in the new frame procedure foo(…); var n : integer; procedure bar (…); begin … end; … begin …; bar(…); … end; foo(…) is both caller and definer, so foo(…) sets up the access links in the new frame for bar(…) How to (2a) CSCI337 Organization of Prog. Lang
(2b) if the calling subprogram was defined in the same scope as the callee, then they have identical access links. So the caller copies its access link into the new frame procedure foo(…); var n : integer; procedure bar(…); begin … end; procedure gee(…); begin bar(…); end; gee() called bar(), but they are in the same scope of foo(), so gee() copies its links into new frame How to (2b) CSCI337 Organization of Prog. Lang
How to (2c) (2c) otherwise, if the calling subprogram P was defined inside of the called subprogram Q, the access link of P is followed to find the frame of the defining subprogram. So P sets Q’s access link as the current access link followed n times where n is the access distance between P and Q CSCI337 Organization of Prog. Lang
(2c) procedure A (…); procedure B (…); procedure C (…); procedure D (…); procedure E (…); …; B (…); … end; end; end; end; end; CSCI337 Organization of Prog. Lang
How to (2d) (2d) otherwise P doesn’t know the name of Q and therefore cannot call it. CSCI337 Organization of Prog. Lang
So What’s Going On When You Call? • allocate space on top of the stack for a new frame • the new frame’s control link is set to current frame • pass parameters into new frame • save instruction pointer (return address) in the current frame • the new frame’s access link is set to the frame of defining subprogram • increment frame pointer (new frame becomes current) • enter the code of the called subprogram CSCI337 Organization of Prog. Lang
What’s Going On When You Leave? • frame pointer is set to frame control link • pop top frame off the stack • enter the code pointed by IP of the current frame CSCI337 Organization of Prog. Lang
Implementing Parameter Passing 0 • Pass by value • copy variable values into proper stack locations upon subprogram activation • to access the values during execution, indirect addressing is used (via offset from frame pointer) • Pass by result • copy variable values to the stack locations in the caller frame prior to returning • Pass by value result • both of the above CSCI337 Organization of Prog. Lang
Implementing Parameter Passing 1 • Pass by Reference • copy variable addresses into proper stack locations upon subprogram activation • to access the values during execution, double indirect addressing is used • use an offset from the frame pointer to get address • dereference the address to get the value pointed • if used frequently, the complier copies the address into a register so only indirect or direct access is used (this goes for any value used in the stack) • if an expression is sent in, the complier must generate code to evaluate the expression prior to activating the callee CSCI337 Organization of Prog. Lang
Implementing Parameter Passing 2 • Pass by name • parameters are implemented as parameter-less thunks • thunks are codes generated at the call site by the compiler • the codes are called each place where the parameter is used • it evaluates the reference given the current environment CSCI337 Organization of Prog. Lang
in C nested subprogram declarations are not permitted use control links but access links are not required only 2 places to look for a declaration of a name – either within the current subprogram or outside all subprograms in Pascal nested subprogram declarations are permitted both control and access links are required Nesting Again: C vs Pascal CSCI337 Organization of Prog. Lang
Additional Topics: Optimization • Tail-Recursion Elimination – applicable generally to reduce the number of activations, optimize for run time • Displays – apply to statically scoped language that support nesting of subprogram declarations, e.g. Pascal, to optimize access to nonlocals, optimize for compile time CSCI337 Organization of Prog. Lang
Tail Recursive Subprogram • when the last statement executed in the body of a subprogram P is a recursive call, the call is said to be tail recursive. • reminder: recursive here means either calling itself directly within its own body or indirectly through other subprograms which call the initial subprogram. • a subprogram is a tail recursive, if all of its recursive calls are tail recursive. CSCI337 Organization of Prog. Lang
Tail Elimination vs General Elimination • tail recursive subprograms must be of in a special form, so not all recursive subprograms are tail recursive • there are general techniques to convert any recursive subprograms into non-recursive ones , we’ll focus on tail elimination only • elimination of recursive calls does not compromise the expressive power of the program, Fortran for instance is non-recursive - has 1 AR frame per declaration, only one call to a given subprogram CSCI337 Organization of Prog. Lang
Example Binary Search: in C • the example focus on tail recursive calls that call the subprogram itself directly • the basic idea: just use goto to repeatedly execute the body of the subprogram whenever the tail-recursive call is made CSCI337 Organization of Prog. Lang
Example Binary Search: in C, continue • a tail-recursive call P(a, b) with formal x, y can be replace by x = a; y = b; goto L; • where the label L is attached to the first executable statement in P CSCI337 Organization of Prog. Lang
Cost and Benefit of Recursive Calls Elimination • Benefit: in some languages, subprogram calls may be more costly then assignment statements, so a program may have faster run time by a large constant factor if recursive calls can be eliminated • Cost: recursion simplifies the structure of many programs, wholesale elimination of recursion may make programs hard to read or understand • compromise: only eliminate recursion in the most frequently executed portion of the program CSCI337 Organization of Prog. Lang
Display: Optimizing Variable Access • problem: accessing non-locals variables (names) requires traversing links up the access link chain • if a subprogram is at nesting depth n, it may have to follow n-1 access links to find variable addresses, this can be costly • solution (for static scope only): maintain a vector of current-active access-chain frames • called the display • pioneered in Algol60 • makes addresses directly accessible • no need to traverse CSCI337 Organization of Prog. Lang
Display • a display is a global array of pointers to stack frames • D[i] points to the most recent frame with ANL=i • to access a variable defined at ANL=i: • D[i] gives the frame in which the variable is stored; • performed an offset in this frame to access it • the size of the display is bounded by the maximum ANL (and small generally) • note that a display must be maintained with run-time stacks CSCI337 Organization of Prog. Lang
A B 1 2 3 C 4 B Display Example procedure A(…) ANL=1 procedure B(…) ANL=2 procedure C (…)ANL=3 begin B(6); end; begin C(5); end; begin B(4); end; CSCI337 Organization of Prog. Lang