From dfa04f4922bf6790c4783749edec362a45da626e Mon Sep 17 00:00:00 2001 From: dzaima Date: Tue, 26 Oct 2021 16:15:33 +0300 Subject: [PATCH] =?UTF-8?q?properly=20free=20=F0=9D=95=A9=20when=20needed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- makefile | 2 ++ src/builtins.h | 3 ++- src/builtins/internal.c | 9 +++++++-- src/builtins/sysfn.c | 3 +++ src/singeli/builtins/cmp.c | 10 ++++++++-- src/singeli/src/cmp.singeli | 21 ++++++++++----------- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/makefile b/makefile index a4fb566b..96908725 100644 --- a/makefile +++ b/makefile @@ -23,6 +23,8 @@ o3ng-singeli: @${MAKE} singeli=1 t=o3ng_si f="-g -O3 -march=native" c debugn-singeli: @${MAKE} singeli=1 t=debugn_si f="-g -DDEBUG -march=native" c +heapverifyn-singeli: + @${MAKE} singeli=1 t=heapverifyn_si f="-g -DDEBUG -DHEAP_VERIFY -march=native" c diff --git a/src/builtins.h b/src/builtins.h index 128df9ba..c8bfa196 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -10,7 +10,8 @@ /* sysfn.c*/M(type,"•Type") M(decp,"•Decompose") M(primInd,"•PrimInd") M(glyph,"•Glyph") A(fill,"•FillFn") M(sys,"•getsys") A(grLen,"•GroupLen") D(grOrd,"•GroupOrd") \ /* sysfn.c*/M(repr,"•Repr") M(fmt,"•Fmt") A(asrt,"!") A(casrt,"!") M(out,"•Out") M(show,"•Show") A(bqn,"•BQN") M(sh,"•SH") M(fromUtf8,"•FromUTF8") \ /* sysfn.c*/D(cmp,"•Cmp") A(hash,"•Hash") M(unixTime,"•UnixTime") M(monoTime,"•MonoTime") M(delay,"•Delay") M(makeRand,"•MakeRand") M(reBQN,"•ReBQN") M(exit,"•Exit") M(getLine,"•GetLine") \ -/*internal.c*/M(itype,"•internal.Type") M(refc,"•internal.Refc") M(squeeze,"•internal.Squeeze") M(deepSqueeze,"•internal.DeepSqueeze") 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") \ +/*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") #define FOR_PM1(A,M,D) \ diff --git a/src/builtins/internal.c b/src/builtins/internal.c index 58f958d6..c6c8565f 100644 --- a/src/builtins/internal.c +++ b/src/builtins/internal.c @@ -17,6 +17,11 @@ B itype_c1(B t, B x) { dec(x); return r; } +B elType_c1(B t, B x) { + B r = m_i32(isArr(x)? TI(x,elType) : selfElType(x)); + dec(x); + return r; +} B refc_c1(B t, B x) { B r = isVal(x)? m_i32(v(x)->refc) : m_str8l("(not heap-allocated)"); dec(x); @@ -266,8 +271,8 @@ B getInternalNS() { listVariations_def = m_str8l("if"); gc_addFn(variation_gcRoot); #define F(X) inc(bi_##X), - B fn = bqn_exec(m_str32(U"{⟨ Type, Refc, Squeeze, IsPure, Info, ListVariations, Variation, ClearRefs, Unshare, DeepSqueeze⟩⇐𝕩}"), emptyCVec(), emptySVec()); - B arg = m_caB(10,(B[]){F(itype)F(refc)F(squeeze)F(isPure)F(info)F(listVariations)F(variation)F(clearRefs)F(unshare)F(deepSqueeze)}); + B fn = bqn_exec(m_str32(U"{⟨ Type, ElType, Refc, Squeeze, IsPure, Info, ListVariations, Variation, ClearRefs, Unshare, DeepSqueeze⟩⇐𝕩}"), emptyCVec(), emptySVec()); + B arg = m_caB(11,(B[]){F(itype)F(elType)F(refc)F(squeeze)F(isPure)F(info)F(listVariations)F(variation)F(clearRefs)F(unshare)F(deepSqueeze)}); #undef F internalNS = c1(fn,arg); gc_add(internalNS); diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index bd7730c1..39684d43 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -656,6 +656,9 @@ B delay_c1(B t, B x) { return m_f64(ts.tv_sec-ts0.tv_sec+(ts.tv_nsec-ts0.tv_nsec)*1e-9); } B exit_c1(B t, B x) { + #ifdef HEAP_VERIFY + printf("(heapverify doesn't run on •Exit)\n"); + #endif bqn_exit(q_i32(x)? o2i(x) : 0); } B getLine_c1(B t, B x) { diff --git a/src/singeli/builtins/cmp.c b/src/singeli/builtins/cmp.c index 86c173ac..c8047c29 100644 --- a/src/singeli/builtins/cmp.c +++ b/src/singeli/builtins/cmp.c @@ -7,6 +7,10 @@ static NOINLINE void fillBits(u64* dst, u64 sz, bool v) { u64 am = (sz+63)/64; assert(am>0); for (usz i = 0; i < am; i++) dst[i] = x; } +static NOINLINE void fillBitsDec(u64* dst, u64 sz, bool v, u64 x) { + dec(b(x)); + fillBits(dst, sz, v); +} bool please_tail_call_cmp_err = 1; static NOINLINE void cmp_err() { if (please_tail_call_cmp_err) thrM("Invalid comparison"); } @@ -58,11 +62,13 @@ static void* tyany_ptr(B x) { } \ AL(w); \ if (ria) lut_avx2_##NAME##AS [we](rp, (u8*)tyany_ptr(w), x.u, ria); \ + else dec(x); \ dec(w); return r; \ } else if (isArr(x)) { u8 xe = TI(x,elType); if (xe==el_B) goto end; AL(x); \ if (ria) lut_avx2_##RNAME##AS[xe](rp, (u8*)tyany_ptr(x), w.u, ria); \ - dec(x); return r; \ - } \ + else dec(w); \ + dec(x); return r; \ + } \ if (isF64(w)&isC32(x)) return m_i32(FC); \ if (isC32(w)&isF64(x)) return m_i32(CF); \ end:; diff --git a/src/singeli/src/cmp.singeli b/src/singeli/src/cmp.singeli index d11761d1..dba3518d 100644 --- a/src/singeli/src/cmp.singeli +++ b/src/singeli/src/cmp.singeli @@ -16,23 +16,21 @@ def cif{v, G} = { show{'cif argument not known at compile time!'}; G{} } def cif{v, G & match{v,0}} = 0 def cif{v, G & match{v,1}} = G{0} -def fillbits{dst:*u64, len:(Size), v} = { - emit{void, 'fillBits', dst, len, v} - return{} -} +def fillbits{dst:*u64, len:(Size), v } = { emit{void, 'fillBits', dst, len, v }; return{}; } +def fillbits{dst:*u64, len:(Size), v, x} = { emit{void, 'fillBitsDec', dst, len, v, x}; return{}; } def cmp_err{x} = { emit{void, 'cmp_err'}; return{}; } cmpIX(dst:*u64, len:Size, x:u64, v:u1) : void = { nan:u1 = q_f64{x} if (~(nan | q_chr{x})) cmp_err{x} - fillbits{dst, len, v & ~nan} + fillbits{dst, len, v & ~nan, x} } def eqne{op} = match{op,__eq}|match{op,__ne} def pathAS{dst, len, T, op, x & issigned{T}} = { def R{f & eqne{op}} = { - if (rare{floor{f}!=f}) fillbits{dst, len, op{0,1}} # also includes check for NaN/sNaN + if (rare{floor{f}!=f}) fillbits{dst, len, op{0,1}, x} # also includes check for NaN/sNaN ftrunc_i64{f} } def R{f & match{op,__lt}|match{op,__ge}} = ftrunc_i64{ceil{f}} @@ -53,7 +51,7 @@ def pathAS{dst, len, T, op, x & issigned{T}} = { def pathAS{dst, len, T, op, x & T==f64} = { if (rare{~q_f64{x}}) { cif{~eqne{op}, {_}=>{ if(~q_chr{x}) cmp_err{x}; }} - fillbits{dst, len, op{0,1}} + fillbits{dst, len, op{0,1}, x} } from_B{T,x} } @@ -61,7 +59,7 @@ def pathAS{dst, len, T, op, x & T==f64} = { def pathAS{dst, len, T, op, x & isunsigned{T}} = { if (rare{~q_chr{x}}) { cif{~eqne{op}, {_}=>{ if(~q_f64{x}) cmp_err{x}; }} - fillbits{dst, len, op{1,0}} + fillbits{dst, len, op{1,0}, x} } xc32:u32 = from_B{u32,x} if (xc32 > maxvalue{T}) fillbits{dst, len, op{0,1}} @@ -110,9 +108,10 @@ bitAS{op}(dst:*u64, wr:*u8, x:u64, len:Size) : void = { # show{'bitAS'} r0:u1 = op{0,xf} r1:u1 = op{1,xf} if (r0==r1) { - cif{~eqne{op}, {_}=>{ - if (rare{isNaN{xf}}) { call{cmpIX, dst, len, x, op{0,1}}; return{}; } - }} + if (rare{isNaN{xf}}) { + if (eqne{op}) fillbits{dst, len, r0, x} + else { call{cmpIX, dst, len, x, op{0,1}}; return{}; } + } fillbits{dst, len, r0} return{} }