Merge pull request #10286 from hercules-ci/various

Allocate a bit less
This commit is contained in:
Robert Hensing 2024-03-22 11:19:58 +01:00 committed by GitHub
commit a223280664
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 55 additions and 19 deletions

View file

@ -437,6 +437,12 @@ EvalState::EvalState(
vEmptyList.mkList(buildList(0)); vEmptyList.mkList(buildList(0));
vNull.mkNull(); vNull.mkNull();
vTrue.mkBool(true);
vFalse.mkBool(false);
vStringRegular.mkString("regular");
vStringDirectory.mkString("directory");
vStringSymlink.mkString("symlink");
vStringUnknown.mkString("unknown");
/* Initialise the Nix expression search path. */ /* Initialise the Nix expression search path. */
if (!evalSettings.pureEval) { if (!evalSettings.pureEval) {
@ -931,6 +937,9 @@ ListBuilder::ListBuilder(EvalState & state, size_t size)
state.nrListElems += size; state.nrListElems += size;
} }
Value * EvalState::getBool(bool b) {
return b ? &vTrue : &vFalse;
}
unsigned long nrThunks = 0; unsigned long nrThunks = 0;

View file

@ -187,10 +187,35 @@ public:
Value vEmptyList; Value vEmptyList;
/** /**
* Null constant. * `null` constant.
*
* This is _not_ a singleton. Pointer equality is _not_ sufficient.
*/ */
Value vNull; Value vNull;
/**
* `true` constant.
*
* This is _not_ a singleton. Pointer equality is _not_ sufficient.
*/
Value vTrue;
/**
* `true` constant.
*
* This is _not_ a singleton. Pointer equality is _not_ sufficient.
*/
Value vFalse;
/** `"regular"` */
Value vStringRegular;
/** `"directory"` */
Value vStringDirectory;
/** `"symlink"` */
Value vStringSymlink;
/** `"unknown"` */
Value vStringUnknown;
/** /**
* The accessor for the root filesystem. * The accessor for the root filesystem.
*/ */
@ -625,6 +650,11 @@ public:
return ListBuilder(*this, size); return ListBuilder(*this, size);
} }
/**
* Return a boolean `Value *` without allocating.
*/
Value *getBool(bool b);
void mkThunk_(Value & v, Expr * expr); void mkThunk_(Value & v, Expr * expr);
void mkPos(Value & v, PosIdx pos); void mkPos(Value & v, PosIdx pos);

View file

@ -896,10 +896,11 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va
try { try {
state.forceValue(*args[0], pos); state.forceValue(*args[0], pos);
attrs.insert(state.sValue, args[0]); attrs.insert(state.sValue, args[0]);
attrs.alloc("success").mkBool(true); attrs.insert(state.symbols.create("success"), &state.vTrue);
} catch (AssertionError & e) { } catch (AssertionError & e) {
attrs.alloc(state.sValue).mkBool(false); // `value = false;` is unfortunate but removing it is a breaking change.
attrs.alloc("success").mkBool(false); attrs.insert(state.sValue, &state.vFalse);
attrs.insert(state.symbols.create("success"), &state.vFalse);
} }
// restore the debugRepl pointer if we saved it earlier. // restore the debugRepl pointer if we saved it earlier.
@ -1775,20 +1776,20 @@ static RegisterPrimOp primop_hashFile({
.fun = prim_hashFile, .fun = prim_hashFile,
}); });
static std::string_view fileTypeToString(InputAccessor::Type type) static Value * fileTypeToString(EvalState & state, InputAccessor::Type type)
{ {
return return
type == InputAccessor::Type::tRegular ? "regular" : type == InputAccessor::Type::tRegular ? &state.vStringRegular :
type == InputAccessor::Type::tDirectory ? "directory" : type == InputAccessor::Type::tDirectory ? &state.vStringDirectory :
type == InputAccessor::Type::tSymlink ? "symlink" : type == InputAccessor::Type::tSymlink ? &state.vStringSymlink :
"unknown"; &state.vStringUnknown;
} }
static void prim_readFileType(EvalState & state, const PosIdx pos, Value * * args, Value & v) static void prim_readFileType(EvalState & state, const PosIdx pos, Value * * args, Value & v)
{ {
auto path = realisePath(state, pos, *args[0], std::nullopt); auto path = realisePath(state, pos, *args[0], std::nullopt);
/* Retrieve the directory entry type and stringize it. */ /* Retrieve the directory entry type and stringize it. */
v.mkString(fileTypeToString(path.lstat().type)); v = *fileTypeToString(state, path.lstat().type);
} }
static RegisterPrimOp primop_readFileType({ static RegisterPrimOp primop_readFileType({
@ -1819,8 +1820,8 @@ static void prim_readDir(EvalState & state, const PosIdx pos, Value * * args, Va
Value * readFileType = nullptr; Value * readFileType = nullptr;
for (auto & [name, type] : entries) { for (auto & [name, type] : entries) {
auto & attr = attrs.alloc(name);
if (!type) { if (!type) {
auto & attr = attrs.alloc(name);
// Some filesystems or operating systems may not be able to return // Some filesystems or operating systems may not be able to return
// detailed node info quickly in this case we produce a thunk to // detailed node info quickly in this case we produce a thunk to
// query the file type lazily. // query the file type lazily.
@ -1832,7 +1833,7 @@ static void prim_readDir(EvalState & state, const PosIdx pos, Value * * args, Va
} else { } else {
// This branch of the conditional is much more likely. // This branch of the conditional is much more likely.
// Here we just stringize the directory entry type. // Here we just stringize the directory entry type.
attr.mkString(fileTypeToString(*type)); attrs.insert(state.symbols.create(name), fileTypeToString(state, *type));
} }
} }
@ -2193,11 +2194,8 @@ bool EvalState::callPathFilter(
Value arg1; Value arg1;
arg1.mkString(pathArg); arg1.mkString(pathArg);
Value arg2;
// assert that type is not "unknown" // assert that type is not "unknown"
arg2.mkString(fileTypeToString(st.type)); Value * args []{&arg1, fileTypeToString(*this, st.type)};
Value * args []{&arg1, &arg2};
Value res; Value res;
callFunction(*filterFun, 2, args, res, pos); callFunction(*filterFun, 2, args, res, pos);
@ -2847,8 +2845,7 @@ static void prim_functionArgs(EvalState & state, const PosIdx pos, Value * * arg
auto attrs = state.buildBindings(args[0]->lambda.fun->formals->formals.size()); auto attrs = state.buildBindings(args[0]->lambda.fun->formals->formals.size());
for (auto & i : args[0]->lambda.fun->formals->formals) for (auto & i : args[0]->lambda.fun->formals->formals)
// !!! should optimise booleans (allocate only once) attrs.insert(i.name, state.getBool(i.def), i.pos);
attrs.alloc(i.name, i.pos).mkBool(i.def);
v.mkAttrs(attrs); v.mkAttrs(attrs);
} }

View file

@ -159,7 +159,7 @@ public:
iterator begin() { return &elems[0]; } iterator begin() { return &elems[0]; }
iterator end() { return &elems[size]; } iterator end() { return &elems[size]; }
friend class Value; friend struct Value;
}; };