mirror of
https://github.com/NixOS/nix
synced 2025-06-25 06:31:14 +02:00
Merge pull request #9582 from pennae/misc-opts
a packet of small optimizations
This commit is contained in:
commit
ee439734e9
20 changed files with 148 additions and 76 deletions
|
@ -163,7 +163,17 @@ void Value::print(const SymbolTable &symbols, std::ostream &str,
|
|||
break;
|
||||
case tThunk:
|
||||
case tApp:
|
||||
str << "<CODE>";
|
||||
if (!isBlackhole()) {
|
||||
str << "<CODE>";
|
||||
} else {
|
||||
// Although we know for sure that it's going to be an infinite recursion
|
||||
// when this value is accessed _in the current context_, it's likely
|
||||
// that the user will misinterpret a simpler «infinite recursion» output
|
||||
// as a definitive statement about the value, while in fact it may be
|
||||
// a valid value after `builtins.trace` and perhaps some other steps
|
||||
// have completed.
|
||||
str << "«potential infinite recursion»";
|
||||
}
|
||||
break;
|
||||
case tLambda:
|
||||
str << "<LAMBDA>";
|
||||
|
@ -180,15 +190,6 @@ void Value::print(const SymbolTable &symbols, std::ostream &str,
|
|||
case tFloat:
|
||||
str << fpoint;
|
||||
break;
|
||||
case tBlackhole:
|
||||
// Although we know for sure that it's going to be an infinite recursion
|
||||
// when this value is accessed _in the current context_, it's likely
|
||||
// that the user will misinterpret a simpler «infinite recursion» output
|
||||
// as a definitive statement about the value, while in fact it may be
|
||||
// a valid value after `builtins.trace` and perhaps some other steps
|
||||
// have completed.
|
||||
str << "«potential infinite recursion»";
|
||||
break;
|
||||
default:
|
||||
printError("Nix evaluator internal error: Value::print(): invalid value type %1%", internalType);
|
||||
abort();
|
||||
|
@ -256,9 +257,8 @@ std::string showType(const Value & v)
|
|||
case tPrimOpApp:
|
||||
return fmt("the partially applied built-in function '%s'", std::string(getPrimOp(v)->primOp->name));
|
||||
case tExternal: return v.external->showType();
|
||||
case tThunk: return "a thunk";
|
||||
case tThunk: return v.isBlackhole() ? "a black hole" : "a thunk";
|
||||
case tApp: return "a function application";
|
||||
case tBlackhole: return "a black hole";
|
||||
default:
|
||||
return std::string(showType(v.type()));
|
||||
}
|
||||
|
@ -1646,15 +1646,15 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
return;
|
||||
} else {
|
||||
/* We have all the arguments, so call the primop. */
|
||||
auto name = vCur.primOp->name;
|
||||
auto * fn = vCur.primOp;
|
||||
|
||||
nrPrimOpCalls++;
|
||||
if (countCalls) primOpCalls[name]++;
|
||||
if (countCalls) primOpCalls[fn->name]++;
|
||||
|
||||
try {
|
||||
vCur.primOp->fun(*this, vCur.determinePos(noPos), args, vCur);
|
||||
fn->fun(*this, vCur.determinePos(noPos), args, vCur);
|
||||
} catch (Error & e) {
|
||||
addErrorTrace(e, pos, "while calling the '%1%' builtin", name);
|
||||
addErrorTrace(e, pos, "while calling the '%1%' builtin", fn->name);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
@ -1691,18 +1691,18 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
for (size_t i = 0; i < argsLeft; ++i)
|
||||
vArgs[argsDone + i] = args[i];
|
||||
|
||||
auto name = primOp->primOp->name;
|
||||
auto fn = primOp->primOp;
|
||||
nrPrimOpCalls++;
|
||||
if (countCalls) primOpCalls[name]++;
|
||||
if (countCalls) primOpCalls[fn->name]++;
|
||||
|
||||
try {
|
||||
// TODO:
|
||||
// 1. Unify this and above code. Heavily redundant.
|
||||
// 2. Create a fake env (arg1, arg2, etc.) and a fake expr (arg1: arg2: etc: builtins.name arg1 arg2 etc)
|
||||
// so the debugger allows to inspect the wrong parameters passed to the builtin.
|
||||
primOp->primOp->fun(*this, vCur.determinePos(noPos), vArgs, vCur);
|
||||
fn->fun(*this, vCur.determinePos(noPos), vArgs, vCur);
|
||||
} catch (Error & e) {
|
||||
addErrorTrace(e, pos, "while calling the '%1%' builtin", name);
|
||||
addErrorTrace(e, pos, "while calling the '%1%' builtin", fn->name);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
@ -2056,6 +2056,29 @@ void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
|||
}
|
||||
|
||||
|
||||
void ExprBlackHole::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
state.error("infinite recursion encountered")
|
||||
.debugThrow<InfiniteRecursionError>();
|
||||
}
|
||||
|
||||
// always force this to be separate, otherwise forceValue may inline it and take
|
||||
// a massive perf hit
|
||||
[[gnu::noinline]]
|
||||
void EvalState::tryFixupBlackHolePos(Value & v, PosIdx pos)
|
||||
{
|
||||
if (!v.isBlackhole())
|
||||
return;
|
||||
auto e = std::current_exception();
|
||||
try {
|
||||
std::rethrow_exception(e);
|
||||
} catch (InfiniteRecursionError & e) {
|
||||
e.err.errPos = positions[pos];
|
||||
} catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EvalState::forceValueDeep(Value & v)
|
||||
{
|
||||
std::set<const Value *> seen;
|
||||
|
@ -2065,7 +2088,7 @@ void EvalState::forceValueDeep(Value & v)
|
|||
recurse = [&](Value & v) {
|
||||
if (!seen.insert(&v).second) return;
|
||||
|
||||
forceValue(v, [&]() { return v.determinePos(noPos); });
|
||||
forceValue(v, v.determinePos(noPos));
|
||||
|
||||
if (v.type() == nAttrs) {
|
||||
for (auto & i : *v.attrs)
|
||||
|
@ -2457,7 +2480,7 @@ bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_v
|
|||
return v1.boolean == v2.boolean;
|
||||
|
||||
case nString:
|
||||
return v1.string_view().compare(v2.string_view()) == 0;
|
||||
return strcmp(v1.c_str(), v2.c_str()) == 0;
|
||||
|
||||
case nPath:
|
||||
return
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue