diff --git a/docs/system.md b/docs/system.md index 6a9680ad..6ca045be 100644 --- a/docs/system.md +++ b/docs/system.md @@ -100,6 +100,7 @@ Namespace of various internal functions. May change at any time. | `•internal.IsPure` | Whether the vm considers the argument pure (i.e. it can execute it safely for computing fills) | | `•internal.Info` | General internal info about the object; a left argument of `1` gives more details | | `•internal.HeapDump` | Create a heap dump file; saves to `•wdpath`-relative path `𝕩` or `CBQNHeapDump` if `𝕩` isn't an array | +| `•internal.HeapStats` | If argument is `@`, returns `⟨total heap size ⋄ used heap size⟩`. If argument is a string, prints the equivalent of `)mem the-string` | | `•internal.HasFill` | Returns whether the argument has a fill element (may give `0` even if `1↑0⥊𝕩` doesn't error in some CBQN configurations) | | `•internal.Squeeze` | Try to convert the argument to its most compact representation | | `•internal.DeepSqueeze` | Try to convert the argument and all its subarrays to its most compact representation; won't squeeze namespace fields | diff --git a/src/builtins.h b/src/builtins.h index 487425c3..673edfba 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -17,7 +17,8 @@ /* sysfn.c*/M(tRawMode,"•term.RawMode") 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*/D(eequal,"•internal.EEqual") M(heapDump,"•internal.HeapDump") M(internalGC,"•internal.GC") M(squeeze,"•internal.Squeeze") M(deepSqueeze,"•internal.DeepSqueeze") \ +/*internal.c*/M(heapDump,"•internal.HeapDump") M(internalGC,"•internal.GC") M(heapStats,"•internal.HeapStats") \ +/*internal.c*/D(eequal,"•internal.EEqual") M(squeeze,"•internal.Squeeze") M(deepSqueeze,"•internal.DeepSqueeze") \ /*internal.c*/A(internalTemp,"•internal.Temp") M(iHasFill,"•internal.HasFill") M(iKeep,"•internal.Keep") \ /*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") D(atan2,"•math.Atan2") D(hypot,"•math.Hypot") \ diff --git a/src/builtins/internal.c b/src/builtins/internal.c index dec50d1e..943c8234 100644 --- a/src/builtins/internal.c +++ b/src/builtins/internal.c @@ -345,6 +345,23 @@ B internalGC_c1(B t, B x) { #endif } + +void heap_printInfoStr(char* str); +B vfyStr(B x, char* name, char* arg); +B heapStats_c1(B t, B x) { + if (isC32(x)) { + f64* rp; B r = m_f64arrv(&rp, 2); + rp[0] = mm_heapAlloc; + rp[1] = mm_heapUsed(); + return r; + } + vfyStr(x, "•internal.HeapStats", "𝕩"); + char* cs = toCStr(x); + heap_printInfoStr(cs); + freeCStr(cs); + return m_f64(1); +} + B iHasFill_c1(B t, B x) { B f = getFillR(x); dec(x); @@ -378,8 +395,8 @@ B getInternalNS(void) { #undef F #define F(X) incG(bi_##X), - Body* d = m_nnsDesc("type","eltype","refc","squeeze","ispure","info", "keep","listvariations","variation","clearrefs", "hasfill","unshare","deepsqueeze","heapdump","eequal", "gc", "temp"); - internalNS = m_nns(d,F(itype)F(elType)F(refc)F(squeeze)F(isPure)F(info)F(iKeep)F(listVariations)F(variation)F(clearRefs)F(iHasFill)F(unshare)F(deepSqueeze)F(heapDump)F(eequal)F(internalGC)F(internalTemp)); + Body* d = m_nnsDesc("type","eltype","refc","squeeze","ispure","info", "keep","listvariations","variation","clearrefs", "hasfill","unshare","deepsqueeze","heapdump","eequal", "gc", "temp","heapstats"); + internalNS = m_nns(d,F(itype)F(elType)F(refc)F(squeeze)F(isPure)F(info)F(iKeep)F(listVariations)F(variation)F(clearRefs)F(iHasFill)F(unshare)F(deepSqueeze)F(heapDump)F(eequal)F(internalGC)F(internalTemp)F(heapStats)); #undef F gc_add(internalNS); } diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 8e13d61f..d5e2af1e 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -1855,7 +1855,7 @@ u32* dsv_text[] = { U"•file.Accessed",U"•file.At",U"•file.Bytes",U"•file.Chars",U"•file.Created",U"•file.CreateDir",U"•file.Exists",U"•file.Lines",U"•file.List", U"•file.MapBytes",U"•file.Modified",U"•file.Name",U"•file.Parent",U"•file.path",U"•file.RealPath",U"•file.Remove",U"•file.Rename",U"•file.Size",U"•file.Type", - U"•internal.ClearRefs",U"•internal.DeepSqueeze",U"•internal.EEqual",U"•internal.ElType",U"•internal.GC",U"•internal.HasFill",U"•internal.HeapDump",U"•internal.Info",U"•internal.IsPure",U"•internal.Keep",U"•internal.ListVariations",U"•internal.Refc",U"•internal.Squeeze",U"•internal.Temp",U"•internal.Type",U"•internal.Unshare",U"•internal.Variation", + U"•internal.ClearRefs",U"•internal.DeepSqueeze",U"•internal.EEqual",U"•internal.ElType",U"•internal.GC",U"•internal.HasFill",U"•internal.HeapDump",U"•internal.HeapStats",U"•internal.Info",U"•internal.IsPure",U"•internal.Keep",U"•internal.ListVariations",U"•internal.Refc",U"•internal.Squeeze",U"•internal.Temp",U"•internal.Type",U"•internal.Unshare",U"•internal.Variation", U"•math.Acos",U"•math.Acosh",U"•math.Asin",U"•math.Asinh",U"•math.Atan",U"•math.Atan2",U"•math.Atanh",U"•math.Cbrt",U"•math.Comb",U"•math.Cos",U"•math.Cosh",U"•math.Erf",U"•math.ErfC",U"•math.Expm1",U"•math.Fact",U"•math.GCD",U"•math.Hypot",U"•math.LCM",U"•math.Log10",U"•math.Log1p",U"•math.Log2",U"•math.LogFact",U"•math.Sin",U"•math.Sinh",U"•math.Sum",U"•math.Tan",U"•math.Tanh", U"•ns.Get",U"•ns.Has",U"•ns.Keys", diff --git a/src/core/heap.c b/src/core/heap.c index d124d517..36297f8c 100644 --- a/src/core/heap.c +++ b/src/core/heap.c @@ -100,3 +100,14 @@ void heap_printInfo(bool sizes, bool types, bool freed, bool chain) { #endif fflush(stderr); } +void heap_printInfoStr(char* str) { + bool sizes=0, types=0; + i32 freed=0; + char c; + while ((c=*(str++)) != 0) { + if (c=='t') types=1; + if (c=='s') sizes=1; + if (c=='f') freed++; + } + heap_printInfo(sizes, types, freed!=0, freed>=2); +} diff --git a/src/main.c b/src/main.c index 46c1d565..e6b7c0f2 100644 --- a/src/main.c +++ b/src/main.c @@ -601,7 +601,7 @@ static NOINLINE f64 timeBlockN(Block* block, i64 rep) { bool ryu_s2d_n(u8* buffer, int len, f64* result); #endif -void heap_printInfo(bool sizes, bool types, bool freed, bool chain); +void heap_printInfoStr(char* str); void cbqn_runLine0(char* ln, i64 read) { if (ln[0]==0 || read==0) return; @@ -667,15 +667,7 @@ void cbqn_runLine0(char* ln, i64 read) { timeRep = am; output = 0; } else if (isCmd(cmdS, &cmdE, "mem ")) { - bool sizes=0, types=0; - i32 freed=0; - char c; - while ((c=*(cmdE++)) != 0) { - if (c=='t') types=1; - if (c=='s') sizes=1; - if (c=='f') freed++; - } - heap_printInfo(sizes, types, freed!=0, freed>=2); + heap_printInfoStr(cmdE); return; } else if (isCmd(cmdS, &cmdE, "erase ")) { char* name = cmdE;