BCS 324 Notes_unit4
BCS 324 Notes_unit4
Run-Time Environments
1
Introduction
As execution proceeds, the same name in the source
text can denote different data objects in the target
machine
This chapter examines the relationship between names
and data objects
The allocation and de-allocation of data objects is
managed by the run-time package consisting of routines
loaded the generated code.
Each execution of a procedure is referred to as an
activation of the procedure
If the procedure is recursive, then several of its
activations may be alive at the same time.
2
Source language issues
Here we try to distinguish between the
source and of a procedure and its
activations at run time.
Procedures
◦ A procedure definition is a declaration that in
its simplest form associates an identifier with
a statement
◦ The identifier is the procedure name and the
statement is the procedure body
3
◦ Procedures that return values are called
functions in many languages
◦ A complete program is treated as a
procedure
◦ When a procedure name appears with an
executable statement, we say the procedure
has been called (invoked), which executes the
procedure body.
4
Activation trees
We make the following assumptions about the
flow of control among procedures during the
execution of a program
◦ Control flows sequentially i.e. execution follows
sequential steps, one at a time
◦ Each execution procedure starts at the beginning of
the procedure body and eventually returns control to
the point immediately following the place where the
procedure was called
◦ This means we can use trees to depict flow of control
between procedures.
5
Execution of a procedure body is called
an activation of the procedure
The lifetime of an activation of the
procedure p is the sequence of steps
between first and last steps in the
execution, including time spent executing
called (invoked) procedures i.e.
lifetime = No. of steps during execution +
No. of steps of called procedures
6
Procedures can be overlapping or nested
A procedure is recursive if a new
activation can begin before an earlier
activation of same procedure has ended.
We use activation trees to show the way
control enters and leaves activations
7
An activation tree:
1. Each node representing an activation of a
procedure
2. The root representing the activation of main
program
3. The node for a is the parent of the node for b if
and only if control flows from activation a to b, and
4. The node for a is to the left of the node for b if
and only if the lifetime of a occurs before the
lifetime of b.
Control is always at a node when it is in the
activation represented by the node.
8
Control stacks
◦ The flow of control in a program corresponds to a
depth-first traversal of the activation tree that starts
at the root, visits a node before its children, and
recursively visits children at each node in a left-to-
right order.
◦ A control-stack is a type of stack that keeps track of
live procedure activations
◦ The idea is to push the node for an activations onto
the control stack as the activation begins and to pop
the node when the activation ends. Then the contents
of the control stack are related to paths to the root
of the activation tree.
9
Scope of a declaration
◦ A declaration in a language is a syntactic construct
that associates information with a name
◦ Declarations may be explicit as in the Pascal fragment
var i: integer;
◦ Or they may be implicit e.g. a variable name starting
with I in Fortran is assumed to denote an integer
unless otherwise stated as in IStudentNumber
10
The scope rules of a language determine which
declaration of a name applies when the name
appears in the text of a program
The portion of the program to which a
declaration applies is called the scope of that
declaration
An occurrence of a name in a procedure is said
to be local to the procedure if it is in the scope
of a declaration within the procedure,
otherwise the occurrence is said to be nonlocal.
11
Binding of names
◦ Even if each name is declared once in a program, the
same name may denote different data objects at run
time
◦ The informal term “data object” corresponds to a
storage location that can hold values
◦ In programming languages, the term environment
refers to the function that maps a name to a storage
location, and the term state refers to a function
that maps a storage location to the value held there
as illustrated in the figure below.
12
An environment maps a name to a
storage location, and a state maps the
storage location to the value held.
environment state
13
Environments and states are different; an
assignment changes the state, but not the
environment e.g.
◦ Suppose storage address 100 associated with
variable pi, holds 0
◦ After assignment pi = 3.14, the same
storage address is associated with pi, but the
value held there is 3.14.
14
Storage organization
Organization of runtime storage may be
used for languages such as Fortran, Pascal
and C
Topics under storage organization include
◦ Subdivision of runtime memory
◦ Activation records
◦ Compile time layout of the local data.
15
Subdivision of runtime memory
◦ Suppose that the compiler obtains a block of
storage from the Operating System for the
compiled program to run in
◦ The runtime storage may be subdivided to
hold
1. The generated target code
2. Data objects
3. A counterpart of the control stack to keep track
of procedure activations.
16
The size of the generated target code is
fixed at compile time, so the compiler can
place it in a statistically determined area,
perhaps in the lower end of memory.
Data objects whose sizes are known at
compile time may also be stored statically
A separate area of runtime memory,
called a heap, holds all the other
information.
17
The size of the stack and the heap can change
as program executes.
By convention, stacks grow down towards the
bottom
code
Static data
stack
heap
Typical subdivision of runtime meory into code and data areas
18
Activation records
Information needed by a single execution of a
procedure is managed using a contiguous block
of storage called an activation record or frame,
consisting of a collection of fields shown in the
figure below
The purpose of the fields of an activation
record is as follows, starting from the field for
temporaries
1. Temporary values, such as those arising in the
evaluation of expressions, are stored in the fields for
temporaries
19
2. The field for local data holds data that is
local to an execution of a procedure. The
layout of this field is discussed below
3. The field for saved machine status holds
information about the state of the machine
just before the procedure is called. This
information includes the values of the
program counter and machine registers that
have to be restored when control returns
from the procedure.
20
4. The optional access link is used in the
control stack diagram to refer to non local
data held in other activation records
5. The optional control link points to the
activation records of the caller
6. The field for actual parameters is used by
the calling procedure to supply parameters
to the called procedure
7. The field for the returned value is used by
the called procedure to return a value to
the calling procedure.
21
returned value
actual parameters
optional control link
optional access link
saved machine status
local data
temporaries
22
Compile time layout of local data
◦ Suppose runtime storage comes in blocks of
contiguous bytes, where a byte is the smallest unit of
addressable memory
◦ A byte is usually 8 bits, and a number of bytes for a
word (e.g. 2 or 4 depending on the machine)
◦ Multi-byte objects are stored in consecutive bytes and
given the address of the first byte
◦ The field for local data is laid out as the declarations
in a procedure are examined at compile time.
23
◦ Variable-length data is kept outside this field
◦ We keep a count of the memory locations that have
been allocated for previous declarations
◦ From the count we determine a relative address of
the storage for a local with respect to some position
such as the beginning of the activation record
Padding
◦ space left unused due to alignment considerations is
referred to as padding.
24
Storage allocation strategies
A different storage allocation strategy is
used in each of the three data areas in the
organization
a) Static allocation
Lays out storage for all data objects at compile time
b) Stack allocation
Manages runtime storage as a stack
c) Heap allocation
Allocates and de-allocates storage as needed at
runtime from a data area known as a heap.
25
a) Static allocation
◦ Names are bound to storage as the program
is compiled, so there is no need for runtime
support package
◦ This property allows the values of local names
to be retained across activations of a
procedure
◦ The compiler must eventually decide where
the activation records go, relative to the
target code and to one another.
26
◦ Limitations with using static allocation alone
1. The size of a data object and constraints on its
position in memory must be known at compile
time
2. Recursive procedures are restricted because all
activations of a procedure use the same bindings
for local names
3. Data structures cannot be created dynamically,
since there is no mechanism for storage allocation
at runtime.
27
b) 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.
◦ Storage for the locals in each call of a procedure is
contained in the activation record for that call. Thus
locals are bound to fresh storage in each activation,
because a new activation record is pushed onto the
stack when a call is made e.g.
If a register top marks the top of stack. At runtime, an
activation record can be allocated and de-allocated by
incrementing and decrementing top, respectively, by the side of
the record.
28
Calling sequences
◦ Procedure calls are implemented by generating calling
sequences in the target code
◦ A call sequence allocates an activation record and
enters information into its fields.
◦ A return sequence restores the state of the machine
so the calling procedure can continue execution.
◦ The code for the callee can access its temporaries
and local data using offsets from the top-sp
29
◦ A possible call sequence is:
1. Caller evaluates actuals
2. Caller stores a return address and the old value
of top-sp into the callee’s activation record. Caller
then increments top-sp i.e. top-sp is moved past
the caller’s local data and temporaries and the
callee’s parameter and status fields.
3. Callee saves register values and other status
information
4. Callee initializes its local data and begins
execution.
30
◦ A possible return sequence is:
1. Callee places a return value next to the activation
record of the caller
2. Using the information in the status field, the callee
restores top-sp and other registers and branches
to a return address in the caller’s code
3. Although top-sp has been decremented, the caller
can copy the returned value into its own
activation record and use it to evaluate an
expression.
31
◦ Dangling references
Whenever storage can be de-allocated, the problem
of dangling references arise
A dangling reference occurs when there is a
reference to storage that has been de-allocated
It is a logical error to use dangling references, since
the value of de-allocated storage is undefined
according to the semantics of most programming
languages.
32
c) Heap allocation
◦ The stack allocation strategy discussed above
cannot be used if either of the following is
possible
Values of local names must be retained when an
activation ends
A called activation outlives the caller.
◦ In each of the above two cases, the de-
allocation of activation records need not
occur in a last-in-first-out (LIFO) fashion – so
a stack becomes irrelevant.
33
◦ In a heap, the record for an activation of
procedure r is retained when the activation
ends
◦ The record for the new activation q(1,9)
therefore cannot follow that for s physically, as
it did in stack
◦ If the retained activation record for s is de-
allocated, there will be free space in the heap
between activation records for s and q(1,9).
34
Parameter passing
◦ When one procedure calls another, the usual method
for communication between them is through
parameters of the called procedure e.g.
Uses both non locals and parameters in the procedure to
exchange the values of a[i] and a[j]. Here the array a is non
local to the procedure exchange, and i and j are parameters.
(1) Procedure exchange(i,j: integer);
(2) var x: integer;
(3) begin
(4) x := a[i]; a[i] := a[j]; a[j] := x
(5) end
Pascal procedure swap with non locals and parameters
35
◦ Methods for associating actual and formal
parameters include:
i) call-by-value
ii) call-by-reference
iii) copy-restore
iv) call-by-name
v) Macro expansion
36
i) Call-by-value
Simplest methods can be implemented
as
◦ A formal parameter is treated like a local
name so its storage is in the activation
record of the called procedure
◦ The caller evaluates the actual parameters
and places their r-values in the storage for
formals.
37
ii) Call-by-reference(or call by address/location)
◦ A caller passes to the called procedure a pointer to the storage
address of each actual parameter
iii) Call-by-name
◦ A procedure is treated as if it were a macro i.e. its body is
substituted for the call in the caller, with the actual parameters
literally substituted for the formals. This substitution is called
macro expansion.
◦ Local names of the called procedure are kept distinct from the
name of the calling procedure. Its like each local of the called
procedure is being systematically renamed into a distinct new
name before the macro expansion is done.
◦ The actual parameters are surrounded by parentheses if
necessary to preserve their integrity.
38