Trace the eval.cc functions with Tracy
We're leveraging the ZoneTransientN macro to send dynamic strings containing the expression type, file and position in that file of the expression Nix is currently evaluating. We had to add a new showExprType method to the Expr class to get a const string containing the name of an expression.
This commit is contained in:
parent
0905dea80f
commit
f2e832d0f8
|
@ -55,6 +55,11 @@
|
|||
|
||||
#endif
|
||||
|
||||
#define TRACY_TRACE(evalstate, expr) \
|
||||
std::ostringstream tracyss; \
|
||||
tracyss << evalstate.positions[(expr)->getPos()] << " " << (expr)->showExprType(); \
|
||||
ZoneTransientN(nix, tracyss.str().c_str(), true);
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace nix {
|
||||
|
@ -1204,29 +1209,34 @@ void Expr::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprInt::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
v = this->v;
|
||||
}
|
||||
|
||||
|
||||
void ExprFloat::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
v = this->v;
|
||||
}
|
||||
|
||||
void ExprString::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
v = this->v;
|
||||
}
|
||||
|
||||
|
||||
void ExprPath::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
v = this->v;
|
||||
}
|
||||
|
||||
|
||||
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
v.mkAttrs(state.buildBindings(attrs.size() + dynamicAttrs.size()).finish());
|
||||
auto dynamicEnv = &env;
|
||||
|
||||
|
@ -1311,6 +1321,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
/* Create a new environment that contains the attributes in this
|
||||
`let'. */
|
||||
Env & env2(state.allocEnv(attrs->attrs.size()));
|
||||
|
@ -1329,6 +1340,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprList::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
state.mkList(v, elems.size());
|
||||
for (auto [n, v2] : enumerate(v.listItems()))
|
||||
const_cast<Value * &>(v2) = elems[n]->maybeThunk(state, env);
|
||||
|
@ -1337,6 +1349,7 @@ void ExprList::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
Value * ExprList::maybeThunk(EvalState & state, Env & env)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
if (elems.empty()) {
|
||||
return &state.vEmptyList;
|
||||
}
|
||||
|
@ -1346,6 +1359,7 @@ Value * ExprList::maybeThunk(EvalState & state, Env & env)
|
|||
|
||||
void ExprVar::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
Value * v2 = state.lookupVar(&env, *this, false);
|
||||
state.forceValue(*v2, pos);
|
||||
v = *v2;
|
||||
|
@ -1373,7 +1387,7 @@ static std::string showAttrPath(EvalState & state, Env & env, const AttrPath & a
|
|||
|
||||
void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
ZoneScopedN("select");
|
||||
TRACY_TRACE(state, this)
|
||||
Value vTmp;
|
||||
PosIdx pos2;
|
||||
Value * vAttrs = &vTmp;
|
||||
|
@ -1438,6 +1452,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this)
|
||||
Value vTmp;
|
||||
Value * vAttrs = &vTmp;
|
||||
|
||||
|
@ -1463,6 +1478,7 @@ void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprLambda::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this)
|
||||
v.mkLambda(&env, this);
|
||||
}
|
||||
|
||||
|
@ -1720,6 +1736,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
|
||||
void ExprCall::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
Value vFun;
|
||||
fun->eval(state, env, vFun);
|
||||
|
||||
|
@ -1797,6 +1814,7 @@ https://nixos.org/manual/nix/stable/language/constructs.html#functions.)", symbo
|
|||
|
||||
void ExprWith::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
Env & env2(state.allocEnv(1));
|
||||
env2.up = &env;
|
||||
env2.values[0] = attrs->maybeThunk(state, env);
|
||||
|
@ -1807,6 +1825,7 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprIf::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
// We cheat in the parser, and pass the position of the condition as the position of the if itself.
|
||||
(state.evalBool(env, cond, pos, "while evaluating a branch condition") ? then : else_)->eval(state, env, v);
|
||||
}
|
||||
|
@ -1814,6 +1833,7 @@ void ExprIf::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprAssert::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
if (!state.evalBool(env, cond, pos, "in the condition of the assert statement")) {
|
||||
std::ostringstream out;
|
||||
cond->show(state.symbols, out);
|
||||
|
@ -1825,12 +1845,14 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprOpNot::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
v.mkBool(!state.evalBool(env, e, getPos(), "in the argument of the not operator")); // XXX: FIXME: !
|
||||
}
|
||||
|
||||
|
||||
void ExprOpEq::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
Value v1; e1->eval(state, env, v1);
|
||||
Value v2; e2->eval(state, env, v2);
|
||||
v.mkBool(state.eqValues(v1, v2, pos, "while testing two values for equality"));
|
||||
|
@ -1839,6 +1861,7 @@ void ExprOpEq::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprOpNEq::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
Value v1; e1->eval(state, env, v1);
|
||||
Value v2; e2->eval(state, env, v2);
|
||||
v.mkBool(!state.eqValues(v1, v2, pos, "while testing two values for inequality"));
|
||||
|
@ -1847,6 +1870,7 @@ void ExprOpNEq::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprOpAnd::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
v.mkBool(state.evalBool(env, e1, pos, "in the left operand of the AND (&&) operator") && state.evalBool(env, e2, pos, "in the right operand of the AND (&&) operator"));
|
||||
}
|
||||
|
||||
|
@ -1859,12 +1883,14 @@ void ExprOpOr::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprOpImpl::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
v.mkBool(!state.evalBool(env, e1, pos, "in the left operand of the IMPL (->) operator") || state.evalBool(env, e2, pos, "in the right operand of the IMPL (->) operator"));
|
||||
}
|
||||
|
||||
|
||||
void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
Value v1, v2;
|
||||
state.evalAttrs(env, e1, v1, pos, "in the left operand of the update (//) operator");
|
||||
state.evalAttrs(env, e2, v2, pos, "in the right operand of the update (//) operator");
|
||||
|
@ -1903,6 +1929,7 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
Value v1; e1->eval(state, env, v1);
|
||||
Value v2; e2->eval(state, env, v2);
|
||||
Value * lists[2] = { &v1, &v2 };
|
||||
|
@ -1941,6 +1968,7 @@ void EvalState::concatLists(Value & v, size_t nrLists, Value * * lists, const Po
|
|||
|
||||
void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
NixStringContext context;
|
||||
std::vector<BackedStringView> s;
|
||||
size_t sSize = 0;
|
||||
|
@ -2033,12 +2061,14 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
state.mkPos(v, pos);
|
||||
}
|
||||
|
||||
|
||||
void ExprBlackHole::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
TRACY_TRACE(state, this);
|
||||
state.error("infinite recursion encountered")
|
||||
.debugThrow<InfiniteRecursionError>();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ libexpr_SOURCES := \
|
|||
$(d)/parser-tab.cc \
|
||||
$(d)/tracy/public/TracyClient.cpp
|
||||
|
||||
libexpr_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/libmain -I src/libexpr -I src/libexpr/tracy/public
|
||||
libexpr_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/libmain -I src/libexpr -I src/libexpr/tracy/public -DTRACY_ENABLE=1
|
||||
|
||||
libexpr_LIBS = libutil libstore libfetchers
|
||||
|
||||
|
@ -49,3 +49,4 @@ $(d)/primops.cc: $(d)/imported-drv-to-derivation.nix.gen.hh
|
|||
$(d)/eval.cc: $(d)/primops/derivation.nix.gen.hh $(d)/fetchurl.nix.gen.hh $(d)/flake/call-flake.nix.gen.hh
|
||||
|
||||
$(buildprefix)src/libexpr/primops/fromTOML.o: ERROR_SWITCH_ENUM =
|
||||
$(buildprefix)src/libexpr/tracy/public/TracyClient.o: ERROR_SWITCH_ENUM =
|
||||
|
|
|
@ -156,6 +156,7 @@ struct Expr
|
|||
virtual Value * maybeThunk(EvalState & state, Env & env);
|
||||
virtual void setName(Symbol name);
|
||||
virtual PosIdx getPos() const { return noPos; }
|
||||
virtual const char* showExprType() const { return "undefined"; }
|
||||
};
|
||||
|
||||
#define COMMON_METHODS \
|
||||
|
@ -168,6 +169,7 @@ struct ExprInt : Expr
|
|||
Value v;
|
||||
ExprInt(NixInt n) { v.mkInt(n); };
|
||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||
const char* showExprType() const { return "int"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -176,6 +178,7 @@ struct ExprFloat : Expr
|
|||
Value v;
|
||||
ExprFloat(NixFloat nf) { v.mkFloat(nf); };
|
||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||
const char* showExprType() const { return "float"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -185,6 +188,7 @@ struct ExprString : Expr
|
|||
Value v;
|
||||
ExprString(std::string &&s) : s(std::move(s)) { v.mkString(this->s.data()); };
|
||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||
const char* showExprType() const { return "string"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -198,6 +202,7 @@ struct ExprPath : Expr
|
|||
v.mkPath(&*accessor, this->s.c_str());
|
||||
}
|
||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||
const char* showExprType() const { return "path"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -229,6 +234,7 @@ struct ExprVar : Expr
|
|||
ExprVar(const PosIdx & pos, Symbol name) : pos(pos), name(name) { };
|
||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||
PosIdx getPos() const override { return pos; }
|
||||
const char* showExprType() const { return "var"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -240,6 +246,7 @@ struct ExprSelect : Expr
|
|||
ExprSelect(const PosIdx & pos, Expr * e, AttrPath attrPath, Expr * def) : pos(pos), e(e), def(def), attrPath(std::move(attrPath)) { };
|
||||
ExprSelect(const PosIdx & pos, Expr * e, Symbol name) : pos(pos), e(e), def(0) { attrPath.push_back(AttrName(name)); };
|
||||
PosIdx getPos() const override { return pos; }
|
||||
const char* showExprType() const { return "select"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -249,6 +256,7 @@ struct ExprOpHasAttr : Expr
|
|||
AttrPath attrPath;
|
||||
ExprOpHasAttr(Expr * e, AttrPath attrPath) : e(e), attrPath(std::move(attrPath)) { };
|
||||
PosIdx getPos() const override { return e->getPos(); }
|
||||
const char* showExprType() const { return "op_has_attr"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -278,6 +286,7 @@ struct ExprAttrs : Expr
|
|||
ExprAttrs(const PosIdx &pos) : recursive(false), pos(pos) { };
|
||||
ExprAttrs() : recursive(false) { };
|
||||
PosIdx getPos() const override { return pos; }
|
||||
const char* showExprType() const { return "attrs"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -285,6 +294,7 @@ struct ExprList : Expr
|
|||
{
|
||||
std::vector<Expr *> elems;
|
||||
ExprList() { };
|
||||
const char* showExprType() const { return "list"; }
|
||||
COMMON_METHODS
|
||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||
|
||||
|
@ -345,6 +355,7 @@ struct ExprLambda : Expr
|
|||
std::string showNamePos(const EvalState & state) const;
|
||||
inline bool hasFormals() const { return formals != nullptr; }
|
||||
PosIdx getPos() const override { return pos; }
|
||||
const char* showExprType() const { return "lambda"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -357,6 +368,7 @@ struct ExprCall : Expr
|
|||
: fun(fun), args(args), pos(pos)
|
||||
{ }
|
||||
PosIdx getPos() const override { return pos; }
|
||||
const char* showExprType() const { return "call"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -365,6 +377,7 @@ struct ExprLet : Expr
|
|||
ExprAttrs * attrs;
|
||||
Expr * body;
|
||||
ExprLet(ExprAttrs * attrs, Expr * body) : attrs(attrs), body(body) { };
|
||||
const char* showExprType() const { return "let"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -376,6 +389,7 @@ struct ExprWith : Expr
|
|||
ExprWith * parentWith;
|
||||
ExprWith(const PosIdx & pos, Expr * attrs, Expr * body) : pos(pos), attrs(attrs), body(body) { };
|
||||
PosIdx getPos() const override { return pos; }
|
||||
const char* showExprType() const { return "with"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -385,6 +399,7 @@ struct ExprIf : Expr
|
|||
Expr * cond, * then, * else_;
|
||||
ExprIf(const PosIdx & pos, Expr * cond, Expr * then, Expr * else_) : pos(pos), cond(cond), then(then), else_(else_) { };
|
||||
PosIdx getPos() const override { return pos; }
|
||||
const char* showExprType() const { return "if"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -394,6 +409,7 @@ struct ExprAssert : Expr
|
|||
Expr * cond, * body;
|
||||
ExprAssert(const PosIdx & pos, Expr * cond, Expr * body) : pos(pos), cond(cond), body(body) { };
|
||||
PosIdx getPos() const override { return pos; }
|
||||
const char* showExprType() const { return "assert"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -422,6 +438,7 @@ struct ExprOpNot : Expr
|
|||
} \
|
||||
void eval(EvalState & state, Env & env, Value & v) override; \
|
||||
PosIdx getPos() const override { return pos; } \
|
||||
const char* showExprType() const { return #name; } \
|
||||
};
|
||||
|
||||
MakeBinOp(ExprOpEq, "==")
|
||||
|
@ -440,6 +457,7 @@ struct ExprConcatStrings : Expr
|
|||
ExprConcatStrings(const PosIdx & pos, bool forceString, std::vector<std::pair<PosIdx, Expr *>> * es)
|
||||
: pos(pos), forceString(forceString), es(es) { };
|
||||
PosIdx getPos() const override { return pos; }
|
||||
const char* showExprType() const { return "concat_strings"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -448,6 +466,7 @@ struct ExprPos : Expr
|
|||
PosIdx pos;
|
||||
ExprPos(const PosIdx & pos) : pos(pos) { };
|
||||
PosIdx getPos() const override { return pos; }
|
||||
const char* showExprType() const { return "pos"; }
|
||||
COMMON_METHODS
|
||||
};
|
||||
|
||||
|
@ -457,6 +476,7 @@ struct ExprBlackHole : Expr
|
|||
void show(const SymbolTable & symbols, std::ostream & str) const override {}
|
||||
void eval(EvalState & state, Env & env, Value & v) override;
|
||||
void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env) override {}
|
||||
const char* showExprType() const { return "blackhole"; }
|
||||
};
|
||||
|
||||
extern ExprBlackHole eBlackHole;
|
||||
|
|
Loading…
Reference in New Issue