More on Rntime Environments How to efficiently implement procedre call and retrn in the presence of higher-order fnctions? 1. what are higher-order fnctions? 2. how to ext frames to spport higher-order fnctions? 3. efficiency isses (exection time, space sage)? How to efficiently spport memory allocation and de-allocation? 1. what are the data representations? 2. what are the memory layot? 3. explicit vs implicit memory de-allocation? (malloc-free vs. garbage collection) rocedre arameters (in ascal) rocedre parameters permit procedres to be invoked ot-of-scope ; 1 program main(inpt, otpt); 2 3 procedre b(fnction h(n : integer): integer); 4 var m : integer; 5 begin m := 6; writeln(h(2)) ; 6 7 procedre c; 8 var m : integer; 9 fnction f(n: integer): integer; 10 begin f := m + n ; 11 begin m := 0; b(f) ; 12 begin c. Qestion: how to get the correct environment when calling h inside b? Soltion: mst pass static link along with f as if it had been called at the point it was passed (line 11). Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 1 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 2 of 32 Restrictions in C & ascal C does not allow nested procedres --- names in C are either local to some procedre or are global and visible in all procedres. rocedres in C can be passed as argments or retrned as reslts. program conter Traditional Stack Scheme STACK (activation records) parameters and retrned vales ascal (or Modla-2, Modla-3, Algol ) allows procedre declarations to be nested, bt procedre parameters are of restricted se, and procedres cannot be retrned as reslt. Fnctional langages (e.g. ML, Haskell, Scheme, Lisp) spport higherorder fnctions --- spporting both nested procedres and procedres passed as parameters or retrned as reslts. code REGISTERS HEA (dynamic data) STATIC (code and globals) links and saved stats temporaries and local data Activation Record garbage collector spporting it is a big challenge to the compiler writers! Memory Layot Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 3 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 4 of 32
rocedre Activations rocedre Activations (cont d) ested Fnctions in ML val BIG = big()... (v,,,y)... in... Q()... val reslt = (BIG,0,0,0) control links v=big w=x=y=0 Q, R access links ested Fnctions in ML val BIG = big()... (v,,,y)... in... Q()... val reslt = (BIG,0,0,0) control links v=big w=x=y=0 Q, R v=v,w= x=,y=y Q, access links Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 5 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 6 of 32 Higher-Order Fnctions Higher-Order Fnctions (cont d) How to create a closre for Q? v=big w=x=y=0 Q lost track of its environment val reslt = S() Q val reslt = S() Q Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 7 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 8 of 32
Higher-Order Fnctions (cont d) Higher-Order Fnctions (cont d) Q mst copy the frame! v=big w=x=y=0 Q s environment is in the! val reslt = S() val reslt = S() Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 9 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 10 of 32 Applying Higher-Order Fnctions ested Higher-Order Fnctions Accessing the Closre Q! val reslt = S() Qor S R val reslt = T() Qor S R Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 11 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 12 of 32
Linked Closres Flat Closres R or T R or T val reslt = T() R val reslt = T() R w x y copying!!! Fast creation, Slow access! Slow creation, Fast access! Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 13 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 14 of 32 Better Representations? Closres cannot point to frame (different life time, so yo mst copy.) Linked closres --- fast creation, slow access Flat closres --- slow creation, fast access Stack frames with access links are similar to linked closres (accessing non-local variables is slow.) GOAL : We need good closre representations that have both fast access and fast creation! Space Usage Space Leaks for Linked Closres (,w+x+y+3) fn loop (n,res) = if n<1 then res else ( val S = (big(),0,0,0) in loop(n-1,t::res) ) val reslt = loop(,[]) Linked Closres : O( 2 ) R -1 Flat Closres : O() R w x y Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 15 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 16 of 32
Space Usage (cont d) Better Space Usage? Space Leaks for Stack Allocations fn (x) =... fn Q(n) = val = big(n) val v = () val w = hd() in if n > 0 then Q(n-1)+v(w) else... val reslt = Q() Q,v,w n= Q,v,w n=-1 Q,v,w n=-2-1 -1-2 -2-3 Use O( 2 ) Space! is dead after this call! The safe for space complexity rle : Local variable mst be assmed dead after its last se within its scope! Stacks and linked closres are OT safe for space Flat closres are safe for space SML/J : nsafe version = (2 to 80) x safe version Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 17 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 18 of 32 Drawbacks of Stack Allocation inefficient space sage slow access to non-local variables expensive copying between and (activation records cannot be shared by closres) scanning roots is expensive in generational GC very slow first-class continations (call/cc) correct implementation is complicated and messy Efficient Heap-based Compilation An efficient -based scheme has the following advantages: very good space sage (safe for space complexity!) very fast closre creation and closre access closres can be shared with activation records fast call/cc and fast generational GC simple implementation Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 19 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 20 of 32
re Heap-based Scheme Safely Linked Closres Safe for Space : se O() space THE TRICK: program conter code REGISTERS HEA (dynamic data) (activation records) STATIC (code and globals) Memory Layot Ideas: no rntime! safely linked closres good se of registers garbage collector (,w+x+y+3) fn loop (n,res) = if n<1 then res else ( val S = (big(),0,0,0) in loop(n-1,t::res) ) val reslt = loop(,[]) Variables w,x,y have same life time! R Q v -1 w x y Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 21 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 22 of 32 Safely Linked Closres (cont d) Shorter Access ath! fn S() = w+x+y+3 in (S,) val T = (big(),0,0,0) THE TRICK: Variables w,x,y have same life time! R Q v S w x y Good Use of Registers To avoid memory traffic, modern compilers often pass argments, retrn reslts, and allocate local variables in machine registers. Typical parameter-passing convention on modern machines: the first k argments ( k = 4 or 6) of a fnction are passed in registers R p,..., R p+k-1, the rest are passed on the. roblem : extra memory traffic cased by passing args. in registers fnction g(x : int, y : int, z :int) : int = x*y*z fnction f(x : int, y : int, z : int) = val a := g(z+3, y+3, x+4) in a*x+y+z The nmber of links traversed is at most 1. -1 Sppose fnction f and g pass their argments 1, R 2, R 3 ; then f mst save R 1, R 2, and R 3 to the memory before calling g, Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 23 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 24 of 32
Good Use of Registers (cont d) how to avoid extra memory traffic? Leaf procedres (or fnctions) are procedres that do not call other procedres; e.g, the fnction exchange. The parameters of leaf procedres can be allocated in registers withot casing any extra memory traffic. Closres egisters? o! Modle FOO: (in file foo.sml ) fn pred(x) =...v(w,x)... val reslt = BAR.filter(pred,...) Modle BAR : (in file bar.sml ) pred is an escaping fnction! Its closre mst be bilt on the! Use global register allocation, different fnctions se different set of registers to pass their argments. Use register windows (as on SARC) --- each fnction invocation can allocate a fresh set of registers. Allocate closres in registers or se callee-save registers When all fails --- save to the frame or to the. fn filter(p,l) = fn h(s,z) = if (s=[]) then rev z else ( val a = car s val r = cdr s in if p a then h(r,a::z) else h(r,z) ) in h(l,[]) Escaping fnctions: fnctions whose call sites are not all known at compile time! Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 25 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 26 of 32 Closres egisters? es! Lambda Lifting fn filter(p,l) = Known fnctions: fn filter(p,l) = fn h(s,z) = if (s=[]) then rev z else ( val a = car s val r = cdr s in if p a then h(r,a::z) else h(r,z) ) fnctions whose call sites are all known at compile time! h fn h(s,z,rev,p) = if (s=[]) then rev z else ( val a = car s val r = cdr s in if p a then h(r,a::z,rev,p) else h(r,z,rev,p) ) r 0 r 1 r 2 r 3 s z rev p h s=[] in h(l,[]) h is a known fnction! Its closre can be pt in registers! (e.g., {rev,p}) s=[] p a rev z in h(l,[],rev,p) known fnctions can be rewritten into fnctions that are flly closed! (i.e. with no free variables!) p a rev z Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 27 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 28 of 32
Spilled Activation Records Callee-save Registers We do not know how p treats the registers! a::z h r 0 r 1 r 2 r 3 r 4 r 5 s z rev p s=[] r 0 r 1 r 2 r 3 r 4 r 5 r z rev p a Convention : Reserve k special registers! Every fnction promises to always preserve these registers! Example : k=3 (r 4,r 5,r 6 ) f g general registers r 0 r 1 r 2 r 3 g v w g v x callee-save registers r 4 r 5 r 6 A B C w g A B C r 0 r 1 r 2 r 3 r 4 r 5 r rev p a p a Mst save and load everything here! r 0 r 1 r 2 r 3 r 4 r 5 r z rev p a rev z fn f(g,,v,w) = val x = g(,v) val y = g(x,w) in x+y+w g f retrn g x w y w x A B C Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 29 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 30 of 32 Callee-save Registers (cont d) 6 callee-save registers : r 4,r 5,r 6,r 7,r 8,r 9 a::z s=[] r 4 r 5 r 6 r 7 r 8 r 9 p a r rev p a no need to save and load anymore! h r 0 r 1 r 2 r 3 s z rev p r 4 r 5 r 6 r 7 r 8 r 9 s z rev p r 4 r 5 r 6 r 7 r 8 r 9 r z rev p a r 4 r 5 r 6 r 7 r 8 r 9 r z rev p a r 4 r 5 r 6 r 7 r 8 r 9 A B C D E F A B C D E F recover everything! rev z Smmary : A Uniform Soltion Take advantage of variable life time and compiime control flow information! Spilled activation records are also thoght as closres! no rntime ---------- everything is sharable all se safely-linked closres ---------- to maximize sharing pass argments and retrn reslts in registers allocating most closres in registers good se of callee-save registers Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 31 of 32 Copyright 1994-2010 Zhong Shao, ale University More on Rntime Environments: age 32 of 32