added gc module
This commit is contained in:
parent
f32a16ea8e
commit
565d50b639
|
@ -3,6 +3,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/log.h>
|
||||
#include <gc/gc.h>
|
||||
|
||||
struct AST_Node_t *AST_new_node(enum AST_SyntaxElement_t kind, const char* value) {
|
||||
DEBUG("creating new AST node: %d \"%s\"", kind, value);
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
//
|
||||
// Created by servostar on 5/7/24.
|
||||
//
|
||||
|
||||
#include <gc/gc.h>
|
||||
#include <sys/log.h>
|
||||
#include <string.h>
|
||||
|
||||
#undef malloc
|
||||
#undef free
|
||||
#undef realloc
|
||||
|
||||
#define GC_HEAP_PREALLOC_CNT 10
|
||||
|
||||
typedef struct GC_Heap_Statistics_t {
|
||||
size_t bytes;
|
||||
} GC_Heap_Statistics;
|
||||
|
||||
static struct GC_Heap_t {
|
||||
RAW_PTR* blocks;
|
||||
size_t cap;
|
||||
size_t len;
|
||||
GC_Heap_Statistics statistics;
|
||||
} GC_GLOBAL_HEAP;
|
||||
|
||||
static void __GC_teardown(void) {
|
||||
INFO("Used %ld bytes in total", GC_GLOBAL_HEAP.statistics.bytes);
|
||||
|
||||
if (GC_GLOBAL_HEAP.blocks == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < GC_GLOBAL_HEAP.len; i++) {
|
||||
free(GC_GLOBAL_HEAP.blocks[i]);
|
||||
}
|
||||
|
||||
free(GC_GLOBAL_HEAP.blocks);
|
||||
|
||||
GC_GLOBAL_HEAP.blocks = NULL;
|
||||
}
|
||||
|
||||
static void __GC_check_init(void) {
|
||||
if (GC_GLOBAL_HEAP.blocks == NULL) {
|
||||
GC_GLOBAL_HEAP.cap = GC_HEAP_PREALLOC_CNT;
|
||||
const size_t bytes = sizeof(RAW_PTR) * GC_GLOBAL_HEAP.cap;
|
||||
GC_GLOBAL_HEAP.blocks = malloc(bytes);
|
||||
GC_GLOBAL_HEAP.len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GC_init(void) {
|
||||
atexit(__GC_teardown);
|
||||
}
|
||||
|
||||
static void __GC_check_overflow(void) {
|
||||
if (GC_GLOBAL_HEAP.len >= GC_GLOBAL_HEAP.cap) {
|
||||
GC_GLOBAL_HEAP.cap += GC_HEAP_PREALLOC_CNT;
|
||||
const size_t bytes = sizeof(RAW_PTR) * GC_GLOBAL_HEAP.cap;
|
||||
GC_GLOBAL_HEAP.blocks = realloc(GC_GLOBAL_HEAP.blocks, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
RAW_PTR GC_malloc(const size_t bytes) {
|
||||
const RAW_PTR ptr = malloc(bytes);
|
||||
|
||||
if (ptr == NULL) {
|
||||
FATAL("unable to allocate memory");
|
||||
}
|
||||
|
||||
__GC_check_init();
|
||||
__GC_check_overflow();
|
||||
|
||||
GC_GLOBAL_HEAP.blocks[GC_GLOBAL_HEAP.len++] = ptr;
|
||||
|
||||
GC_GLOBAL_HEAP.statistics.bytes += bytes;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void __GC_swap_ptr(RAW_PTR old, RAW_PTR new) {
|
||||
for (size_t i = 0; i < GC_GLOBAL_HEAP.len; i++) {
|
||||
if (GC_GLOBAL_HEAP.blocks[i] == old) {
|
||||
GC_GLOBAL_HEAP.blocks[i] = new;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RAW_PTR GC_realloc(RAW_PTR ptr, size_t bytes) {
|
||||
const RAW_PTR new_ptr = (RAW_PTR) realloc(ptr, bytes);
|
||||
|
||||
if (new_ptr == NULL) {
|
||||
FATAL("unable to reallocate memory");
|
||||
}
|
||||
|
||||
__GC_swap_ptr(ptr, new_ptr);
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void GC_free(RAW_PTR ptr) {
|
||||
DEBUG("freeing memory: %p", ptr);
|
||||
|
||||
for (size_t i = 0; i < GC_GLOBAL_HEAP.len; i++) {
|
||||
|
||||
if (ptr == GC_GLOBAL_HEAP.blocks[i]) {
|
||||
free(GC_GLOBAL_HEAP.blocks[i]);
|
||||
|
||||
GC_GLOBAL_HEAP.len--;
|
||||
|
||||
memcpy(&GC_GLOBAL_HEAP.blocks[i], &GC_GLOBAL_HEAP.blocks[i + 1], GC_GLOBAL_HEAP.len - i);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Created by servostar on 5/7/24.
|
||||
//
|
||||
|
||||
#ifndef GC_H
|
||||
#define GC_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define malloc GC_malloc
|
||||
#define free GC_free
|
||||
#define realloc GC_realloc
|
||||
|
||||
typedef void* RAW_PTR;
|
||||
|
||||
void GC_init(void);
|
||||
|
||||
RAW_PTR GC_malloc(size_t bytes);
|
||||
|
||||
RAW_PTR GC_realloc(RAW_PTR ptr, size_t bytes);
|
||||
|
||||
void GC_free(RAW_PTR ptr);
|
||||
|
||||
#endif //GC_H
|
|
@ -2,6 +2,7 @@
|
|||
%{
|
||||
#include <yacc/parser.tab.h>
|
||||
#include <sys/log.h>
|
||||
#include <gc/gc.h>
|
||||
|
||||
int yyLineNumber = 1;
|
||||
int yylex();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <sys/log.h>
|
||||
#include <yacc/parser.tab.h>
|
||||
#include <ast/ast.h>
|
||||
#include <gc/gc.h>
|
||||
|
||||
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
||||
|
||||
|
@ -47,6 +48,8 @@ void setup(void)
|
|||
// actual setup
|
||||
AST_init();
|
||||
|
||||
GC_init();
|
||||
|
||||
DEBUG("finished starting up gemstone...");
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define _SYS_ERR_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <gc/gc.h>
|
||||
|
||||
#define LOG_DEFAULT_STREAM stderr
|
||||
|
||||
|
|
Loading…
Reference in New Issue