diff options
author | Théophane Hufschmitt <regnat@users.noreply.github.com> | 2021-12-21 08:50:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-21 08:50:29 +0100 |
commit | de273bbff2722c8abd134ddffd69e457a3938056 (patch) | |
tree | 426d9a6c71141f027316e3aba1e408fb6f0b2865 | |
parent | 6e6e998930f0d7361d64644eb37d9134e74e8501 (diff) | |
parent | 09b245690a9ab40847e3faa96646e4bd6ce033e0 (diff) |
Merge pull request #5809 from pennae/small-perf-improvements
small perf improvements
-rw-r--r-- | src/libexpr/eval.cc | 17 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 3 |
2 files changed, 19 insertions, 1 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 8cf4d9549..a95726f5f 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -821,8 +821,23 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) Value * EvalState::allocValue() { + /* We use the boehm batch allocator to speed up allocations of Values (of which there are many). + GC_malloc_many returns a linked list of objects of the given size, where the first word + of each object is also the pointer to the next object in the list. This also means that we + have to explicitly clear the first word of every object we take. */ + if (!valueAllocCache) { + valueAllocCache = GC_malloc_many(sizeof(Value)); + if (!valueAllocCache) throw std::bad_alloc(); + } + + /* GC_NEXT is a convenience macro for accessing the first word of an object. + Take the first list item, advance the list to the next item, and clear the next pointer. */ + void * p = valueAllocCache; + GC_PTR_STORE_AND_DIRTY(&valueAllocCache, GC_NEXT(p)); + GC_NEXT(p) = nullptr; + nrValues++; - auto v = (Value *) allocBytes(sizeof(Value)); + auto v = (Value *) p; return v; } diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 1aab8e166..cc63294c6 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -133,6 +133,9 @@ private: /* Cache used by prim_match(). */ std::shared_ptr<RegexCache> regexCache; + /* Allocation cache for GC'd Value objects. */ + void * valueAllocCache = nullptr; + public: EvalState( |