From d2674db956f58f937ce21a76c89cc6fd00340858 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sun, 6 Mar 2022 15:38:30 +0200 Subject: [PATCH] heap dump --- .gitignore | 3 ++- src/builtins.h | 2 +- src/builtins/internal.c | 10 ++++++++-- src/h.h | 4 +--- src/opt/mm_2buddy.c | 4 ++++ src/opt/mm_2buddy.h | 1 + src/opt/mm_buddy.h | 1 + src/opt/mm_buddyTemplate.c | 11 +++++++++++ src/opt/mm_malloc.c | 1 + src/opt/mm_malloc.h | 1 + src/utils/file.c | 36 +++++++++++++++++++++++++++++++++++- src/utils/file.h | 1 + 12 files changed, 67 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 6ab67394..77b62c3e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ perf.* /obj/ /asm_* /src/singeli/gen -/Singeli \ No newline at end of file +/Singeli +CBQNHeapDump \ No newline at end of file diff --git a/src/builtins.h b/src/builtins.h index 9ea64354..04c47bb9 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -14,7 +14,7 @@ /* sysfn.c*/M(fName,"•file.Name") \ /* sysfn.c*/M(tRaw,"•term.Raw") M(tFlush,"•term.Flush") M(tCharB,"•term.CharB") M(tCharN,"•term.CharN") M(tOutRaw,"•term.OutRaw") M(tErrRaw,"•term.ErrRaw") \ /* inverse.c*/M(setInvReg, "(SetInvReg)") M(setInvSwap, "(SetInvSwap)") M(nativeInvReg, "(NativeInvReg)") M(nativeInvSwap, "(NativeInvSwap)") \ -/*internal.c*/M(itype,"•internal.Type") M(elType,"•internal.ElType") M(refc,"•internal.Refc") M(isPure,"•internal.IsPure") A(info,"•internal.Info") \ +/*internal.c*/M(itype,"•internal.Type") M(elType,"•internal.ElType") M(refc,"•internal.Refc") M(isPure,"•internal.IsPure") A(info,"•internal.Info") M(heapDump,"•internal.HeapDump") \ /*internal.c*/M(squeeze,"•internal.Squeeze") M(deepSqueeze,"•internal.DeepSqueeze") \ /*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare") \ /* arithm.c*/M(sin,"•math.Sin") M(cos,"•math.Cos") M(tan,"•math.Tan") M(asin,"•math.Asin") M(acos,"•math.Acos") M(atan,"•math.Atan") diff --git a/src/builtins/internal.c b/src/builtins/internal.c index 49f20147..98587020 100644 --- a/src/builtins/internal.c +++ b/src/builtins/internal.c @@ -1,5 +1,6 @@ #include "../core.h" #include "../utils/mut.h" +#include "../utils/file.h" #include "../builtins.h" #include "../ns.h" @@ -257,6 +258,11 @@ static B unshare(B x) { } } +B heapDump_c1(B t, B x) { + cbqn_heapDump(); + return m_c32(0); +} + B unshare_c1(B t, B x) { if (!isArr(x)) thrM("•internal.Unshare: Argument must be an array"); B r = unshare(x); @@ -272,8 +278,8 @@ B getInternalNS() { listVariations_def = m_str8l("if"); gc_addFn(variation_gcRoot); #define F(X) inc(bi_##X), - Body* d = m_nnsDesc("type","eltype","refc","squeeze","ispure","info","listvariations","variation","clearrefs","unshare","deepsqueeze"); - internalNS = m_nns(d,F(itype)F(elType)F(refc)F(squeeze)F(isPure)F(info)F(listVariations)F(variation)F(clearRefs)F(unshare)F(deepSqueeze)); + Body* d = m_nnsDesc("type","eltype","refc","squeeze","ispure","info","listvariations","variation","clearrefs","unshare","deepsqueeze","heapdump"); + internalNS = m_nns(d,F(itype)F(elType)F(refc)F(squeeze)F(isPure)F(info)F(listVariations)F(variation)F(clearRefs)F(unshare)F(deepSqueeze)F(heapDump)); #undef F gc_add(internalNS); } diff --git a/src/h.h b/src/h.h index 4731bc7e..158a0294 100644 --- a/src/h.h +++ b/src/h.h @@ -213,10 +213,8 @@ typedef union B { /*32*/ F(comp) F(block) F(body) F(scope) F(scopeExt) F(blBlocks) \ /*38*/ F(ns) F(nsDesc) F(fldAlias) F(vfyObj) F(hashmap) F(temp) F(nfn) F(nfnDesc) \ /*46*/ F(freed) F(harrPartial) F(customObj) \ - /*49*/ F(fun_invReg ) F(md1_invReg ) F(md2_invReg ) \ - /*52*/ F(fun_invSwap) F(md1_invSwap) F(md2_invSwap) \ \ - /*55*/ IF_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap)) + /*49*/ IF_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap)) enum Type { #define F(X) t_##X, diff --git a/src/opt/mm_2buddy.c b/src/opt/mm_2buddy.c index 6b1d2bc1..6e875ede 100644 --- a/src/opt/mm_2buddy.c +++ b/src/opt/mm_2buddy.c @@ -39,6 +39,10 @@ void mm_forFreedHeap(V2v f) { b1_forFreedHeap(f); b3_forFreedHeap(f); } +void mm_dumpHeap(FILE* f) { + b1_dumpHeap(f); + b3_dumpHeap(f); +} u64 mm_heapUsed() { u64 r = 0; diff --git a/src/opt/mm_2buddy.h b/src/opt/mm_2buddy.h index 99230c8d..37bdfdd8 100644 --- a/src/opt/mm_2buddy.h +++ b/src/opt/mm_2buddy.h @@ -40,6 +40,7 @@ static u64 mm_size(Value* x) { else return 1ull<<(x->mmInfo&63); } void mm_forHeap(V2v f); +void mm_dumpHeap(FILE* f); #undef BN #undef BSZ diff --git a/src/opt/mm_buddy.h b/src/opt/mm_buddy.h index b5121510..0fb92437 100644 --- a/src/opt/mm_buddy.h +++ b/src/opt/mm_buddy.h @@ -32,6 +32,7 @@ static u64 mm_size(Value* x) { return BSZ(x->mmInfo&63); } void mm_forHeap(V2v f); +void mm_dumpHeap(FILE* f); #undef LOG2 #undef BN diff --git a/src/opt/mm_buddyTemplate.c b/src/opt/mm_buddyTemplate.c index 95f3fd50..854c47db 100644 --- a/src/opt/mm_buddyTemplate.c +++ b/src/opt/mm_buddyTemplate.c @@ -1,3 +1,4 @@ +#include "../utils/file.h" #define AllocInfo BN(AllocInfo) #define buckets BN(buckets) #define al BN(al) @@ -97,6 +98,16 @@ void BN(forFreedHeap)(V2v f) { } } +void BN(dumpHeap)(FILE* f) { + for (u64 i = 0; i < alSize; i++) { + AllocInfo ci = al[i]; + u64 addrI = (u64) ci.p; + u8 size[8]; for (i32 i = 0; i < 8; i++) size[i] = (ci.sz>>(8*i)) & 0xff; fwrite(&size, 1, 8, f); + u8 addr[8]; for (i32 i = 0; i < 8; i++) addr[i] = (addrI>>(8*i)) & 0xff; fwrite(&addr, 1, 8, f); + fwrite(ci.p, 1, ci.sz, f); + } +} + #undef MMAP #undef AllocInfo #undef buckets diff --git a/src/opt/mm_malloc.c b/src/opt/mm_malloc.c index c3cb6b84..5765e00b 100644 --- a/src/opt/mm_malloc.c +++ b/src/opt/mm_malloc.c @@ -9,3 +9,4 @@ void gc_forceGC() { } void gc_visitRoots() { } void mm_forHeap(V2v f) { } u64 mm_heapUsed() { return 123; } // idk +void mm_dumpHeap(FILE* f) { } diff --git a/src/opt/mm_malloc.h b/src/opt/mm_malloc.h index e5bc8e88..718ea702 100644 --- a/src/opt/mm_malloc.h +++ b/src/opt/mm_malloc.h @@ -30,6 +30,7 @@ void gc_maybeGC(void); void gc_forceGC(void); void gc_visitRoots(void); void mm_forHeap(V2v f); +void mm_dumpHeap(FILE* f); static u64 mm_round(usz x) { return x; } static u64 mm_size(Value* x) { return malloc_usable_size(x); } diff --git a/src/utils/file.c b/src/utils/file.c index 1eba4562..9bb97d78 100644 --- a/src/utils/file.c +++ b/src/utils/file.c @@ -235,4 +235,38 @@ char path_type(B path) { if (S_ISBLK (mode)) return 'b'; if (S_ISCHR (mode)) return 'c'; thrM("Unexpected file type"); -} \ No newline at end of file +} +void cbqn_heapDump() { + char* name = "CBQNHeapDump"; + FILE* f = fopen(name, "w"); + if (f==NULL) { + fprintf(stderr, "Failed to dump heap - could not open file for writing\n"); + return; + } + // fwrite(&size, 8, 1, f); + u8 t8 = 0; + fwrite(&t8, 1, 1, f); // version + + // sizeof(ur), sizeof(usz) + u8 urW[4]; for (i32 i = 0; i < 4; i++) urW[i] = (sizeof(ur )>>(8*i)) & 0xff; fwrite( &urW, 1, 4, f); + u8 uszW[4]; for (i32 i = 0; i < 4; i++) uszW[i] = (sizeof(usz)>>(8*i)) & 0xff; fwrite(&uszW, 1, 4, f); + + // t_names + #define F(X) { t8=t_##X; fwrite(&t8, 1, 1, f); char* s = #X; fwrite(s, 1, strlen(s)+1, f); } + FOR_TYPE(F) + #undef F + t8 = 255; fwrite(&t8, 1, 1, f); // end of t_names + + t8 = 12; fwrite(&t8, 1, 1, f); // number of tag names + u8 t16a[2]; + #define F(X) { \ + t16a[0] = X##_TAG&0xff; t16a[1] = (X##_TAG>>8)&0xff; fwrite(&t16a, 1, 2, f); \ + char* s = #X"_TAG"; fwrite(s, 1, strlen(s)+1, f); \ + } + F(C32)F(TAG)F(VAR)F(EXT)F(RAW)F(MD1)F(MD2)F(FUN)F(NSP)F(OBJ)F(ARR)F(VAL) + #undef F + + mm_dumpHeap(f); + fprintf(stderr, "Heap dumped to \"%s\"\n", name); + fclose(f); +} diff --git a/src/utils/file.h b/src/utils/file.h index 8e145b97..2489e859 100644 --- a/src/utils/file.h +++ b/src/utils/file.h @@ -19,3 +19,4 @@ void file_wBytes(FILE* file, B name, B x); // consumes x B path_list(B path); // consumes char path_type(B path); // consumes +void cbqn_heapDump();