move scope_dec cycle handling to a noinline function
This commit is contained in:
parent
d18ebc3d07
commit
8882fb959a
17
src/vm.c
17
src/vm.c
@ -646,6 +646,23 @@ FORCE_INLINE Scope* m_scopeI(Body* body, Scope* psc, u16 varAm, i32 initVarAm, B
|
|||||||
return sc;
|
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) {
|
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");
|
if (body==NULL) thrF("No header matched argument%S", q_N(sc->vars[2])?"":"s");
|
||||||
|
|
||||||
|
|||||||
22
src/vm.h
22
src/vm.h
@ -255,26 +255,10 @@ DEF_FREE(scope) {
|
|||||||
u16 am = c->varAm;
|
u16 am = c->varAm;
|
||||||
for (u32 i = 0; i < am; i++) dec(c->vars[i]);
|
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!!
|
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)) scope_freeF((Value*) sc);
|
||||||
if (LIKELY(sc->refc==1)) goto free;
|
else scope_decF(sc);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user