Skip to content

Commit

Permalink
primops: Name stack reservation limits
Browse files Browse the repository at this point in the history
  • Loading branch information
roberth committed Nov 16, 2023
1 parent 3af090d commit c4d4797
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/libexpr/eval.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "eval.hh"
#include "eval-settings.hh"
#include "hash.hh"
#include "primops.hh"
#include "types.hh"
#include "util.hh"
#include "store-api.hh"
Expand Down Expand Up @@ -2014,7 +2015,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
return result;
};

boost::container::small_vector<Value, 16> values(es->size());
boost::container::small_vector<Value, conservativeStackReservation> values(es->size());
Value * vTmpP = values.data();

for (auto & [i_pos, i] : *es) {
Expand Down
6 changes: 3 additions & 3 deletions src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2728,7 +2728,7 @@ static void prim_catAttrs(EvalState & state, const PosIdx pos, Value * * args, V
auto attrName = state.symbols.create(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.catAttrs"));
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.catAttrs");

boost::container::small_vector<Value *, 256> res(args[1]->listSize());
boost::container::small_vector<Value *, nonRecursiveStackReservation> res(args[1]->listSize());
size_t found = 0;

for (auto v2 : args[1]->listItems()) {
Expand Down Expand Up @@ -3063,7 +3063,7 @@ static void prim_filter(EvalState & state, const PosIdx pos, Value * * args, Val

state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.filter");

boost::container::small_vector<Value *, 256> vs(args[1]->listSize());
boost::container::small_vector<Value *, nonRecursiveStackReservation> vs(args[1]->listSize());
size_t k = 0;

bool same = true;
Expand Down Expand Up @@ -3452,7 +3452,7 @@ static void prim_concatMap(EvalState & state, const PosIdx pos, Value * * args,
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.concatMap");
auto nrLists = args[1]->listSize();

boost::container::small_vector<Value, 16> lists(nrLists);
boost::container::small_vector<Value, conservativeStackReservation> lists(nrLists);
size_t len = 0;

for (unsigned int n = 0; n < nrLists; ++n) {
Expand Down
12 changes: 12 additions & 0 deletions src/libexpr/primops.hh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@

namespace nix {

/**
* For functions where we do not expect deep recursion, we can use a sizable
* part of the stack a free allocation space.
*/
constexpr size_t nonRecursiveStackReservation = 256;

/**
* Functions that maybe applied to self-similar inputs, such as concatMap on a
* tree, should reserve a smaller part of the stack for allocation.
*/
constexpr size_t conservativeStackReservation = 16;

struct RegisterPrimOp
{
typedef std::vector<PrimOp> PrimOps;
Expand Down

0 comments on commit c4d4797

Please sign in to comment.