Yash Report
Yash Report
COMPILER DESIGN
OPEN ENDED EXPERIMENT REPORT
BACHELOR OF ENGINEERING IN
COMPUTER SCIENCE AND ENGINEERING
Submitted by:
Name: YASHASWINI B
USN: 1MJ20CS246
PROBLEM STATEMENT:
INTRODUCTION:
A program as a source code is merely a collection of text (code, statements etc.) and to
make it alive, it requires actions to be performed on the target machine. A program needs
memory resources to execute instructions. A program contains names for procedures,
identifiers etc., that require mapping with the actual memory location at runtime.
By runtime, we mean a program in execution. Runtime environment is a state of the target
machine, which may include software libraries, environment variables, etc., to provide
services to the processes running in the system.
Activation Trees:
Storage Allocation
Runtime environment manages runtime memory requirements for the following entities:
• Code : It is known as the text part of a program that does not change at
runtime. Its memory requirements are known at the compile time.
• Procedures : Their text part is static but they are called in a random manner.
That is why, stack storage is used to manage procedure calls and activations.
• Variables : Variables are known at the runtime only, unless they are global or
constant. Heap memory allocation scheme is used for managing allocation
and de-allocation of memory for variables in runtime.
3
Static Allocation
In this allocation scheme, the compilation data is bound to a fixed location in the memory
and it does not change when the program executes. As the memory requirement and
storage locations are known in advance, runtime support package for memory allocation
and de-allocation is not required.
Stack Allocation
Procedure calls and their activations are managed by means of stack memory allocation. It
works in last-in-first-out (LIFO) method and this allocation strategy is very useful for
recursive procedure calls.
The stack is a region of memory that is allocated for local variables, function calls, and return
addresses. It is a contiguous block of memory that grows and shrinks dynamically during program
execution. In the runtime environment, the stack is managed by the operating system, and the
compiler generates code that manipulates the stack through instructions like push and pop. The
stack typically grows from higher memory addresses to lower memory addresses, and when a
function is called, its local variables are pushed onto the stack, and when the function returns, the
stack pointer is adjusted to remove the local variables.
4
Heap Allocation
Variables local to a procedure are allocated and de-allocated only at runtime. Heap
allocation is used to dynamically allocate memory to the variables and claim it back when
the variables are no more required.
Except statically allocated memory area, both stack and heap memory can grow and shrink
dynamically and unexpectedly. Therefore, they cannot be provided with a fixed amount of
memory in the system.
The heap is another region of memory that is allocated for dynamic memory allocation. It is a more
flexible memory region that can grow and shrink dynamically as required during program execution.
In the runtime environment, the heap is also managed by the operating system, and the compiler
generates code that uses the malloc and free functions to allocate and deallocate memory on the
heap. When memory is allocated on the heap, the operating system returns a pointer to the start of
the allocated memory block, which the program can use to access the allocated memory.
The runtime environment also includes a memory manager that tracks and manages the usage of
both the stack and the heap. This memory manager keeps track of the available memory, allocates
memory as required, and deallocates memory when it is no longer needed. The memory manager
also performs other important functions like garbage collection, memory defragmentation, and
memory protection.
5
#include <stdio.h>
#include <stdlib.h>
int main() {
int stack_var = 42;
int *heap_var = (int*) malloc(sizeof(int));
*heap_var = 13;
free(heap_var);
return 0;
}
In this program, a stack variable stack_var is declared and initialized to 42, and a heap
variable heap_var is allocated using the malloc() function and initialized to 13. The
sizeof() operator is used to allocate the correct amount of memory for the heap_var
variable.
The values of both variables are then printed to the console using the printf()
function, and the free() function is used to deallocate the memory allocated for
heap_var.
During program execution, the stack variable is allocated on the stack, which is
managed by the operating system, and the heap variable is allocated on the heap,
which is also managed by the operating system. The memory manager in the runtime
environment keeps track of the usage of both the stack and the heap and deallocates
the memory when it is no longer needed.
Output:
Stack variable value: 42
Heap variable value: 13
6
CONCLUSION:
In summary, stack and heap management are two important aspects of memory
management in compilers and runtime environments. The stack is a region of
memory that is allocated for local variables, function calls, and return addresses, and
the heap is a region of memory that is allocated for dynamic memory allocation.
In the runtime environment, both the stack and the heap are managed by the
operating system, and the compiler generates code that manipulates the stack and
heap through instructions like push, pop, malloc, and free. The memory manager in
the runtime environment keeps track of the usage of both the stack and the heap,
allocates memory as required, and deallocates memory when it is no longer needed.
Overall, stack and heap management in runtime environments are crucial aspects of
compiler design, and require careful attention to ensure efficient and reliable
memory management during program execution.