Skip to content

Commit

Permalink
Implement arena allocator, add preprocessor arena
Browse files Browse the repository at this point in the history
  • Loading branch information
fuhsnn committed Dec 21, 2024
1 parent c716393 commit 35fdac6
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 4 deletions.
73 changes: 73 additions & 0 deletions alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ const char *__asan_default_options(void) {
#endif

#define FREE_THRESHOLD (100 * 1024)
#define PAGE_SIZE 4064

struct Page {
char buf[PAGE_SIZE];
Page *next;
};

Arena pp_arena;
bool free_alloc;

bool check_mem_usage(void) {
Expand All @@ -29,3 +36,69 @@ bool check_mem_usage(void) {
return stat.ru_maxrss > FREE_THRESHOLD;
#endif
}

static Page *new_page(void) {
Page *p = malloc(sizeof(Page));
p->next = NULL;
#if USE_ASAN
__asan_poison_memory_region(&p->buf, PAGE_SIZE);
#endif
return p;
}

static void *allocate(Arena *arena, size_t sz, bool clear) {
size_t aligned_sz = (sz + 15) & -16LL;

void *ptr;
if ((arena->used + aligned_sz) <= PAGE_SIZE) {
ptr = &arena->page->buf[arena->used];
arena->used += aligned_sz;
} else {
if (!arena->page->next)
arena->page->next = new_page();

arena->page = arena->page->next;
ptr = &arena->page->buf;
arena->used = aligned_sz;
}

#if USE_ASAN
__asan_unpoison_memory_region(ptr, sz);
if (clear)
memset(ptr, 0, sz);
#else
if (clear)
for (int i = 0; i < (aligned_sz >> 3); i++)
((int64_t *)ptr)[i] = 0;
#endif
return ptr;
}

void arena_on(Arena *arena) {
if (!arena->head_page)
arena->head_page = new_page();

arena->page = arena->head_page;
arena->on = true;
arena->used = 0;
}

void arena_off(Arena *arena) {
arena->on = false;

if (free_alloc) {
while (arena->head_page) {
Page *nxt = arena->head_page->next;
free(arena->head_page);
arena->head_page = nxt;
}
}
}

void *arena_malloc(Arena *a, size_t sz) {
return allocate(a, sz, false);
}

void *arena_calloc(Arena *a, size_t sz) {
return allocate(a, sz, true);
}
13 changes: 9 additions & 4 deletions preprocess.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,15 +425,15 @@ static void add_macro2(Macro *m, char *name, bool is_objlike, Token *body) {
}

static Macro *add_macro(char *name, bool is_objlike, Token *body) {
Macro *m = calloc(1, sizeof(Macro));
Macro *m = arena_calloc(&pp_arena, sizeof(Macro));
add_macro2(m, name, is_objlike, body);
return m;
}

static Macro *read_macro_params(Token **rest, Token *tok) {
Token head = {0};
Token *cur = &head;
Macro *m = calloc(1, sizeof(Macro));
Macro *m = arena_calloc(&pp_arena, sizeof(Macro));

while (!consume(rest, tok, ")")) {
if (m->arg_cnt++)
Expand Down Expand Up @@ -589,7 +589,7 @@ static MacroArg *find_arg(Token **rest, Token *tok, MacroContext *ctx) {
// __VA_OPT__(x) is treated like a parameter which expands to parameter-
// substituted (x) if macro-expanded __VA_ARGS__ is not empty.
if (equal(tok, "__VA_OPT__") && equal(tok->next, "(")) {
MacroArg *arg = malloc(sizeof(MacroArg));
MacroArg *arg = arena_malloc(&pp_arena, sizeof(MacroArg));
arg->tok = read_macro_arg_one(&tok, tok->next->next, true);

if (has_non_empty_va_arg(ctx, NULL))
Expand Down Expand Up @@ -1551,6 +1551,8 @@ static char *format_time(struct tm *tm) {
}

void init_macros(void) {
arena_on(&pp_arena);

// Define predefined macros
define_macro("_LP64", "1");
define_macro("__BYTE_ORDER__", "1234");
Expand Down Expand Up @@ -1791,8 +1793,10 @@ Token *preprocess(Token *tok) {
if (opt_E)
return tok;

if (!(free_alloc = check_mem_usage()))
if (!(free_alloc = check_mem_usage())) {
arena_off(&pp_arena);
return preprocess3(tok);
}

Token *t = tok;
for (; t->kind != TK_EOF; t = t->next) {
Expand All @@ -1818,5 +1822,6 @@ Token *preprocess(Token *tok) {
}

free(cond_incl.data);
arena_off(&pp_arena);
return tok;
}
13 changes: 13 additions & 0 deletions slimcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,21 @@ typedef struct Relocation Relocation;
//
// alloc.c

typedef struct Page Page;
typedef struct {
int used;
bool on;
Page *head_page;
Page *page;
} Arena;

void arena_on(Arena *arena);
void arena_off(Arena *arena);
void *arena_calloc(Arena *a, size_t sz);
void *arena_malloc(Arena *a, size_t sz);
bool check_mem_usage(void);

extern Arena pp_arena;
extern bool free_alloc;

//
Expand Down

0 comments on commit 35fdac6

Please sign in to comment.