Skip to content

Commit

Permalink
push lol
Browse files Browse the repository at this point in the history
  • Loading branch information
ShawSumma committed Dec 21, 2023
1 parent 3420cce commit 3f893bf
Show file tree
Hide file tree
Showing 77 changed files with 9,312 additions and 2,350 deletions.
4 changes: 2 additions & 2 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ VM_SRCS := vm/ir/ir.c vm/lib.c vm/ir/type.c vm/ast/build.c vm/ast/comp.c vm/ast/
ALL_SRCS = $(VM_SRCS) $(STD_SRCS) $(EXTRA_SRCS) $(TREES_SRCS)
ALL_OBJS = $(ALL_SRCS:%.c=$(OBJ_DIR)/%.o)

TB_SRCS := vendor/common/common.c vendor/common/perf.c vendor/tb/src/libtb.c vendor/tb/src/x64/x64.c
TB_SRCS := vendor/common/common.c vendor/common/perf.c vendor/tb/src/libtb.c vendor/tb/src/x64/x64_target.c
TB_OBJS = $(TB_SRCS:%.c=$(OBJ_DIR)/%.o)

OBJS = $(ALL_OBJS) $(GC_OBJS) $(TB_OBJS)
Expand Down Expand Up @@ -77,7 +77,7 @@ minivm$(EXE) $(BIN_DIR)/minivm$(EXE): $(OBJ_DIR)/main/minivm.o $(OBJS)

$(TB_OBJS): $(@:$(OBJ_DIR)/%.o=%.c)
@mkdir -p $$(dirname $(@))
$(CC) -w -c $(OPT) $(@:$(OBJ_DIR)/%.o=%.c) -o $(@) $(CFLAGS) -I vendor/tb/include -I vendor/common -DCUIK_USE_TB -DLOG_SUPPRESS
$(CC) -w -c $(OPT) $(@:$(OBJ_DIR)/%.o=%.c) -o $(@) $(CFLAGS) -I vendor/tb/include -I vendor/common -DCUIK_USE_TB -DLOG_SUPPRESS -DTB_HAS_X64

$(PROG_OBJS) $(ALL_OBJS) $(GC_OBJS): $(@:$(OBJ_DIR)/%.o=%.c)
@mkdir -p $$(dirname $(@))
Expand Down
10 changes: 10 additions & 0 deletions vendor/common/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
////////////////////////////////////////////////////////////////////////////////
// Cuik repository common utilities
////////////////////////////////////////////////////////////////////////////////

This is used by all kinds of components within the project, almost everything
will be including it. It has nice macros and includes.

TODO:

* move everything to using the iterator macros
2 changes: 2 additions & 0 deletions vendor/common/arena.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ TB_API void tb_arena_destroy(TB_Arena* restrict arena);
TB_API void* tb_arena_unaligned_alloc(TB_Arena* restrict arena, size_t size);
TB_API void* tb_arena_alloc(TB_Arena* restrict arena, size_t size);

TB_API void* tb_arena_realloc(TB_Arena* restrict arena, void* old, size_t size);

// return false on failure
TB_API bool tb_arena_free(TB_Arena* restrict arena, void* ptr, size_t size);
TB_API void tb_arena_pop(TB_Arena* restrict arena, void* ptr, size_t size);
Expand Down
80 changes: 80 additions & 0 deletions vendor/common/chunked_array.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Arena-backed arrays without fully contiguous memory
#ifndef NL_CHUNKED_ARRAY_H
#define NL_CHUNKED_ARRAY_H

typedef struct NL_ArrChunk NL_ArrChunk;
struct NL_ArrChunk {
NL_ArrChunk* next;
size_t cap;
size_t count;
void* elems[];
};

typedef struct NL_ChunkedArr {
TB_Arena* arena;
TB_ArenaSavepoint sp;

NL_ArrChunk* first;
NL_ArrChunk* last;
} NL_ChunkedArr;

NL_ChunkedArr nl_chunked_arr_alloc(TB_Arena* arena);
void nl_chunked_arr_put(NL_ChunkedArr* arr, void* v);
void nl_chunked_arr_reset(NL_ChunkedArr* arr);

// we're done with growing it, so we don't wanna take up any more reserved space
void nl_chunked_arr_trim(NL_ChunkedArr* arr);

#endif // NL_CHUNKED_ARRAY_H

#ifdef NL_CHUNKED_ARRAY_IMPL
#include <common.h>

NL_ChunkedArr nl_chunked_arr_alloc(TB_Arena* arena) {
TB_ArenaSavepoint sp = tb_arena_save(arena);
tb_arena_realign(arena);

ptrdiff_t leftovers = arena->high_point - (arena->watermark + sizeof(NL_ChunkedArr));
if (leftovers < 64) {
leftovers = arena->chunk_size - sizeof(NL_ArrChunk);
}

ptrdiff_t num_elems = leftovers / sizeof(void*);
NL_ArrChunk* arr = tb_arena_unaligned_alloc(arena, sizeof(NL_ArrChunk) + num_elems*sizeof(void*));
arr->next = NULL;
arr->cap = num_elems;
arr->count = 0;

return (NL_ChunkedArr){ arena, sp, arr, arr };
}

void nl_chunked_arr_put(NL_ChunkedArr* arr, void* v) {
NL_ArrChunk* last = arr->last;
if (last->cap == last->count) {
// allocate new chunk
ptrdiff_t leftovers = arr->arena->chunk_size - sizeof(NL_ArrChunk);
ptrdiff_t num_elems = leftovers / sizeof(void*);
NL_ArrChunk* new_chk = tb_arena_alloc(arr->arena, sizeof(NL_ChunkedArr) + num_elems*sizeof(void*));

// append
arr->last->next = new_chk;
arr->last = new_chk;
}
last->elems[last->count++] = v;
}

void nl_chunked_arr_reset(NL_ChunkedArr* arr) {
tb_arena_restore(arr->arena, arr->sp);
}

void nl_chunked_arr_trim(NL_ChunkedArr* arr) {
TB_Arena* arena = arr->arena;

void* top = &arr->last->elems[arr->last->count];
tb_arena_pop(arena, top, (arr->last->cap - arr->last->count) * sizeof(void*));
arr->last->cap = arr->last->count;

tb_arena_realign(arena);
}

#endif // NL_CHUNKED_ARRAY_IMPL
23 changes: 20 additions & 3 deletions vendor/common/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
#include <hash_map.h>

#define NL_HASH_SET_IMPL
#include <hash_set.h>
#include <new_hash_map.h>

#define NL_CHUNKED_ARRAY_IMPL
#include <chunked_array.h>

#define LOG_USE_COLOR
#include "log.c"
Expand Down Expand Up @@ -58,8 +61,7 @@ void* cuik__valloc(size_t size) {
cuik__page_size = 4096;
cuik__page_mask = 4095;

// return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
return GC_malloc(size);
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
#endif
}

Expand Down Expand Up @@ -119,6 +121,20 @@ void* tb_arena_unaligned_alloc(TB_Arena* restrict arena, size_t size) {
}
}

TB_API void* tb_arena_realloc(TB_Arena* restrict arena, void* old, size_t size) {
char* p = old;
if (p + size == arena->watermark) {
// try to resize
arena->watermark = old;
}

char* dst = tb_arena_unaligned_alloc(arena, size);
if (dst != p && old) {
memcpy(dst, old, size);
}
return dst;
}

void tb_arena_pop(TB_Arena* restrict arena, void* ptr, size_t size) {
char* p = ptr;
assert(p + size == arena->watermark); // cannot pop from arena if it's not at the top
Expand Down Expand Up @@ -159,6 +175,7 @@ void tb_arena_restore(TB_Arena* arena, TB_ArenaSavepoint sp) {
}

arena->top = sp.top;
arena->top->next = NULL;
arena->watermark = sp.watermark;
arena->high_point = &sp.top->data[arena->chunk_size - sizeof(TB_ArenaChunk)];
}
Expand Down
11 changes: 4 additions & 7 deletions vendor/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,10 @@
#define cuik_realloc(ptr, size) mi_realloc(ptr, size)
#define cuik_strdup(x) mi_strdup(x)
#else
void *GC_malloc(size_t size);
void *GC_realloc(void *ptr, size_t size);
void *GC_free(void *ptr);
#define cuik_malloc(size) GC_malloc(size)
#define cuik_calloc(count, size) GC_malloc((count) * (size))
#define cuik_free(size) ((void)(size))
#define cuik_realloc(ptr, size) GC_realloc(ptr, size)
#define cuik_malloc(size) malloc(size)
#define cuik_calloc(count, size) calloc(count, size)
#define cuik_free(size) free(size)
#define cuik_realloc(ptr, size) realloc(ptr, size)

#ifdef _WIN32
#define cuik_strdup(x) _strdup(x)
Expand Down
11 changes: 4 additions & 7 deletions vendor/common/hash_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@
#define NL_REALLOC(p, s) mi_realloc(p, s)
#define NL_FREE(p) mi_free(p)
#else
void *GC_malloc(size_t size);
void *GC_realloc(void *ptr, size_t size);
void *GC_free(void *ptr);
#define NL_MALLOC(s) GC_malloc(s)
#define NL_CALLOC(c, s) GC_malloc((c) * s)
#define NL_REALLOC(p, s) GC_realloc(p, s)
#define NL_FREE(p) ((void)(p))
#define NL_MALLOC(s) malloc(s)
#define NL_CALLOC(c, s) calloc(c, s)
#define NL_REALLOC(p, s) realloc(p, s)
#define NL_FREE(p) free(p)
#endif

#define NL_Map(K, V) struct { K k; V v; }*
Expand Down
2 changes: 1 addition & 1 deletion vendor/common/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ typedef void (*log_LockFn)(bool lock, void *udata);

enum { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };

#if !defined(LOG_SUPPRESS)
#if 0
#define log_trace(...) log_log(LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__)
#define log_debug(...) log_log(LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define log_info(...) log_log(LOG_INFO, __FILE__, __LINE__, __VA_ARGS__)
Expand Down
131 changes: 128 additions & 3 deletions vendor/common/hash_set.h → vendor/common/new_hash_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#define NL_HASHSET_HIGH_BIT (~(SIZE_MAX >> ((size_t) 1)))
#define NL_HASHSET_INDEX_BITS (SIZE_MAX >> ((size_t) 1))

////////////////////////////////
// Hashset
////////////////////////////////
typedef struct NL_HashSet {
TB_Arena* allocator;

Expand Down Expand Up @@ -35,6 +38,31 @@ void nl_hashset_remove2(NL_HashSet* restrict hs, void* ptr, NL_HashFunc hash, NL
#define nl_hashset_capacity(hs) (1ull << (hs)->exp)
#define nl_hashset_for(it, hs) for (void **it = (hs)->data, **_end_ = &it[nl_hashset_capacity(hs)]; it != _end_; it++) if (*it != NULL && *it != NL_HASHSET_TOMB)

////////////////////////////////
// Hashmap
////////////////////////////////
typedef struct {
void *k, *v;
} NL_TableEntry;

typedef struct {
TB_Arena* allocator;

size_t exp, count;
NL_TableEntry* data;
} NL_Table;

NL_Table nl_table_alloc(size_t cap);
NL_Table nl_table_arena_alloc(TB_Arena* arena, size_t cap);
void nl_table_free(NL_Table tbl);

bool nl_table_put(NL_Table* restrict tbl, void* k, void* v);
void* nl_table_get(NL_Table* restrict tbl, void* k);
size_t nl_table_lookup(NL_Table* restrict tbl, void* k);

#define nl_table_capacity(tbl) (1ull << (tbl)->exp)
#define nl_table_for(it, tbl) for (NL_TableEntry *it = (tbl)->data, *_end_ = &it[nl_table_capacity(tbl)]; it != _end_; it++) if (it->k != NULL && it->k != NL_HASHSET_TOMB)

#endif /* NL_HASH_SET_H */

#ifdef NL_HASH_SET_IMPL
Expand All @@ -53,9 +81,7 @@ NL_HashSet nl_hashset_alloc(size_t cap) {
size_t exp = 64 - __builtin_clzll(cap - 1);
#endif

cap = (cap == 1 ? 1 : 1 << exp);

return (NL_HashSet){ .exp = exp, .data = cuik_calloc(cap, sizeof(void*)) };
return (NL_HashSet){ .exp = exp, .data = cuik_calloc(1u << exp, sizeof(void*)) };
}

NL_HashSet nl_hashset_arena_alloc(TB_Arena* arena, size_t cap) {
Expand Down Expand Up @@ -219,4 +245,103 @@ void nl_hashset_clear(NL_HashSet* restrict hs) {
hs->count = 0;
}

////////////////////////////////
// Hashmap
////////////////////////////////
NL_Table nl_table_alloc(size_t cap) {
cap = (cap * 4) / 3;
if (cap < 4) cap = 4;

// next power of two
#if defined(_MSC_VER) && !defined(__clang__)
size_t exp = 64 - _lzcnt_u64(cap - 1);
#else
size_t exp = 64 - __builtin_clzll(cap - 1);
#endif

return (NL_Table){ .exp = exp, .data = cuik_calloc(1u << exp, sizeof(NL_TableEntry)) };
}

NL_Table nl_table_arena_alloc(TB_Arena* arena, size_t cap) {
cap = (cap * 4) / 3;
if (cap < 4) cap = 4;

// next power of two
#if defined(_MSC_VER) && !defined(__clang__)
size_t exp = 64 - _lzcnt_u64(cap - 1);
#else
size_t exp = 64 - __builtin_clzll(cap - 1);
#endif

void* data = tb_arena_alloc(arena, cap * sizeof(NL_TableEntry));
memset(data, 0, cap * sizeof(NL_TableEntry));
return (NL_Table){ .exp = exp, .data = data };
}

void nl_table_free(NL_Table tbl) {
if (tbl.allocator == NULL) {
cuik_free(tbl.data);
} else {
tb_arena_pop(tbl.allocator, tbl.data, (1ull << tbl.exp) * sizeof(NL_TableEntry));
}
}

bool nl_table_put(NL_Table* restrict tbl, void* k, void* v) {
uint32_t post_load_factor = ((1ull << tbl->exp) * 3) / 4;
if (tbl->count >= post_load_factor) {
// rehash
assert(tbl->allocator == NULL && "arena hashsets can't be resized!");
NL_Table new_tbl = nl_table_alloc(nl_table_capacity(tbl));
nl_table_for(p, tbl) {
nl_table_put(&new_tbl, p->k, p->v);
}
nl_table_free(*tbl);
*tbl = new_tbl;
}

uint32_t h = NL_HASHSET_HASH(k);
size_t mask = (1 << tbl->exp) - 1;
size_t first = h & mask, i = first;

do {
if (tbl->data[i].k == NULL) {
// insert
tbl->count++;
tbl->data[i].k = k;
tbl->data[i].v = v;
return true;
} else if (tbl->data[i].k == NL_HASHSET_TOMB) {
// recycle tombstone
tbl->data[i].k = k;
tbl->data[i].v = v;
return true;
} else if (tbl->data[i].k == k) {
tbl->data[i].v = v;
return true;
}

i = (i + 1) & mask;
} while (i != first);

abort();
}

void* nl_table_get(NL_Table* restrict tbl, void* k) {
uint32_t h = NL_HASHSET_HASH(k);
size_t mask = (1 << tbl->exp) - 1;
size_t first = h & mask, i = first;

do {
if (tbl->data[i].k == NULL) {
return NULL;
} else if (tbl->data[i].k == k) {
return tbl->data[i].v;
}

i = (i + 1) & mask;
} while (i != first);

return NULL;
}

#endif /* NL_HASH_SET_IMPL */
Loading

0 comments on commit 3f893bf

Please sign in to comment.