380 likes | 468 Views
Scope, Function and Storage Management. Chapter 7. Topics. Block-structured languages and stack storage In-line Blocks activation records storage for local, global variables First-order functions parameter passing tail recursion and iteration Higher-order functions
E N D
Scope, Function and Storage Management Chapter 7 ICS 535 -091
Topics • Block-structured languages and stack storage • In-line Blocks • activation records • storage for local, global variables • First-order functions • parameter passing • tail recursion and iteration • Higher-order functions • deviations from stack discipline • language expressiveness => implementation complexity ICS 535 -091
new variables declared in nested blocks outer block inner block local variable global variable Block-Structured Languages • Nested blocks, local variables • Example { int x = 2; { int y = 3; x = y+2; } } • Storage management • Enter block: allocate space for variables • Exits block: some or all space may be deallocated ICS 535 -091
Examples • Blocks in common languages • C { … } • Algol begin … end • ML let … in … end • Two forms of blocks • In-line blocks • Blocks associated with functions or procedures • We look at memory management for three classes of variables: local variables, parameters, global variables. ICS 535 -091
Simplified Machine Model Registers Code Data Stack Program Counter Heap Environment Pointer ICS 535 -091
Interested in Memory Mgmt Only • Registers, Code segment, Program counter • Registers for short term storage of addresses and data. • Will not be concerned with registers or the instruction. • Data Segment • Stack contains data related to block entry/exit • Heap contains data that will exist longer than the execution of the current block. • Environment pointer points to current activation record. • Block entry: add new activation record to stack • Block exit: remove most recent activation record ICS 535 -091
Some basic concepts • Scope • Region of program text where declaration is visible. • Lifetime • Period of time when location is allocated to program. • Inner declaration of x hides outer one. • Inner block is called “hole in scope” of the outer declaration of x. • Lifetime of outer x includes time when inner block is executed, but the scope of the outer x does not include the scope of the inner one. • Lifetime scope • { int x = … ; • { int y = … ; • { int x = … ; • …. • }; • }; • }; ICS 535 -091
Push record with space for x, y • Set values of x, y • Push record for inner block • Set space and value of z • Pop record for inner block • Pop record for outer block • { int x=0; • int y=x+1; • { int z=(x+y)*(x-y); • }; • }; In-line Blocks • Activation record • Data structure stored on run-time stack • Contains space for local variables • Example May need space for variables and intermediate results like (x+y), (x-y) ICS 535 -091
Control link Control link Local variables Local variables Intermediate results Intermediate results Activation record for in-line block • Control link • pointer to previous record on stack • Push record on stack: • Set new control link to point to old env ptr • Set env ptr to new record • Pop record off stack • Follow control link of current record to reset environment pointer Environment Pointer ICS 535 -091
Control link x 0 y 1 Control link • Push record with space for x, y • Set values of x, y • Push record for inner block • Set value of z • Pop record for inner block • Pop record for outer block • { int x=0; • int y=x+1; • { int z=(x+y)*(x-y); • }; • }; z -1 x+y 1 x-y -1 Environment Pointer Example ICS 535 -091
{ int x=0; • int y=x+1; • { int z=(x+y)*(x-y); • }; • }; Scoping rules • Global and local variables • x, y are local to outer block • z is local to inner bock • x, y are global to inner block • Static scope • global refers to declaration in closest enclosing block • Dynamic scope • global refers to most recent activation record These are same until we consider function calls. ICS 535 -091
Functions and procedures • Syntax of procedures (Algol) and functions (C) procedure P (<pars>) <type> function f(<pars>) begin { <local vars> <local vars> <proc body> <function body> end; } • Activation record must include space for • parameters • return address • local variables, intermediate results • return value (an intermediate result) • location to put return value on function exit ICS 535 -091
Activation record for function Control link • Return address • Location of code to execute on function return • Return-result address • Address in activation record of calling block to receive return result • Parameters • Locations to contain data from calling block Return address Return-result addr Parameters Local variables Intermediate results Environment Pointer ICS 535 -091
Example Control link • Function fact(n) = if n<= 1 then 1 else n * fact(n-1) • Return result address is a location to put fact(n) • Parameter • set to value of n by calling sequence • Intermediate result • locations to contain value of fact(n-1) Return address Return result addr Parameters Local variables Intermediate results Environment Pointer ICS 535 -091
fact(k) fact(3) Control link Control link Return-result addr Return-result addr n 3 n k fact(n-1) fact(n-1) fact(2) Control link Environment Pointer Return-result addr n 2 fact(n-1) fact(1) Control link Return-result addr n 1 fact(n-1) Function return next slide Function call Return address omitted; would be ptr into code segment • fact(n) = if n<= 1 then 1 • else n * fact(n-1) ICS 535 -091
Function return fact(3) fact(3) Control link Control link Return result addr Return result addr n 3 n 3 fact(n-1) fact(n-1) 2 fact(2) fact(2) Control link Control link Return result addr Return result addr n 2 n 2 fact(n-1) 1 fact(n-1) 1 fact(1) Control link Return result addr • fact(n) = if n<= 1 then 1 • else n * fact(n-1) n 1 fact(n-1) ICS 535 -091
Topics for first-order functions • Parameter passing • pass-by-value: copy value to new activation record • pass-by-reference: copy ptr to new activation record • Access to global variables • global variables are contained in an activation record higher “up” the stack • Tail recursion • an optimization for certain recursive functions ICS 535 -091
Parameter passing • General terminology: L-values and R-values • Assignment y := x • Identifier on left refers to location, called its L-value • Identifier on right refers to contents, called R-value • Pass-by-reference • Place L-value (address) in activation record • Function can assign to variable that is passed • Pass-by-value • Place R-value (contents) in activation record • Function cannot change value of caller’s variable • Reduces aliasing (alias: two names refer to same loc) ICS 535 -091
Example pseudo-code activation records y 0 pass-by-ref f(y) f(y) Control link • function f (x) = • { x = x+1; return x; } • var y = 0; • print (f(y)+y); Return result addr x y 0 pass-by-value f(y) f(y) Control link Return result addr x 0 ICS 535 -091
Access to global variables • Two possible scoping conventions • Static scope: refer to closest enclosing block • Dynamic scope: most recent activation record on stack • Example • var x=1; • function g(z) { return x+z; } • function f(y) { • var x = y+1; • return g(y*x); • } • f(3); outer block x 1 f(3) y 3 x 4 g(12) z 12 Which x is used for expression x+z ? ICS 535 -091
Activation record for static scope Control link • Control link • Link to activation record of previous (calling) block • Access link • Link to activation record of closest enclosing block in program text • Difference • Control link depends on dynamic behavior of prog • Access link depends on static form of program text Access link Return address Return result addr Parameters Local variables Intermediate results Environment Pointer ICS 535 -091
x f g 1 … … Static scope with access links Use access link to find global variable: • Access link is always set to frame of closest enclosing lexical block • For function body, this is the block that contains function declaration outer block • var x=1; • function g(z) = { return x+z; } • function f(y) = • { var x = y+1; • return g(y*x); } • f(3); control link access link control link access link f(3) control link access link y 3 x 4 g(12) control link access link ICS 535 -091 z 12
not a tail call tail call Tail recursion • Function g makes a tail call to function f if • Return value of function f is return value of g • Example fun g(x) = if x>0 then f(x) else f(x)*2 • A function f is tail recursive if all recursive calls in the body of f are tail calls to f. ICS 535 -091
Example – Tail recursive function tlfact(3, 1) control fun tlfact(n, a) { if n <= 1 then a else tlfact(n-1, n*a); } tlfact(3, 1); return val n 3 a 1 control return val n 2 • After 3rd call terminates, it passes its value to 2nd which passes it to 1st. • Instead of allocationg, deallocating activation records (ARs), we can use one AR for all three calls. a 3 control return val n 1 a 6 ICS 535 -091
Tail recursion elimination tlfact(3, 1) tlfact(2, 3) tlfact(1, 6) fun tlfact(n, a) { if n <= 1 then a else tlfact(n-1, n*a); } tlfact(3, 1); control control control return val return val return val n 3 n 2 n 1 a 1 a 3 a 6 • For the 1st call an AR is created. • For the 2nd call, the parameter values are changed to (2, 3). • Tail recursion elimination reuses a single AR for all recursive calls, using assignment to change the values of the parameter on each call. ICS 535 -091
Tail recursion and iteration • Tail recursive elimination compiles tail recursive function into iterative loops itfact(3, 1) • function itfact(n, a) { • while (n>0) { • a = n*a; • n = n-1 } • return a; • } itfact(3, 1) control return val n 3 a 1 • An AR for itfact looks like an AR for tlfact. • Values of n and a change on each iteration the same way as for tail recursive calls. ICS 535 -091
Higher-Order Functions • First-class functions: A language has first-class functions if functions can be: • Declared within any scope. • Passed as arguments to other functions. • Returned as a result of functions. • In a language with first-class functions and static scope, a function value is generally represented by a closure. • A closure is a pair consisting of a pointer to function code and a pointer to an AR. ICS 535 -091
Pass function as argument Pseudo-JavaScript • { int x = 4; • { function f(y) {return x*y}; • { function g(h) { • int x = 7; • return h(3) + x; • }; • g(f); • } } } • The body of f contains a global variable x that is declared in the outer block. • When f is called inside g, the value of x must be retrieved from the AR of the outer block. ICS 535 -091
g x y h f x 3 7 4 Run-time stack after calling f from g Code for f { int x = 4; { function f(y) {return x*y}; { function g(h) { int x=7; return h(3) + x; }; g(f); } } } Code for g g(f) h(3) x * y local var follow access link • How is access link for h(3) set? ICS 535 -091
Result of function call ICS 535 -091
Closures • The standard solution for maintaining static scope when a function are passed to another function or returned as a result is to use a data structure called a closure. • A closure = ptr to env (AR), ptr to code • When a function is passed to another function, the actual value that is passed is a pointer to a closure. ICS 535 -091
Closures • The following steps are used for calling a function, given a closure: • Allocate an activation record for the function that is called, as usual. • Set the access link in the AR using the AR pointer from the closure. ICS 535 -091
access h access y g access access x x f 3 7 4 g(f) h(3) Function Argument and Closures • Run-time stack with access links • { var x = 4; • { function f(y){return x*y}; • { function g(h) { • int x=7; • return h(3)+x; • }; • g(f); • }}} Code for f Code for g access link set from closure ICS 535 -091
Return Function as Result • A function Returning another function as a result is called upward funarg problem or upward fun-result problem. • Example function compose(f,g) {return function(x) { return g(f (x)) }}; • Given two function arguments f and g, function compose returns the function composition of f and g. • The body of compose is a code that requires a function parameter x and then computes g(f(x)). ICS 535 -091
Example: Return fctn with private state JS functionmk_counter (init) { var count = init; function counter(inc) {count=count+inc; return count}; return counter }; var c = mk_counter(1); c(2) + c(2); • Function make_counter allocate a local variable count, intialized to value of the parameter init. • Mak_counter then returns a function that, when called, increments count by parameter inc, and then returns the new value of count. ICS 535 -091
inc access count counter access mk_c access c 2 1 init 1 c(2) JS Example- Storage alloc/dealloc. function mk_counter (init) { var count = init; function counter(inc) {count=count+inc; return count}; return counter}; var c = mk_counter(1); c(2) + c(2); Code for mk_counter mk_counter(1) 3 Code for counter ICS 535 -091
Example- Storage alloc/dealloc. • The steps involved in producing the activation records on run-time stack are: • Declaration of mak_counter: the value is a closure. • Declaration of block c: the value of c is a function, represented by a closure. The access pointer points to the first AR. • Call to make_counter: An AR is allocated to execute make-counter. It contains space for parameter init, local var count and function counter that will be the return result of the call. • First call c(2): An AR is created when c(2) is evaluated. The AR has an access pointer that is set from closure for c (third AR). ICS 535 -091
Problem • There is a problem with the previous run-time stack. What is it??? ICS 535 -091