mild optimization of v_set argument consumption
This commit is contained in:
parent
3ccef1fe86
commit
1619b6087b
@ -160,18 +160,18 @@ INS B i_EXTU(u32 p, Scope* sc) {
|
|||||||
vars[p] = bi_optOut;
|
vars[p] = bi_optOut;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
INS B i_SETN(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, false, true); dec(s); return x; }
|
INS B i_SETN(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, false, true, true, false); return x; }
|
||||||
INS B i_SETU(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, true, true); dec(s); return x; }
|
INS B i_SETU(B s, B x, Scope** pscs, u32* bc) { POS_UPD; v_set(pscs, s, x, true, true, true, false); return x; }
|
||||||
INS B i_SETM(B s, B f, B x, Scope** pscs, u32* bc) { POS_UPD;
|
INS B i_SETM(B s, B f, B x, Scope** pscs, u32* bc) { POS_UPD;
|
||||||
B w = v_get(pscs, s, true);
|
B w = v_get(pscs, s, true);
|
||||||
B r = c2(f,w,x); dec(f);
|
B r = c2(f,w,x); dec(f);
|
||||||
v_set(pscs, s, r, true, false); dec(s);
|
v_set(pscs, s, r, true, false, true, false);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
INS B i_SETC(B s, B f, Scope** pscs, u32* bc) { POS_UPD;
|
INS B i_SETC(B s, B f, Scope** pscs, u32* bc) { POS_UPD;
|
||||||
B x = v_get(pscs, s, true);
|
B x = v_get(pscs, s, true);
|
||||||
B r = c1(f,x); dec(f);
|
B r = c1(f,x); dec(f);
|
||||||
v_set(pscs, s, r, true, false); dec(s);
|
v_set(pscs, s, r, true, false, true, false);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
FORCE_INLINE B gotoNextBodyJIT(Scope* sc, Body* body) {
|
FORCE_INLINE B gotoNextBodyJIT(Scope* sc, Body* body) {
|
||||||
|
|||||||
31
src/vm.c
31
src/vm.c
@ -498,15 +498,18 @@ FORCE_INLINE bool v_merge(Scope* pscs[], B s, B x, bool upd, bool hdr) {
|
|||||||
SGet(x)
|
SGet(x)
|
||||||
for (usz i = 0; i < oia; i++) {
|
for (usz i = 0; i < oia; i++) {
|
||||||
B cx = m_unit(Get(x,i));
|
B cx = m_unit(Get(x,i));
|
||||||
if (!hdr) v_set (pscs, op[i], cx, upd, true);
|
if (!hdr) v_set(pscs, op[i], cx, upd, true, false, true);
|
||||||
else if (!v_seth(pscs, op[i], cx)) { dec(cx); return false; }
|
else {
|
||||||
|
bool ok = v_seth(pscs, op[i], cx);
|
||||||
dec(cx);
|
dec(cx);
|
||||||
|
if (!ok) return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
B cells = toCells(incG(x));
|
B cells = toCells(incG(x));
|
||||||
B* xp = harr_ptr(cells);
|
B* xp = harr_ptr(cells);
|
||||||
for (usz i = 0; i < oia; i++) {
|
for (usz i = 0; i < oia; i++) {
|
||||||
if (!hdr) v_set (pscs, op[i], xp[i], upd, true);
|
if (!hdr) v_set (pscs, op[i], xp[i], upd, true, false, false);
|
||||||
else if (!v_seth(pscs, op[i], xp[i])) { dec(cells); return false; }
|
else if (!v_seth(pscs, op[i], xp[i])) { dec(cells); return false; }
|
||||||
}
|
}
|
||||||
dec(cells);
|
dec(cells);
|
||||||
@ -524,25 +527,25 @@ NOINLINE void v_setF(Scope* pscs[], B s, B x, bool upd) {
|
|||||||
B c = sp[i];
|
B c = sp[i];
|
||||||
if (isVar(c)) {
|
if (isVar(c)) {
|
||||||
Scope* sc = pscs[(u16)(c.u>>32)];
|
Scope* sc = pscs[(u16)(c.u>>32)];
|
||||||
v_set(pscs, c, ns_getU(x, pos2gid(sc->body, (u32)c.u)), upd, true);
|
v_set(pscs, c, ns_getU(x, pos2gid(sc->body, (u32)c.u)), upd, true, false, false);
|
||||||
} else if (isExt(c)) {
|
} else if (isExt(c)) {
|
||||||
ScopeExt* ext = pscs[(u16)(c.u>>32)]->ext;
|
ScopeExt* ext = pscs[(u16)(c.u>>32)]->ext;
|
||||||
v_set(pscs, c, ns_getNU(x, ext->vars[(u32)c.u + ext->varAm], true), upd, true);
|
v_set(pscs, c, ns_getNU(x, ext->vars[(u32)c.u + ext->varAm], true), upd, true, false, false);
|
||||||
} else if (isObj(c)) {
|
} else if (isObj(c)) {
|
||||||
assert(TY(c) == t_fldAlias);
|
assert(TY(c) == t_fldAlias);
|
||||||
FldAlias* cf = c(FldAlias,c);
|
FldAlias* cf = c(FldAlias,c);
|
||||||
v_set(pscs, cf->obj, ns_getU(x, cf->p), upd, true);
|
v_set(pscs, cf->obj, ns_getU(x, cf->p), upd, true, false, false);
|
||||||
} else thrM("Assignment: extracting non-name from namespace");
|
} else thrM("Assignment: extracting non-name from namespace");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SGetU(x)
|
SGet(x)
|
||||||
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], GetU(x,i), upd, true);
|
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], Get(x,i), upd, true, false, true);
|
||||||
} else if (s.u == bi_N.u) {
|
} else if (s.u == bi_N.u) {
|
||||||
return;
|
return;
|
||||||
} else if (isObj(s)) {
|
} else if (isObj(s)) {
|
||||||
if (TY(s) == t_arrMerge) v_merge(pscs, s, x, upd, false);
|
if (TY(s) == t_arrMerge) v_merge(pscs, s, x, upd, false);
|
||||||
else if (TY(s) == t_fldAlias) thrF("Assignment: Cannot assign non-namespace to a list containing aliases"); // v_set(pscs, c(FldAlias, s)->obj, x, upd, true);
|
else if (TY(s) == t_fldAlias) thrF("Assignment: Cannot assign non-namespace to a list containing aliases");
|
||||||
else UD;
|
else UD;
|
||||||
} else if (isExt(s)) {
|
} else if (isExt(s)) {
|
||||||
Scope* sc = pscs[(u16)(s.u>>32)];
|
Scope* sc = pscs[(u16)(s.u>>32)];
|
||||||
@ -581,7 +584,7 @@ NOINLINE bool v_sethF(Scope* pscs[], B s, B x) {
|
|||||||
}
|
}
|
||||||
if (TY(s)==t_vfyObj) return equal(c(WrappedObj,s)->obj,x);
|
if (TY(s)==t_vfyObj) return equal(c(WrappedObj,s)->obj,x);
|
||||||
if (TY(s)==t_arrMerge) return v_merge(pscs, s, x, false, true);
|
if (TY(s)==t_arrMerge) return v_merge(pscs, s, x, false, true);
|
||||||
if (TY(s)==t_fldAlias) return false; // return v_seth(pscs, c(FldAlias, s)->obj, x);
|
if (TY(s)==t_fldAlias) return false;
|
||||||
UD;
|
UD;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -827,19 +830,19 @@ B evalBC(Body* b, Scope* sc, Block* bl) { // doesn't consume
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SETN: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, false, true); dec(s); ADD(x); break; }
|
case SETN: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, false, true, true, false); ADD(x); break; }
|
||||||
case SETU: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, true, true); dec(s); ADD(x); break; }
|
case SETU: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, true, true, true, false); ADD(x); break; }
|
||||||
case SETM: { P(s)P(f)P(x) GS_UPD; POS_UPD;
|
case SETM: { P(s)P(f)P(x) GS_UPD; POS_UPD;
|
||||||
B w = v_get(pscs, s, true);
|
B w = v_get(pscs, s, true);
|
||||||
B r = c2(f,w,x); dec(f);
|
B r = c2(f,w,x); dec(f);
|
||||||
v_set(pscs, s, r, true, false); dec(s);
|
v_set(pscs, s, r, true, false, true, false);
|
||||||
ADD(r);
|
ADD(r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SETC: { P(s)P(f) GS_UPD; POS_UPD;
|
case SETC: { P(s)P(f) GS_UPD; POS_UPD;
|
||||||
B x = v_get(pscs, s, true);
|
B x = v_get(pscs, s, true);
|
||||||
B r = c1(f,x); dec(f);
|
B r = c1(f,x); dec(f);
|
||||||
v_set(pscs, s, r, true, false); dec(s);
|
v_set(pscs, s, r, true, false, true, false);
|
||||||
ADD(r);
|
ADD(r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/vm.h
13
src/vm.h
@ -66,7 +66,7 @@ enum {
|
|||||||
FN1Ci, FN1Oi, FN2Ci, FN2Oi, // FN__ alternatives that don't take the function from the stack, but instead as an 2×u32 immediate in the bytecode
|
FN1Ci, FN1Oi, FN2Ci, FN2Oi, // FN__ alternatives that don't take the function from the stack, but instead as an 2×u32 immediate in the bytecode
|
||||||
SETNi, SETUi, SETMi, SETCi, // SET_ alternatives that expect the set variable as a depth-position pair like VAR_
|
SETNi, SETUi, SETMi, SETCi, // SET_ alternatives that expect the set variable as a depth-position pair like VAR_
|
||||||
SETNv, SETUv, SETMv, SETCv, // SET_i alternatives that also don't return the result
|
SETNv, SETUv, SETMv, SETCv, // SET_i alternatives that also don't return the result
|
||||||
SETH1, SETH2, PRED1, PRED2, // internal versions of SETH and PRED, with 2×u64 arguments (only 1 for PRED1) specifying bodies to jump to on fail (or NULL if is last)
|
SETH1, SETH2, PRED1, PRED2, // versions of SETH and PRED with 2×u64 arguments (only 1 for PRED1) specifying bodies to jump to on fail (or NULL if is last)
|
||||||
DFND0, DFND1, DFND2, // internal versions of DFND with a specific type, and a u64 argument representing the block pointer
|
DFND0, DFND1, DFND2, // internal versions of DFND with a specific type, and a u64 argument representing the block pointer
|
||||||
FAIL, // this body cannot be called monadically/dyadically
|
FAIL, // this body cannot be called monadically/dyadically
|
||||||
BC_SIZE
|
BC_SIZE
|
||||||
@ -299,9 +299,14 @@ FORCE_INLINE void v_setI(Scope* sc, u32 p, B x, bool upd, bool chk) { // consume
|
|||||||
sc->vars[p] = x;
|
sc->vars[p] = x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FORCE_INLINE void v_set(Scope* pscs[], B s, B x, bool upd, bool chk) { // doesn't consume; if chk is false, content variables _may_ not be checked to be set
|
FORCE_INLINE void v_set(Scope* pscs[], B s, B x, bool upd, bool chk, bool consumeS, bool consumeX) { // if chk is false, content variables _may_ not be checked to be set
|
||||||
if (RARE(!isVar(s))) v_setF(pscs, s, x, upd);
|
if (LIKELY(isVar(s))) {
|
||||||
else v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, inc(x), upd, chk);
|
v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, consumeX? x : inc(x), upd, chk);
|
||||||
|
} else {
|
||||||
|
v_setF(pscs, s, x, upd);
|
||||||
|
if (consumeX) dec(x);
|
||||||
|
if (consumeS) dec(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool v_seth(Scope* pscs[], B s, B x) { // doesn't consume; s cannot contain extended variables
|
FORCE_INLINE bool v_seth(Scope* pscs[], B s, B x) { // doesn't consume; s cannot contain extended variables
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user