Heap Allocator
C0 Heap Allocator
Implemented in ./utility/memory.ts
interface C0HeapAllocator {
// Basic Operations
malloc(size: number): C0Pointer
free(ptr: C0Pointer): void
// Clear the whole heap memory, called when C0VM restarts
clear(): void
// Return the memory pool as ArrayBuffer - used for debug only
// Should not change the memory by altering the ArrayBuffer here
debug_getMemPool(): ArrayBuffer | undefined
// Operations on Heap Memory
cmstore(ptr: C0Pointer, value: DataView): void
cmload(ptr: C0Pointer): DataView
imstore(ptr: C0Pointer, value: DataView): void
imload(ptr: C0Pointer): DataView
amstore(ptr: C0Pointer, stored_ptr: C0Pointer): void
amload(ptr: C0Pointer): DataView
deref(ptr: C0Pointer, block_size: number): DataView
}
// Factory Function for HeapAllocator
export function createHeap(
allocator: C0HeapAllocatorConstructor,
size ?: number
): C0HeapAllocatorIn C0VM.ts, we use a ArrayBuffer to simulate the heap memory of a C program.
Since we are following the C's convention (0x0000000000000000 is a NULLpointer), the memory address at 0x00 is reserved and never touched.
malloc & free Functions
malloc & free FunctionsA C0HeapAllocator is able to manage its own memory pool and encapsulate the details with malloc and free interface.
malloc will allocate a block of memory and return a C0Pointer that referes to the starting position of the allocated memory segment.
free will free/release a block of memory. When the pointer given to free does not points to the start of memory segment, c0_memory_error should be throw to caller. (since free a memory with result of pointer arithmetic will lead to undefined behavior in C)
deref Function
deref FunctionThe deref function is a simulation of the * operator in C.
Given a C0Pointer, the deref function will return a DataView that is an alias of the ArrayBuffer of the memory block that pointer is pointing to.
Naïve Implementation of C0HeapAllocator
A naïve implementation of C0HeapAllocator is the VM_Memory class. Defined as follow:
export class VM_Memory implements C0HeapAllocator {
private memory_pool: ArrayBuffer;
private heap_top_address: number;
private memory_size: number;
constructor(size?: number);
malloc(size: number): C0Pointer;
free(ptr: C0Pointer): void;
clear(): void;
debug_getMemPool(): ArrayBuffer;
cmstore(ptr: C0Pointer, value: DataView): void;
cmload(ptr: C0Pointer): DataView;
imstore(ptr: C0Pointer, value: DataView): void;
imload(ptr: C0Pointer): DataView;
amstore(ptr: C0Pointer, stored_ptr: DataView): void;
amload(ptr: C0Pointer): DataView;
deref(ptr: DataView, block_size: number): DataView
}Written in ./utility/memory.ts, the VM_Memory class is a naïve implementation to the C0HeapAllocator interface.
The private property heap_top_address will keep track of the boundary between allocated and unallocated parts of the memory pool. Whenever a malloc is called to allocate n bytes of heap memory, the allocator will give the memory segment [heap_top, heap_top + n) to the caller and make heap_top += n.
Since 0x00 is reserved for NULL, allocator will start to allocate memory from 0x01.
free is not implemented in this naive implementation! Currently, calling the free will only write zero to the memory block the pointer is pointing at. Memory will NOT be re-claimed or re-allocated anyway.
In the future, we may implement a fancy allocator which will re-claim the freed memory.
Last updated