mirror of
https://github.com/NixOS/nix.git
synced 2025-12-21 16:31:07 +01:00
Merge pull request #14584 from Radvendii/allocbytes-stringdata
libexpr: use allocBytes() to allocate StringData
This commit is contained in:
commit
327e8babf7
20 changed files with 136 additions and 109 deletions
|
|
@ -81,20 +81,20 @@ static const char * makeImmutableString(std::string_view s)
|
|||
return t;
|
||||
}
|
||||
|
||||
StringData & StringData::alloc(size_t size)
|
||||
StringData & StringData::alloc(EvalMemory & mem, size_t size)
|
||||
{
|
||||
void * t = GC_MALLOC_ATOMIC(sizeof(StringData) + size + 1);
|
||||
void * t = mem.allocBytes(sizeof(StringData) + size + 1);
|
||||
if (!t)
|
||||
throw std::bad_alloc();
|
||||
auto res = new (t) StringData(size);
|
||||
return *res;
|
||||
}
|
||||
|
||||
const StringData & StringData::make(std::string_view s)
|
||||
const StringData & StringData::make(EvalMemory & mem, std::string_view s)
|
||||
{
|
||||
if (s.empty())
|
||||
return ""_sds;
|
||||
auto & res = alloc(s.size());
|
||||
auto & res = alloc(mem, s.size());
|
||||
std::memcpy(&res.data_, s.data(), s.size());
|
||||
res.data_[s.size()] = '\0';
|
||||
return res;
|
||||
|
|
@ -849,9 +849,9 @@ DebugTraceStacker::DebugTraceStacker(EvalState & evalState, DebugTrace t)
|
|||
evalState.runDebugRepl(nullptr, trace.env, trace.expr);
|
||||
}
|
||||
|
||||
void Value::mkString(std::string_view s)
|
||||
void Value::mkString(std::string_view s, EvalMemory & mem)
|
||||
{
|
||||
mkStringNoCopy(StringData::make(s));
|
||||
mkStringNoCopy(StringData::make(mem, s));
|
||||
}
|
||||
|
||||
Value::StringWithContext::Context *
|
||||
|
|
@ -862,13 +862,13 @@ Value::StringWithContext::Context::fromBuilder(const NixStringContext & context,
|
|||
|
||||
auto ctx = new (mem.allocBytes(sizeof(Context) + context.size() * sizeof(value_type))) Context(context.size());
|
||||
std::ranges::transform(
|
||||
context, ctx->elems, [](const NixStringContextElem & elt) { return &StringData::make(elt.to_string()); });
|
||||
context, ctx->elems, [&](const NixStringContextElem & elt) { return &StringData::make(mem, elt.to_string()); });
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void Value::mkString(std::string_view s, const NixStringContext & context, EvalMemory & mem)
|
||||
{
|
||||
mkStringNoCopy(StringData::make(s), Value::StringWithContext::Context::fromBuilder(context, mem));
|
||||
mkStringNoCopy(StringData::make(mem, s), Value::StringWithContext::Context::fromBuilder(context, mem));
|
||||
}
|
||||
|
||||
void Value::mkStringMove(const StringData & s, const NixStringContext & context, EvalMemory & mem)
|
||||
|
|
@ -876,9 +876,9 @@ void Value::mkStringMove(const StringData & s, const NixStringContext & context,
|
|||
mkStringNoCopy(s, Value::StringWithContext::Context::fromBuilder(context, mem));
|
||||
}
|
||||
|
||||
void Value::mkPath(const SourcePath & path)
|
||||
void Value::mkPath(const SourcePath & path, EvalMemory & mem)
|
||||
{
|
||||
mkPath(&*path.accessor, StringData::make(path.path.abs()));
|
||||
mkPath(&*path.accessor, StringData::make(mem, path.path.abs()));
|
||||
}
|
||||
|
||||
inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
|
||||
|
|
@ -943,7 +943,7 @@ void EvalState::mkPos(Value & v, PosIdx p)
|
|||
auto origin = positions.originOf(p);
|
||||
if (auto path = std::get_if<SourcePath>(&origin)) {
|
||||
auto attrs = buildBindings(3);
|
||||
attrs.alloc(s.file).mkString(path->path.abs());
|
||||
attrs.alloc(s.file).mkString(path->path.abs(), mem);
|
||||
makePositionThunks(*this, p, attrs.alloc(s.line), attrs.alloc(s.column));
|
||||
v.mkAttrs(attrs);
|
||||
} else
|
||||
|
|
@ -2139,9 +2139,9 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
|||
for (const auto & part : strings) {
|
||||
resultStr += *part;
|
||||
}
|
||||
v.mkPath(state.rootPath(CanonPath(resultStr)));
|
||||
v.mkPath(state.rootPath(CanonPath(resultStr)), state.mem);
|
||||
} else {
|
||||
auto & resultStr = StringData::alloc(sSize);
|
||||
auto & resultStr = StringData::alloc(state.mem, sSize);
|
||||
auto * tmp = resultStr.data();
|
||||
for (const auto & part : strings) {
|
||||
std::memcpy(tmp, part->data(), part->size());
|
||||
|
|
|
|||
|
|
@ -232,13 +232,13 @@ public:
|
|||
* Allocate StringData on the (possibly) GC-managed heap and copy
|
||||
* the contents of s to it.
|
||||
*/
|
||||
static const StringData & make(std::string_view s);
|
||||
static const StringData & make(EvalMemory & mem, std::string_view s);
|
||||
|
||||
/**
|
||||
* Allocate StringData on the (possibly) GC-managed heap.
|
||||
* @param size Length of the string (without the NUL terminator).
|
||||
*/
|
||||
static StringData & alloc(size_t size);
|
||||
static StringData & alloc(EvalMemory & mem, size_t size);
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
|
|
@ -1147,13 +1147,13 @@ public:
|
|||
setStorage(StringWithContext{.str = &s, .context = context});
|
||||
}
|
||||
|
||||
void mkString(std::string_view s);
|
||||
void mkString(std::string_view s, EvalMemory & mem);
|
||||
|
||||
void mkString(std::string_view s, const NixStringContext & context, EvalMemory & mem);
|
||||
|
||||
void mkStringMove(const StringData & s, const NixStringContext & context, EvalMemory & mem);
|
||||
|
||||
void mkPath(const SourcePath & path);
|
||||
void mkPath(const SourcePath & path, EvalMemory & mem);
|
||||
|
||||
inline void mkPath(SourceAccessor * accessor, const StringData & path) noexcept
|
||||
{
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ public:
|
|||
bool string(string_t & val) override
|
||||
{
|
||||
forceNoNullByte(val);
|
||||
rs->value(state).mkString(val);
|
||||
rs->value(state).mkString(val, state.mem);
|
||||
rs->add();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ RegisterPrimOp::PrimOps & RegisterPrimOp::primOps()
|
|||
static inline Value * mkString(EvalState & state, const std::csub_match & match)
|
||||
{
|
||||
Value * v = state.allocValue();
|
||||
v->mkString({match.first, match.second});
|
||||
v->mkString({match.first, match.second}, state.mem);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
|
@ -230,12 +230,12 @@ void derivationToValue(
|
|||
NixStringContextElem::DrvDeep{.drvPath = storePath},
|
||||
},
|
||||
state.mem);
|
||||
attrs.alloc(state.s.name).mkString(drv.env["name"]);
|
||||
attrs.alloc(state.s.name).mkString(drv.env["name"], state.mem);
|
||||
|
||||
auto list = state.buildList(drv.outputs.size());
|
||||
for (const auto & [i, o] : enumerate(drv.outputs)) {
|
||||
mkOutputString(state, attrs, storePath, o);
|
||||
(list[i] = state.allocValue())->mkString(o.first);
|
||||
(list[i] = state.allocValue())->mkString(o.first, state.mem);
|
||||
}
|
||||
attrs.alloc(state.s.outputs).mkList(list);
|
||||
|
||||
|
|
@ -519,7 +519,7 @@ static void prim_typeOf(EvalState & state, const PosIdx pos, Value ** args, Valu
|
|||
v.mkStringNoCopy("lambda"_sds);
|
||||
break;
|
||||
case nExternal:
|
||||
v.mkString(args[0]->external()->typeOf());
|
||||
v.mkString(args[0]->external()->typeOf(), state.mem);
|
||||
break;
|
||||
case nFloat:
|
||||
v.mkStringNoCopy("float"_sds);
|
||||
|
|
@ -1176,7 +1176,7 @@ static void prim_getEnv(EvalState & state, const PosIdx pos, Value ** args, Valu
|
|||
{
|
||||
std::string name(
|
||||
state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.getEnv"));
|
||||
v.mkString(state.settings.restrictEval || state.settings.pureEval ? "" : getEnv(name).value_or(""));
|
||||
v.mkString(state.settings.restrictEval || state.settings.pureEval ? "" : getEnv(name).value_or(""), state.mem);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_getEnv({
|
||||
|
|
@ -1842,8 +1842,10 @@ static RegisterPrimOp primop_derivationStrict(
|
|||
‘out’. */
|
||||
static void prim_placeholder(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
||||
{
|
||||
v.mkString(hashPlaceholder(
|
||||
state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.placeholder")));
|
||||
v.mkString(
|
||||
hashPlaceholder(state.forceStringNoCtx(
|
||||
*args[0], pos, "while evaluating the first argument passed to builtins.placeholder")),
|
||||
state.mem);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_placeholder({
|
||||
|
|
@ -2027,7 +2029,7 @@ static void prim_dirOf(EvalState & state, const PosIdx pos, Value ** args, Value
|
|||
state.forceValue(*args[0], pos);
|
||||
if (args[0]->type() == nPath) {
|
||||
auto path = args[0]->path();
|
||||
v.mkPath(path.path.isRoot() ? path : path.parent());
|
||||
v.mkPath(path.path.isRoot() ? path : path.parent(), state.mem);
|
||||
} else {
|
||||
NixStringContext context;
|
||||
auto path = state.coerceToString(
|
||||
|
|
@ -2144,7 +2146,7 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value ** args, Va
|
|||
auto path =
|
||||
state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument passed to builtins.findFile");
|
||||
|
||||
v.mkPath(state.findFile(lookupPath, path, pos));
|
||||
v.mkPath(state.findFile(lookupPath, path, pos), state.mem);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_findFile(
|
||||
|
|
@ -2293,7 +2295,7 @@ static void prim_hashFile(EvalState & state, const PosIdx pos, Value ** args, Va
|
|||
|
||||
auto path = realisePath(state, pos, *args[1]);
|
||||
|
||||
v.mkString(hashString(*ha, path.readFile()).to_string(HashFormat::Base16, false));
|
||||
v.mkString(hashString(*ha, path.readFile()).to_string(HashFormat::Base16, false), state.mem);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_hashFile({
|
||||
|
|
@ -2382,7 +2384,7 @@ static void prim_readDir(EvalState & state, const PosIdx pos, Value ** args, Val
|
|||
// detailed node info quickly in this case we produce a thunk to
|
||||
// query the file type lazily.
|
||||
auto epath = state.allocValue();
|
||||
epath->mkPath(path / name);
|
||||
epath->mkPath(path / name, state.mem);
|
||||
if (!readFileType)
|
||||
readFileType = &state.getBuiltin("readFileType");
|
||||
attr.mkApp(readFileType, epath);
|
||||
|
|
@ -2763,7 +2765,7 @@ bool EvalState::callPathFilter(Value * filterFun, const SourcePath & path, PosId
|
|||
/* Call the filter function. The first argument is the path, the
|
||||
second is a string indicating the type of the file. */
|
||||
Value arg1;
|
||||
arg1.mkString(path.path.abs());
|
||||
arg1.mkString(path.path.abs(), mem);
|
||||
|
||||
// assert that type is not "unknown"
|
||||
Value * args[]{&arg1, const_cast<Value *>(&fileTypeToString(*this, st.type))};
|
||||
|
|
@ -4541,7 +4543,7 @@ static void prim_hashString(EvalState & state, const PosIdx pos, Value ** args,
|
|||
auto s =
|
||||
state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.hashString");
|
||||
|
||||
v.mkString(hashString(*ha, s).to_string(HashFormat::Base16, false));
|
||||
v.mkString(hashString(*ha, s).to_string(HashFormat::Base16, false), state.mem);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_hashString({
|
||||
|
|
@ -4574,7 +4576,7 @@ static void prim_convertHash(EvalState & state, const PosIdx pos, Value ** args,
|
|||
HashFormat hf = parseHashFormat(
|
||||
state.forceStringNoCtx(*iteratorToHashFormat->value, pos, "while evaluating the attribute 'toHashFormat'"));
|
||||
|
||||
v.mkString(Hash::parseAny(hash, ha).to_string(hf, hf == HashFormat::SRI));
|
||||
v.mkString(Hash::parseAny(hash, ha).to_string(hf, hf == HashFormat::SRI), state.mem);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_convertHash({
|
||||
|
|
@ -4992,8 +4994,8 @@ static void prim_parseDrvName(EvalState & state, const PosIdx pos, Value ** args
|
|||
state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.parseDrvName");
|
||||
DrvName parsed(name);
|
||||
auto attrs = state.buildBindings(2);
|
||||
attrs.alloc(state.s.name).mkString(parsed.name);
|
||||
attrs.alloc("version").mkString(parsed.version);
|
||||
attrs.alloc(state.s.name).mkString(parsed.name, state.mem);
|
||||
attrs.alloc("version").mkString(parsed.version, state.mem);
|
||||
v.mkAttrs(attrs);
|
||||
}
|
||||
|
||||
|
|
@ -5048,7 +5050,7 @@ static void prim_splitVersion(EvalState & state, const PosIdx pos, Value ** args
|
|||
}
|
||||
auto list = state.buildList(components.size());
|
||||
for (const auto & [n, component] : enumerate(components))
|
||||
(list[n] = state.allocValue())->mkString(std::move(component));
|
||||
(list[n] = state.allocValue())->mkString(std::move(component), state.mem);
|
||||
v.mkList(list);
|
||||
}
|
||||
|
||||
|
|
@ -5192,7 +5194,7 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings)
|
|||
});
|
||||
|
||||
if (!settings.pureEval)
|
||||
v.mkString(settings.getCurrentSystem());
|
||||
v.mkString(settings.getCurrentSystem(), mem);
|
||||
addConstant(
|
||||
"__currentSystem",
|
||||
v,
|
||||
|
|
@ -5224,7 +5226,7 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings)
|
|||
.impureOnly = true,
|
||||
});
|
||||
|
||||
v.mkString(nixVersion);
|
||||
v.mkString(nixVersion, mem);
|
||||
addConstant(
|
||||
"__nixVersion",
|
||||
v,
|
||||
|
|
@ -5249,7 +5251,7 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings)
|
|||
)",
|
||||
});
|
||||
|
||||
v.mkString(store->storeDir);
|
||||
v.mkString(store->storeDir, mem);
|
||||
addConstant(
|
||||
"__storeDir",
|
||||
v,
|
||||
|
|
@ -5314,8 +5316,8 @@ void EvalState::createBaseEnv(const EvalSettings & evalSettings)
|
|||
auto list = buildList(lookupPath.elements.size());
|
||||
for (const auto & [n, i] : enumerate(lookupPath.elements)) {
|
||||
auto attrs = buildBindings(2);
|
||||
attrs.alloc("path").mkString(i.path.s);
|
||||
attrs.alloc("prefix").mkString(i.prefix.s);
|
||||
attrs.alloc("path").mkString(i.path.s, mem);
|
||||
attrs.alloc("prefix").mkString(i.prefix.s, mem);
|
||||
(list[n] = allocValue())->mkAttrs(attrs);
|
||||
}
|
||||
v.mkList(list);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ static void prim_unsafeDiscardStringContext(EvalState & state, const PosIdx pos,
|
|||
NixStringContext context;
|
||||
auto s = state.coerceToString(
|
||||
pos, *args[0], context, "while evaluating the argument passed to builtins.unsafeDiscardStringContext");
|
||||
v.mkString(*s);
|
||||
v.mkString(*s, state.mem);
|
||||
}
|
||||
|
||||
static RegisterPrimOp primop_unsafeDiscardStringContext({
|
||||
|
|
@ -218,7 +218,7 @@ static void prim_getContext(EvalState & state, const PosIdx pos, Value ** args,
|
|||
if (!info.second.outputs.empty()) {
|
||||
auto list = state.buildList(info.second.outputs.size());
|
||||
for (const auto & [i, output] : enumerate(info.second.outputs))
|
||||
(list[i] = state.allocValue())->mkString(output);
|
||||
(list[i] = state.allocValue())->mkString(output, state.mem);
|
||||
infoAttrs.alloc(state.s.outputs).mkList(list);
|
||||
}
|
||||
attrs.alloc(state.store->printStorePath(info.first)).mkAttrs(infoAttrs);
|
||||
|
|
|
|||
|
|
@ -86,12 +86,12 @@ static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value ** ar
|
|||
auto attrs2 = state.buildBindings(8);
|
||||
state.mkStorePathString(storePath, attrs2.alloc(state.s.outPath));
|
||||
if (input2.getRef())
|
||||
attrs2.alloc("branch").mkString(*input2.getRef());
|
||||
attrs2.alloc("branch").mkString(*input2.getRef(), state.mem);
|
||||
// Backward compatibility: set 'rev' to
|
||||
// 0000000000000000000000000000000000000000 for a dirty tree.
|
||||
auto rev2 = input2.getRev().value_or(Hash(HashAlgorithm::SHA1));
|
||||
attrs2.alloc("rev").mkString(rev2.gitRev());
|
||||
attrs2.alloc("shortRev").mkString(rev2.gitRev().substr(0, 12));
|
||||
attrs2.alloc("rev").mkString(rev2.gitRev(), state.mem);
|
||||
attrs2.alloc("shortRev").mkString(rev2.gitRev().substr(0, 12), state.mem);
|
||||
if (auto revCount = input2.getRevCount())
|
||||
attrs2.alloc("revCount").mkInt(*revCount);
|
||||
v.mkAttrs(attrs2);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ void emitTreeAttrs(
|
|||
// FIXME: support arbitrary input attributes.
|
||||
|
||||
if (auto narHash = input.getNarHash())
|
||||
attrs.alloc("narHash").mkString(narHash->to_string(HashFormat::SRI, true));
|
||||
attrs.alloc("narHash").mkString(narHash->to_string(HashFormat::SRI, true), state.mem);
|
||||
|
||||
if (input.getType() == "git")
|
||||
attrs.alloc("submodules").mkBool(fetchers::maybeGetBoolAttr(input.attrs, "submodules").value_or(false));
|
||||
|
|
@ -43,13 +43,13 @@ void emitTreeAttrs(
|
|||
if (!forceDirty) {
|
||||
|
||||
if (auto rev = input.getRev()) {
|
||||
attrs.alloc("rev").mkString(rev->gitRev());
|
||||
attrs.alloc("shortRev").mkString(rev->gitShortRev());
|
||||
attrs.alloc("rev").mkString(rev->gitRev(), state.mem);
|
||||
attrs.alloc("shortRev").mkString(rev->gitShortRev(), state.mem);
|
||||
} else if (emptyRevFallback) {
|
||||
// Backwards compat for `builtins.fetchGit`: dirty repos return an empty sha1 as rev
|
||||
auto emptyHash = Hash(HashAlgorithm::SHA1);
|
||||
attrs.alloc("rev").mkString(emptyHash.gitRev());
|
||||
attrs.alloc("shortRev").mkString(emptyHash.gitShortRev());
|
||||
attrs.alloc("rev").mkString(emptyHash.gitRev(), state.mem);
|
||||
attrs.alloc("shortRev").mkString(emptyHash.gitShortRev(), state.mem);
|
||||
}
|
||||
|
||||
if (auto revCount = input.getRevCount())
|
||||
|
|
@ -59,13 +59,14 @@ void emitTreeAttrs(
|
|||
}
|
||||
|
||||
if (auto dirtyRev = fetchers::maybeGetStrAttr(input.attrs, "dirtyRev")) {
|
||||
attrs.alloc("dirtyRev").mkString(*dirtyRev);
|
||||
attrs.alloc("dirtyShortRev").mkString(*fetchers::maybeGetStrAttr(input.attrs, "dirtyShortRev"));
|
||||
attrs.alloc("dirtyRev").mkString(*dirtyRev, state.mem);
|
||||
attrs.alloc("dirtyShortRev").mkString(*fetchers::maybeGetStrAttr(input.attrs, "dirtyShortRev"), state.mem);
|
||||
}
|
||||
|
||||
if (auto lastModified = input.getLastModified()) {
|
||||
attrs.alloc("lastModified").mkInt(*lastModified);
|
||||
attrs.alloc("lastModifiedDate").mkString(fmt("%s", std::put_time(std::gmtime(&*lastModified), "%Y%m%d%H%M%S")));
|
||||
attrs.alloc("lastModifiedDate")
|
||||
.mkString(fmt("%s", std::put_time(std::gmtime(&*lastModified), "%Y%m%d%H%M%S")), state.mem);
|
||||
}
|
||||
|
||||
v.mkAttrs(attrs);
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va
|
|||
case toml::value_t::string: {
|
||||
auto s = toml::get<std::string_view>(t);
|
||||
forceNoNullByte(s);
|
||||
v.mkString(s);
|
||||
v.mkString(s, state.mem);
|
||||
} break;
|
||||
case toml::value_t::local_datetime:
|
||||
case toml::value_t::offset_datetime:
|
||||
|
|
@ -142,7 +142,7 @@ static void prim_fromTOML(EvalState & state, const PosIdx pos, Value ** args, Va
|
|||
s << t;
|
||||
auto str = s.view();
|
||||
forceNoNullByte(str);
|
||||
attrs.alloc("value").mkString(str);
|
||||
attrs.alloc("value").mkString(str, state.mem);
|
||||
v.mkAttrs(attrs);
|
||||
} else {
|
||||
throw std::runtime_error("Dates and times are not supported");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue