iterate through heap

This commit is contained in:
dzaima 2021-04-06 02:15:37 +03:00
parent ccd7669fc3
commit 6e2dcacf57
7 changed files with 118 additions and 55 deletions

View File

@ -115,10 +115,15 @@ typedef struct Arr {
} Arr;
// memory manager
typedef void (*V2v)(Value*);
void* mm_allocN(usz sz, u8 type);
void mm_free(Value* x);
void mm_visit(B x);
u64 mm_round(usz x);
u64 mm_round(usz x);
u64 mm_size(Value* x);
u64 mm_totalAllocated();
void mm_forHeap(V2v f);
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);

View File

@ -44,6 +44,14 @@ u64 nsTime() {
return t.tv_sec*1000000000ull + t.tv_nsec;
}
u64 temp_heapUsage;
void heapUsedFn(Value* p) { temp_heapUsage+= mm_size(p); }
u64 heapUsed() {
temp_heapUsage = 0;
mm_forHeap(heapUsedFn);
return temp_heapUsage;
}
__ssize_t getline (char **__restrict __lineptr, size_t *restrict n, FILE *restrict stream);
int main() {
@ -164,8 +172,12 @@ int main() {
dec(rtRes);
dec(comp);
// printf("done\n");fflush(stdout); while(1);
#ifdef ALLOC_STAT
printf("total bytes allocated: %lu\n", talloc);
printf("total ever allocated: %lu\n", talloc);
printf("final heap size: %ld\n", mm_totalAllocated());
printf("leaked heap size: %ld\n", heapUsed());
printf("ctrA←"); for (i64 i = 0; i < Type_MAX; i++) { if(i)printf(""); printf("%lu", ctr_a[i]); } printf("\n");
printf("ctrF←"); for (i64 i = 0; i < Type_MAX; i++) { if(i)printf(""); printf("%lu", ctr_f[i]); } printf("\n");
for(i64 i = 0; i < actrc; i++) {
@ -173,7 +185,7 @@ int main() {
bool any = false;
for (i64 j = 0; j < Type_MAX; j++) if (c[j]) any=true;
if (any) {
printf("%ld", i);
printf("%ld", i*4);
for (i64 k = 0; k < Type_MAX; k++) printf("‿%u", c[k]);
printf("\n");
}

View File

@ -11,47 +11,55 @@ struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else ca
EmptyValue* next;
};
#define BSZ(x) (1ull<<(x))
#define BSZI(x) (64-__builtin_clzl((x)-1ull))
#define MMI(x) x
#define buckets b1_buckets
#define mm_free b1_free
#define mm_makeEmpty b1_makeEmpty
#define mm_allocL b1_allocL
#define BSZ(X) (1ull<<(X))
#define BSZI(X) (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 mm_free
#undef mm_makeEmpty
#undef mm_allocL
#undef BN
#undef BSZ
#undef BSZI
#define BSZ(x) ((1ull<<(x))*3)
#define BSZI(x) (64-__builtin_clzl((x/3)-1ull))
#define MMI(x) ((x)|64)
#define buckets b3_buckets
#define mm_free b3_free
#define mm_makeEmpty b3_makeEmpty
#define mm_allocL b3_allocL
#define BSZ(X) (3ull<<(X))
#define BSZI(X) (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 mm_free
#undef mm_makeEmpty
#undef mm_allocL
#undef BN
#undef BSZ
#undef BSZI
void* mm_allocN(usz sz, u8 type) {
assert(sz>12);
onAlloc(sz, type);
u8 b1 = 64-__builtin_clzl(sz-1ull);
if (sz <= (1ull<<(b1-2)) * 3) return b3_allocL(b1-2, type);
if (sz <= (3ull<<(b1-2))) return b3_allocL(b1-2, type);
return b1_allocL(b1, type);
}
void mm_free(Value* x) {
if (x->mmInfo&64) b3_free(x);
else b1_free(x);
}
void mm_forHeap(V2v f) {
b1_forHeap(f);
b3_forHeap(f);
}
u64 mm_round(usz sz) {
u8 b1 = 64-__builtin_clzl(sz-1ull);
u64 s3 = (1ull<<(b1-2)) * 3;
if (sz<=s3) return s3;
u64 mm_round(usz x) {
u8 b1 = 64-__builtin_clzl(x-1ull);
u64 s3 = 3ull<<(b1-2);
if (x<=s3) return s3;
return 1ull<<b1;
}
}
u64 mm_size(Value* x) {
u8 m = x->mmInfo;
if (m&64) return 3ull<<(x->mmInfo&63);
else return 1ull<<(x->mmInfo&63);
}
u64 mm_totalAllocated() {
return b1_totalAllocated() + b3_totalAllocated();
}

View File

@ -10,23 +10,29 @@ struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else ca
struct Value;
EmptyValue* next;
};
#define BSZI2(x) (64-__builtin_clzl((x)-1ull))
#define BSZ(x) (1ull<<(x))
#define BSZI BSZI2
#define MMI(x) x
u64 mm_round(usz sz) {
return BSZ(BSZI(sz));
}
#define BSZ(x) (1ull<<(x))
#define BSZI(x) (64-__builtin_clzl((x)-1ull))
#define MMI(x) x
#define BN(x) mm_##x
#include "mm_buddyTemplate.c"
void mm_visit(B x) {
}
#include "mm_buddyTemplate.c"
void* mm_allocN(usz sz, u8 type) {
assert(sz>8);
onAlloc(sz, type);
return mm_allocL(BSZI2(sz), type);
return mm_allocL(BSZI(sz), type);
}
u64 mm_round(usz sz) {
return BSZ(BSZI(sz));
}
u64 mm_size(Value* x) {
return BSZ(x->mmInfo&63);
}
#undef BSZ
#undef BSZI

View File

@ -1,6 +1,18 @@
EmptyValue* buckets[64];
static EmptyValue* mm_makeEmpty(u8 bucket) { // result->next is garbage
#define AllocInfo BN(AllocInfo)
#define al BN(al)
#define alCap BN(alCap)
#define alSize BN(alSize)
typedef struct AllocInfo {
Value* p;
u64 sz;
} AllocInfo;
AllocInfo* al;
u64 alCap;
u64 alSize;
static EmptyValue* BN(makeEmpty)(u8 bucket) { // result->next is garbage
u8 cb = bucket;
EmptyValue* c;
while (true) {
@ -14,6 +26,11 @@ static EmptyValue* mm_makeEmpty(u8 bucket) { // result->next is garbage
if (cb >= 20) {
u64 sz = BSZ(cb);
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);
@ -36,7 +53,7 @@ static EmptyValue* mm_makeEmpty(u8 bucket) { // result->next is garbage
return c;
}
void mm_free(Value* x) {
void BN(free)(Value* x) {
onFree(x);
EmptyValue* c = (EmptyValue*) x;
c->type = t_empty;
@ -45,16 +62,34 @@ void mm_free(Value* x) {
buckets[b] = c;
}
void* mm_allocL(u8 bucket, u8 type) {
void* BN(allocL)(u8 bucket, u8 type) {
EmptyValue* x = buckets[bucket];
if (x==NULL) x = mm_makeEmpty(bucket);
if (x==NULL) x = BN(makeEmpty)(bucket);
else buckets[bucket] = x->next;
x->flags = x->extra = x->type = 0;
x->refc = 1;
x->type = type;
return x;
}
void BN(forHeap)(V2v f) {
for (u64 i = 0; i < alSize; i++) {
AllocInfo ci = al[i];
Value* s = ci.p;
Value* e = ci.sz + (void*)ci.p;
while (s!=e) {
if (s->type!=t_empty) f(s);
s = BSZ(s->mmInfo&63) + (void*)s;
}
}
}
u64 BN(totalAllocated)() {
u64 res = 0;
for (u64 i = 0; i < alSize; i++) res+= al[i].sz;
return res;
}
#undef BSZ
#undef BSZI
#undef MMI
#undef AllocInfo
#undef al
#undef alSize
#undef alCap

View File

@ -15,10 +15,8 @@ void* mm_allocN(usz sz, u8 type) {
return x;
}
u64 mm_round(usz sz) {
return sz;
}
void mm_visit(B x) {
}
void mm_visit(B x) { }
u64 mm_round(usz x) { return x; }
u64 mm_size(Value* x) { return -1; }
u64 mm_totalAllocated() { return -1; }
void mm_forHeap(V2v f) { }

View File

@ -259,8 +259,7 @@ void allocStack(u64 am) {
if (am>left) {
u64 n = gStackEnd-gStackStart + am + 500;
u64 d = gStackStart-gStack;
if (gStack==NULL) gStackStart = malloc(n*sizeof(B));
else gStackStart = realloc(gStackStart, n*sizeof(B));
gStackStart = realloc(gStackStart, n*sizeof(B));
gStack = gStackStart+d;
gStackEnd = gStackStart+n;
}