iterate through heap
This commit is contained in:
parent
ccd7669fc3
commit
6e2dcacf57
7
src/h.h
7
src/h.h
@ -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);
|
||||
|
||||
16
src/main.c
16
src/main.c
@ -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");
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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) { }
|
||||
3
src/vm.c
3
src/vm.c
@ -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;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user