From 70dcc25c519ef72a37fa0c8ce100aef1a174bd6d Mon Sep 17 00:00:00 2001 From: dzaima Date: Sat, 29 May 2021 22:47:21 +0300 Subject: [PATCH] mm_buddyTemplate.c --- src/opt/mm_2buddy.c | 34 ++++++++++++++----- src/opt/mm_2buddy.h | 5 +-- src/opt/mm_buddy.c | 10 +++--- src/opt/mm_buddy.h | 1 + src/opt/mm_buddyTemplate.c | 67 ++++++++++++++++++++++++++++++++++++++ src/opt/mm_buddyTemplate.h | 56 ++----------------------------- src/opt/mm_malloc.c | 2 ++ src/opt/mm_malloc.h | 5 ++- 8 files changed, 110 insertions(+), 70 deletions(-) create mode 100644 src/opt/mm_buddyTemplate.c diff --git a/src/opt/mm_2buddy.c b/src/opt/mm_2buddy.c index 9567d5cc..9b753f0e 100644 --- a/src/opt/mm_2buddy.c +++ b/src/opt/mm_2buddy.c @@ -4,11 +4,29 @@ u64 currObjCounter; #endif -EmptyValue* b1_buckets[64]; -b1_AllocInfo* b1_al; -u64 b1_alCap; -u64 b1_alSize; -EmptyValue* b3_buckets[64]; -b3_AllocInfo* b3_al; -u64 b3_alCap; -u64 b3_alSize; +#define BSZ(X) (1ull<<(X)) +#define BSZI(X) ((u8)(64-__builtin_clzl((X)-1ull))) +#define MMI(X) X +#define BN(X) b1_##X +#define buckets b1_buckets +#include "mm_buddyTemplate.c" +#undef buckets +#undef BN +#undef BSZ +#undef BSZI + +#define BSZ(X) (3ull<<(X)) +#define BSZI(X) ((u8)(64-__builtin_clzl((X)/3-1ull))) +#define MMI(X) ((X)|64) +#define BN(X) b3_##X +#define buckets b3_buckets +#include "mm_buddyTemplate.c" +#undef buckets +#undef BN +#undef BSZ +#undef BSZI + +void mm_forHeap(V2v f) { + b1_forHeap(f); + b3_forHeap(f); +} diff --git a/src/opt/mm_2buddy.h b/src/opt/mm_2buddy.h index 826aa4fc..a6c1d58a 100644 --- a/src/opt/mm_2buddy.h +++ b/src/opt/mm_2buddy.h @@ -51,10 +51,6 @@ static void mm_free(Value* x) { if (x->mmInfo&64) b3_free(x); else b1_free(x); } -static void mm_forHeap(V2v f) { - b1_forHeap(f); - b3_forHeap(f); -} static u64 mm_round(usz x) { u8 b1 = 64-__builtin_clzl(x-1ull); @@ -67,3 +63,4 @@ static u64 mm_size(Value* x) { if (m&64) return 3ull<<(x->mmInfo&63); else return 1ull<<(x->mmInfo&63); } +void mm_forHeap(V2v f); diff --git a/src/opt/mm_buddy.c b/src/opt/mm_buddy.c index d31e493f..d0f0bc29 100644 --- a/src/opt/mm_buddy.c +++ b/src/opt/mm_buddy.c @@ -4,7 +4,9 @@ u64 currObjCounter; #endif -EmptyValue* buckets[64]; -mm_AllocInfo* mm_al; -u64 mm_alCap; -u64 mm_alSize; +#define BSZ(X) (1ull<<(X)) +#define BSZI(X) ((u8)(64-__builtin_clzl((X)-1ull))) +#define MMI(X) X +#define BN(X) mm_##X + +#include "mm_buddyTemplate.c" diff --git a/src/opt/mm_buddy.h b/src/opt/mm_buddy.h index 1f5ec86b..8bf4aa65 100644 --- a/src/opt/mm_buddy.h +++ b/src/opt/mm_buddy.h @@ -36,6 +36,7 @@ static u64 mm_round(usz sz) { static u64 mm_size(Value* x) { return BSZ(x->mmInfo&63); } +void mm_forHeap(V2v f); #undef BSZ #undef BSZI diff --git a/src/opt/mm_buddyTemplate.c b/src/opt/mm_buddyTemplate.c new file mode 100644 index 00000000..269958b9 --- /dev/null +++ b/src/opt/mm_buddyTemplate.c @@ -0,0 +1,67 @@ +#define AllocInfo BN(AllocInfo) +#define al BN(al) +#define alCap BN(alCap) +#define alSize BN(alSize) + +EmptyValue* buckets[64]; +AllocInfo* al; +u64 alCap; +u64 alSize; + +NOINLINE EmptyValue* BN(makeEmpty)(u8 bucket) { // result->next 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) { + u64 sz = BSZ(cb); + if (mm_heapAlloc+sz >= mm_heapMax) { printf("Heap size limit reached\n"); exit(1); } + mm_heapAlloc+= sz; + // gc_maybeGC(); + c = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_NORESERVE|MAP_PRIVATE|MAP_ANON, -1, 0); + if (alSize+1>=alCap) { + alCap = alCap? alCap*2 : 1024; + al = realloc(al, sizeof(AllocInfo)*alCap); + } + al[BN(alSize)++] = (AllocInfo){.p = (Value*)c, .sz = sz}; + if (c==MAP_FAILED) { printf("Failed to allocate memory\n"); exit(1); } + c->type = t_empty; + c->mmInfo = cb; + c->next = 0; + break; + } + } + c->mmInfo = MMI(bucket); + while (cb != bucket) { + cb--; + EmptyValue* b = (EmptyValue*) (BSZ(cb) + (u8*)c); + b->type = t_empty; + b->mmInfo = MMI(cb); + b->next = buckets[cb]; + buckets[cb] = b; + } + return c; +} +void BN(forHeap)(V2v f) { + for (u64 i = 0; i < alSize; i++) { + AllocInfo ci = al[i]; + Value* s = ci.p; + Value* e = (Value*)(ci.sz + (u8*)ci.p); + while (s!=e) { + if (s->type!=t_empty) f(s); + s = (Value*)(BSZ(s->mmInfo&63) + (u8*)s); + } + } +} + +#undef AllocInfo +#undef al +#undef alSize +#undef alCap +#undef MMI diff --git a/src/opt/mm_buddyTemplate.h b/src/opt/mm_buddyTemplate.h index 65c988bd..908ce15d 100644 --- a/src/opt/mm_buddyTemplate.h +++ b/src/opt/mm_buddyTemplate.h @@ -1,9 +1,9 @@ -extern EmptyValue* buckets[64]; - #define AllocInfo BN(AllocInfo) #define al BN(al) #define alCap BN(alCap) #define alSize BN(alSize) + +extern EmptyValue* buckets[64]; typedef struct AllocInfo { Value* p; u64 sz; @@ -12,46 +12,7 @@ extern AllocInfo* al; extern u64 alCap; extern u64 alSize; -static NOINLINE EmptyValue* BN(makeEmpty)(u8 bucket) { // result->next 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) { - u64 sz = BSZ(cb); - if (mm_heapAlloc+sz >= mm_heapMax) { printf("Heap size limit reached\n"); exit(1); } - mm_heapAlloc+= sz; - // gc_maybeGC(); - c = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_NORESERVE|MAP_PRIVATE|MAP_ANON, -1, 0); - if (alSize+1>=alCap) { - alCap = alCap? alCap*2 : 1024; - al = realloc(al, sizeof(AllocInfo)*alCap); - } - al[BN(alSize)++] = (AllocInfo){.p = (Value*)c, .sz = sz}; - if (c==MAP_FAILED) { printf("Failed to allocate memory\n"); exit(1); } - c->type = t_empty; - c->mmInfo = cb; - c->next = 0; - break; - } - } - c->mmInfo = MMI(bucket); - while (cb != bucket) { - cb--; - EmptyValue* b = (EmptyValue*) (BSZ(cb) + (u8*)c); - b->type = t_empty; - b->mmInfo = MMI(cb); - b->next = buckets[cb]; - buckets[cb] = b; - } - return c; -} +extern NOINLINE EmptyValue* BN(makeEmpty)(u8 bucket); // result->next is garbage static void BN(free)(Value* x) { onFree(x); @@ -86,17 +47,6 @@ static void* BN(allocL)(u8 bucket, u8 type) { x->type = type; return x; } -static void BN(forHeap)(V2v f) { - for (u64 i = 0; i < alSize; i++) { - AllocInfo ci = al[i]; - Value* s = ci.p; - Value* e = (Value*)(ci.sz + (u8*)ci.p); - while (s!=e) { - if (s->type!=t_empty) f(s); - s = (Value*)(BSZ(s->mmInfo&63) + (u8*)s); - } - } -} #undef MMI #undef AllocInfo diff --git a/src/opt/mm_malloc.c b/src/opt/mm_malloc.c index 8c1ef1b6..e633dd7f 100644 --- a/src/opt/mm_malloc.c +++ b/src/opt/mm_malloc.c @@ -1,9 +1,11 @@ #include "../core.h" #include #include +u64 mm_heapAlloc = 0ull-1ull; void gc_add(B x) { } void gc_addFn(vfn f) { } void gc_maybeGC() { } void gc_forceGC() { } void gc_visitRoots() { } +void mm_forHeap(V2v f) { } diff --git a/src/opt/mm_malloc.h b/src/opt/mm_malloc.h index 63f82dcb..94a486ad 100644 --- a/src/opt/mm_malloc.h +++ b/src/opt/mm_malloc.h @@ -1,5 +1,8 @@ +#include #include #include +extern u64 mm_heapAlloc; +extern u64 mm_heapMax; static void mm_free(Value* x) { onFree(x); @@ -26,8 +29,8 @@ void gc_addFn(vfn f); void gc_maybeGC(); void gc_forceGC(); void gc_visitRoots(); +void mm_forHeap(V2v f); static u64 mm_round(usz x) { return x; } static u64 mm_size(Value* x) { return malloc_usable_size(x); } static u64 mm_totalAllocated() { return -1; } -static void mm_forHeap(V2v f) { }