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

Similar documents
Run-Time Environments

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

CA Compiler Construction

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

Topic 7: Activation Records

Scope, Functions, and Storage Management

Concepts Introduced in Chapter 7

Run-time Environments

Run-time Environments

Compilers. 8. Run-time Support. Laszlo Böszörmenyi Compilers Run-time - 1

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

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

Compilation 2014 Activation Records

Weeks 6&7: Procedures and Parameter Passing

Compilers and Code Optimization EDOARDO FUSELLA

More on Runtime Environments. Procedure Parameters (in Pascal) Traditional Stack Scheme. Restrictions in C & Pascal. code.

Compilation /15a Lecture 7. Activation Records Noam Rinetzky

Run Time Environments

COMP 303 Computer Architecture Lecture 3. Comp 303 Computer Architecture

Do-While Example. In C++ In assembly language. do { z--; while (a == b); z = b; loop: addi $s2, $s2, -1 beq $s0, $s1, loop or $s2, $s1, $zero

CIT Week13 Lecture

Runtime management. CS Compiler Design. The procedure abstraction. The procedure abstraction. Runtime management. V.

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

Course Administration

Run-time Environment

G Programming Languages - Fall 2012

Run-time Environments. Lecture 13. Prof. Alex Aiken Original Slides (Modified by Prof. Vijay Ganesh) Lecture 13

CS421 COMPILERS AND INTERPRETERS. the point it was passed (line 11). explicit vs implicit memory de-allocation? (malloc-free vs. garbage collection)

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

ECE260: Fundamentals of Computer Engineering

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

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

Compilation 2014 Activation Records (Part 1)

Run-Time Environments

Implementing Subprograms

Intermediate Representations & Symbol Tables

Functions in MIPS. Functions in MIPS 1

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

Intermediate Code Generation. Intermediate Representations (IR) Case Study : itree. itree Statements and Expressions

CS 314 Principles of Programming Languages. Lecture 13

Compiler Theory. (Semantic Analysis and Run-Time Environments)

Compilers and computer architecture: A realistic compiler to MIPS

Functions and Procedures

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

Subroutines. int main() { int i, j; i = 5; j = celtokel(i); i = j; return 0;}

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

Procedure and Object- Oriented Abstraction

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

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

G Programming Languages - Fall 2012

Implementing Subroutines. Outline [1]

Run-Time Environments

CSE Lecture In Class Example Handout

12/4/18. Outline. Implementing Subprograms. Semantics of a subroutine call. Storage of Information. Semantics of a subroutine return

Prof. Kavita Bala and Prof. Hakim Weatherspoon CS 3410, Spring 2014 Computer Science Cornell University. See P&H 2.8 and 2.12, and A.

Procedure Call. Procedure Call CS 217. Involves following actions

Anne Bracy CS 3410 Computer Science Cornell University

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

Procedure Calls Main Procedure. MIPS Calling Convention. MIPS-specific info. Procedure Calls. MIPS-specific info who cares? Chapter 2.7 Appendix A.

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

Code Generation. Lecture 19

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

System Software Assignment 1 Runtime Support for Procedures

Today. Putting it all together

Anne Bracy CS 3410 Computer Science Cornell University

ECE232: Hardware Organization and Design

Control Instructions. Computer Organization Architectures for Embedded Computing. Thursday, 26 September Summary

Control Instructions

Run-time Environments - 2

The Procedure Abstraction

THEORY OF COMPILATION

CS 110 Computer Architecture Lecture 6: More MIPS, MIPS Functions

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

Code Generation & Parameter Passing

Programming Languages Third Edition. Chapter 10 Control II Procedures and Environments

Chapter 10. Implementing Subprograms ISBN

Programming Languages: Lecture 12

Runtime Environments I. Basilio B. Fraguela

Today's Topics. CISC 458 Winter J.R. Cordy

Memory Management and Run-Time Systems

Procedures and Run-Time Storage

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Winter Compiler Construction T11 Activation records + Introduction to x86 assembly. Today. Tips for PA4. Today:

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

Procedures and Run-Time Storage

Chapter 10. Implementing Subprograms

Qualifying Exam in Programming Languages and Compilers

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

LECTURE 19. Subroutines and Parameter Passing

Code Generation. Lecture 12

CS 314 Principles of Programming Languages

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

Informatica 3 Marcello Restelli

CSE 504: Compiler Design. Runtime Environments

Lecture08: Scope and Lexical Address

The Procedure Abstraction Part I: Basics

Machine Language Instructions Introduction. Instructions Words of a language understood by machine. Instruction set Vocabulary of the machine

MIPS Programming. A basic rule is: try to be mechanical (that is, don't be "tricky") when you translate high-level code into assembler code.

Transcription:

Tiger Runtime Environments Compile-time environments are just symbol tables; they are used to assist static semantic analysis, code generation and code optimization. Run-time environments are about how to map each runtime value into the memory? more specifically, here are the main issues how to implement procedure (or function) call? --- stack frames (activation records, access to non-local variables, parameter passing,...) what are the data representations? (primitive data type, records, arrays, dynamic data structure,...) what are the memory layout (i.e., storage organization)? (where to put the static data, code segments, stack, heap?) how to do the memory allocation and de-allocation? (malloc-free package, garbage collection,...) program counter code Typical Runtime Layout REGISTERS STACK (activation records) HEAP (dynamic data) STATIC (code and globals) Memory Layout parameters and returned values links and saved status temporaries and local data Activation Record garbage collector Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 1 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 2 of 24 Example: Nested Functions let type intarray = array of int var a := intarray [9] of 0 function readarray () =... function writearray () =... function exchange(x : int, y : int) = let var z := a[x] in a[x] := a[y]; a[y] := z function quicksort(m : int, n : int) = let function partition(y : int, z : int) : int = let var i := y var j := z + 1 in (while (i < j) do (i := i+1; while a[i] < a[y] do i := i+1; j := j-1; while a[j] > a[y] do j := j-1; if i < j then exchange(i,j)); exchange(y,j); j) Activation Trees main readarray q(0,8) writearray p(0,8) q(0,3) q(5,8) e (1,8) e (2,7) e (4,5) e (0,4) p(0,3) q(0,2) q(4,3) p(5,8) q(5,7) q(9,8) in if n > m then (let var i := partition(m,n) in quicksort(m, i-1); quicksort(i+1, n) ) in readarray(); quicksort(0,8); writearray() input: 10, 32, 567, -1, 789, 3, 18, 0, -51 input: 10, 32, e (0,3) p(0,2) q(0,0) q(2,2) e (6,9) 567, -1, 789, 3, 18, 0, -51 e (0,1) p(5,7) q(5,5) q(8,8) p -> partition q -> quicksort e (5,6) e -> exchange Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 3 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 4 of 24

Activations Each function (or procedure) declaration associates a name with a function body --------- this binding is done at compile time. An activation is created during runtime execution when the function (or procedure) is invoked. The lifetime of an activation is the time between execution of the 1st operation of the body and through the last operation. Activations are either nested or non-overlapping. If two activations are nested, then one must be the descant of another. If two activations are nonoverlapping, then they must be the siblings. A function f is recursive if more than 2 activations of f is nested. Program execution is just depth-first traversal of activation tree! How to implement depth-first traversal? Activation Record An activation record is constructed when a function (or a procedure) is called (activated); it is destroyed when the function returns; the interim is the lifetime of the activation. The activation record often contains the following: relevant machine state (saved registers, return address) space for local data, including temporaries space for return value space for outgoing arguments control link: pointer to caller s activation record (optional) static link: pointer to activation for accessing non-local data Main problem: how to layout the activation record so that the caller and callee can communicate properly? Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 5 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 6 of 24 Stack Frames The most common (and standard) way is to allocate activation records on a sequential stack --- using the following standard frame layout. incoming parameters outgoing parameters argument a n... argument a 2 argument a 1 static link local variables return address temporaries saved registers argument b m... argument b 2 argument b 1 static link previous frame f caller callee current frame g next frame h function f (..)=...g(a 1,...,a n )... frame pointer FP for g function g(..)=...h(b 1,...,b m )... stack pointer SP for g Stack Frames (cont d) Frame Pointer (FP) is a pointer that points to the start of the current frame; Stack Pointer (SP) --- referring to the top of the stack ---- points to the of the current frame. offset -4n-4 argument a n...... -12 argument a 2-8 argument a 1-4 static link 0 4 local variables... return address temporaries saved registers... previous frame f caller callee current frame g frame pointer FP for g stack pointer SP for g All g s arguments and local variables are accessed through FP! Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 7 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 8 of 24

Typical Calling Sequence Question: Suppose function f calls function g(a 1,...,a n ), what will happen at runtime? how f and g communicate? Assuming FP and SP are in two registers. 1. Call sequence (done by the caller f before entering g ) f puts arguments a 1,...,a n onto the stack (or in registers) f puts function g s static link onto the stack (or in a register) f puts the return address of this call to g onto the stack (or in a register) f puts current FP onto the stack (i.e., control link, optional) Jump to g s code 2. Entry sequence (the first thing done after entring the callee g ) move SP to FP decrement SP by the frame size of g (stack grows downwards!!!) (optional: save callee-save registers if any) Typical Calling Sequence (cont d) 3. Return sequence ( the callee g exits and returns back to f ) put the return result into a designated register (optional: restore calleesave registers if any) fetch the return address to a register (if in register, do nothing) fetch the saved FP of f back to the FP register increment SP by the frame size of g (pop off the activation of g) Return back to f Tiger Specifics (also true for many other modern compilers) return address is put in a designated register only maintain SP at runtime (FP is a virtual reg. = SP - framesize) (when implementing Tiger, frame-size of each function is a compile-time constant) Must maintain a separate FP and SP if (1) the frame size of a function may vary (2) the frames are not always contiguous (e.g., linked list) Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 9 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 10 of 24 A Snapshot of Running Quicksort main() a m=0,n=8 q(0,8) i=4 m=0,n=3 q(0,3) i=3 y=0,z=3 p(0,3) i=4,j=3 x=0,y=3 e(0,3) z FP SP Remaining questions: how to find the value of local variables and non-local variables? Local variables are allocated in the current stack frame --- we can access them through the Frame Pointer (notice, the actual value of FP is unknown until runtime, but the each local-variable s offset to FP is known at compile time) Non-local variables must be accessed through the static link, or by using some other tricks... Non-Local Variables let 1 type intarray = array of int var a := intarray [9] of 0 2 function readarray () =... function writearray () =... 2 function exchange(x : int, y : int) = 2 let var z := a[x] in a[x] := a[y]; a[y] := z function quicksort(m : int, n : int) = 2 let function partition(y : int, z : int) : int = 3 let var i := y var j := z + 1 in (while (i < j) do (i := i+1; while a[i] < a[y] do i := i+1; nesting j := j-1; while a[j] > a[y] do j := j-1; depth if i < j then exchange(i,j)); exchange(y,j); j) in if n > m then (let var i := partition(m,n) in quicksort(m, i-1); quicksort(i+1, n) ) in readarray(); quicksort(0,8); writearray() input: 10, 32, 567, -1, 789, 3, 18, 0, -51 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 11 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 12 of 24

main() a m=0,n=8 q(0,8) i=4 m=0,n=3 q(0,3) i=3 y=0,z=3 p(0,3) i=4,j=3 x=0,y=3 e(0,3) z Static Link Static link (also called access link) is used to implement lexical scoping. If function p is nested immediately within q in the source code, then the static link in activation of p is a point to the most recent activation of q. Non-local variable v is found by following static links to an activation (i.e, frame) FP that contains v If v is declared at depth n v and accessed in SP p declared at depth n p, then we need follow n p -n v static links Static Link (cont d) Suppose function q at depth n q calls function p at depth n p. The question is how to access non-local variables once we are inside p? or what is the static link inside p s activation. If n q < n p, then n q = n p -1, p is nested within q; the static link in p s activation = q s activation; e.g., quicksort (2) calls partition (3). If n q >= n p, p and q must have common calling prefix of functions at depths 1,..., n p -1; the static link in p s activation is the activation found by following n q - n p + 1 access links in caller q; e.g., partition (3) calls exchange (2) --- follow 3-2+1=2 links inside partition s activation. Two alternatives to the static link method for accessing non-local variables: 1. Display 2. Lambda-Lifting Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 13 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 14 of 24 Display Lambda-Lifting d[1] d[2] d[3] main() q(0,8) q(0,3) p(0,3) e(0,3) FP SP One alternative to static link is to maintain pointers to the current activation at depth k using a display array d[1...]. Upon entry to p at depth k : save d[k] in p s activation; d[k] = p s activation Upon exit from p at depth k: d[k] = saved d[k] inside p s activation display ---- pros: faster access, constant call/return cost; cons: uses up registers, awkward when functions being passed as arguments. let type intarray = array of int var a := intarray [9] of 0 function readarray (a : intarray) =... function writearray (a : intarray) =... function exchange(a : intarray, x : int, y : int) = let var z := a[x] in a[x] := a[y]; a[y] := z function quicksort(a: intarray, m : int, n : int) = let function partition(a: intarray, y : int, z : int) : int = let var i := y var j := z + 1 in (while (i < j) do (i := i+1; while a[i] < a[y] do i := i+1; j := j-1; while a[j] > a[y] do j := j-1; if i < j then exchange(i,j)); exchange(y,j); j) in if n > m then (let var i := partition(a,m,n) in quicksort(a, m, i-1); quicksort(a, i+1, n) ) in readarray(a); quicksort(a,0,8); writearray(a) Rewriting the program by treating non-local variables as formal parameter Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 15 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 16 of 24

Parameter Passing how to map actual parameters to formal parameters? call-by-value: values of the actual arguments are passed and established as values of formal parameters. Modification to formals have no effect on actuals. Tiger, ML, C always use call-by-value. function swap(x : int, y : int) = let var t : int := x in x := y; y := t call-by-reference: locations of the actuals are passed; references to the formals include implicit indirection to access values of the actuals. Modifications to formals do change actuals. (supported in PASCAL, but not in Tiger) function swap(var x : int, var y : int) = let var t : int := x in x := y; y := t Use of Registers To avoid memory traffic, modern compilers often pass arguments, return results, and allocate local variables in machine registers. Typical parameter-passing convention on modern machines: the first k arguments ( k = 4 or 6) of a function are passed in registers R p,..., R p+k-1, the rest are passed on the stack. Problem : extra memory traffic caused by passing args. in registers function g(x : int, y : int, z :int) : int = x*y*z function f(x : int, y : int, z : int) = let val a := g(z+3, y+3, x+4) in a*x+y+z Suppose function f and g pass their arguments in R 1, R 2, R 3 ; then f must save R 1, R 2, and R 3 to the stack frame before calling g, Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 17 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 18 of 24 Use of Registers (cont d) how to avoid extra memory traffic? Leaf procedures (or functions) are procedures that do not call other procedures; e.g, the function exchange. The parameters of leaf procedures can be allocated in registers without causing any extra memory traffic. Use global register allocation, different functions use different set of registers to pass their arguments. Use register windows (as on SPARC) --- each function invocation can allocate a fresh set of registers. Use callee-save registers When all fails --- save to the corresponding slots in the stack frame. Convention : Reserve k special registers! Every function promises to always preserve these registers! Example : k=3 (r 4,r 5,r 6 ) fun f(u,v,w) = let val x = g(u,v) val y = g(x,w) in x+y+w Callee-save Registers f g g f return general registers r 0 r 1 r 2 r 3 g u v w g u v x g x w y callee-save registers r 4 r 5 r 6 A B C w g w x A B C A B C Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 19 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 20 of 24

Frame Resident Variables Certain values must be allocated in stack frames because the value is too big to fit in a single register the variable is passed by reference --- must have a memory address the variable is an array -- need address arithmetic to extract components the register that the variable stays needs to be used for other purpose! just too many local variables and arguments --- there are not enough registers!!! -------------- SPILLING Open research problem: When to allocate local variables or passing arguments in registers? Needs good heauristics! Stack Frames in Tiger Using abstraction to avoid the machine-level details What do we need to know about each stack frame at compile time? 1. offsets of incoming arguments and the static links 2. offsets of all local variables 3. the frame size signature FRAME = sig type frame val newframe : int -> frame * int list val alloclocal : frame -> int (* other stuff, eventually... *) structure PowerPCFrame : FRAME = struct type frame = {formals: int, offlst: int list, locals: int ref, maxargs: int ref}... structure SparcFrame : FRAME =... Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 21 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 22 of 24 Stack Frames in Tiger (cont d) In the static environment (i.e., the symbol table), associate each variable with the access information; associate each function with the layout information of its activation record (i.e, frame), a static link, and the caller s frame. type offset = int datatype level = LEVEL of {frame: Frame.frame, slink_offset: offset, parent: level} * unit ref TOP type access = level * offset When converting the absyn into intemediate code --- generate accessing code for each local or non-local variable, plus calling sequences for each function call. Limitation of Stack Frames It does not support higher-order functions ---- it cannot support nested functions and procedure passed as arguments and results at the same time. C --- functions passed as args and results, but no nested functions; PASCAL --- nested functions, but cannot be passed as args or res. Alternative to the standard stack allocation scheme ---- 1. use a linked list of chunks to represent the stack 2. allocate the activation record on the heap --- no stack frame pop! advantages: support higher-order functions and parallel programming well (will be discussed several weeks later!) Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 23 of 24 Copyright 1994-2014 Zhong Shao, Yale University Runtime Environments: Page 24 of 24