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;
|
||||
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_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_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, true, false); return x; }
|
||||
INS B i_SETM(B s, B f, B x, Scope** pscs, u32* bc) { POS_UPD;
|
||||
B w = v_get(pscs, s, true);
|
||||
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;
|
||||
}
|
||||
INS B i_SETC(B s, B f, Scope** pscs, u32* bc) { POS_UPD;
|
||||
B x = v_get(pscs, s, true);
|
||||
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;
|
||||
}
|
||||
FORCE_INLINE B gotoNextBodyJIT(Scope* sc, Body* body) {
|
||||
|
||||
33
src/vm.c
33
src/vm.c
@ -498,15 +498,18 @@ FORCE_INLINE bool v_merge(Scope* pscs[], B s, B x, bool upd, bool hdr) {
|
||||
SGet(x)
|
||||
for (usz i = 0; i < oia; i++) {
|
||||
B cx = m_unit(Get(x,i));
|
||||
if (!hdr) v_set (pscs, op[i], cx, upd, true);
|
||||
else if (!v_seth(pscs, op[i], cx)) { dec(cx); return false; }
|
||||
dec(cx);
|
||||
if (!hdr) v_set(pscs, op[i], cx, upd, true, false, true);
|
||||
else {
|
||||
bool ok = v_seth(pscs, op[i], cx);
|
||||
dec(cx);
|
||||
if (!ok) return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
B cells = toCells(incG(x));
|
||||
B* xp = harr_ptr(cells);
|
||||
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; }
|
||||
}
|
||||
dec(cells);
|
||||
@ -524,25 +527,25 @@ NOINLINE void v_setF(Scope* pscs[], B s, B x, bool upd) {
|
||||
B c = sp[i];
|
||||
if (isVar(c)) {
|
||||
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)) {
|
||||
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)) {
|
||||
assert(TY(c) == t_fldAlias);
|
||||
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");
|
||||
}
|
||||
return;
|
||||
}
|
||||
SGetU(x)
|
||||
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], GetU(x,i), upd, true);
|
||||
SGet(x)
|
||||
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) {
|
||||
return;
|
||||
} else if (isObj(s)) {
|
||||
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 if (isExt(s)) {
|
||||
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_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;
|
||||
}
|
||||
|
||||
@ -827,19 +830,19 @@ B evalBC(Body* b, Scope* sc, Block* bl) { // doesn't consume
|
||||
break;
|
||||
}
|
||||
|
||||
case SETN: { P(s) P(x) GS_UPD; POS_UPD; v_set(pscs, s, x, false, true); dec(s); 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 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, true, false); ADD(x); break; }
|
||||
case SETM: { P(s)P(f)P(x) GS_UPD; POS_UPD;
|
||||
B w = v_get(pscs, s, true);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
case SETC: { P(s)P(f) GS_UPD; POS_UPD;
|
||||
B x = v_get(pscs, s, true);
|
||||
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);
|
||||
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
|
||||
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
|
||||
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
|
||||
FAIL, // this body cannot be called monadically/dyadically
|
||||
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;
|
||||
}
|
||||
}
|
||||
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
|
||||
if (RARE(!isVar(s))) v_setF(pscs, s, x, upd);
|
||||
else v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, inc(x), upd, chk);
|
||||
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 (LIKELY(isVar(s))) {
|
||||
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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user