Principles of Programming Languages

Similar documents
Run-time Environment

G Programming Languages - Fall 2012

! Those values must be stored somewhere! Therefore, variables must somehow be bound. ! How?

Run-time Environments - 2

LECTURE 19. Subroutines and Parameter Passing

Scope, Functions, and Storage Management

COMP 303 Computer Architecture Lecture 3. Comp 303 Computer Architecture

CS 4100 Block Structured Languages. Fixed vs Variable. Activation Record. Activation Records. State of an Activation

CSE Lecture In Class Example Handout

CSc 520 final exam Wednesday 13 December 2000 TIME = 2 hours

Procedure and Object- Oriented Abstraction

Lecture 11: Subprograms & their implementation. Subprograms. Parameters

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

System Software Assignment 1 Runtime Support for Procedures

Anne Bracy CS 3410 Computer Science Cornell University

Run Time Environment. Procedure Abstraction. The Procedure as a Control Abstraction. The Procedure as a Control Abstraction

CA Compiler Construction

Module 27 Switch-case statements and Run-time storage management

Principles of Programming Languages Topic: Scope and Memory Professor Louis Steinberg Fall 2004

Run Time Environment. Activation Records Procedure Linkage Name Translation and Variable Access

Compilation /15a Lecture 7. Activation Records Noam Rinetzky

CIT Week13 Lecture

Anne Bracy CS 3410 Computer Science Cornell University

Lecture 9: Procedures & Functions. CS 540 George Mason University

Control Abstraction. Hwansoo Han

Lecture 5: Procedure Calls

Lecture 7: Binding Time and Storage

Lecture #16: Introduction to Runtime Organization. Last modified: Fri Mar 19 00:17: CS164: Lecture #16 1

Lectures 5. Announcements: Today: Oops in Strings/pointers (example from last time) Functions in MIPS

Compilers and computer architecture: A realistic compiler to MIPS

Programming Languages and Compiler Design

COMP3221: Microprocessors and. and Embedded Systems. Overview. Variable Types and Memory Sections. Types of Variables in C

Run-time Environments

Run-time Environments

Concepts Introduced in Chapter 7

Procedure Call and Return Procedure call

Lecture 7: Procedures and Program Execution Preview

CS 314 Principles of Programming Languages. Lecture 13

Implementing Subprograms

CS153: Compilers Lecture 8: Compiling Calls

Calling Conventions. Hakim Weatherspoon CS 3410, Spring 2012 Computer Science Cornell University. See P&H 2.8 and 2.12

Run-Time Environments

Implementing Procedure Calls

Lecture 5. Announcements: Today: Finish up functions in MIPS

Chapter 2. Computer Abstractions and Technology. Lesson 4: MIPS (cont )

Weeks 6&7: Procedures and Parameter Passing

Contents. Slide Set 2. Outline of Slide Set 2. More about Pseudoinstructions. Avoid using pseudoinstructions in ENCM 369 labs

Functions in MIPS. Functions in MIPS 1

Plan. Regression testing: Demo of how to use the regress.sh script.

Run-time Environments - 3

Chapter 10. Implementing Subprograms

The Activation Record (AR)

CSE 504. Expression evaluation. Expression Evaluation, Runtime Environments. One possible semantics: Problem:

Procedure and Function Calls, Part II. Comp 412 COMP 412 FALL Chapter 6 in EaC2e. target code. source code Front End Optimizer Back End

Topic 7: Activation Records

Code Generation. Lecture 19

G53CMP: Lecture 14. Run-Time Organisation I. Henrik Nilsson. University of Nottingham, UK. G53CMP: Lecture 14 p.1/37

See P&H 2.8 and 2.12, and A.5-6. Prof. Hakim Weatherspoon CS 3410, Spring 2015 Computer Science Cornell University

Procedure Call. Procedure Call CS 217. Involves following actions

Branch Addressing. Jump Addressing. Target Addressing Example. The University of Adelaide, School of Computer Science 28 September 2015

This Lecture. G53CMP: Lecture 14 Run-Time Organisation I. Example: Lifetime (1) Storage Areas

Hakim Weatherspoon CS 3410 Computer Science Cornell University

Lecture Outline. Topic 1: Basic Code Generation. Code Generation. Lecture 12. Topic 2: Code Generation for Objects. Simulating a Stack Machine

CS 314 Principles of Programming Languages

Programming Languages

Typical Runtime Layout. Tiger Runtime Environments. Example: Nested Functions. Activation Trees. code. Memory Layout

Code Generation. The Main Idea of Today s Lecture. We can emit stack-machine-style code for expressions via recursion. Lecture Outline.

We can emit stack-machine-style code for expressions via recursion

CSC 2400: Computer Systems. Using the Stack for Function Calls

143A: Principles of Operating Systems. Lecture 4: Calling conventions. Anton Burtsev October, 2017

Lecture 6: Assembly Programs

CS356: Discussion #6 Assembly Procedures and Arrays. Marco Paolieri

Code Genera*on for Control Flow Constructs

Procedures and Run-Time Storage

143A: Principles of Operating Systems. Lecture 5: Calling conventions. Anton Burtsev January, 2017

Principles of Programming Languages

Code Generation. Lecture 12

CS 61C: Great Ideas in Computer Architecture More MIPS, MIPS Functions

Today. Putting it all together

Separate compilation. Topic 6: Runtime Environments p.1/21. CS 526 Topic 6: Runtime Environments The linkage convention

Programming Language Concepts Scoping. Janyl Jumadinova January 31, 2017

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

Procedures and Run-Time Storage

THEORY OF COMPILATION

Chapter 9 :: Subroutines and Control Abstraction

Course Administration

CSE Lecture In Class Example Handout

238P: Operating Systems. Lecture 3: Calling conventions. Anton Burtsev October, 2018

Scope: Global and Local. Concept of Scope of Variable

CS415 Compilers. Procedure Abstractions. These slides are based on slides copyrighted by Keith Cooper, Ken Kennedy & Linda Torczon at Rice University

Example. program sort; var a : array[0..10] of integer; procedure readarray; : function partition (y, z :integer) :integer; var i, j,x, v :integer; :

Implementing Subroutines. Outline [1]

Intermediate Programming, Spring 2017*

Princeton University Computer Science 217: Introduction to Programming Systems. Assembly Language: Function Calls

Compilers and Code Optimization EDOARDO FUSELLA

Compiler Construction Lecture 05 A Simple Stack Machine. Lent Term, Lecturer: Timothy G. Griffin. Computer Laboratory University of Cambridge

LECTURE 14. Names, Scopes, and Bindings: Scopes

Chap. 8 :: Subroutines and Control Abstraction

Compiler Design. Spring Run-Time Environments. Sample Exercises and Solutions. Prof. Pedro C. Diniz

MIPS Functions and Instruction Formats

Transcription:

Principles of Programming Languages Lecture 06 Implementation of Block Structured Languages 1

Activations and Environment Aspects of Subroutines: Static vs Dynamic! Static subroutine: code (``reentrant ) Exactly one subroutine! Subroutine in execution: activation record, AR, activation Many activations of same code possible State of a program in execution! A collection of activations In a stack or in a heap! Contextual relationships among the activations ``environment access pointers & ``control pointers Activation contents! Fixed: program code (shared)! Variable: activation Instruction pointer (ip, ra) also resumption address or return address Control Pointer (dl) also control link, dynamic link Environment pointer (ep, fp) also access link, frame pointer " Local environment (this activation) fp " Nonlocal environment (other activations) sl, static link 2

Contour Diagram (Static) & RT Stack (Dynamic) a Q R b c d S T e Q(); S Q P Assume static binding Calling trace: P, R, Q, T, S, Q, T, S dl = dynamic link to caller at RT control S T sl = static link to statically enclosing activation environment b c b T(); S(); T R Q S T Q Note sl and dl can be far apart Q(); R P R(); 3

Static Nesting Level (snl) and Distance (sd ) snl(a)= 3 sd(a)= 2 a Q R snl(a) = 2 sd(a) = 1 snl = 1 b c d S T b c snl = 2 e b a = b; snl = 2 a = b; snl = 3 e = b; snl = 3 a = b; snl = 0 S T snl(b) = 2 sd(b) = 0 Q snl(b)= 3 sd(b)= 1 snl(b)= 3 sd(b)= 0 R P snl(name declaration) = # of contour lines surrounding declaration snl(name reference) = # contour lines surrounding reference Static Distance of a Symbol Occurrence sd(name occurrence) = # of contours crossed outward from occurrence to declaration = snl(name s occurrence) - snl(that name s decl.) 4

Symbol Table Computes snl Symbol table maps an occurrence of x to! line #! snl (declaration)! Offset among declarations Each name x has an ``address : (line #, snl, offset) Scanner keeps track of! Contour boundaries crossed (e.g. +1 for { & -1 for })! Current name declarations in scope Scanner can therefore! Identify declaration controlling a name occurrence! Replace a name occurrence by pointer to symbol table line # 5

Symbol Table (cont.) Assume for simplicity all variables are int and occupy one address a P # name snl offset type &c Q R b c d S T e e = b; S Q 1 2 3 4 5 P a Q R b 0 1 1 1 2 0 0 1 2 0 int () int int (int) int (int) int b a = b; T 6 7 c d 2 2 1 2 int int b a = b; R 8 9 S T 2 2 3 4 void (int) int (int) c 10 e 3 0 int 11 b 3 0 int a = b; 12 b 2 0 int 13 c 2 1 int 6

Activation Record Stack higher addresses temps saved registers sp stack pointer = next available location dl sl sp fp ra return address dl dynamic link dl sl static link sl locals arguments dl sl fp temps frame pointer = currently executing AR locals 7

Activation Record Stack Model an AR by a struct (pretend all data are int for simplicity) struct AR { int arg[n]; int local[m]; AR* sl; AR* dl; CODE* ra; void* rx; register save area... } Temps are pushed on top (``frame extension ) during execution in the activation record and are abandoned on return Assume stack growth to higher addresses (in reality usually the other way) 8

Registers Special purpose registers: ra, sp, fp General purpose registers divided into two classes! Caller-saves: transient values unlikely to be needed across calls Callee assumes nothing valuable in caller-saves set & can be used at will ( destroyed ) Ex: temp values during expression evaluation in caller Caller saves these during calling sequence and they are restored after subroutine return! Callee-saves: used for local variables and indexes, etc. Caller assumes these registers will not be destroyed by callee Ex: register holding pointer during a list scan Callee saves these in the prologue just after call, and restores in the epilogue just before return 9

Compiler Code Generation What is generated at CT (to be executed at RT):! Upon reference to a variable name x?! In caller before call to subroutine Q & after return to caller the calling sequence?! In callee before execution of body? Prologue! In callee before return to caller? Epilogue Assume we are generating code inside body of a subroutine named P! Compiler maintains a level counter during code generation: curr_level = current static nesting level of site where code is being generated (body of P) 10

Access (Reference) to x inside P From symbol table compiler can compute:! x snl(x), offset(x)! P snl(p)! curr_level = snl(p) + 1 (level at which ref occurs)! sd(x) = curr_level - snl(x) Generate code to compute l-value into lv:! ap = activation record ptr ap = fp; for(i = 0; i < sd(x); i++) ap = ap->sl ; lv = ap + offset(x);! Use lv on LHS of assignment, *lv on RHS 11

Call Q inside P Calling sequence for ``call Q in source Assume arguments passed by value sp->arg[1] = value of argument 1 ;... sp->arg[n] = value of argument n; transmit args fp->ra= resume ; set point to resume execution in caller sp->dl = fp; set callee s return link fp->ry = ry ; ; save caller-saves registers ap = fp; find AR of callee Q s declaration for(i = 0; i < sd(q); i++) ap = ap->sl ; sp->sl = ap; set callee s static link fp = sp; switch to new environment goto entrypoint(q); from symbol table, after Q is compiled resume:! note stack has not been pushed (callee s responsibility) 12

Prologue Code for Subroutine Q Code executed just after caller jumps to callee Note compiler knows size of AR for Q sp = sp + size(ar of Q) ; push stack frame for current activation fp->rx = rx; ; save any callee-saves registers! now sp points to next available stack location! now fp points to subroutine frame base Push could be done by caller (caller knows name of Q at CT)! But this will not work for closures (see below) where caller does not know name of callee at CT 13

Epilogue code for Subroutine Q Code executed just before return to caller Note compiler knows size of AR for Q rx = fp->rx restore any callee-saves registers sp = sp - size(ar of Q) ; pop stack frame for current activation fp = fp->dl; make caller s activation current one ry = fp->ry; ; restore caller-saves registers goto fp->ra; resume execution in caller just after point of call! now sp points to next available stack location! now fp points to frame base of caller 14

Display Method Linked list replaced by array! Replace traversal of static chain by a single memory reference more efficient calculation of non-local environment references At CT, the maximum static nesting level is known; possible snl values are 1.. maxsnl The display is an array D of maxsnl elements D[i] = fp for that part of the environment that is in an AR at snl i Equivalent static chain Executing at snl = 4 D[maxsnl]... D[4] D[3] D[2] D[1] 15

Access (Reference) to x inside P Generate code to compute l-value into lv: lv = *D[snl(x)]+ offset(x)! Use lv on LHS of assignment, *lv on RHS 16

Call Q inside P Q sp Inactive inactive D[u]... P sp fp D[u] disp... fp P...... D[d+1] D[d+1] D[d] D[d] Before call Q Executing at snl = u in P Subr. Q defined at snl = d u After call Q Executing at snl = d + 1 (body of Q one level deeper) D[d+1] overwritten to point to new AR 17

Call Q inside P (cont.) Q defined at snl d new AR executes at snl d+1 D[d+1] points to new AR for Q Old D[d+1] (dotted link) destroyed Saved in caller s AR (since part of caller s display)! New AR field fp->disp Other elements D[i] where i d + 2 left alone! An AR deeper in the stack might need them upon return 18

Call Q inside P (cont.) Calling sequence for ``call Q in source Let u = snl(p) & d = snl(q)! Note fp == D[u] sp->arg[1] = value of argument 1 ; transmit args... sp->arg[n] = value of argument n; fp->ra= resume ; set return point in caller sp->dl = fp; set callee s return link fp->ry = ry; ; save caller-saves registers fp->disp = D[d+1]; save caller s display entry to reset on return D[d+1] = sp; set display for callee; D[1..d]are shared fp = sp; switch to callee environment goto entrypoint(q); from symbol table, after Q is compiled resume: 19

Prologue/Epilogue code for Subroutine Q Prologue same as before sp = sp + size(ar of Q) ; push stack frame for current activation fp->rx = rx; ; save any callee-saves registers Epilogue restores caller s display! Let u = snl(q) this is known to compiler rx = fp->rx; ; restore callee-save registers sp = sp - size(ar of Q) ; pop stack frame for current activation fp = fp->dl; make caller s activation current D[u] = fp->disp; restore caller s display ry = fp->ry; ; restore caller-saves registers goto fp->ra; resume execution in caller just after point of call 20

Costs: Static Chain vs Display Compare count of memory references! Exclude argument transmission, reg. saves (common to both)! Assume fp, sp held in registers Analyze calling sequence for static chain instruction # refs fp->ra= resume ; 1 sp->dl = fp; 1 sp->ry = ry; ; - ap = fp; 0 for(i = 0; i < sd(q); i++) ap = ap->sl; sd(q) sp->sl = ap; 1 fp = sp; 0 goto entrypoint(q); 0 sd(q)+3 21

Costs (cont.) Comparison by # memory references: Operation Static chain Display Access local l-value Access nonlocal x l-value Call Q 1 sd(x) sd(q)+ 3 1 2 5 Q Prologue 0 0 Q Epilogue 3 5 Need lots of sd(x)> 2 & sd(q)> 2 to make worth it 22

Funargs (Procedure/Function Arguments) P U R void P(int x); x void U(int F(int)); F T F(2); void R(); R(); y U(P); U(T); function formal void R(int y); T P U R function actual P P Consider call U(T); (both U and T are visible in body of R) T is not visible to U no T activation in the static chain of U at the call T(2) in U, cannot locate definition environment of T! How is the call F(2) implemented?! Must work for any F actual What is passed to U in U(T)? 23

Funargs (cont.) Consider call F(2); Previous calling sequence cannot be used. Missing information shown in blue: sp->arg[1] = value of argument 1 ; ; transmit args fp->ra= resume ; set return point in caller sp->dl = fp; fp->ry = ry ; ; ap = fp; set callee s return link save caller-saves registers find AR of callee F s declaration for(i = 0; i < sd(f); i++) ap = ap->sl ; sp->sl = ap; fp = sp; set callee s static link switch to new environment goto entrypoint(f); from symbol table, after F is compiled esume: Don t know what F really is at CT and don t know sd(f) and entrypoint(f) 24

Calling a Formal: F( ); inside U(F) sd(f) is unknown at CT At RT, the actual functional argument need not even be in U s static chain it is inaccessible from the current AR environment of definition of each funarg must be passed to U as part of actual argument A funarg or closure is a pair (ip, ep) where:! ip = entry address of the actual argument procedure! ep = reference to most recent activation of definition environment of actual argument procedure 25

Closure Implementation A closure is a pair of references: struct CL { CODE* ip; instruction pointer (entrypoint) AR* ep; environment pointer } Closure f is built in caller when a named procedure is passed as an actual f is copied to callee U as actual corresponding to formal F : effectively ``F = f When U calls F, the static link in the new activation is set by sp->sl = F.ep and the jump is by goto F.ip 26

Call F inside U Calling sequence for ``call F in source where F is a function formal sp->arg[1] = value of argument 1 ; transmit args... sp->arg[n] = value of argument n; fp->ra= resume ; set return point to resume execution sp->dl = fp; set callee s return link fp->ry = ry ; ; save caller-save registers ap = fp; find AR of callee Q s declaration for(i = 0; i < sd(q); i++) ap = ap->sl ; sp->sl = F.ep; set callee s static link fp = sp; switch to new environment goto F.ip; entrypoint of code of actual resume: 27

Constructing and Passing Closure Consider call U(T)in AR for R Case: actual proc T is visible, named proc & so is U sp->arg[1].ip = entrypoint(t); fp->ra= resume ; set return point to resume execution sp->dl = fp; set callee s return link fp->ry = ry ; ; save caller-save registers ap = fp; find AR of argument T s declaration for(i = 0; i < sd(t); i++) ap = ap->sl ; sp->arg[1].ep = ap; environment of T set in callee ap = fp; for(i = 0; i < sd(u); i++) ap = ap->sl ; sp->sl = ap; set callee s static link fp = sp; switch to new environment goto entrypoint(u); from symbol table resume: 28

Prologue/Epilogue Code Same as for ``named calls, since code is generated once for each possible named actual such as T Information for allocation/deallocation known at CT for T 29

Calls with Formal Procedures: Cases Let F, F name formal functional parameters and let U name a visible, actual proc Discuss implementation of calling sequences for each of:! U(F);! F(T);! F(F ); 30

Calls with Formal Procedures: F(T) Call to a formal proc with an actual visible named proc sp->arg[1].ip = entrypoint(t); ap = fp; find AR of argument T s declaration for(i = 0; i < sd(t); i++) ap = ap->sl ; sp->arg[1].ep = ap; environment of T set in callee fp->ra= resume ; set return point to resume execution sp->dl = fp; set callee s return link fp->ry = ry ; ; save caller-save registers ap = fp; for(i = 0; i < sd(f); i++) ap = ap->sl ; sp->sl = ap; set callee s static link sp#sl = F.ep; set callee s static link fp = sp; switch to new environment goto F.ip; from closure of F resume: 31

Challenge Can we implement functional parameters using the display?! Where does F get its display? (No static chain to unravel given only a starting environment F.ep)! How is display restored upon return? 32

Blocks Extend existing environment: { int x;... } Special case of subroutine:! No parameters! No name! Called in one place where defined! Statically prior env. (surrounding block) == dynamically prior surrounding void function B(); { float x,y; { float x, y; x = z; y = 3; x = z; y = 3; w = y; w = y; } } block surrounding B(); block 33

Block Activation/Deactivation A block is like a procedure, but! Nameless (because called from only one place)! Parameterless! Defined at its point of invocation (inline text)! Same static binding rules apply (static link == dynamic link) sp->sl = fp; set callee s return link fp = sp; switch to new environment sp = sp + size(ar of B) ; push stack frame for block activation entrypoint(b):... Body of B... sp = sp - size(ar of B) ; pop stack frame for current activation fp = fp->sl; reactivate containing block resume: Why are references in body of B resolved correctly? Can remove need for new AR by allowing caller s AR to grow and shrink 34

Exercise! Show how to handle block entry/exit with using the display method Q sp D[u+1] D[u]...... P sp fp D[u+1] D[u]... disp... B P fp Before block B entry Executing at snl = u in P After block B entry Executing at snl = u + 1 (body of B one level deeper) D[u+1] overwritten to point to new AR 35

Solution to Exercise: fp->disp = D[u+1]; save caller s display entry D[u+1] = sp; set callee s display fp = sp; switch to new environment sp = sp + size(ar of B) ; push stack frame for block activation entrypoint(b):... Body of B... sp = sp - size(ar of B) ; pop stack frame for current activation fp = D[u]; reactivate containing block optimization fp = sp - size(ar of P) ; D[u+1] = fp->disp; reactivate containing block restore caller s display resume: 36

Non-local goto s label L B C D D C B A D C B A sp fp A sp fp C(); {... goto L;... } D(); { B(); L: print x; } sd(l) = snl(use L) snl(def L) = snl(d)+1 snl(l) ap = fp; for(i = 0; i < sd(l); i++) ap = ap->sl ; fp = ap; sp = fp + size(ar of A) ; goto address(l); What if display is used? How restore environment of A? 37

Label Scope Rules Vary /* In C, labels have entire function as scope */ #include <stdio.h> main() { int i = 3; int n = 10; printf("before forward jump i = %d\n", i); goto fore; back: printf("after back jump i = %d\n", i); if (n < 3) { int i = 7; int j = 13; fore: i = i + 1; printf("after forward jump i = %d\n", i); printf("after forward jump j = %d\n", j); goto back; } else { int i = 99; printf("after else i = %d\n", i); } printf("before return i = %d\n", i); } 38

Label Scope Rules (cont.) opu> cc labels.c opu> a.out before forward jump i = 3 after forward jump i = 1 after forward jump j = 0 after back jump i = 3 after else i = 99 before return i = 3 opu> 39

Returned Subroutines main() { int(int) makemult(int n) { int t(int x){ return n*x; }; return t; } int(int) f; int y; f = makemult(3); y = f(2); } 40

Returned Subroutines (cont.) code Before call to makemult(3)! null pointer = frame pointer = At prologue of makemult(3) main makemult ra dl sl f y ra dl sl n 3 fp fp fp At return from makemult(3) main ra dl sl f y (closure): typically in register ep ip... r0 = makemult(3) f = r0... code r0 = x r1 = n r0 = mul r0 r1 41

Returned Subroutines (cont.) After assignment f =... fp At prologue of call f(2) main main ra dl sl f y ra dl sl f y makemult ra makemult ra dl sl n 3 dl sl n 3 ep ep ip ip f ra dl sl Note static and dynamic links differ x 2 fp... r0 = makemult(3) f = r0 r0 = f(2) r0 = x r1 = n r0 = mul r0 r1 r0 = x r1 = n r0 = mul r0 r1 code 42

Returned Subroutines (cont.) After assignment y = f(2) main ra dl sl f makemult ra dl sl n 3 fp y 6 ep ip r0 = x r1 = n r0 = mul r0 r1 The AR for makemult(3) is never ``popped while main() is active! main activation refers to a function value f! functional value f requires definition of n in makemult AR! function f in environment can be called again many times So lifetime of makemult AR is lifetime of main ARs now managed on a heap, along with closures 43