Lecture Outline Code Generation (II) Adapted from Lectures b Profs. Ale Aiken and George Necula (UCB) Allocating temporaries in the Activation Record Let s optimie cgen a little Code generation for OO languages Object memor laout Dnamic dispatch Parameter passing mechanisms call-b-value, call-b-reference, call-b-name CS78(Prasad) LCG CS78(Prasad) LCG Revie An Optimiation: Allocate Space for Temporaries in the Activation Record (AR) Topic I CS78(Prasad) LCG The stack machine has activation records and intermediate results interleaved on the stack AR These get put here hen e evaluate compound Temporaries eprs like e + e (hen e AR need to store value of e Temporaries hile evaluating e ) Advantage: Simple code generation Disadvantage: Slo code Storing/loading temporaries requires a store/load and $sp adjustment CS78(Prasad) LCG cgen(e ) ; eval e s $a ($sp) ; save its value addiu $sp $sp - ; adjust $sp (!) cgen(e ) ; eval e l $t ($sp) ; get e An Optimiation Idea: Predict ho $sp ill move at run time Do this prediction at compile time Move $sp to its limit, at the beginning The code generator must staticall assign a location in the AR for each temporar ; $a = e + e addiu $sp $sp ; adjust $sp (!) CS78(Prasad) LCG CS78(Prasad) LCG 6
Improved Code Old method cgen(e ) s $a ($sp) addiu $sp $sp - cgen(e ) l $t ($sp) addiu $sp $sp Ne idea cgen(e ) s $a?($fp) staticall allocate cgen(e ) l $t?($fp) Eample def add(,,,) = + ( + ( +.f())) What intermediate values are placed on the stack? Ho man slots are needed in the AR to hold these values? CS78(Prasad) LCG 7 CS78(Prasad) LCG 8 Ho man Stack Slots? Let NS(e) = # of slots needed to evaluate e Includes slots for arguments to methods E.g: NS(e + e ) Needs at least as man slots as NS(e ) Needs at least one slot to hold value of e, plus as man slots as NS(e ), i.e., + NS(e ) Space used for temporaries in e can be reused for temporaries in e CS78(Prasad) LCG 9 The Equations NS(e + e ) = ma(ns(e ), + NS(e )) NS(e -e ) = ma(ns(e ), + NS(e )) NS(if e = e then e else e ) = ma(ns(e ), + NS(e ), NS(e ), NS(e )) NS(f(e,,e n )) = ma(ns(e ), + NS(e ), + NS(e ),, (n-) + NS(e n ), n) NS(int) = NS(id) = Rule for f(e,, e n ): Each time e evaluate an argument, e put it on the stack. CS78(Prasad) LCG The Revised Activation Record Picture: Activation Record For a function definition f(,, n ) = e the AR has + NS(e) elements Return address Frame pointer NS(e) locations for intermediate results Note that f s arguments are no considered to be part of its caller s AR CS78(Prasad) LCG popped b callee FP FP increasing values of addresses n Old FP Return Addr. Temp NS(e) Temp direction of stack groth pushed b caller saved b callee (this diagram disagrees slightl ith earlier lecture: here, the callee saves FP)
Revised Code Generation Code generator must kno ho man slots are in use at each point Add a ne argument to code generator: the position of the net available slot The slots for temporar values are still used like a stack, but e predict usage at compile time This saves us from doing that ork at run time Allocate all needed slots at the start of method Improved Code Old method cgen(e ) s $a ($sp) addiu $sp $sp - cgen(e ) l $t ($sp) addiu $sp $sp Ne method cgen(e + e, ns) = cgen(e, ns) s $a ns($fp) static allocation cgen(e, ns- ) l $t ns($fp) compile-time prediction CS78(Prasad) LCG CS78(Prasad) LCG OO code generation and memor laout Code Generation for OO Languages Topic II Ho are objects represented in memor? Ho is dnamic dispatch implemented? OO Slogan: If C (child) is a subclass of P (parent), then an instance of class C can be used herever an instance of class P is epected This means that P s methods should ork ith an instance of class C (code reuse) CS78(Prasad) LCG CS78(Prasad) LCG 6 Object Representation class P : Int <- ; : String <- Hi ; : Int ; : Bool <- true; : String ; ; Wh method pointers? Wh the tag? self tag: P Hi P.f: return self [] true P.g: return self [] self To call f: dnamic dispatch l $t ($s) jalr $t case CS78(Prasad) LCG 7 Subclass Representation class P.. (same).. ; self class C inherits P P : Int <- 6; // ne : Int ; // override : Bool ; // ne ; C overridden Hi C.f: return self [6] true P.g: return self [] 6 C.h: return self [] inherited To call f: l $t ($s) CS78(Prasad) LCG jalr $t 8 Idea: Append ne fields 6 7
Subclasses (Cont.) The offset for an attribute is the same in an instance of a class and all of its subclasses An method for an A can be used on a subclass A Consider laout for A n < < A < A < A Header A attrs A attrs A attrs A object A object A object What about multiple inheritance? LCG 9 Simple Just append subclass fields Efficient Code can ignore dnamic tpe -- just act as if it is the static tpe Supports overriding of methods Just replace the appropriate dispatch pointers We implement tpe conformance (compile- time concept) ith representation conformance (run- time concept) CS78(Prasad) LCG An optimiation: Dispatch Tables Observation Consider instances of class C: C.h: return self [] C.f: return self [6] P.g: return self [] Ever instance of a given class has the same values for all of its method pointers Space optimiation: Put all method pointers for a given class into a common table, called the dispatch table Each instance has a pointer to the dispatch table CS78(Prasad) CS78(Prasad) LCG Picture ith Dispatch Table Subclassing Again Consider again instances of C: Objects are smaller Dispatch is sloer C.f: return self [] P.g: return self [] C.h: return self [] minor point: the offsets have changed since e removed the method ptrs CS78(Prasad) LCG P.f: return self [] call f: l $t ($s) l $t ($t) jalr $t tag: P P.g: return self [] C.f: return self [] C.h: return self []
Real COOL Object Laout Actuall, the first ords of Cool objects contain header information: Needed for garbage collector Class Tag Object Sie Dispatch Ptr Attribute Attribute Offset (in btes) 8 6 Parameter Passing Mechanisms Topic III CS78(Prasad) LCG CS78(Prasad) LCG 6 Parameter Passing Mechanisms There are man semantic issues in programming languages centering on hen values are computed, and the scopes of names Evaluation is heart of computation Names are most primitive abstraction mechanism We ll focus on parameter passing When are arguments of function calls evaluated? What are formal parameters bound to? CS78(Prasad) LCG 7 Call-b-value C uses call- callbvalue(int ) = + ; print(); int = ; print(); callbvalue(); print(); b- value everhere (ecept macros...) output: = = = s value does not change hen s value is changed CS78(Prasad) LCG 8 Call-b-reference Available in C++ ith the & tpe constructor callbref(int &) = + ; print(); int = ; print(); callbref(); print(); output: = = = s value changes hen s value is changed CS78(Prasad) LCG 9 Call-b-reference can be faked ith pointers C++: C: callbref(int &) = + ; print(); int = ; print(); callbref(); print(); fakecallbref(int *) * = * + ; print(*); must eplicitl take the address of a local variable int = ; print(); fakecallbref(&); print(); CS78(Prasad) LCG
Pointers to fake call-b-reference (cont.) It s not quite the same A pointer can be reassigned to point at something else; a C++ reference cannot The pointer itself as passed b value This is ho ou pass structures in C What about Java? Primitive tpes (int, boolean, etc.) are alas passed b value Objects are not quite -b-value nor -b-reference: If ou reassign an object reference, the caller s argument does not get reassigned (like -b-value) But if ou modif the object referred-to, the caller ill see that modification (like -b-reference) It s reall ordinar call-b-value ith pointers, but the pointers are not sntacticall obvious. COOL is the same a. CS78(Prasad) LCG CS78(Prasad) LCG Call-b-name Whole different ballgame: it s like passing the tet of the argument epression, unevaluated Also passes the environment, so free variables are still bound according to rules of static scoping The argument is not evaluated until it is actuall used, inside the callee. Might not get evaluated at all! Used in some functional languages (e.g. Haskell) CS78(Prasad) LCG Call-b-name eample (in C++-Etra ) callbname(int closure ) eval print(); print(); // => print( = +) int = ; print(); callbname( [[ = + ]] ); print(); closure code + environment (env has just here) both evals have side effects output: = = = = s value changes hen is evaluated CS78(Prasad) LCG