diff --git a/asmBuild b/asmBuild deleted file mode 100755 index 79a14fe9..00000000 --- a/asmBuild +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -clang -std=c11 -Wall -Wno-microsoft-anon-tag -fms-extensions -O3 -masm=intel -S src/main.c diff --git a/build b/build index 7db09716..294a39ab 100755 --- a/build +++ b/build @@ -1,2 +1,2 @@ #!/usr/bin/env bash -clang -std=c11 -O3 -Wall -Wno-microsoft-anon-tag -fms-extensions -o BQN -lm src/main.c +clang -std=gnu11 -O3 -Wall -Wno-microsoft-anon-tag -fms-extensions -o BQN -lm src/main.c diff --git a/debugBuild b/debugBuild index d628a21e..ea2a4b0a 100755 --- a/debugBuild +++ b/debugBuild @@ -1,2 +1,2 @@ #!/usr/bin/env bash -clang -DDEBUG -std=c11 -g -Wall -Wno-microsoft-anon-tag -fms-extensions -o BQN -lm src/main.c +clang -DDEBUG -std=gnu11 -g -Wall -Wno-microsoft-anon-tag -fms-extensions -o BQN -lm src/main.c diff --git a/src/h.h b/src/h.h index 35134e79..4aaacc7d 100644 --- a/src/h.h +++ b/src/h.h @@ -116,10 +116,13 @@ typedef struct Arr { } Arr; // memory manager -B mm_alloc (usz sz, u8 type, u64 tag); void* mm_allocN(usz sz, u8 type); void mm_free(Value* x); void mm_visit(B x); +B mm_alloc(usz sz, u8 type, u64 tag) { + assert(tag>1LL<<16 || tag==0); // make sure it's `ftag`ged :| + return b((u64)mm_allocN(sz,type) | tag); +} // some primitive actions void dec(B x); @@ -474,3 +477,34 @@ void arr_print(B x) { return x; } #endif + +#ifdef ALLOC_STAT +u64* ctr_a = 0; +u64* ctr_f = 0; +u64 actrc = 21000; +u64 talloc = 0; +u32** actrs; +#endif + +void onAlloc(usz sz, u8 type) { + #ifdef ALLOC_STAT + if (!actrs) { + actrs = malloc(sizeof(u32*)*actrc); + ctr_a = calloc(Type_MAX, sizeof(u64)); + ctr_f = calloc(Type_MAX, sizeof(u64)); + for (i32 i = 0; i < actrc; i++) actrs[i] = calloc(Type_MAX, sizeof(u32)); + } + assert(type=actrc? actrc-1 : (sz+3)/4][type]++; + ctr_a[type]++; + talloc+= sz; + #endif +} +void onFree(Value* x) { + #ifdef ALLOC_STAT + ctr_f[x->type]++; + #endif + #ifdef DEBUG + x->refc = 0x61616161; + #endif +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 1a368e04..f8d38d7c 100644 --- a/src/main.c +++ b/src/main.c @@ -8,7 +8,7 @@ #define FAKE_RUNTIME false #include "h.h" -#include "mm.c" +#include "mm_buddy.c" #include "harr.c" #include "i32arr.c" #include "utf.c" diff --git a/src/mm.c b/src/mm.c deleted file mode 100644 index 0d4ba37d..00000000 --- a/src/mm.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "h.h" -#include - -#ifdef ALLOC_STAT -u64* ctr_a = 0; -u64* ctr_f = 0; -u64 actrc = 21000; -u64 talloc = 0; -u32** actrs; -#endif - -void* aalloc(usz sz) { // actual allocate - void* p = malloc(sz); - return p; -} -void mm_free(Value* x) { - #ifdef ALLOC_STAT - ctr_f[x->type]++; - x->refc = 0x61616161; - #endif - free(x); -} - -void* mm_allocN(usz sz, u8 type) { - Value* x = aalloc(sz); - #ifdef ALLOC_STAT - if (!actrs) { - actrs = malloc(sizeof(u32*)*actrc); - ctr_a = calloc(Type_MAX, sizeof(u64)); - ctr_f = calloc(Type_MAX, sizeof(u64)); - for (i32 i = 0; i < actrc; i++) actrs[i] = calloc(Type_MAX, sizeof(u32)); - } - assert(type=actrc? actrc-1 : (sz+3)/4][type]++; - ctr_a[type]++; - talloc+= sz; - #endif - #ifdef DEBUG - memset(x, 'a', sz); - #endif - x->flags = x->extra = x->mmInfo = x->type = 0; - x->refc = 1; - x->type = type; - return x; -} -B mm_alloc(usz sz, u8 type, u64 tag) { - assert(tag>1LL<<16); // make sure it's `ftag`ged :| - return b((u64)mm_allocN(sz,type) | tag); -} -void mm_visit(B x) { - -} diff --git a/src/mm_buddy.c b/src/mm_buddy.c new file mode 100644 index 00000000..d437b144 --- /dev/null +++ b/src/mm_buddy.c @@ -0,0 +1,77 @@ +#include "h.h" +#include + +#ifndef MAP_NORESERVE + #define MAP_NORESERVE 0 // apparently needed for freebsd or something +#endif + +typedef struct EmptyValue EmptyValue; +struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else can be garbage + struct Value; + EmptyValue* next; +}; + +EmptyValue* buckets[64]; + +#define BSZ(x) (1ull<<(x)) + +EmptyValue* makeBucket(u8 bucket) { // next field of output is garbage + u8 cb = bucket; + EmptyValue* c; + while (true) { + cb++; + if (buckets[cb]) { + c = buckets[cb]; + assert((c->mmInfo&63)==cb); + buckets[cb] = c->next; + break; + } + if (cb >= 20) { + c = mmap(NULL, BSZ(cb), PROT_READ|PROT_WRITE, MAP_NORESERVE|MAP_PRIVATE|MAP_ANON, -1, 0); + if (c==MAP_FAILED) { + printf("failed to allocate memory\n"); + exit(1); + } + c->type = t_empty; + c->mmInfo = cb; + c->next = 0; + break; + } + } + while (cb != bucket) { + cb--; + EmptyValue* b = (EmptyValue*) (((char*)c)+BSZ(cb)); + b->type = t_empty; + b->mmInfo = cb; + b->next = 0; assert(buckets[cb]==0); + buckets[cb] = b; + } + c->mmInfo = bucket; + return c; +} + +void mm_free(Value* x) { + onFree(x); + EmptyValue* c = (EmptyValue*) x; + c->type = t_empty; + u8 b = c->mmInfo&63; + c->next = buckets[b]; + buckets[b] = c; +} + +void* mm_allocN(usz sz, u8 type) { + assert(sz>8); + u8 bucket = 64-__builtin_clzl(sz-1ull); // inverse of BSZ + EmptyValue* x = buckets[bucket]; + if (x==NULL) x = makeBucket(bucket); + else buckets[bucket] = x->next; + onAlloc(sz, type); + x->flags = x->extra = x->type = 0; + x->refc = 1; + x->type = type; + return x; +} + +void mm_visit(B x) { + +} diff --git a/src/mm_malloc.c b/src/mm_malloc.c new file mode 100644 index 00000000..eb5c3046 --- /dev/null +++ b/src/mm_malloc.c @@ -0,0 +1,19 @@ +#include "h.h" +#include + +void mm_free(Value* x) { + onFree(x); + free(x); +} + +void* mm_allocN(usz sz, u8 type) { + Value* x = malloc(sz); + onAlloc(sz, type); + x->flags = x->extra = x->mmInfo = x->type = 0; + x->refc = 1; + x->type = type; + return x; +} +void mm_visit(B x) { + +}