aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThéophane Hufschmitt <regnat@users.noreply.github.com>2021-12-21 08:50:29 +0100
committerGitHub <noreply@github.com>2021-12-21 08:50:29 +0100
commitde273bbff2722c8abd134ddffd69e457a3938056 (patch)
tree426d9a6c71141f027316e3aba1e408fb6f0b2865
parent6e6e998930f0d7361d64644eb37d9134e74e8501 (diff)
parent09b245690a9ab40847e3faa96646e4bd6ce033e0 (diff)
Merge pull request #5809 from pennae/small-perf-improvements
small perf improvements
-rw-r--r--src/libexpr/eval.cc17
-rw-r--r--src/libexpr/eval.hh3
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(