From 8882fb959ac16d7c1b7d7169dae60a29b28b7994 Mon Sep 17 00:00:00 2001 From: dzaima Date: Mon, 27 Jun 2022 19:49:30 +0300 Subject: [PATCH] move scope_dec cycle handling to a noinline function --- src/vm.c | 17 +++++++++++++++++ src/vm.h | 22 +++------------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/vm.c b/src/vm.c index 4d175223..fb739b1a 100644 --- a/src/vm.c +++ b/src/vm.c @@ -646,6 +646,23 @@ FORCE_INLINE Scope* m_scopeI(Body* body, Scope* psc, u16 varAm, i32 initVarAm, B return sc; } +NOINLINE void scope_decF(Scope* sc) { + i32 varAm = sc->varAm; + i32 innerRef = 1; + for (i32 i = 0; i < varAm; i++) { + B c = sc->vars[i]; + if (isVal(c) && v(c)->refc==1) { + u8 t = v(c)->type; + if (t==t_funBl && c(FunBlock,c)->sc==sc) innerRef++; + else if (t==t_md1Bl && c(Md1Block,c)->sc==sc) innerRef++; + else if (t==t_md2Bl && c(Md2Block,c)->sc==sc) innerRef++; + } + } + assert(innerRef <= sc->refc); + if (innerRef==sc->refc) scope_freeF((Value*) sc); + else sc->refc--; // refc>0 guaranteed by refc!=1 from scope_dec +} + FORCE_INLINE B gotoNextBody(Block* bl, Scope* sc, Body* body) { if (body==NULL) thrF("No header matched argument%S", q_N(sc->vars[2])?"":"s"); diff --git a/src/vm.h b/src/vm.h index edea6558..750f194d 100644 --- a/src/vm.h +++ b/src/vm.h @@ -255,26 +255,10 @@ DEF_FREE(scope) { u16 am = c->varAm; for (u32 i = 0; i < am; i++) dec(c->vars[i]); } +NOINLINE void scope_decF(Scope* sc); FORCE_INLINE void scope_dec(Scope* sc) { // version of ptr_dec for scopes, that tries to also free trivial cycles. force-inlined!! - i32 varAm = sc->varAm; - if (LIKELY(sc->refc==1)) goto free; - i32 innerRef = 1; - for (i32 i = 0; i < varAm; i++) { - B c = sc->vars[i]; - if (isVal(c) && v(c)->refc==1) { - u8 t = v(c)->type; - if (t==t_funBl && c(FunBlock,c)->sc==sc) innerRef++; - else if (t==t_md1Bl && c(Md1Block,c)->sc==sc) innerRef++; - else if (t==t_md2Bl && c(Md2Block,c)->sc==sc) innerRef++; - } - } - assert(innerRef <= sc->refc); - if (innerRef==sc->refc) goto free; - sc->refc--; // refc>0 guaranteed by previous refc!=1 result - return; - - free: - scope_freeF((Value*) sc); + if (LIKELY(sc->refc==1)) scope_freeF((Value*) sc); + else scope_decF(sc); }