From 6d118419f208cc4f991c5b3ef30e4e28c8e0c69d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 29 Apr 2019 15:34:05 +0200 Subject: [PATCH] Garbage-collect paths --- src/libexpr/eval.cc | 34 ++++------------------------------ src/libexpr/gc.cc | 2 +- src/libexpr/nixexpr.cc | 2 +- src/libexpr/nixexpr.hh | 5 ++--- src/libexpr/primops.cc | 2 +- src/libexpr/value-to-json.cc | 2 +- src/libexpr/value-to-xml.cc | 2 +- src/libexpr/value.hh | 9 +++------ 8 files changed, 14 insertions(+), 44 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index e4438afa1..784def811 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -24,19 +24,6 @@ namespace nix { SymbolTable symbols; -unsigned long stringBytes = 0; - -// FIXME -static char * dupString(const char * s) -{ - char * t; - stringBytes += strlen(s) + 1; - t = strdup(s); - if (!t) throw std::bad_alloc(); - return t; -} - - static void printValue(std::ostream & str, std::set & active, const Value & v) { checkInterrupt(); @@ -67,7 +54,7 @@ static void printValue(std::ostream & str, std::set & active, con str << "\""; break; case tPath: - str << v.path; // !!! escaping? + str << v.path->s; // !!! escaping? break; case tNull: str << "null"; @@ -500,12 +487,6 @@ Value & mkString(Value & v, const string & s, const PathSet & context) } -void mkPath(Value & v, const char * s) -{ - mkPathNoCopy(v, dupString(s)); -} - - inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) { for (size_t l = var.level; l; --l, env = env->up) ; @@ -1492,7 +1473,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } if (v.type == tPath) { - Path path(canonPath(v.path)); + Path path(canonPath(v.path->s)); return copyToStore ? copyPathToStore(context, path) : path; } @@ -1603,7 +1584,7 @@ bool EvalState::eqValues(Value & v1, Value & v2) return v1.boolean == v2.boolean; case tPath: - return strcmp(v1.path, v2.path) == 0; + return strcmp(v1.path->s, v2.path->s) == 0; case tNull: return true; @@ -1719,7 +1700,6 @@ void EvalState::printStats() topObj.attr("nrLookups", nrLookups); topObj.attr("nrPrimOpCalls", nrPrimOpCalls); topObj.attr("nrFunctionCalls", nrFunctionCalls); - topObj.attr("stringBytes", stringBytes); if (countCalls) { { @@ -1770,12 +1750,6 @@ size_t valueSize(Value & v) { std::set seen; - auto doString = [&](const char * s) -> size_t { - if (seen.find(s) != seen.end()) return 0; - seen.insert(s); - return strlen(s) + 1; - }; - std::function doValue; std::function doEnv; @@ -1790,7 +1764,7 @@ size_t valueSize(Value & v) sz += v.string.s->words() * WORD_SIZE; break; case tPath: - sz += doString(v.path); + sz += v.path->words() * WORD_SIZE; break; case tAttrs: if (seen.find(v.attrs) == seen.end()) { diff --git a/src/libexpr/gc.cc b/src/libexpr/gc.cc index b38efab79..ba71d2747 100644 --- a/src/libexpr/gc.cc +++ b/src/libexpr/gc.cc @@ -167,7 +167,7 @@ void GC::gc() } case tPath: - // FIXME + push(((Value *) obj)->path); break; case tAttrs: diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 63cbef1dd..9320900f0 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -80,7 +80,7 @@ void ExprString::show(std::ostream & str) const void ExprPath::show(std::ostream & str) const { - str << s; + str << v->path->s; } void ExprVar::show(std::ostream & str) const diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 82161291f..f3a754663 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -134,11 +134,10 @@ struct ExprIndStr : Expr struct ExprPath : Expr { - string s; Ptr v; - ExprPath(const string & s) : s(s) { + ExprPath(const string & s) { v = gc.alloc(Value::words()); - mkPathNoCopy(v, this->s.c_str()); + mkPath(v, s); }; COMMON_METHODS Ptr maybeThunk(EvalState & state, Env & env) override; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 3a3fb01c9..73c8e670f 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -344,7 +344,7 @@ struct CompareValues case tFloat: return v1->fpoint < v2->fpoint; case tPath: - return strcmp(v1->path, v2->path) < 0; + return strcmp(v1->path->s, v2->path->s) < 0; default: throw EvalError(format("cannot compare %1% with %2%") % showType(*v1) % showType(*v2)); } diff --git a/src/libexpr/value-to-json.cc b/src/libexpr/value-to-json.cc index 217fe0c3c..97389ee4a 100644 --- a/src/libexpr/value-to-json.cc +++ b/src/libexpr/value-to-json.cc @@ -34,7 +34,7 @@ void printValueAsJSON(EvalState & state, bool strict, break; case tPath: - out.write(state.copyPathToStore(context, v.path)); + out.write(state.copyPathToStore(context, v.path->s)); break; case tNull: diff --git a/src/libexpr/value-to-xml.cc b/src/libexpr/value-to-xml.cc index 7d1a8d51f..79ff10b79 100644 --- a/src/libexpr/value-to-xml.cc +++ b/src/libexpr/value-to-xml.cc @@ -77,7 +77,7 @@ static void printValueAsXML(EvalState & state, bool strict, bool location, break; case tPath: - doc.writeEmptyElement("path", singletonAttrs("value", v.path)); + doc.writeEmptyElement("path", singletonAttrs("value", v.path->s)); break; case tNull: diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh index 6801dd5d7..5c26aabbb 100644 --- a/src/libexpr/value.hh +++ b/src/libexpr/value.hh @@ -120,7 +120,7 @@ struct Value : Object Context * context; } string; const char * staticString; - const char * path; + String * path; Bindings * attrs; PtrList * bigList; Value * smallList[2]; @@ -288,16 +288,13 @@ static inline void mkString(Value & v, const Symbol & s) } -static inline void mkPathNoCopy(Value & v, const char * s) +static inline void mkPath(Value & v, const std::string & s) { + v.path = String::alloc(s.c_str()); v.type = tPath; - v.path = s; } -void mkPath(Value & v, const char * s); - - /* Compute the size in bytes of the given value, including all values and environments reachable from it. Static expressions (Exprs) are not included. */