Upload
sawyer-herrera
View
19
Download
0
Embed Size (px)
DESCRIPTION
Course Overview. PART I: overview material 1Introduction 2Language processors (tombstone diagrams, bootstrapping) 3 Architecture of a compiler PART II: inside a compiler 4Syntax analysis 5Contextual analysis 6 Runtime organization 7Code generation PART III: conclusion - PowerPoint PPT Presentation
Citation preview
1Runtime Organization (Chapter 6)
Course Overview
PART I: overview material1 Introduction
2 Language processors (tombstone diagrams, bootstrapping)
3 Architecture of a compiler
PART II: inside a compiler4 Syntax analysis
5 Contextual analysis
6 Runtime organization
7 Code generation
PART III: conclusion8 Interpretation
9 Review
2Runtime Organization (Chapter 6)
Arguments
We have already discussed how space on the stack is allocated for arguments to routines.
We now discuss some specific issues about• passing by value versus passing by reference• passing of functional and procedural parameters
3Runtime Organization (Chapter 6)
Arguments: by value or by reference
Some programming languages allow two kinds of parameter passing to functions/procedures.
Example: in Triangle (similar in Pascal or C++)
let proc S(var n:Integer, i:Integer) ~ n:=n+i; var today: record y:integer, m:Integer, d:Integer end;in begin b := {y ~ 2002, m ~ 2, d ~ 22}; ! b is non-local S(var b.m, 6);end
let proc S(var n:Integer, i:Integer) ~ n:=n+i; var today: record y:integer, m:Integer, d:Integer end;in begin b := {y ~ 2002, m ~ 2, d ~ 22}; ! b is non-local S(var b.m, 6);end
Constant/value parameterVar/reference parameter
4Runtime Organization (Chapter 6)
Arguments: by value or by reference
Value parameters:At the call site the argument is an expression. The evaluation of that expression leaves some value on the stack. This value is passed to the procedure/function.Typical instructions for putting a value parameter on the stack:LOADL 6 LOAD 3[L1]
Var/reference parameters:Instead of passing a value on the stack, the address of a memory location is pushed. This implies a restriction that only “variable-like” things can be passed to a var parameter. In Triangle there is an explicit keyword var at the call-site, to signal passing a var parameter. In Pascal and C++ the reference is created implicitly (but the same restrictions apply). Typical instructions for putting a var parameter on the stack:LOADA 5[LB] LOADA 10[SB]
5Runtime Organization (Chapter 6)
Functional / Procedural ParametersIn Triangle (and Pascal) a limited version of higher-order programming is possible. One may pass functions/procedures as arguments to other functions/procedures. (Unlike Scheme, they are not first-class values!) Example 1: let func twice(func doIt(Integer x): Integer,
Integer i) ~ doIt(doIt(i)); func double(Integer d): Integer ~ d*2; var twenty : Integerin begin twenty := twice(double,5);end
let func twice(func doIt(Integer x): Integer, Integer i) ~
doIt(doIt(i)); func double(Integer d): Integer ~ d*2; var twenty : Integerin begin twenty := twice(double,5);end
A procedural/functional parameter is passed by pushing a “closure” on the stack. A closure consists of two parts:1. the static link of the procedure/function2. the address of the procedure/function
6Runtime Organization (Chapter 6)
Functional / Procedural Parameters
Example 2: (illustrates we can pass non-global functions as well)
let func twice(func doIt(Integer x): Integer, Integer i) ~ doIt(doIt(i)); func cubed(Integer b): Integer ~ let func multiply(Integer x): Integer ~ x*b in twice(multiply, b); in begin ... ... cubed(4) ... end
let func twice(func doIt(Integer x): Integer, Integer i) ~ doIt(doIt(i)); func cubed(Integer b): Integer ~ let func multiply(Integer x): Integer ~ x*b in twice(multiply, b); in begin ... ... cubed(4) ... end
accesses lexically scoped var
See pictures of stack beginning on next slide…
7Runtime Organization (Chapter 6)
Functional / Procedural Parameters
4
SB
LBarg b
ST
linkdata
right after calling cubed right before call to twice
4LB
arg b
ST
linkdata
multiplyclosure
4
arg #1
arg #2
static link
function address
multiplyfunctioncode
8Runtime Organization (Chapter 6)
Functional / Procedural Parameters
right after call to twice
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
before first call to doIt
4arg #1
multiply multiply
multiplyclosure multiply
Note: to avoid clutter, dynamiclinks are not shown.Only some static links are shown.
closure to call
9Runtime Organization (Chapter 6)
Functional / Procedural Parameters
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
before first call to doIt
4arg #1
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
right after first call to doIt
4arg x
multiply multiply
linkdata
multiplyclosure multiply
execution of CALLI instruction (Call Indirect)
closure to call
10Runtime Organization (Chapter 6)
Functional / Procedural Parameters
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
right after first call to doIt
4arg x
multiply
linkdata
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
just before x*b in multiply
4arg x
multiply
linkdata
4value of xvalue of b 4
LOAD [-1]LBLOAD [-1]L1
11Runtime Organization (Chapter 6)
Functional / Procedural Parameters
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
just before return doIt/multiply
4arg x
multiply
linkdata16value of x*b
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
just after return doIt/multiply
multiply
16value of doIt(4)
12Runtime Organization (Chapter 6)
Functional / Procedural Parameters
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
just before second call to doIt
multiply
16arg #1multiplyclosure multiply
closure to call
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
just before x*b in multiply
16arg x
multiply
linkdata16value of x
value of b 4LOAD [-1]LBLOAD [-1]L1
13Runtime Organization (Chapter 6)
Functional / Procedural Parameters
4
LB
arg b
ST
linkdata
multiplyclosure
4
arg doIt
arg ilinkdata
just after return doIt/multiply= just before return from “twice”
multiply
64value of doIt(16)
4LB
ST
linkdata
multiplyclosure
64
arg doIt
value of twice(multiply,4)multiply
just after return from “twice”=just before return from cubed
64
just after return from cubed
value of cubed(4)ST
14Runtime Organization (Chapter 6)
Functional / Procedural Parameters
Why does the stack allocation model for functional/procedural parameters work?
More precisely, why can closure objects and the static frames they point to be completely in the stack? (In Scheme for example static environments are allocated in the heap.)
It is sufficient to ensure that every closure object can never outlive the static frame to which it points.
multiplyclosure
Pointsupwardis OK!
multiplyclosure
Points downwardwould be BAD!
15Runtime Organization (Chapter 6)
Recursion
How are recursive functions and procedures supported on a low-level machine?=> Surprise! The stack memory allocation model already works!Example:let func fac(n:Integer) ~ if (n<=1) then 1 else n*fac(n-1);in begin putint(fac(6));end
let func fac(n:Integer) ~ if (n<=1) then 1 else n*fac(n-1);in begin putint(fac(6));end
Why does it work? Because every activation of a function gets its own activation record on the stack, with its own parameters, locals etc. All procedures and functions are “reentrant”.Older languages (e.g. FORTRAN) that use static allocation for locals have problems with recursion.
16Runtime Organization (Chapter 6)
Recursion: General Idea
Why the stack allocation model works for recursion:Like other function/procedure calls, lifetimes of local variables and parameters for recursive calls behave like a stack.
fac(3)
fac(2)
fac(1)
fac(4) fac(4)
fac(3)
fac(2)
fac(4)fac(4)
fac(3) fac(3)
fac(2)
fac(2)
fac(1)
fac(3)
fac(2)
fac(4)
fac(3)?
?
fac(4)
17Runtime Organization (Chapter 6)
Recursion: In Detail
let func fac(n:Integer) ~ if (n<=1) then 1 else n*fac(n-1);in begin putint(fac(6));end
let func fac(n:Integer) ~ if (n<=1) then 1 else n*fac(n-1);in begin putint(fac(6));end
SB arg 1 6ST
before call to facSB arg 1 6
ST
right after enteringfac
linkdata
SB arg n 6
right before recursivecall to fac
linkdata
LB
ST
LB
6value of n5arg: value of n-
1
18Runtime Organization (Chapter 6)
Recursion
SB arg n 6
right before recursivecall to fac
linkdata
ST
LB
6value of n5arg
SB arg n 6
right before next recursive call to fac
linkdata
ST
LB
6value of n5arg n
linkdata
54
value of narg
SB arg n 6
right before next recursive call to fac
linkdata
LB
6value of n5arg n
linkdata
54
value of narg
linkdata
43
ST
value of narg
19Runtime Organization (Chapter 6)
Recursion
LB
ST
Is the spaghetti of static and dynamic links getting confusing?
Let’s zoom in on just a single activation of the fac procedure. The pattern is always the same:
argument n
link data
to caller context (= previous LB)to lexical context (= SB)
nn-1
Intermediate results in the computation of n*fac(n-1);
?
just before recursive call in fac
20Runtime Organization (Chapter 6)
Recursion
LB
ST
link data
result = 1
just before the return from the “deepest call”: n=1 after return from deepest call
LB
STresult=1
?caller frame
(what’s in here?)
argument n=2
link data
n=2 Next step:multiplyargument n=1
21Runtime Organization (Chapter 6)
Recursion
just before the return from the “second deepest call”: n=2(after return from deepest call and multiply)
LB
ST?
caller frame(what’s in here?)
argument n=2
link data
2*fac(1)=2 Next step: return
to caller contextto lexical context (= SB)
result
From here on down the stack is shrinking,multiplying each time with a bigger n
22Runtime Organization (Chapter 6)
Recursion
LB
ST
argument n
link data
nrecurs. arg: n-1
just before recursive call in fac
LB
ST
argument n
link data
nfac(n-1)
after completing recursive call
Calling a recursive function is just like calling any other function. After completion it just leaves its result on the top of the stack!A recursive call can happen in the midst of expression evaluation.Intermediate results, local variables, etc. simply remain on the stack, and computation proceeds when the recursive call is completed.