some details of implementation

21
Catriel Beeri Pls/Winter 2004/5 environment 1 Some details of implementation As part of / extension of type-checking: Each declaration d(x) associated with a type type & size information Compiler decides on Address (see below) Size of storage Each use u(x) associated with some d(x) – compiler generates code to access allocated address (for read/write/…)

Upload: gaye

Post on 29-Jan-2016

33 views

Category:

Documents


0 download

DESCRIPTION

Some details of implementation. As part of / extension of type-checking: Each declaration d(x) associated with a type  type & size information Compiler decides on Address (see below) Size of storage - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 1

Some details of implementation

As part of / extension of type-checking:• Each declaration d(x) associated with a type

type & size information

Compiler decides on– Address (see below)

– Size of storage

• Each use u(x) associated with some d(x) – compiler generates code to access allocated address (for read/write/…)

Page 2: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 2

On address allocation :• For global block – fixed addresses• For functions:

– Many calls many allocations

– Allocated at run-time address allocation and access code are

relative to (yet unknown) base address (assumed to be stored in a register at run-time)

If total size for parameters is M, compiler – associates M with the compiled function

– generates code to allocate M at run-time when the function is called

(the estimate M is modified below)

Page 3: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 3

At run-time when a function value is applied :• a memory chunk S of size M is allocated• the values of the arguments are stored:

– In S (in right positions) , or

– Elsewhere (in the heap); references are stored in S• Arg. Values may be variable size (inconvenient for

implementation)• Another reason – next chapter

• Base address of S is put into a register, valid for this activation

• Access for resolution of a use is by relative addressing one machine instruction

Page 4: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 4

Extension for other blocks (let/let*/letrec/letrec*):• Compiler also knows types & sizes of variables

declared locally in a function

It associates a relative address also to each variable

name conflicts (variable x in different blocks) are no problem — each d(x) is associated with a distinct address

(essentially, variables are re-named to distinct names --- the addresses)

• Each use u(x) is associated with one d(x) – relative access code is generated (scope rules used here)

• The size M for a function & the allocated chunk S include the parameters & all locals

(same for global block)

Page 5: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 5

When a function value is applied (revisited) :• A memory S of size M for the arguments and

locals is allocated (only exception: real-time with small memory)

-- essentially frames of parameters and locals are merged into an extended frame – the values of the arguments are stored immediately– variables bound to cells – these are effectively allocated – Other variable bindings – code for processing the

defining expressions is generated in the right places (their use only in scope was assured at compile-time )

• Address allocation, relative addressing (for locals) – as described above

Access for resolution of parameters & locals is by one machine instruction

Page 6: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 6

Example ( C) :

int x;

int f(double x) {

int y, z;

Note: the actual names are not used at run-time

x y z

memory chunk for f’s value

x ref to fv

memory chunk for global block

Page 7: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 7

Parameters and locals are accessed efficiently

What about global variable access?

The static (nesting) depth, of a use u(x), sd(u(x)) – # of function boundaries to its binding declaration d(x)

(given that local blocks are merged into function, the compiled static depth counts only function boundaries)

sd(u(x)) -- the number of frame hops needed to get to a binding for it

this number is known to the compiler!

Page 8: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 8

Cont’d:

Compiler compiles each non-local use v to code for a loop to traverse sd(v) links of static parents , followed by relative access to right position

Summary:

Variable declarations are replaced by positions

Uses (both locals and non-locals) are compiled to access code to these positions

Compilation generates efficient computation

*(~ rule alpha!)

*

Page 9: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 9

Implementation of function values :

A function value is implemented by a pair of pointers• To the compiled code, (including code to allocate

storage, to store return value, ….. )

• To a [(extended) frame, static parent] pair (its environment)

Page 10: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 10

Life and death on the stack

Two approaches to programming languages implementation :

• Stack-based: a run-time stack of activation records (one per function activation – corresponds to conceptual activation stack) – common for imperative/OO pl’s

• Continuation-based: do not employ a stack –common for functional languages

We discuss the stack-based

Page 11: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 11

An activation record contains activation-relevant data:• Saved registers• Return address• Dynamic pointer• ….. (more such data)• one of

– [(extended) frame , static (parent) pointer] (automatic storage)

– A reference to [frame, static pointer] (heap storage)

Heap: A storage area allocated for a program, contains

• Internal, run-time data structure

• Program data

Q: what determines which of these two is selected?

Page 12: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 12

We consider two questions:• What determines whether a frame is stored in the

activation record on the stack, or in the heap?• Can cells be allocated for parameters/locals on the

stack, or should they be allocated in the heap?

Pros & cons of stack allocation:+ (de-)allocation is very efficient (hardware support)

– Data stored in activation record die when it is poppedNeed to understand liveness (only for the 2 questions)

Page 13: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 13

Example: (a simple counter object)(define counter

(let ((count 0))

(lambda (msg)

(cond ((eqv? msg ‘show) count)

((eqv? msg ‘inc) (set! count (+ 1 count))))))

counter is bound to a function value with a reference to a frame that corresponded to a dead activation (de-allocated from stack)

This frame is live (reachable from a live activation)

The frame must reside in the heap

Page 14: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 14

Liveness definition for func. values, frames, bindings(conservative definition)

Liveness = reachable• A binding is reachable if it is stored in reachable

frame

• A frame is reachable if it is – Associated with a live activation– Frame of a reachable function value– Reachable by static parent reference from a reachable

frame

• A function value is reachable if it is the value in a reachable binding

(the above contains mutual recursion, what is the base case?)

Page 15: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 15

Addition: a func. value is live, but not bound, when1 Created as anonymous function2 Is the value of an expression (e.g., a function call)

In 1st case, – if immediately applied, then use and throw -- not

stored, irrelevant to current discussion

– If bound to an identifier, then covered by the definition

– If expression value – that is 2nd case

In 2nd case, the interesting situations are (why?)• It is the return value from a function call• It is passed as a parameter to a function call Of these two, only the first should really worry us – why?

Page 16: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 16

Restriction P (used in Pascal):

Pascal allows nesting of function expressions, but

A locally generated function can be passed :• to functions invoked in the activation (stack grows)

• but never out of the activation down the stack

when activation dies, so does the frame, and the bindings in it (there is no live function value that references it)

The restriction must apply also to functions stored in cells or data structures: cannot return anything containing a function

a function call cannot return a function value

Page 17: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 17

Example :Main{ func D(func z, int x) { …. z(x), } func E(int x){ func F(func C) { } func G(int y) { …F(D),…..D(F,y),…} G(x+3) }E(5)}

Main starts values d and e for D, E are created

Calls e(5) values f and g for F and G are created

Starts g(8) can call a static brother (f) / a static uncle (d) of g

In either case, the dynamic activation stack grows

Mutually recursive

Mutually recursive

Page 18: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 18

In Pascal, frame with bindings stored in activation record (when activation dies, they certainly cease to be live)

Functions can be created locally, then passed as parameters

Static pointer (reference to static parent) is needed

It always points to an activation record deeper in the stack

(there is an alternative implementation strategy – store static pointers for activations in a vector – we skip)

Page 19: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 19

Restriction C (used in C):

• All the bindings generated in program outside functions are stored in one global frame (fixed)

(addresses for all global variables computed at compile-time)

• A function value knows about the variables declared before it in program

• That it uses only these is checked by the compiler • Bindings for parameters & locals in a function call are

stored in a extended frame for the activation• The static parent of each activation record is the

global frame not needed

No function nesting allowed –all functions are global

Page 20: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 20

Summary: In Pascal, C (and similar imperative pl’s):

Restrictions on functions guarantee that frame and bindings created for an activation die with it

Bindings stored in activation record (automatic) fast (de-)allocation

Additionally:• That uses are in scope is checked at compile-time

Page 21: Some details of implementation

Catriel Beeri Pls/Winter 2004/5 environment 21

At one extreme is C:

Does not believe in function nesting Extremely simple environment structure

At the other extreme are functional pl’s:

No restrictions on nesting, heavy use of higher-order functions

Environment structure (frames) separated from run-time stack, stored in heap

Rely on garbage collection

(In some implementations, even an activation stack is absent)