Refactor BlockHeader type on heap

main
Bram van den Heuvel 2025-02-21 16:47:33 +01:00
parent 570553aadb
commit d54125daa6
1 changed files with 68 additions and 15 deletions

75
low.c
View File

@ -11,7 +11,11 @@ typedef struct Text Text;
typedef struct UnionType UnionType; typedef struct UnionType UnionType;
typedef struct Var Var; typedef struct Var Var;
#define MEM_SIZE 200//1024 * 1024 // 1 MB // You can change this number to decide how much memory the program is allowed
// 0 - 193 bytes -> The program refuses to start
// 194 - 217 bytes -> The program starts but doesn't do anything
// 218 + bytes -> The program runs successfully
#define MEM_SIZE 193 //1024 * 1024 // 1 MB
#define EXIT_GRACEFULLY 0 #define EXIT_GRACEFULLY 0
#define EXIT_MEMORY_LIMIT_TOO_LOW 11 #define EXIT_MEMORY_LIMIT_TOO_LOW 11
@ -38,11 +42,20 @@ typedef struct Var Var;
// Memory block structure // Memory block structure
// This block functions as a header for memory allocations on the heap // This block functions as a header for memory allocations on the heap
typedef struct BlockHeader { typedef struct BlockHeader {
size_t size;
int free; int free;
struct BlockHeader *next; struct BlockHeader *next;
} BlockHeader; } BlockHeader;
#define BLOCK_SIZE(header) ({ \
size_t s; \
if (header->next) { \
s = (uint8_t *)(header->next) - (uint8_t *)header; \
} else { \
s = (uint8_t *)(stack_top) - (uint8_t *)header; \
} \
s - sizeof(BlockHeader); \
})
// Global memory pool // Global memory pool
static uint8_t *memory = NULL; static uint8_t *memory = NULL;
static uintptr_t heap_base; static uintptr_t heap_base;
@ -69,7 +82,6 @@ void init_memory() {
BlockHeader *curr = (BlockHeader *)heap_base; BlockHeader *curr = (BlockHeader *)heap_base;
curr->free = 1; curr->free = 1;
curr->size = MEM_SIZE - sizeof(BlockHeader);
curr->next = NULL; curr->next = NULL;
} }
@ -78,17 +90,19 @@ void init_memory() {
void *ptr = NULL; \ void *ptr = NULL; \
BlockHeader *curr = (BlockHeader *)heap_base; \ BlockHeader *curr = (BlockHeader *)heap_base; \
while(curr) { \ while(curr) { \
if (curr->free && curr->size >= (nbytes)) { \ size_t size = (BLOCK_SIZE(curr)); \
if (curr->free && size >= (nbytes)) { \
/* If there's enough memory left over, split off into two */ \ /* If there's enough memory left over, split off into two */ \
if (curr->size >= (nbytes) + sizeof(BlockHeader) + 1) { \ if (size >= (nbytes) + sizeof(BlockHeader) + 1) { \
BlockHeader *new_block = (BlockHeader *)( \ BlockHeader *new_block = (BlockHeader *)( \
(uint8_t *)curr + sizeof(BlockHeader) + (nbytes) \ (uint8_t *)curr + sizeof(BlockHeader) + (nbytes) \
); \ ); \
new_block->size = curr->size - (nbytes) - sizeof(BlockHeader); \
new_block->free = 1; \ new_block->free = 1; \
new_block->next = curr->next; \ new_block->next = curr->next; \
curr->size = (nbytes); \
curr->next = new_block; \ curr->next = new_block; \
if ((uint8_t *)heap_top < (uint8_t *)new_block) { \
heap_top = (uintptr_t)new_block + sizeof(BlockHeader); \
} \
} \ } \
/* Assign block to new memory */ \ /* Assign block to new memory */ \
curr->free = 0; \ curr->free = 0; \
@ -126,23 +140,24 @@ void init_memory() {
#define HEAP_PRINT() ({ \ #define HEAP_PRINT() ({ \
BlockHeader *curr = (BlockHeader *)heap_base; \ BlockHeader *curr = (BlockHeader *)heap_base; \
while (curr) { \ while (curr) { \
size_t size = BLOCK_SIZE(curr); \
printf("BlockHeader at address %ld (physical %p): %lu byte", \ printf("BlockHeader at address %ld (physical %p): %lu byte", \
(uint8_t *)curr - memory, curr, curr->size \ (uint8_t *)curr - memory, curr, size \
); \ ); \
if (curr->size == 1) { printf(" of "); } else { printf("s of "); } \ if (size == 1) { printf(" of "); } else { printf("s of "); } \
if (curr->free) { \ if (curr->free) { \
printf("free memory\n "); \ printf("free memory\n "); \
} else { \ } else { \
printf("reserved memory\n "); \ printf("reserved memory\n "); \
} \ } \
unsigned char *content = (uint8_t *)curr; \ unsigned char *content = (uint8_t *)curr; \
for (int i = 0; i < curr->size + sizeof(BlockHeader); i++) { \ for (int i = 0; i < size + sizeof(BlockHeader); i++) { \
if (i == sizeof(BlockHeader)) { printf("| "); } \ if (i == sizeof(BlockHeader)) { printf("| "); } \
printf("%02X ", content[i]); \ printf("%02X ", content[i]); \
if (i > HEAP_PRINT_WIDTH) { printf("..."); break; } \ if (i > HEAP_PRINT_WIDTH) { printf("..."); break; } \
} \ } \
printf("\n "); \ printf("\n "); \
for (int i = 0; i < curr->size + sizeof(BlockHeader); i++) { \ for (int i = 0; i < size + sizeof(BlockHeader); i++) { \
if (i == sizeof(BlockHeader)) { printf("| "); } \ if (i == sizeof(BlockHeader)) { printf("| "); } \
if (content[i] == 0) { printf(" "); \ if (content[i] == 0) { printf(" "); \
} else if (content[i] >= 32 && content[i] < 127) { \ } else if (content[i] >= 32 && content[i] < 127) { \
@ -235,6 +250,43 @@ void init_memory() {
stack_top += (nbytes); \ stack_top += (nbytes); \
}) })
#define MEM_DIAGNOSTICS(curr) ({ \
printf("----------------------------\n"); \
printf("Heap base at address %ld (physical %p)\n", \
(uint8_t *)heap_base - (uint8_t *)memory, (uint8_t *)heap_base \
); \
printf("Heap top at address %ld (physical %p)\n", \
(uint8_t *)heap_top - (uint8_t *)memory, (uint8_t *)heap_top \
); \
HEAP_PRINT(); \
printf("----------------------------\n"); \
printf("Heap base at address %ld (physical %p)\n", \
(uint8_t *)heap_base - (uint8_t *)memory, (uint8_t *)heap_base \
); \
printf("Heap top at address %ld (physical %p)\n", \
(uint8_t *)heap_top - (uint8_t *)memory, (uint8_t *)heap_top \
); \
printf("Stack top at address %ld (physical %p)\n", \
(uint8_t *)stack_top - (uint8_t *)memory, (uint8_t *)stack_top \
); \
printf("Stack base at address %ld (physical %p)\n", \
(uint8_t *)stack_base - (uint8_t *)memory, (uint8_t *)stack_base \
); \
printf("----------------------------\n"); \
if (curr) { \
STACK_PRINT(curr); \
} else { \
printf("Stack is NULL!\n"); \
} \
printf("Stack top at address %ld (physical %p)\n", \
(uint8_t *)stack_top - (uint8_t *)memory, (uint8_t *)stack_top \
); \
printf("Stack base at address %ld (physical %p)\n", \
(uint8_t *)stack_base - (uint8_t *)memory, (uint8_t *)stack_base \
); \
printf("----------------------------\n"); \
})
/* ============================================================================ /* ============================================================================
* VARIABLES & VALUES * VARIABLES & VALUES
@ -380,6 +432,7 @@ int main(void) {
// STACK_PRINT(curr); // STACK_PRINT(curr);
while (curr) { while (curr) {
// MEM_DIAGNOSTICS(curr);
switch (curr->code_id) { switch (curr->code_id) {
case CODE_F: { case CODE_F: {
// f(x) = print(x) and return x // f(x) = print(x) and return x