Runtime Environments in Compiler Design (original) (raw)

Last Updated : 30 Apr, 2026

A runtime environment refers to the system that supports the execution of a compiled program. It connects the static program written in the source code with the dynamic actions performed during execution. The runtime environment manages memory, procedure calls, parameter passing, and other services required while the program runs.

**Activation Tree

An activation tree represents the sequence of procedure (function) calls during program execution. Each execution of a procedure is called an activation. Activations may be non-overlapping, nested, or recursive, depending on how functions call each other.

Properties

**Example - Consider the following program of Quicksort

void main() {
int n;
readarray();
quicksort(1, n);
}

void quicksort(int m, int n) {
if (m >= n) return; // base condition added
int i = partition(m, n);
quicksort(m, i - 1);
quicksort(i + 1, n);
}

The activation tree for this program will be: 1First main function as the root then main calls readarray and quicksort. Quicksort in turn calls partition and quicksort again. The flow of control in a program corresponds to a pre-order depth-first traversal of the activation tree which starts at the root.

Control Stack and Activation Records

Control stack or runtime stack is used to keep track of the active procedure activations i.e the procedures whose execution have not been completed. When a procedure is called, an activation record (stack frame) is pushed onto the stack. When the procedure finishes, the activation record is removed from the stack.

An activation record stores information required for a single procedure execution, including:

2

3

Control stack for the above quicksort example:

4

Subdivision of Runtime Memory

Runtime memory is divided into different regions to store program data during execution.

5

Storage Allocation Techniques

**Static Storage Allocation

Memory locations for variables are determined at compile time. Each variable is bound to the same memory location during all procedure activations.

Ex: FORTRAN was designed to permit static storage allocation.

**Stack Storage Allocation

Memory is managed using a stack structure where activation records are pushed and popped as procedures are called and completed.

**Heap Storage Allocation

Memory can be allocated and deallocated at any time during program execution.

Parameter Passing

Parameter passing is the mechanism used to transfer data between the calling procedure and the called procedure.

**Basic terminology

Parameter Passing Methods

Call by Value

The value of the actual parameter is copied into the formal parameter. Changes inside the function do not affect the original variable.

C++ `

#include using namespace std;

void swap(int a, int b) // call by value { int temp = a; a = b; b = temp; }

int main() { int a = 10, b = 20; swap(a, b); cout << a << " " << b << endl; return 0; }

`

Call by Reference

The address of the actual parameter is passed to the function. Any modification inside the function affects the original variable.

C++ `

#include using namespace std;

void swap(int &a, int &b) // call by reference { int temp = a; a = b; b = temp; }

int main() { int a = 10, b = 20; swap(a, b); cout << a << " " << b << endl; return 0; }

`

Call by Copy-Restore

Values are copied to the formal parameters during the call and copied back to the actual parameters when the function returns.

C++ `

#include using namespace std;

void swap(int &a, int &b) { /* A hybrid between call-by-value and call-by-reference is copy-restore linkage (also known as copy in and copy out ,or value-result) */

int copy_a, copy_b;
copy_a = a; // copy in phase
copy_b = b;

int temp = copy_a; // function proper
copy_a = copy_b;
copy_b = temp;

a = copy_a; // copy out phase
b = copy_b;

}

int main() { int a = 10, b = 20; swap(a, b); cout << a << " " << b << endl; return 0; } // code added by raunakraj232

`

Call by Name

Actual parameters are substituted for formal parameters in the function body and evaluated only when needed. This mechanism is mainly theoretical and not supported in most modern languages. This concept is mainly theoretical and is not directly supported in modern programming languages like C++. Therefore, no direct implementation is provided.

We can simulate Call by Name behavior using macros (approximation).

#include using namespace std;

#define SWAP(x, y)
do {
int temp = x;
x = y;
y = temp;
} while(0)

int main() { int a = 10, b = 20;

SWAP(a, b);

cout << "a = " << a << " b = " << b << endl;
return 0;

}

`

Advantages

Disadvantages