Refactor BlockHeader type on heap
parent
570553aadb
commit
d54125daa6
75
low.c
75
low.c
|
@ -11,7 +11,11 @@ typedef struct Text Text;
|
|||
typedef struct UnionType UnionType;
|
||||
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_MEMORY_LIMIT_TOO_LOW 11
|
||||
|
@ -38,11 +42,20 @@ typedef struct Var Var;
|
|||
// Memory block structure
|
||||
// This block functions as a header for memory allocations on the heap
|
||||
typedef struct BlockHeader {
|
||||
size_t size;
|
||||
int free;
|
||||
struct BlockHeader *next;
|
||||
} 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
|
||||
static uint8_t *memory = NULL;
|
||||
static uintptr_t heap_base;
|
||||
|
@ -69,7 +82,6 @@ void init_memory() {
|
|||
|
||||
BlockHeader *curr = (BlockHeader *)heap_base;
|
||||
curr->free = 1;
|
||||
curr->size = MEM_SIZE - sizeof(BlockHeader);
|
||||
curr->next = NULL;
|
||||
}
|
||||
|
||||
|
@ -78,17 +90,19 @@ void init_memory() {
|
|||
void *ptr = NULL; \
|
||||
BlockHeader *curr = (BlockHeader *)heap_base; \
|
||||
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 (curr->size >= (nbytes) + sizeof(BlockHeader) + 1) { \
|
||||
if (size >= (nbytes) + sizeof(BlockHeader) + 1) { \
|
||||
BlockHeader *new_block = (BlockHeader *)( \
|
||||
(uint8_t *)curr + sizeof(BlockHeader) + (nbytes) \
|
||||
); \
|
||||
new_block->size = curr->size - (nbytes) - sizeof(BlockHeader); \
|
||||
new_block->free = 1; \
|
||||
new_block->next = curr->next; \
|
||||
curr->size = (nbytes); \
|
||||
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 */ \
|
||||
curr->free = 0; \
|
||||
|
@ -126,23 +140,24 @@ void init_memory() {
|
|||
#define HEAP_PRINT() ({ \
|
||||
BlockHeader *curr = (BlockHeader *)heap_base; \
|
||||
while (curr) { \
|
||||
size_t size = BLOCK_SIZE(curr); \
|
||||
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) { \
|
||||
printf("free memory\n "); \
|
||||
} else { \
|
||||
printf("reserved memory\n "); \
|
||||
} \
|
||||
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("| "); } \
|
||||
printf("%02X ", content[i]); \
|
||||
if (i > HEAP_PRINT_WIDTH) { printf("..."); break; } \
|
||||
} \
|
||||
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 (content[i] == 0) { printf(" "); \
|
||||
} else if (content[i] >= 32 && content[i] < 127) { \
|
||||
|
@ -235,6 +250,43 @@ void init_memory() {
|
|||
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
|
||||
|
@ -380,6 +432,7 @@ int main(void) {
|
|||
// STACK_PRINT(curr);
|
||||
|
||||
while (curr) {
|
||||
// MEM_DIAGNOSTICS(curr);
|
||||
switch (curr->code_id) {
|
||||
case CODE_F: {
|
||||
// f(x) = print(x) and return x
|
||||
|
|
Loading…
Reference in New Issue