diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index c8b1f27d7..f30ab2a13 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -966,10 +967,9 @@ void ExprVar::eval(EvalState & state, Env & env, Value & v) std::ostringstream ossName; ossName << *this; string name = ossName.str(); - ProfilerCallLevel lvl {&(this->pos), name, ProfilerCallLevel::var}; - state.profState.jumpInValue(lvl); + state.profState.jumpInValue(&(this->pos), name, ProfilerCallType::var); state.forceValue(*v2, pos); - state.profState.createCallgraphentry(lvl); + state.profState.jumpOutValue(); } v = *v2; } @@ -1032,10 +1032,10 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) std::ostringstream ossName; ossName << *this; string name = ossName.str(); - ProfilerCallLevel lvl {pos2 != NULL ? pos2 : &(this->pos), name, ProfilerCallLevel::select}; - state.profState.jumpInValue(lvl); - state.forceValue(*vAttrs, ( pos2 != NULL ? *pos2 : this->pos ) ); - state.profState.createCallgraphentry(lvl); + Pos* fpos = pos2 != NULL ? pos2 : &(this->pos); + state.profState.jumpInValue(fpos, name, ProfilerCallType::select); + state.forceValue(*vAttrs, *fpos); + state.profState.jumpOutValue(); } } catch (Error & e) { @@ -2035,7 +2035,8 @@ static GlobalConfig::Register r1(&evalSettings); */ ProfilerState::ProfilerState(): - nestedLevel(0) + nestedLevel(0), + lastProfilerCall(NULL) {} CompressedFileId ProfilerState::registerFile(FileName& fName) { @@ -2066,35 +2067,46 @@ CompressedFuncId ProfilerState::registerFunction(CostCenterName& fName) { return fid; } -void ProfilerState::jumpInValue(ProfilerCallLevel& call) { +void ProfilerState::jumpInValue(Pos* pos, CostCenterName name, ProfilerCallType type) { + ProfilerCallLevel* call = new ProfilerCallLevel{lastProfilerCall, std::forward_list(), pos, name, type}; string delim=""; string opStr=""; std::ostringstream srcPos; - callGraphStack.push(call); + + if (lastProfilerCall) { + lastProfilerCall->children.push_front(call); + } + callGraphStack.push(*call); + lastProfilerCall = call; + + // Printing stuff int stackSize = callGraphStack.size(); for(int i=0;ifile.set()) { + if(pos->file.set()) { std::ostringstream ossFi; - ossFi << call.pos->file; + ossFi << pos->file; string fileName = ossFi.str(); - srcPos << fileName << " " << call.pos->line << ":" << call.pos->column; + srcPos << fileName << " " << pos->line << ":" << pos->column; } else { srcPos << "NOT DEFINED"; } - std::cout << delim << " " << opStr << "::" << call.name << " " << srcPos.str() << std::endl; + std::cout << delim << " " << opStr << "::" << name << " " << srcPos.str() << std::endl; + } -void ProfilerState::createCallgraphentry(ProfilerCallLevel& call) { +void ProfilerState::jumpOutValue() { + if (!callGraphStack.empty()) + lastProfilerCall = callGraphStack.top().parent; callGraphStack.pop(); } diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 466a5b600..51fad18e3 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -11,6 +11,7 @@ #include #include #include +#include namespace nix { @@ -48,11 +49,14 @@ struct ProfCostOcc { int selfCost; }; +enum ProfilerCallType { select=0, var}; struct ProfilerCallLevel { + ProfilerCallLevel* parent; + std::forward_list children; Pos* pos; CostCenterName name; - enum { select=0, var} callType; + ProfilerCallType type; }; class ProfilerState { @@ -63,8 +67,8 @@ public: CompressedFuncId registerFunction(CostCenterName& fName); ProfCostOcc& getFuncOcc(FileName& fName, CostCenterName& fnName); void saveCost(ProfCostOcc& occCost); - void jumpInValue(ProfilerCallLevel& call); - void createCallgraphentry(ProfilerCallLevel& call); + void jumpInValue(Pos* pos, CostCenterName name, ProfilerCallType type); + void jumpOutValue(); int nestedLevel; private: @@ -75,6 +79,7 @@ private: CompressedFuncId currentFuncId; CompressedFileId currentFileId; std::stack callGraphStack; + ProfilerCallLevel* lastProfilerCall; };