libexpr: rename confusing makeImmutableString -> gcCopyStringIfNeeded

The purpose of this function has little to do with immutability. Value's
strings are never mutated, and the point of this function is to
singleton empty strings.

Change-Id: Ifd41dd952409d54e4d3de9ab59064e6928b0e480
This commit is contained in:
Qyriad 2024-07-15 18:19:54 -06:00
parent a3361557e3
commit e67dac1d74
4 changed files with 32 additions and 18 deletions

View file

@ -49,21 +49,6 @@ using json = nlohmann::json;
namespace nix { namespace nix {
// When there's no need to write to the string, we can optimize away empty
// string allocations.
// This function handles makeImmutableString(std::string_view()) by returning
// the empty string.
static const char * makeImmutableString(std::string_view s)
{
const size_t size = s.size();
if (size == 0)
return "";
auto t = gcAllocString(size + 1);
memcpy(t, s.data(), size);
t[size] = '\0';
return t;
}
RootValue allocRootValue(Value * v) RootValue allocRootValue(Value * v)
{ {
#if HAVE_BOEHMGC #if HAVE_BOEHMGC
@ -784,7 +769,7 @@ DebugTraceStacker::DebugTraceStacker(EvalState & evalState, DebugTrace t)
void Value::mkString(std::string_view s) void Value::mkString(std::string_view s)
{ {
mkString(makeImmutableString(s)); mkString(gcCopyStringIfNeeded(s));
} }
@ -795,7 +780,7 @@ static void copyContextToValue(Value & v, const NixStringContext & context)
v.string.context = (const char * *) v.string.context = (const char * *)
gcAllocBytes((context.size() + 1) * sizeof(char *)); gcAllocBytes((context.size() + 1) * sizeof(char *));
for (auto & i : context) for (auto & i : context)
v.string.context[n++] = makeImmutableString(i.to_string()); v.string.context[n++] = gcCopyStringIfNeeded(i.to_string());
v.string.context[n] = 0; v.string.context[n] = 0;
} }
} }
@ -815,7 +800,7 @@ void Value::mkStringMove(const char * s, const NixStringContext & context)
void Value::mkPath(const SourcePath & path) void Value::mkPath(const SourcePath & path)
{ {
mkPath(makeImmutableString(path.path.abs())); mkPath(gcCopyStringIfNeeded(path.path.abs()));
} }

23
src/libexpr/gc-alloc.cc Normal file
View file

@ -0,0 +1,23 @@
#include "gc-alloc.hh"
#include <cstring>
#include <string_view>
namespace nix
{
char const * gcCopyStringIfNeeded(std::string_view toCopyFrom)
{
if (toCopyFrom.empty()) {
return "";
}
size_t const size = toCopyFrom.size();
char * cstr = gcAllocString(size + 1);
memcpy(cstr, toCopyFrom.data(), size);
cstr[size] = '\0';
return cstr;
}
}

View file

@ -7,6 +7,7 @@
#include <list> #include <list>
#include <map> #include <map>
#include <new> #include <new>
#include <string_view>
#include <vector> #include <vector>
#if HAVE_BOEHMGC #if HAVE_BOEHMGC
@ -116,4 +117,8 @@ inline char * gcAllocString(size_t size)
return cstr; return cstr;
} }
/// Returns a C-string copied from @ref toCopyFrom, or a single, static empty
/// string if @ref toCopyFrom is also empty.
char const * gcCopyStringIfNeeded(std::string_view toCopyFrom);
} }

View file

@ -22,6 +22,7 @@ libexpr_sources = files(
'eval.cc', 'eval.cc',
'function-trace.cc', 'function-trace.cc',
'get-drvs.cc', 'get-drvs.cc',
'gc-alloc.cc',
'json-to-value.cc', 'json-to-value.cc',
'nixexpr.cc', 'nixexpr.cc',
'parser/parser.cc', 'parser/parser.cc',