1 / 44

All about binding

Learn about how variables are bound to values and stored in memory. Explore different lifetimes and activation records.

tbaines
Download Presentation

All about binding

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. All about binding Memory Locations for Variables (Ch. 12) • Variables are bound (dynamically) to values • values must be stored somewhere in the memory. IT 327

  2. Imperative Functional a := 0; a := 1; val a = 0; val a = 1; • Imperative languages a := 0 • Store a zero in a’s memory location • Functional languages val a = 0 • Binda to the value zero IT 327

  3. Function Activations • Activation of a function : The lifetime of one execution of the function, from call to corresponding return. If each activation has itsown binding for variables, the variables are called activation-specificvariable (dynamic or automatic) most modern languages IT 327

  4. Block Activations • A variable might be specific to a particular block (within a function): fun fact n = if (n=0) then 1 else let val b = fact (n-1) in n*b end; Do we have it in C++/JAVA? IT 327

  5. Other Lifetimes For Variables • We usually have a way to declare a variable that is bound to memory independent from any functions • static allocation, the loader does the job of allocation int count = 0; int nextcount() { int inc = 1; count = count + inc; return count;} IT 327

  6. Scope  Activation (lifetime) • In most modern languages, variables with local scope have activation-specific lifetimes, by default • some exception int nextcount() {static int count = 0; int inc = 1; count = count + inc; return count;} not activation-specific IT 327

  7. there are other lifetimes for variables In addition to activation-specific variables • In OOP, some variables’ lifetimes are associated with object lifetimes • Some variables may last across multiple executions of the program IT 327

  8. Activation Records Each function being executed has an activation record An activation record contains information about : • Activation-specific variables • Return address (or pointer to the current instructions) • Link to caller’s activation record IT 327

  9. Block Activation Records • When a block is entered, space (memory) must be found for the local variables of that block • Possibile implementations: • Preallocate in the containing function’s activation record • Extend the function’s activation record when the block is entered (and revert when exited) • Allocate separate block activation records IT 327

  10. Static Allocation • The simplest approach: allocate one activation record for every function, statically • Older dialects of Fortran and Cobol used this system • Simple and fast, but....(what’s the problem?) IT 327

  11. Static activation record Fortran Example FUNCTION AVG (ARR, N) DIMENSION ARR(N)SUM = 0.0 DO 100 I = 1, NSUM = SUM + ARR(I)100 CONTINUEAVG = SUM / FLOAT(N)RETURN END IT 327

  12. Drawback • Each function has one activation record, thus There can be only one activation. Modern languages (including modern dialects Cobol and Fortran) do not obey this restriction for: • Recursion • Multithreading IT 327

  13. Stacks Of Activation Records • To support recursion, we need to allocate a new activation record for each activation • Dynamic allocation: allocate  deallocate • A stack of activation records: stack frames pushpop IT 327

  14. Current Activation Recordthe one for the function that is running • Static: location of activation record was determined before runtime • Dynamic: location of the current activation record is not known until runtime • A function must know how to find the address of its current activation record. A machine register is reserved to hold this IT 327

  15. C Example The evaluation of fact(3)before the 1st recursive call, fact(2) int fact(int n) { int result; if (n<2) result = 1; else result = n * fact(n-1); return result;} .... cout << ... << fact(3) << .... ..... somewhere calling fact(3) IT 327

  16. int fact(int n) { int result; if (n<2) result = 1; else result = n * fact(n-1); return result;} calling fact(2) calling fact(3) After calling fact(2) before calling fact(1) IT 327

  17. int fact(int n) { int result; if (n<2) result = 1; else result = n * fact(n-1);return result;} Beforefact(1)returns calling fact(2) calling fact(3) calling fact(1) IT 327

  18. The second activation is about to return. int fact(int n) { int result; if (n<2) result = 1; else result = n * fact(n-1); return result;} 2 2 1 IT 327

  19. The first activation is about to return with the result fact(3) = 6. int fact(int n) { int result; if (n<2) result = 1; else result = n * fact(n-1); return result;} IT 327

  20. ML Example fun halve nil = (nil, nil)| halve [a] = ([a], nil)| halve (a::b::cs) = let val (x, y) = halve cs in (a::x, b::y) end; halve [1,2,3,4] IT 327

  21. halve [3,4] This shows the contents of memory just before the third activation. fun halve nil = (nil, nil)| halve [a] = ([a], nil)| halve (a::b::cs) = let val (x, y) = halve cs in (a::x, b::y) end; IT 327

  22. halve [] This shows the contents of memory just before the third activation returns. fun halve nil = (nil, nil)| halve [a] = ([a], nil)| halve (a::b::cs) = let val (x, y) = halve cs in (a::x, b::y) end; IT 327

  23. The second activation is about to return. fun halve nil = (nil, nil)| halve [a] = ([a], nil)| halve (a::b::cs) = let val (x, y) = halve cs in (a::x, b::y) end; IT 327

  24. The first activation is about to return with the result halve [1,2,3,4] =([1,3],[2,4]) fun halve nil = (nil, nil)| halve [a] = ([a], nil)| halve (a::b::cs) = let val (x, y) = halve cs in (a::x, b::y) end; IT 327

  25. Nesting Functions • Function definitions can be nested inside other function definitions • Inner functions can refer to local variables of the outer functions (under the usual block scoping rule) • ML, Ada, Pascal provide such feature; • C, Java don’t. (for good reasons) IT 327

  26. An easy solution: further trace down the previous activation record. Called by a recursive call. f(…) { int i = 3; … g(…) … } f(…) { int i = 3; } Called by another inner function g(…) { … g(…)… … i … } g(…) { … g(…)… … i … } h(…) { g(…) … … } int i = 2; What is i in function g? …… h(…) …… The tricky part is that, the previous activation record may not help IT 327

  27. Static Scoping vs Dynamic Scoping static scoping f(…) { int i = 3; } • What is the value of i in function g ? g(…) { … i … } dynamic scoping ……g(…)…… • Static Scoping  • Dynamic Scoping  i = 3 i = 3 h(…) { int i = 2; …… f(…) …… } (h  f  g) IT 327

  28. Static Scoping andNesting Link static scoping For Static Scoping: • An inner function needs to find the address of the most recent activation of the outerfunction, not the caller (caller is for dynamic) • We can keep a nesting linkin the activation record… f(…) { int i = 3; } g(…) { … i … } dynamic scoping ……g(…)…… h(…) { int i = 2; …… g(…) …… } IT 327

  29. Quick Sort in ML fun split nil = (nil,nil) | split [a] = ([a],nil) | split [a,b] = if (a <= b) then ([a],[b]) else ([b],[a]) | split (a::b::c) = let val (x,y) = split (a::c) in if (a < b) then (x, b::y) else (b::x, y) end; fun quicksort nil = nil | quicksort [a] = [a] | quicksort a = let val (x,y) = split a in quicksort(x)@quicksort(y) end; pivot IT 327

  30. Better ML fun quicksort nil = nil| quicksort (pivot::rest) = let fun split(nil) = (nil,nil) | split(x::xs) = let val (below, above) = split(xs) in if x < pivot then (x::below, above) else (below, x::above) end; val (below, above) = split(rest) in quicksort below @ [pivot] @ quicksort above end; IT 327

  31. time Current Activation Record Register Split(…) Split(…) Split(…) QuickSort(…) Return Address Return Address Return Address Return Address Previous Activation Record Previous Activation Record Previous Activation Record Previous Activation Record Split local variable: x, xs, … Split local variable: x, xs, … Split local variable: x, xs, … QuickSort local variable: pivote, rest, … Can’t find pivot here IT 327

  32. time Current Activation Record Split(…) Split(…) Split(…) QuickSort(…) Return Address Return Address Return Address Return Address Previous Activation Record Previous Activation Record Previous Activation Record Previous Activation Record Split local variable: x, xs, … Split local variable: x, xs, … Split local variable: x, xs, … QuickSort local variable: pivote, rest, … Nesting link Nesting link Nesting link Nesting link null 3 3 2 1 The rules to setup the nesting links: 1, 2, 3 IT 327

  33. How to Set Nesting Links • For one level of nesting: • 1. Calling from outer to outer: (non-nesting function, e.g. main calls quicksort) set to null • 2. Calling from outer to inner: (e.g. quicksort calls split, where split is defined inside quicksort) set nesting link same to caller’s activation record • 3. Calling from inner to inner: (e.g. split calls split) set nesting link same to caller’s nesting link IT 327

  34. Multiple Levels Of Nesting f(…) { int fi; } g(…) { int gi; } • References n nesting levels away chain back throughn nesting links h(…) { int hi … … hi, gi, fi } IT 327

  35. Common methods for referring to non-local variables in outer functions • Nesting links in activation records • Displays: no nesting links in the activation records, but collected in a single static array • Lambda lifting: passing all needed variables as parameters (i.e., as hidden parameters) IT 327

  36. Functions As Parameters • What really gets passed? • Source code, compiled code, pointer to code, or implementation in some other form macro expanding OOP objects C’s way functional languages IT 327

  37. Example fun addXToAll (x,theList) = let fun addX y = y + x; in map addX theList end; 5, [2,3,4]  [7,8,9] Nesting link where to? map’s activation record? In the previous example: quicksort (call) split Nesting link addXToAll (call)map, map (call)addX, addX(refers)x (in addXToAll’s activation record) IT 327

  38. When mapaddX, what nesting link will addX be given? • Not map’s activation record: because addX is not nested inside map • Not map’s nesting link: because map is not nested inside any other funcion • Therefore, the parameteraddX passed to map must include the nesting link to use when addX is called, i.e., the nesting link of addx should be prepared when addToAll tries to pass it as an argument to map IT 327

  39. Example Current Activation Record fun addXToAll (x,theList) = let fun addX y = y + x; in map addX theList end; Right before the call tomap. The variable addX is bound to a function-value including code and nesting link. y=>y+x Nesting link IT 327

  40. Not Just For Parameters • Functional languages allow many more kinds of operations on function-values: • passed as parameters, • returned from functions, • constructed by expressions, etc. • Function-values include both code to call, and nesting link to use when calling it IT 327

  41. One More Complication • What happens if a function created is to be returned as a value? fun funToAddX x = let fun addX y = y + x; in addX end; fun test = let val f = funToAddX 3; in f 5 end; return a function that add x IT 327

  42. Current Activation Record fun test = let val f = funToAddX 3; in f 5 end; fun funToAddX x = let fun addX y = y + x; in addX end; y=>y+x Nesting link BeforefunToAddXreturnsaddx. IT 327

  43. Current Activation Record fun test = let val f = funToAddX 3; in f 5 end; fun funToAddX x = let fun addX y = y + x; in addX end; y=>y+x Nesting link AfterfunToAddXreturns, f is the bound to the new function-value. Any Problem ? IT 327

  44. Problem -- This will fail if the language system deallocated that activation record when the function returned Solution: keep all activation records (ML’s way) New problem: waste too much memory Solution: Garbage collection New problem: ?? IT 327

More Related