CSCU9A5 Week 3

By the end of this week you should have the ability to:

Runtime Organisation: Static Storage Allocation

Memory is basically like a very long list with each element having an address and a value.

If we have a variable that might change in size, and indirect representation is used - a pointer. This mean that the variable can occupy a fixed size space in memory because it just points to the address of where the data is really stored (usually in the heap).

Stack storage allocation

Stacks are last-in-first-out data structures: think of a stack of paper where you can only add or remove from the top. Stacks are an effective way to store local variables throughout the lifetime of a program.

Stack Storage Allocation:

Example of Routines and returns

let
    var g: Integer;
    func F(m: Integer, n: Integer): Integer ~
        m * n
        
in
    begin
        getint(var g)
        putint(F(g, g+1))
    end
PUSH    1
LOADA   0[SB]
CALL    getint
LOAD    0[SB]
LOAD    0[SB]
PUSH    1
CALL    add
CALL(SB) F
CALL    putint
POP
HALT

F:
    LOAD    -2[LB]
    LOAD    -1[LB]
    CALL    mult
    RETURN(1) 2

Heap Storage Allocation and Garbage Collection

Heap storage allocation is another way to organise memory, and is good for indirect storage of variables.

A heap variable is allocated by a special command called an allocator in Java. This is whenever you use the keyword new and in C it is malloc(). These return a pointer to the variable in the heap. They exist in memory until it is unallocated (via free() in C or automatically in Java).

Heap is placed in opposite to the stack:

[   Stack   ] <-SB
[   a       ]
[   b       ]
[   ......  ] <-ST
[           ]
[   8       ] <-HT
[   H       ]
[           ]
[    Heap   ] <-HB

Heap Storage Allocation:

Code Generation: Code Selection

Code Selection is the process of choosing the specific machine code instructions that are needed to represent a high high-level code structure. Code Templates are used for this purpose, though it is complicated by dealing with special cases.

Storage Allocation is the process of deciding the addresses for each variable in the program. This is why we have spent some time discussing stack and heap memory.

We have parsed the program to an AST and applied contextual analysis to that AST to ensure that all the types are valid! We are now ready to generate the target code for our program.

n := n + 1
LOAD    n
LOAD    1
ADD     
STORE   n

Adding one to a variable is very common thing to do. We can instead use this instruction

LOAD    n
SUCC
STORE   n

SUCC, means successor instruction to increase the value on the top of the stack by one. This uses 3 instructions instead of 4, meaning it is around 25% faster.

The Triangle Abstract Machine

The Triangle Abstract Machine (TAM) is a virtual machine designed as the target for our case study compiler. It is also implemented in Java, and you have a copy of it by virtue of cloning the Triangle-Tools project. TAM has the following features:

A full description of TAM is given in the extracts from Programming Language Processors in Java given in the Canvas Reading List. You don’t need to become familiar with this but the text is there to serve as reference material and you will likely want to refer to it when reading and extending the compiler.

From Programming Language Processors in Java: Compilers and Interpreters by Watt, D.A

Yarr link be here! https://www.cin.ufpe.br/~jml/programming-language-processors-in-java-compilers-and-interpreters.9780130257864.25356.pdf

Layout of a TAM frame

2023-09-28_42

TAM instruction format

All TAM instructions have a common format.

[  op  ][  r  ][    n    ][         d       ]
 4 bits  4 bits   8 bits         16 bits 

TAM instructions

2023-09-28_55