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; } Arr;
// memory manager // memory manager
typedef void (*V2v)(Value*);
void* mm_allocN(usz sz, u8 type); void* mm_allocN(usz sz, u8 type);
void mm_free(Value* x); void mm_free(Value* x);
void mm_visit(B 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) { B mm_alloc(usz sz, u8 type, u64 tag) {
assert(tag>1LL<<16 || tag==0); // make sure it's `ftag`ged :| assert(tag>1LL<<16 || tag==0); // make sure it's `ftag`ged :|
return b((u64)mm_allocN(sz,type) | tag); return b((u64)mm_allocN(sz,type) | tag);

View File

@ -44,6 +44,14 @@ u64 nsTime() {
return t.tv_sec*1000000000ull + t.tv_nsec; 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); __ssize_t getline (char **__restrict __lineptr, size_t *restrict n, FILE *restrict stream);
int main() { int main() {
@ -164,8 +172,12 @@ int main() {
dec(rtRes); dec(rtRes);
dec(comp); dec(comp);
// printf("done\n");fflush(stdout); while(1);
#ifdef ALLOC_STAT #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("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"); 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++) { for(i64 i = 0; i < actrc; i++) {
@ -173,7 +185,7 @@ int main() {
bool any = false; bool any = false;
for (i64 j = 0; j < Type_MAX; j++) if (c[j]) any=true; for (i64 j = 0; j < Type_MAX; j++) if (c[j]) any=true;
if (any) { if (any) {
printf("%ld", i); printf("%ld", i*4);
for (i64 k = 0; k < Type_MAX; k++) printf("‿%u", c[k]); for (i64 k = 0; k < Type_MAX; k++) printf("‿%u", c[k]);
printf("\n"); printf("\n");
} }

View File

@ -11,47 +11,55 @@ struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else ca
EmptyValue* next; EmptyValue* next;
}; };
#define BSZ(x) (1ull<<(x)) #define BSZ(X) (1ull<<(X))
#define BSZI(x) (64-__builtin_clzl((x)-1ull)) #define BSZI(X) (64-__builtin_clzl((X)-1ull))
#define MMI(x) x #define MMI(X) X
#define buckets b1_buckets #define BN(X) b1_##X
#define mm_free b1_free #define buckets b1_buckets
#define mm_makeEmpty b1_makeEmpty
#define mm_allocL b1_allocL
#include "mm_buddyTemplate.c" #include "mm_buddyTemplate.c"
#undef buckets #undef buckets
#undef mm_free #undef BN
#undef mm_makeEmpty #undef BSZ
#undef mm_allocL #undef BSZI
#define BSZ(x) ((1ull<<(x))*3) #define BSZ(X) (3ull<<(X))
#define BSZI(x) (64-__builtin_clzl((x/3)-1ull)) #define BSZI(X) (64-__builtin_clzl((X)/3-1ull))
#define MMI(x) ((x)|64) #define MMI(X) ((X)|64)
#define buckets b3_buckets #define BN(X) b3_##X
#define mm_free b3_free #define buckets b3_buckets
#define mm_makeEmpty b3_makeEmpty
#define mm_allocL b3_allocL
#include "mm_buddyTemplate.c" #include "mm_buddyTemplate.c"
#undef buckets #undef buckets
#undef mm_free #undef BN
#undef mm_makeEmpty #undef BSZ
#undef mm_allocL #undef BSZI
void* mm_allocN(usz sz, u8 type) { void* mm_allocN(usz sz, u8 type) {
assert(sz>12); assert(sz>12);
onAlloc(sz, type); onAlloc(sz, type);
u8 b1 = 64-__builtin_clzl(sz-1ull); 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); return b1_allocL(b1, type);
} }
void mm_free(Value* x) { void mm_free(Value* x) {
if (x->mmInfo&64) b3_free(x); if (x->mmInfo&64) b3_free(x);
else b1_free(x); else b1_free(x);
} }
void mm_forHeap(V2v f) {
b1_forHeap(f);
b3_forHeap(f);
}
u64 mm_round(usz sz) { u64 mm_round(usz x) {
u8 b1 = 64-__builtin_clzl(sz-1ull); u8 b1 = 64-__builtin_clzl(x-1ull);
u64 s3 = (1ull<<(b1-2)) * 3; u64 s3 = 3ull<<(b1-2);
if (sz<=s3) return s3; if (x<=s3) return s3;
return 1ull<<b1; 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; struct Value;
EmptyValue* next; 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) { #define BSZ(x) (1ull<<(x))
return BSZ(BSZI(sz)); #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) { void mm_visit(B x) {
} }
#include "mm_buddyTemplate.c"
void* mm_allocN(usz sz, u8 type) { void* mm_allocN(usz sz, u8 type) {
assert(sz>8); assert(sz>8);
onAlloc(sz, type); 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]; 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; u8 cb = bucket;
EmptyValue* c; EmptyValue* c;
while (true) { while (true) {
@ -14,6 +26,11 @@ static EmptyValue* mm_makeEmpty(u8 bucket) { // result->next is garbage
if (cb >= 20) { if (cb >= 20) {
u64 sz = BSZ(cb); u64 sz = BSZ(cb);
c = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_NORESERVE|MAP_PRIVATE|MAP_ANON, -1, 0); 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) { if (c==MAP_FAILED) {
printf("failed to allocate memory\n"); printf("failed to allocate memory\n");
exit(1); exit(1);
@ -36,7 +53,7 @@ static EmptyValue* mm_makeEmpty(u8 bucket) { // result->next is garbage
return c; return c;
} }
void mm_free(Value* x) { void BN(free)(Value* x) {
onFree(x); onFree(x);
EmptyValue* c = (EmptyValue*) x; EmptyValue* c = (EmptyValue*) x;
c->type = t_empty; c->type = t_empty;
@ -45,16 +62,34 @@ void mm_free(Value* x) {
buckets[b] = c; buckets[b] = c;
} }
void* mm_allocL(u8 bucket, u8 type) { void* BN(allocL)(u8 bucket, u8 type) {
EmptyValue* x = buckets[bucket]; EmptyValue* x = buckets[bucket];
if (x==NULL) x = mm_makeEmpty(bucket); if (x==NULL) x = BN(makeEmpty)(bucket);
else buckets[bucket] = x->next; else buckets[bucket] = x->next;
x->flags = x->extra = x->type = 0; x->flags = x->extra = x->type = 0;
x->refc = 1; x->refc = 1;
x->type = type; x->type = type;
return x; 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 MMI
#undef AllocInfo
#undef al
#undef alSize
#undef alCap

View File

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

View File

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