Lecture #24: Achieving Runtime Effects—Functions

Lecture #24: Achieving Runtime Effects—Functions

Lecture #24: Achieving Runtime Effects—Functions • Language design and runtime design interact. Semantics of func- tions make good example. • Levels of function features: 1. Plain: no recursion, no nesting, fixed-sized data with size known by compiler. 2. Add recursion. 3. Add variable-sized unboxed data. 4. Allow nesting of functions, up-level addressing. 5. Allow function values w/ properly nested accesses only. 6. Allow general closures. 7. Allow continuations. • Tension between these effects and structure of machines: – Machine languages typically only make it easy to access things at addresses like R + C, where R is an address in a register and C is a relatively small integer constant. – Therefore, fixed offsets good, data-dependent offsets bad. Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 1 1: No recursion, no nesting, fixed-sized data • Total amount of data is bounded, and there is only one instantiation of a function at a time. • So all variables, return addresses, and return values can go in fixed locations. • No stack needed at all. • Characterized FORTRAN programs in the early days. • In fact, can dispense with call instructions altogether: expand func- tion calls in-line. E.g., def f (x): x *= 42 x_1 = 3 y=9+x; =⇒ =⇒ x_1 *= 42 g (x, y) becomes y_1 = 9 + x_1 g (x_1, y_1) f (3) • However, program may get bigger than you want. Typically, one in- lines only small, frequently executed functions. Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 2 2: Add recursion Top of stack f’s • Now, total amount of data is un- locals fixed distance bounded, and several instantiations of ra Base of a function can be active simultaneously. arguments 1st frame • Calls for some kind of expandable data to f structure: a stack. g’s • However, variable sizes still fixed, so locals size of each activation record (stack ra frame) is fixed. arguments to g • All local-variable addresses and the value of dynamic link are known offsets f’s from stack pointer, which is typically in locals a register. ra . Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 3 Calling Sequence when Frame Size is Fixed Top of stack f’s • So dynamic links not really needed. locals fixed distance ra Base of • Suppose f calls g calls f, as at right. arguments 1st frame • When called, the initial code of g (its to f prologue) decrements the stack pointer g’s by the size of g’s activation record. locals • g’s exit code (its epilogue): ra arguments – increments the stack pointer by this to g same size, f’s – pops off the return address, and locals – branches to address just popped. ra . Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 4 3: Add Variable-Sized Unboxed Data • “Unboxed” means “not on heap.” • Boxing allows all quantities on stack to Top of stack have fixed size. unboxed storage • So Java implementations have fixed- other size stack frames. locals • But does cost heap allocation, so local some languages also provide for placing pointer variable-sized data directly on stack DL (“heap allocation on the stack”) ra Frame pointer arguments • alloca in C, e.g. to g • Now we do need dynamic link (DL). f’s • But can still insure fixed offsets of locals data from frame base (frame pointer) DL ra using pointers. • To right, f calls g, which has variable- sized unboaxed array (see right). Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 5 Other Uses of the Dynamic Link • Often use dynamic link even when size of AR is fixed. • Allows use of same strategy for all ARs, simplifies code generation. • Makes it easier to write general functions that unwind the stack (i.e., pop ARs off, thus returning). Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 6 4: Allow Nesting of Functions, Up-Level Addressing • When functions can be nested, there are three classes of variable: Top of stack a. Local to function. g’s b. Local to enclosing function. frame c. Global . • Accessing (a) or (c) is easy. It’s (b) g’s How far??? that’s interesting. frame • Consider (in Pyth or Python): def f (): g’s y = 42 # Local to f frame def g (n, q): Enclosing f if n == 0: return q+y f’s else: return g (n-1, q*2) frame • Here, y can be any distance away from top of stack. Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 7 Static Links • To overcome this problem, go back to environment diagrams! Top of stack • Each diagram had a pointer to g’s frame SL lexically enclosing environment DL • In Pyth example from last slide, ra g’s frame each ‘g’ frame contains a pointer SL to the ‘f’ frame where that ‘g’ DL was defined: the static link (SL) ra g’s frame • To access local variable, use SL frame-base pointer (or maybe DL ra stack pointer). f’s frame • SL To access global, use absolute DL address. ra • To access local of nesting func- . tion, follow static link once per difference in levels of nesting. Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 8 The Global Display • Historically, first solution to nested function problem used an array indexed by call level, rather than static links. def f0 (): q = 42; g1 () def f1 (): def f2 (): ... g2 () ... def g2 (): ... g2 () ... g1 () ... def g1 (): ... f1 () ... g1 1 • Each time we enter a function at lexical level k f0 0 (i.e., nested inside k functions), save pointer to its frame base in DISPLAY[k]; restore on exit. • Access variable at lexical level k through g1’s DISPLAY[k]. frame • Relies heavily on scope rules and proper f0’s DISPLAY function-call nesting frame Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 9 The Global Display • Historically, first solution to nested function problem used an array indexed by call level, rather than static links. def f0 (): q = 42; g1 () def f1 (): def f2 (): ... g2 () ... def g2 (): ... g2 () ... g1 () ... def g1 (): ... f1 () ... f1 1 • Each time we enter a function at lexical level k f0 0 (i.e., nested inside k functions), save pointer to f1’s its frame base in DISPLAY[k]; restore on exit. frame • Access variable at lexical level k through g1’s DISPLAY[k]. frame • Relies heavily on scope rules and proper f0’s DISPLAY function-call nesting frame Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 9 The Global Display • Historically, first solution to nested function problem used an array indexed by call level, rather than static links. def f0 (): q = 42; g1 () def f1 (): def f2 (): ... g2 () ... def g2 (): ... g2 () ... g1 () ... def g1 (): ... f1 () ... f1’s f1 1 • Each time we enter a function at lexical level k frame f0 0 (i.e., nested inside k functions), save pointer to f1’s its frame base in DISPLAY[k]; restore on exit. frame • Access variable at lexical level k through g1’s DISPLAY[k]. frame • Relies heavily on scope rules and proper f0’s DISPLAY function-call nesting frame Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 9 The Global Display • Historically, first solution to nested function problem used an array indexed by call level, rather than static links. def f0 (): q = 42; g1 () def f1 (): def f2 (): ... g2 () ... f2’s def g2 (): ... g2 () ... g1 () ... frame def g1 (): ... f1 () ... f2 2 f1’s f1 1 • Each time we enter a function at lexical level k frame f0 0 (i.e., nested inside k functions), save pointer to f1’s its frame base in DISPLAY[k]; restore on exit. frame • Access variable at lexical level k through g1’s DISPLAY[k]. frame • Relies heavily on scope rules and proper f0’s DISPLAY function-call nesting frame Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 9 The Global Display • Historically, first solution to nested function problem used an array indexed by call level, rather than static links. def f0 (): q = 42; g1 () g2’s def f1 (): frame def f2 (): ... g2 () ... f2’s def g2 (): ... g2 () ... g1 () ... frame def g1 (): ... f1 () ... g2 2 f1’s f1 1 • Each time we enter a function at lexical level k frame f0 0 (i.e., nested inside k functions), save pointer to f1’s its frame base in DISPLAY[k]; restore on exit. frame • Access variable at lexical level k through g1’s DISPLAY[k]. frame • Relies heavily on scope rules and proper f0’s DISPLAY function-call nesting frame Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 9 The Global Display • Historically, first solution to nested function problem used an array indexed by call level, rather than static links. g2’s frame def f0 (): q = 42; g1 () g2’s def f1 (): frame def f2 (): ... g2 () ... f2’s def g2 (): ... g2 () ... g1 () ... frame def g1 (): ... f1 () ... g2 2 f1’s f1 1 • Each time we enter a function at lexical level k frame f0 0 (i.e., nested inside k functions), save pointer to f1’s its frame base in DISPLAY[k]; restore on exit. frame • Access variable at lexical level k through g1’s DISPLAY[k]. frame • Relies heavily on scope rules and proper f0’s DISPLAY function-call nesting frame Last modified: Mon Mar 31 10:58:48 2008 CS164: Lecture #24 9 The Global Display • Historically, first solution to nested function g1’s problem used an array indexed by call level, frame rather than static links.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    23 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us