Refactor BlockHeader type on heap
parent
570553aadb
commit
d54125daa6
79
low.c
79
low.c
|
@ -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; \
|
||||||
|
@ -123,26 +137,27 @@ void init_memory() {
|
||||||
|
|
||||||
// Pointer for debugging: print the heap to stdout
|
// Pointer for debugging: print the heap to stdout
|
||||||
#define HEAP_PRINT_WIDTH 60
|
#define HEAP_PRINT_WIDTH 60
|
||||||
#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
|
||||||
|
|
Loading…
Reference in New Issue