Top Banner
1 Chapter 7: Runtime Environments
39

1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

Dec 19, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

1

Chapter 7: Runtime Environments

Page 2: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

int * larger (int a, int b){ if (a > b) return &a; //wrong else return &b; //wrong}

int * larger (int *a, int *b){ if (*a > *b) return a; //OK else return b; //OK}

Page 3: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

3

Memory of a computer

Register RAM

- Code Area

- Data Area

Page 4: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

4

General Organization of Runtime Storage

code area

stack

SP

global/static data area

free space

heap

Page 5: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

5

Code Area

code for procedure1

code for procedure2

code for procedure3

.

. code for procedureN

SP

entrypointentrypoint

entrypoint

entrypoint

Page 6: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

6

Fully Static Runtime Environments

code for main procedure

code for procedure 1

……….

code for procedure N

global data area

activation record for main

procedure

activation record for proc 1

SP

Code Area

Data Area

…………….activation record for proc N

Page 7: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

7

Activation Record

- a contiguous block of storage recording the state of an activation of a function, not all the compilers set the same fields.

Each execution of a procedure is referred to as an activation of the procedure. If the procedure is recursive, several of its activation may be alive at the same time.

Page 8: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

8

What is the contents of the activation record?

temporary values local data saved machine status optional access link to refer to non-local data

held in other activation records optional control link to refer to the activation actual parameters returned value

Page 9: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

General Organization of a Activation Record

Local & temp. data

Old SP

Return value

Return address

Argument count

Parameter tn

.................

Parameter t2

Parameter t1

0

2n-1

..

..

..

SP

Directionof Growthcaller’s

responsibility

callee’s duty

Page 10: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

10

So, local data are accessed by negative offsets from SP

(stack pointer, a register holding a particular position of

currently activated procedure). A local name X can be

referenced by X[SP] ([SP] means the address of SP), where

X is the (negative) offset for the name from the location

pointed to by SP. Parameter can be referred to by an

positive offset from SP. That is, the ith parameter can be

referenced by (4+n-i)[SP] (assume each entry takes one

unit of space)

Page 11: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

Suppose the Memory structure for C program is organized as below, where function P calls Q and Q calls R

0 .. Static area for programs and global (static) data

 

 

..2n-1

Top

Extra storage for R

Activation record for R

Direction

Extra storage for Q

Activation record for Q

SP

of growthExtra storage for P

Activation record for P

(fp)

(sp)

Page 12: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

TOP is a register holding the top address of the stack. SP is also a permanently allocated register (stack pointer) holding a specific address in the activation record of the currently active procedure. We use SP to indirectly refer to the local variables, parameters, etc.

Extra storage is used for storing pointers on the display, variable-length data such as dynamically allocated arrays, etc.

Page 13: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

13

Page 14: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

14

Growthdirection

2n-1

0

Page 15: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

15

Page 16: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

At run-timee.g. p (T1, T2, ..., Tn) ==> param T1 => push (T1) param T2 => push (T2) ... .. ... .. param Tn => push (Tn) call p, n => push (n)

=> push (l1)

=> push () => push (SP)

=> goto l2

l1 denotes the return address; l2 denotes the address of the

first statement of the called procedure.

Page 17: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

17

e.g., p (A+B*C, D) ==> T1 = B * C

T2 = A + T1

Param T2

Param D

Call p, 2

Temporary variable

Page 18: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

At run-time

* Assume TOP points to the lowest-numbered used location on the stack and the memory locations are counted by words.

 'param T' is translated into 'push(T)' which stands for TOP = TOP - 1; /* now TOP points to an available entry */ *TOP = T; /* save T into the memory 'call p, n' is translated into the following instructions: push (n) /*store the argument count */

push (l1) /* l1 is the return address */push () /* leave one space for the return value */push (SP) /* store the old stack pointer */

goto l2 /* l2 is the first statement of the called procedure p */

Page 19: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

General Organization of a Activation Record

Local & temp. data

Old SP

Return value

Return address

Argument count

Parameter tn

.................

Parameter t2

Parameter t1

0

2n-1

..

..

..

TOP

Directionof Growthcaller’s

responsibility

SP

Page 20: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

The first statement of the called procedure must be a special three-address code 'procbegin', which (1) sets the stack pointer to the place holding the old SP and (2) sets TOP to the top of the activation record (or the stack), so 'procbegin' stands for:

SP = TOP; // now SP points to old SP value TOP = SP + size_of_p; /* size_of_p is the size of p, i.e., the number of words taken by the local data for p */

The first statement of the called procedure

Page 21: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

General Organization of a Activation Record

Local & temp. data

Old SP

Return value

Return address

Argument count

Parameter tn

.................

Parameter t2

Parameter t1

0

2n-1

..

..

..

SP

Directionof Growthcaller’s

responsibility

callee’s duty

TOP

Page 22: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

The ‘return’ statement The return statement in c can have the form 'return (expression);' This statement can be implemented by three-address code to evaluate the expression into a temporary T followed by:   1[SP] = T /* 1 is the offset for the location of the return value */ TOP = SP + 2 /* TOP now point to the return address */ SP = *SP /* restore SP, SP now points to old location */ L = *TOP /* the value of L is now the return address */ TOP = TOP + 1 /* TOP points to the argument count */ TOP = TOP + 1 + *TOP /* *TOP is the number of parameter of P. We restore TOP to the top of extra storage for the activation record below */ go to *L

Page 23: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

23

Do not expect a procedure to do anything that requires it to know the size of the activation record of another procedure.

Page 24: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

24

Control Link & Access Link

Control (Dynamic) Link

- link the caller’s activation record and thus allows us to restore the state (activation record) of the caller upon procedure exit.

Access (Static) Link

   - a link used to access non-local variables

Page 25: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

B

P

.

.

.

P

Q

B

P

.

.

.

P

P

Q

Control Links Access and Control Links

growthdirection

P

Two procedures P and Q are defined in procedure B; P callsitself recursively several times before it calls Q.

Procedure B procedure P { P….. Q….. } procedure Q {…… …… }…P….

AccessLinks

Control Link

Page 26: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

Nested Block Structures in Ce.g. Int test( )

{ int x,y,m;

…..

{ int m=1, n=2;

x = m + n;

….

}

…..

{ int w=2, k =4;

m = w * k;

}

…..

}

Page 27: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

Access variables for activation record with access links For local variables e.g., fetch (-1)[SP] // assume (-1) is the offset of a local variable. For non-local variables with static distance 1 e.g., EP = (1)[SP] //EP is a register; assume access link is stored in (1)[SP]. EP = (-1)[EP] // EP now points to what the SP should point to. fetch (-3)[EP] // (-3) is the offset of the non-local variable. For non-local variables with static distance 2 e.g., EP = (1)[SP] EP = *EP // the content of EP is saved in EP EP = (-1)[EP] // EP now points to what the SP should point to. fetch (-5)[EP] // assume (-5) is the offset of the non-local

Page 28: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

28

Steps to access a non-local variable at run-time

1. Skip down the access links given by the static distance to get the activation record in which the variable resides. The static distance between the use and the declaration of the variable is a constant computed by the compiler at compile-time.

2. The address of the variable is obtained by adding the fixed offset of the variable to the address obtained in step 1. The offset is also a constant computed by the compiler at compile-time.

Page 29: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

29

Variable-Length Data

A common strategy for handling variable-length data is shown below, where procedure p has three local arrays. The storage for these arrays is not part of the activation record for p; only a pointer to the beginning of each array appears in the activation record. The relative addresses of these pointers are known at compile-time, so the target code can access array elements through pointers.

Page 30: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

control linkPointer to APointer to B

array A

array B

activation record for P

arraysof P

control link

TOP

Activation recordof Q called by P

array of q

SP

Access to dynamically allocated arrays

int x[10];

int A[w];Int B[m];……

read w;m= w * 10;

w*2

Page 31: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

31

Passing function as a parameter

Page 32: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

Program HP

proc p (func h)

h

proc q

func f

p(g)

p(f)

func g

q

HP

q

p

f

Stack configurationafter the call to p(f)and (dashed) afterthe call to h.

call to h

After the callto p(f)

access links

Page 33: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

Program HP

proc p (func h)

h

proc q

func f

p(g)

p(f)

func g

q

HP

q

p

f

Stack configurationafter the call to p(g)and (dashed) afterthe call to h.

call to h

p

g

after callto p(g)

Page 34: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

34

Display

An array data structure (array of pointers to entries of activation record, e.g., d[ ]) used to store the specific location of (1) currently activated function’s activation record and (2) the activation records of each level of declared nested functions. Therefore, storage for a non-local variable a at nesting depth i is in the activation record pointed to by display element d[i].

Page 35: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

e.g. program s (input, output); var a: array[0..10] of integer; x: integer; procedure r; var i: integer; begin ... a ... end; /* r */ procedure e (i,j: integer); begin x := a[i]; a[i] = a[j]; a[j] := x end; /* e */ procedure q (m,n: integer); var k,v: integer; function p (y,z: integer):integer; var i,j: integer; begin ... a ... ... v ... e (i,j); end; /* p */ begin ...... end; /* q */ begin ... end. /* s */

Page 36: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

d [1]

d [2]q (1,9)

saved d [2]

S

q (1,9)

saved d [2]

S

d [1]d [2]

q(1,3)

saved d [2]

growthdirection

(a)

(b)

Page 37: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

q (1,9)

saved d [2]

S

d [1]d [2]

q(1,3)

saved d [3]

growthdirection

d [3]

p(1,3)

saved d [2]

( c )

Page 38: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

q (1,9)

saved d [2]

S

d [1]d [2]

q(1,3)

saved d [3]

growthdirection

d [3]

p(1,3)

saved d [2]

( d )

e(1,3)

saved d[2]

Page 39: 1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)

39

Assignment #5b

Do exercises 6.2, 6.14, 7.2, 7.10 of the

textbook.