From 83a775313d8473d8f7f69f77d73cca916861fde5 Mon Sep 17 00:00:00 2001 From: Andreas Rammhold Date: Thu, 20 Oct 2022 11:48:31 +0200 Subject: [PATCH] Add initial tracing prototype --- src/libexpr/eval.cc | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 6cb756b1a..acd4e42b5 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -37,6 +37,85 @@ namespace nix { +struct TraceData { + // Dummy + std::string file; + size_t line; + + static TraceData fromPos(Pos &p) { + return TraceData { + p.file, + p.line + }; + } +}; + +template +struct TracingChunk { + + struct Entry { + uint64_t ts_entry; + uint64_t ts_exit; + Data data; + }; + + struct EntryRAII { + Entry* e; + EntryRAII(Entry* e, Data d) : e(e) { + e->ts_entry = now(); + e->data = d; + } + + ~EntryRAII() { + e->ts_exit = now(); + } + }; + + Entry data[size]; + size_t pos; + + TracingChunk(): pos(0) {} + + + inline bool has_capacity() const { + return pos < size - 1; + } + + inline EntryRAII create(Data d) { + // assert(has_capacity()); -- we are writing C++ to go fast, who cares about correctness?!? + auto e = &data[pos++]; + return EntryRAII(e, d); + } +}; + +template +struct TracingBuffer { + + typedef TracingChunk TC; + // Linked-list of all the chunks that we know about, the last chunk in the list is the latest + std::list chunks; + TC& current_chunk; // FIXME: undefined before alloc_new_chunk + + TracingBuffer() { + alloc_next_chunk(); + } + + inline void alloc_next_chunk() { + current_chunk = chunks.emplace_back(TC()); + } + + inline TC::EntryRAII create(Data d) { + if (unlikely(!current_chunk.has_capacity())) { + alloc_next_chunk(); + } + + return current_chunk.create(d); + } +}; + +std::unique_ptr> trace; + + static char * allocString(size_t size) { char * t; @@ -1271,6 +1350,13 @@ void EvalState::cacheFile( void EvalState::eval(Expr * e, Value & v) { + + auto t; // RAII container to ensure that exiting the call actually calls the destructor, actual type is std::optional + + if (trace) { + t = std::optional(trace->create(TraceData::fromPos(e->getPos()))); + } + e->eval(*this, baseEnv, v); }