0% found this document useful (0 votes)
33 views51 pages

Run-Time Environments

COMPILER DESIGN STUDY MATERIAL - Run-time Environments

Uploaded by

deeplyfwind7
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views51 pages

Run-Time Environments

COMPILER DESIGN STUDY MATERIAL - Run-time Environments

Uploaded by

deeplyfwind7
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 51

Run-time Environments

• Relationship between names and data objects (of target


machine)

• Allocation & de-allocation is managed by run time support


package

• Each execution of a procedure is an activation of the


procedure. If procedure is recursive, several activations may
be alive at the same time.

• If a and b are activations of two procedures then their lifetime is


either non overlapping or nested

• A procedure is recursive if an activation can begin before an earlier


activation of the same procedure has ended

2
Source language issues
Procedures
• A procedure definition is a declaration that
associates an identifier with a statement
(procedure body)

• When a procedure name appears in an


executable statement, it is called at that point

• Formal parameters are the one that appear in


declaration. Actual Parameters are the one that
appear in when a procedure is called.

4
Example of Procedures
program sort; procedure quicksort (m, n
var a : array[0..10] of integer; :integer);
var i :integer;
procedure readarray; :
i:= partition (m,n);
var i :integer;
quicksort (m,i-1);
:
quicksort(i+1, n);
function partition (y, z :
:integer) :integer; begin{main}
var i, j ,x, v :integer; readarray;
: quicksort(1,9)
end.

5
Output- Activation of procedures
Execution begins…
enter readarray
leave readarray
enter quicksort (1,9)
enter partition (1,9)
leave partition (1,9)
enter quicksort (1,3)

leave quicksort (1,3)


enter quicksort (5,9)

leave quicksort (5,9)


leave quicksort (1,9)
Execution terminated.
Activation trees
• Control flows sequentially

• Execution of a procedure starts at the beginning of body

• It returns control to place where procedure was called from

• An activation tree can be used to depict the way control enters and leaves
activations

• The root represents the activation of main program

• Each node represents an activation of procedure

• The node for a is parent of the node b if and only if control flows from activation
to b, and

• The node for a is to the left of node b if and only if the lifetime of a occurs
before the lifetime of b

7
Activation tree
Sort

r q(1,9)

p(1,9) q(1,3) q(5,9)

p(1,3) q(1,0) q(2,3) p(5,9) q(5,5) q(7,9)

p(2,3) q(2,1) q(3,3) p(7,9) q(7,7) q(9,9)

8
Control Stacks
• Flow of control in program corresponds to a depth first
traversal of the activation tree that starts at the root and
recursively visits children at each node in a left-to-right order

• Use a stack called control stack to keep track of live


procedure activations

• Idea is to push the node for an activation onto the control


stack as the activation begins and to pop the node when
activation ends

• When the node n is at the top of the stack the stack contains
the nodes along the path from n to the root

9
Control Stack
s

r
q(1,9)

p(1,9)
q(1,3)

p(1,3) q(1,0) q(2,3)


Scope of a declaration
• A declaration is a syntactic construct that associates information with a name

– Explicit declaration as in Pascal fragment


var i : integer;

– Implicit declaration: Fortran


Any variable name starting with I is assumed to be integer

- otherwise declared

• There may be independent declarations of same name in a program.

• Scope rules determine which declaration applies to a name

• Name binding
environment state
name storage value

11
Bindings of Names
• Even if each name is declared once in a
program, the same name may indicate
different objects at run time.
• “Data object” corresponds to a storage
location hold values.
• The term “environment” refers to a function
that maps a name to a storage location and
“state” refers to a function that maps a
storage location to the value held there.
Storage organization
• The runtime storage might
be subdivided into code

– Target code static data

stack
– Data objects

– Stack to keep track of


procedure activation
heap
– Heap to keep all other
information Subdivision of runtime memory

13
Activation Record
Information needed by a single execution of a
procedure is managed using a contiguous block
of storage called activation record consisting of Temporaries
fields:
• temporaries: used in expression evaluation local data

• local data: field for local data Saved machine status

• saved machine status: holds info about machine Optional Access links
status before procedure call
Optional Control links
• Optional access link : to access non local data
Parameters
• Optional control link :points to activation record of
caller
Return value
• actual parameters: field to hold actual parameters

• returned value: field for holding value to be returned


14
Compile-time Layout of local data
• Assume byte is the smallest unit

• Multi-byte objects are stored in consecutive bytes and given


address of first byte

• The amount of storage needed for name is determined from its


type

• Memory allocation is done as the declarations are processed

• Data may have to be aligned (in a word) padding is done to


have alignment.
– when space is at premium, compiler may pack the data so no padding is
left
– Additional instructions may be required to execute packed data

15
Storage Allocation Strategies
• Static allocation: lays out storage at
compile time for all data objects

• Stack allocation: manages the runtime


storage as a stack

• Heap allocation: allocates and de-allocates


storage as needed at runtime from a data
area known as heap

16
Static allocation
• Names are bound to storage as the program is
compiled

• No runtime support is required

• Bindings do not change at run time

• On every invocation of procedure names are


bound to the same storage

• Values of local names are retained across


activations of a procedure
17
Static allocation
• Type of a name determines the amount of storage to be
set aside

• Address of a storage consists of an offset from the end of


an activation record

• Compiler decides location of each activation

• All the addresses can be filled at compile time

• Constraints

– Size of all data objects must be known at compile time

– Recursive procedures are not allowed

– Data structures cannot be created dynamically 18


Stack Allocation
• Based on the idea of a control stack
• Storage is organized as stack, and activation
records are pushed and popped as activations
begin and end, respectively
• Locals are bound to fresh storage in each
activation because new activation record is
pushed onto the stack when a call is made.
• Values of locals are deleted when the activation
ends, that is, the values are lost because the
storage for locals disappears when the activation
record is popped.

19
Stack Allocation
Position in Activation Tree Activation Records on the stack
Sort Sort

Sort Sort
r r

Sort Sort

r q (1,9) q(1,9)

Sort
Sort
r q (1,9)
q (1,9)
p(1,9) q (1,3)
q (1,3)
p(1,3) q (1,0) 20
Calling Sequence
• Procedure calls are …..
implemented by generating Parameter and
Return value
what are known as calling
Control link Caller’s
sequences in the target Activation
code. Links and saved values record
Space for temporaries
And local data
• A call sequence allocates an
Caller’s
responsibility Parameters and
Return value
activation record and enters
Control link Callee’s
information into its field Activation
Links and saved values record
Callee’s
responsibility Space for temporaries
• A return sequence restores And local data

the state of the machine so


that calling procedure can
continue execution
21
Call Sequence
• Caller evaluates the actual parameters

• Caller stores return address and other values


(control link) into callee’s activation record

• Callee saves register values and other status


information

• Callee initializes its local data and begins


execution

22
Return Sequence
• Callee places a return value next to activation
record of caller

• Restores registers using information in status


field

• Branch to return address in the caller’s code

• Caller copies return value into its own activation


record and use it to evaluate an expression

23
Variable Length Data
Dangling references
• Whenever storage can be deallocated, the problem of
dangling references arises
• Occurs when there is a reference to storage that has been
deallocated
• It is a logical error to use dangling references, since the
value of deallocated storage is undefined according to the
semantics of the value of most languages

25
Dangling references
Referring to locations which have been deallocated
main()
{int *p;
p = dangle(); /* dangling reference */
}

int *dangle();
{
int i=23;
return &i;
}
26
Heap Allocation
• Stack allocation cannot be used if:
– The values of the local variables must be retained when an
activation ends
– A called activation outlives the caller. This possibility cannot occur
for those languages where activation trees correctly depict the
flow of control between procedures.

• In such a case de-allocation of activation record


cannot occur in last-in first-out fashion, so
storage cannot be organized as stack

• Heap allocation gives out pieces of contiguous


storage for activation records
27
Heap Allocation
• Pieces may be deallocated in any order

• Over time the heap will consist of alternate areas


that are free and in use

• Heap manager is supposed to make use of the


free space

• For efficiency reasons it may be helpful to handle


small activations as a special case

• For each size of interest keep a linked list of free


blocks of that size

28
Heap Allocation
• Fill a request of size s with block of size s′ where s′
is the smallest size greater than or equal to s

• For large blocks of storage use heap manager

• For large amount of storage computation may


take some time to use up memory so that time
taken by the manager may be negligible
compared to the computation time

29
Access to non-local names
• Scope rules determine the treatment of
non-local names

• A common rule is lexical scoping or static


scoping (most languages use lexical
scoping) which determines the declaration
that applies to a name by examining the
program text alone.

30
Blocks
• A block statement contains its own data declarations

• Blocks can be nested

• The property is referred to as block structured

• Scope of the declaration is given by most closely nested rule


– The scope of a declaration in block B includes B
– If a name X is not declared in B
then an occurrence of X is in the scope of declarator X in B′ such that
• B′ has a declaration of X
• B′ is most closely nested around B

31
Example: Blocks in C program
main()
{ BEGINNING of B0
int a=0 Scope B0, B1, B2
int b=0 Scope B0, B1
{ BEGINNING of B1
int b=1 Scope B1, B2, B3
{ BEGINNING of B2
int a=2 Scope B2
print a, b
} END of B2

{ BEGINNING of B3
int b=3 Scope B3
print a, b
} END of B3
print a, b
} END of B1
print a, b
} END of B0
32
Blocks
• Blocks are simpler to handle
than procedures
a0

• Blocks can be treated as b0


parameter less procedures
b1

• Use stack for memory allocation a2,b3

• Allocate space for complete


procedure body at one time

33
Parameter Passing
• When one procedure calls another, the usual
method of communication between them
through nonlocal names and through parameters
of the called procedure

34
Parameter Passing: Call by value
• Call by value

– actual parameters are evaluated and their r-values are


passed to the called procedure

– used in Pascal and C

– formal is treated just like a local name

– caller evaluates the actual parameters and places their


r-values in the storage for formals

– call has no effect on the activation record of caller

35
Parameter Passing: Call by reference
• Call by reference (call by address)

– the caller passes a pointer to each location of


actual parameters

– if an actual parameter is a name/expression


having an l-value, then l-value is passed itself

– if actual parameter is an expression that has no l-


value, then it is evaluated in a new location, and
the address of that location is passed
36
Parameter Passing : Copy Restore
• A hybrid between call-by-value and call-by-
reference is copy restore linkage(also known as
copy-in copy-out or value-result)

– Before control flows to the called procedure, the


actual parameters are evaluated. The r-values of the
actuals are passed to the called procedure as in call by
value. The l-values of those actual parameters having l-
values are determined before the call

– when control returns, the current r-values of the


formal parameters are copied back into the l-values of
the actuals, using l-values computed before the call.

37
Parameter Passing : Call by name
• Call by name (used in Algol)

– names are copied

– local names are different from names of calling


procedure

swap(i,a[i])
temp = i
i = a[i]
a[i] = temp
38
Symbol Table
• Keep track of scope and binding information about
names
• It is searched everytime a name is encountered in
the source text
• Changes to the table made if a new name or new
information about an existing name is discovered.
• Mechanism should allow the addition of new entries
and search for existing entries are efficient.
• Symbol table mechanisms are: linear list and hash
tables
Symbol Table
• Linear list- simple to implement but performance is
poor when number of entries (e) and enquiries(e)
get large.
• Hashing schemes- Better performance for somewhat
better programming effort and space overhead.
• Both mechanisms can be adopted readily to handle
the most closely nested scope rule.
• Study about hash table and linear list structure from
CD book.
Symbol Table
• When identifiers are found, they will be
entered into a symbol table, which will hold
all relevant information about identifiers.
• This information will be used later by the
semantic analyzer and the code generator.
Lexical Syntax Semantic Code
Analyzer Analyzer Analyzer Generator

Symbol
Table
Symbol Table Entries
• Each entry of the symbol table is for the
declaration of a name
• Format for entries may not be uniform as the
information saved about a name depends on
the usage of a name.
• Information is entered at various times
• Keywords are entered into table initially
Symbol Table Entries
• This information is stored in an object called
an IdEntry.
• This information may not all be known at
once.
• We may begin by knowing only the name and
data type, and then later learn the block level,
scope, and the offset.
Language Facility for Dynamic Storage
Allocation
• Storage is usually taken from heap

• Allocated data is retained until deallocated

• Allocation can be either explicit or implicit

– Pascal : explicit allocation and de-allocation by new()


and dispose()

– Lisp : implicit allocation when cons is used, and de-


allocation through garbage collection
44
Explicit Allocation of Fixed Sized Blocks
• Link the blocks in a list

• Allocation and de-allocation can be done with very little


overhead
available

allocated

available

allocated

45
Explicit Allocation of Fixed Sized Blocks …

• Blocks are drawn from contiguous area of storage

• An area of each block is used as pointer to the next block

• A pointer available points to the first block

• Allocation means removing a block from the available list

• De-allocation means putting the block in the available list

• Compiler routines need not know the type of objects to be held in the blocks

• Each block is treated as a variant record

46
Explicit Allocation of Variable Size Blocks
• Storage can become fragmented
• Situation may arise
• If program allocates five blocks
• then de-allocates second and fourth block

free free free

• Fragmentation is of no consequence if blocks are of fixed


size
• Blocks can not be allocated even if space is available

47
First Fit Method
• When a block of size s is to be allocated
– search first free block of size f ≥ s
– sub divide into two blocks of size s and f-s
– time overhead for searching a free block
• When a block is de-allocated
– check if it is next to a free block
– combine with the free block to create a larger
free block

48
Implicit De-allocation
• Requires co-operation
between user program Optional Block size

and run time system


Optional Reference count

• Run time system needs to Optional mark

know when a block is no


Pointers to blocks
longer in use

• Implemented by fixing the User info


format of storage blocks

49
Recognizing Block boundaries
• If block size is fixed then position information can be used

• Otherwise keep size information to determine the block boundaries

Whether Block is in Use


• References may occur through a pointer or a sequence of pointers

• Compiler needs to know position of all the pointers in the storage

• Pointers are kept in fixed positions and user area does not contain
any pointers

50
Reference Count
• Keep track of number of blocks which point directly to the
present block

• If count drops to 0 then block can be de-allocated

• Maintaining reference count is costly

– assignment p:=q leads to change in the reference counts of the


blocks pointed to by both p and q

• Reference counts are used when pointers do not appear


in cycles

51
Marking Techniques
• Suspend execution of the user program

• use frozen pointers to determine which blocks are in use

• This approach requires knowledge of all the pointers

• Go through the heap marking all the blocks unused

• Then follow pointers marking a block as used that is reachable

• De-allocate a block still marked unused

• Compaction: move all used blocks to the end of heap. All the
pointers must be adjusted to reflect the move
52

You might also like