Chapter 10
Implementing
Subprograms
ISBN 0-321-33025-0
Chapter 10 Topics
• The General Semantics of Calls and Returns
• Implementing “Simple” Subprograms
• Implementing Subprograms with Stack-Dynamic
Local Variables
• Nested Subprograms
• Blocks
• Implementing Dynamic Scoping
Copyright © 2006 Addison-Wesley. All rights reserved. 1-2
The General Semantics of Calls and
Returns
• The subprogram call and return operations
of a language are together called its
subprogram linkage
• A subprogram call has numerous actions
associated with it
– Parameter passing methods
– Static local variables
– Execution status of calling program
– Transfer of control
– Subprogram nesting
Copyright © 2006 Addison-Wesley. All rights reserved. 1-3
Implementing “Simple”
Subprograms: Call Semantics
• Save the execution status of the caller
• Carry out the parameter-passing process
• Pass the return address to the callee
• Transfer control to the callee
Copyright © 2006 Addison-Wesley. All rights reserved. 1-4
Implementing “Simple”
Subprograms: Return Semantics
• If pass-by-value-result parameters are
used, move the current values of those
parameters to their corresponding actual
parameters
• If it is a function, move the functional value
to a place the caller can get it
• Restore the execution status of the caller
• Transfer control back to the caller
Copyright © 2006 Addison-Wesley. All rights reserved. 1-5
Implementing “Simple”
Subprograms: Parts
• Two separate parts: the actual code and the
noncode part (local variables and data that
can change)
• The format, or layout, of the noncode part
of an executing subprogram is called an
activation record
• An activation record instance is a concrete
example of an activation record (the
collection of data for a particular
subprogram activation)
Copyright © 2006 Addison-Wesley. All rights reserved. 1-6
An Activation Record for “Simple”
Subprograms
Copyright © 2006 Addison-Wesley. All rights reserved. 1-7
Code and Activation
Records of a Program
with “Simple”
Subprograms
Copyright © 2006 Addison-Wesley. All rights reserved. 1-8
Implementing Subprograms with
Stack-Dynamic Local Variables
• More complex activation record
– The compiler must generate code to cause
implicit allocation and de-allocation of local
variables
– Recursion must be supported (adds the
possibility of multiple simultaneous activations
of a subprogram)
Copyright © 2006 Addison-Wesley. All rights reserved. 1-9
Typical Activation Record for a Language
with Stack-Dynamic Local Variables
Copyright © 2006 Addison-Wesley. All rights reserved. 1-10
Implementing Subprograms with Stack-
Dynamic Local Variables: Activation Record
• The activation record format is static, but
its size may be dynamic
• The dynamic link points to the top of an
instance of the activation record of the
caller
• An activation record instance is dynamically
created when a subprogram is called
• Run-time stack
Copyright © 2006 Addison-Wesley. All rights reserved. 1-11
An Example Function
void sub(real total, ineteger part)
{
integer list[5];
real sum;
…
}
Copyright © 2006 Addison-Wesley. All rights reserved. 1-12
An Example Without Recursion
void A(integer X) {
integer Y;
...
C(Y);
...
}
void B(real R) {
integer S, T;
... main calls B
B calls A
A(S);
...
}
void C(integer Q) { A calls C
...
}
void main() {
real P;
...
B(P);
...
}
Copyright © 2006 Addison-Wesley. All rights reserved. 1-13
An Example Without Recursion
Copyright © 2006 Addison-Wesley. All rights reserved. 1-14
Dynamic Chain and Local Offset
• The collection of dynamic links in the stack at a
given time is called the dynamic chain, or call
chain
• Local variables can be accessed by their offset
from the beginning of the activation record. This
offset is called the local_offset
• The local_offset of a local variable can be
determined by the compiler at compile time
Copyright © 2006 Addison-Wesley. All rights reserved. 1-15
An Example With Recursion
• The activation record used in the
previous example supports recursion,
e.g.
int factorial (int n) {
<-----------------------------1
if (n <= 1) return 1;
else return (n * factorial(n - 1));
<-----------------------------2
}
void main() {
int value;
value = factorial(3);
<-----------------------------3
}
Copyright © 2006 Addison-Wesley. All rights reserved. 1-16
Activation Record for factorial
Copyright © 2006 Addison-Wesley. All rights reserved. 1-17
Nested Subprograms
• Some non-C-based static-scoped
languages (e.g., Fortran 95, Ada,
JavaScript) use stack-dynamic local
variables and allow subprograms to be
nested
• All variables that can be non-locally
accessed reside in some activation record
instance in the stack
• The process of locating a non-local
reference:
1. Find the correct activation record instance
2. Determine the correct offset within that
activation record instance
Copyright © 2006 Addison-Wesley. All rights reserved. 1-18
Locating a Non-local Reference
• Finding the offset is easy
• Finding the correct activation record
instance
– Static semantic rules guarantee that all non-
local variables that can be referenced have been
allocated in some activation record instance that
is on the stack when the reference is made
Copyright © 2006 Addison-Wesley. All rights reserved. 1-19
Implementing Dynamic Scoping
• Deep Access: non-local references are
found by searching the activation record
instances on the dynamic chain
• Shallow Access: put locals in a central place
– One stack for each variable name
– Central table with an entry for each variable
name
Copyright © 2006 Addison-Wesley. All rights reserved. 1-20
Example
procedure MAIN_6{ procedure B{
declare u, v; declare w, x;
... ...
} }
procedure C{
procedure A{
declare x, z;
declare w, v;
...
... }
}
MAIN_6 calls A, A calls A, A calls B, B calls C
Copyright © 2006 Addison-Wesley. All rights reserved. 1-21
Using Shallow Access to Implement
Dynamic Scoping
Copyright © 2006 Addison-Wesley. All rights reserved. 1-22
Static Scoping
• A static chain is a chain of static links that
connects certain activation record instances
• The static link in an activation record
instance for subprogram A points to one of
the activation record instances of A's static
parent
• The static chain from an activation record
instance connects it to all of its static
ancestors
Copyright © 2006 Addison-Wesley. All rights reserved. 1-23
Example Pascal Program
program MAIN_2;
var X : integer;
procedure BIGSUB;
var A, B, C : integer;
procedure SUB1;
var A, D : integer;
begin { SUB1 }
A := B + C; <-----------------------1
end; { SUB1 }
procedure SUB2(X : integer);
var B, E : integer;
procedure SUB3;
var C, E : integer;
begin { SUB3 }
SUB1;
E := B + A: <--------------------2
end; { SUB3 }
begin { SUB2 }
SUB3;
A := D + E; <-----------------------3
end; { SUB2 }
begin { BIGSUB }
SUB2(7);
end; { BIGSUB }
begin
BIGSUB;
end; { MAIN_2 }
Copyright © 2006 Addison-Wesley. All rights reserved. 1-24
Example Pascal Program (continued)
• Call sequence for MAIN_2
MAIN_2 calls BIGSUB
BIGSUB calls SUB2
SUB2 calls SUB3
SUB3 calls SUB1
Copyright © 2006 Addison-Wesley. All rights reserved. 1-25
Stack Contents at
Position 1
Copyright © 2006 Addison-Wesley. All rights reserved. 1-26
Displays
• An alternative to static chains
• Static links are stored in a single array
called a display
• The contents of the display at any given
time is a list of addresses of the accessible
activation record instances
Copyright © 2006 Addison-Wesley. All rights reserved. 1-27
Use of displays
Problem with static links:
Many links to follow if deeply nested. (how common?)
Use of displays reduces access always to 2 instructions:
1. Access Display[I] = Act. Rec. pointer at level I
2. Get L-value of variable (fixed offset in act. rec.)
Activation record structure:
Copyright © 2006 Addison-Wesley. All rights reserved. 1-28
Display example
Copyright © 2006 Addison-Wesley. All rights reserved. 1-29
Accessing variables
Data access is always a 2-step process:
1. [If non-local] Load Reg1, Display[I]
2. [For all] Load Reg2, L-value offset (Reg1)
Size of activation record for a procedure:
• Housekeeping storage (Fixed size = K):
– Dynamic Link
– Return address (in source program)
– End of activation record
– Registers
• Display
• Local data storage
Copyright © 2006 Addison-Wesley. All rights reserved. 1-30
Creating activation records
To create new activation record (e.g., P calls Q):
Assume have pointer to P's activation record.
1. Get EndStack pointer from P's activation record.
This is start of Q's activation record.
2. Add K+NewDisplaySize+LocalStorageSize.
3. Save as new EndStack in Q's activation record.
4. Set DL in Q to point to old activation record (P).
5. Fill in housekeeping in Q's activation record.
6. Set up new display in Q's activation record.
To create a new display to call from level I to level J:
Copy Display[1..J-1] from calling activation record.
Add new activation record pointer as Display[J].
To return:
Use dynamic link in current activation record to get old
activation record.
Use return address in housekeeping area to jump to.
Copyright © 2006 Addison-Wesley. All rights reserved. 1-31
Blocks
• Blocks are user-specified local scopes for variables
• An example in C
{int temp;
temp = list [upper];
list [upper] = list [lower];
list [lower] = temp
}
• The lifetime of temp in the above example begins
when control enters the block
• An advantage of using a local variable like temp is
that it cannot interfere with any other variable with
the same name
Copyright © 2006 Addison-Wesley. All rights reserved. 1-32
Implementing Blocks
• Two Methods:
1. Treat blocks as parameter-less subprograms
that are always called from the same location
– Every block has an activation record; an instance is
created every time the block is executed
2. Since the maximum storage required for a
block can be statically determined, this amount
of space can be allocated after the local
variables in the activation record
Copyright © 2006 Addison-Wesley. All rights reserved. 1-33
Optimizations in activation record
design
1. Instead of displays, use M registers only:
E.g., M1, M2, M3, M4 only.
What if a procedure is nested 5 deep?
1. Illegal program?
2. Spill to displays only in this case?
2. Note that C was designed for efficient execution:
• No nested procedures
• No need for displays or static links
• But needs dynamic links.
Copyright © 2006 Addison-Wesley. All rights reserved. 1-34
C++ storage access
General properties
1. Procedure allocations follow general rules of C
• Allocate activation records on a stack
• No need for static links, but need dynamic links
2. Class variables are allocated like structs in C.
[Structs in C++ can have function members. Functions
in structs are by default public, while in a class
are by default private.]
3. Static functions are not represented in runtime
activation records
4. Objects requiring dynamic binding (i.e., virtual
functions) are present in runtime activation
records
Copyright © 2006 Addison-Wesley. All rights reserved. 1-35
Sample C++ allocation example
class A {
public: int x;
virtual void p() {...};
void q() {...p()...};
protected: int y;
private: int Z;
...}
class B:A {
public: int w;
virtual void p() {...};
void r() {...p()...};
private: int v;
virtual void s() {...};
...}
Copyright © 2006 Addison-Wesley. All rights reserved. 1-36
Symbol table for example
Name Type Access Mode Location
X var public static A(1)
P func public dynamic A(2)
Q func public static addr of proc
Y var protected static A(3)
Z var private static A(4)
W var public static B(5)
P func public dynamic A(2)
R func public static Addr of proc
V var private static B(6)
S func private dynamic B(7)
Copyright © 2006 Addison-Wesley. All rights reserved. 1-37
Class instance records at runtime
X: R-value X: R-value
P: Addr of P in A P: Addr of P in B
Y: R-value Y: R-value
Z: R-value
Z: R-value
Class A W: R-value
V: R-value
S: Addr of S in B
Copyright © 2006 Addison-Wesley. All rights reserved. Class B 1-38
Summary
• Subprogram linkage semantics requires
many action by the implementation
• Simple subprograms have relatively basic
actions
• Stack-dynamic languages are more
complex
• Subprograms with stack-dynamic local
variables and nested subprograms have two
components
– actual code
– activation record
Copyright © 2006 Addison-Wesley. All rights reserved. 1-39
Summary (continued)
• Activation record instances contain formal
parameters and local variables among other
things
• Static chains are the primary method of
implementing accesses to non-local
variables in static-scoped languages with
nested subprograms
• Access to non-local variables in dynamic-
scoped languages can be implemented by
use of the dynamic chain or thru some
central variable table method
Copyright © 2006 Addison-Wesley. All rights reserved. 1-40