diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 9c10a9b3a6a7..2cea7f1a3600 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1366,7 +1366,12 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) sort = true; } - bindings.bindings->pos = pos; + /* Empty attrsets share the static Bindings::emptyBindings, which we + must not write to: apart from being a data race, it causes false + sharing on emptyBindings' cache line (which may also hold other hot + globals such as Counter::enabled) between all evaluator threads. */ + if (bindings.bindings != &Bindings::emptyBindings) + bindings.bindings->pos = pos; v.mkAttrs(sort ? bindings.finish() : bindings.alreadySorted()); }