about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2020-07-18T03·44+0100
committertazjin <mail@tazj.in>2020-07-18T18·08+0000
commit56614c75e4a187c34706af718d9d8d69685c41b2 (patch)
tree070f39fa29e49444e0484e1a21e646b61f69a352
parenteffbb277c3b78ebbb78f6faca372ec19881059e1 (diff)
refactor(3p/nix/libexpr): Store nix::Env values in a std::vector r/1376
This has several advantages:

* we can ensure that the vector is traced by the GC
* we don't need to unsafely allocate memory to make an Env

Note that there was previously a check about the size of the
environment, but it's unclear why this was the case (git history
yielded nothing interesting) and it seems to have no effect.

Change-Id: I4998b879a728a6fb68e1bd187c521e2304e5047e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/1265
Tested-by: BuildkiteCI
Reviewed-by: isomer <isomer@tvl.fyi>
Reviewed-by: Kane York <rikingcoding@gmail.com>
Reviewed-by: glittershark <grfn@gws.fyi>
-rw-r--r--third_party/nix/src/libexpr/eval.cc8
-rw-r--r--third_party/nix/src/libexpr/eval.hh12
2 files changed, 11 insertions, 9 deletions
diff --git a/third_party/nix/src/libexpr/eval.cc b/third_party/nix/src/libexpr/eval.cc
index 0f3b7fabe0..16e6907214 100644
--- a/third_party/nix/src/libexpr/eval.cc
+++ b/third_party/nix/src/libexpr/eval.cc
@@ -338,8 +338,6 @@ EvalState::EvalState(const Strings& _searchPath, const ref<Store>& store)
 
   assert(gcInitialised);
 
-  static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes");
-
   /* Initialise the Nix expression search path. */
   if (!evalSettings.pureEval) {
     Strings paths = parseNixPath(getEnv("NIX_PATH", ""));
@@ -637,13 +635,9 @@ Env& EvalState::allocEnv(size_t size) {
 
   nrEnvs++;
   nrValuesInEnvs += size;
-  Env* env = (Env*)allocBytes(sizeof(Env) + size * sizeof(Value*));
-  env->size = (decltype(Env::size))size;
+  Env* env = new Env(size);
   env->type = Env::Plain;
 
-  /* We assume that env->values has been cleared by the allocator; maybeThunk()
-   * and lookupVar fromWith expect this. */
-
   return *env;
 }
 
diff --git a/third_party/nix/src/libexpr/eval.hh b/third_party/nix/src/libexpr/eval.hh
index 11cc295b23..3da0961b6f 100644
--- a/third_party/nix/src/libexpr/eval.hh
+++ b/third_party/nix/src/libexpr/eval.hh
@@ -3,6 +3,10 @@
 #include <map>
 #include <optional>
 #include <unordered_map>
+#include <vector>
+
+#include <gc/gc_allocator.h>
+#include <gc/gc_cpp.h>
 
 #include "libexpr/attr-set.hh"
 #include "libexpr/nixexpr.hh"
@@ -28,12 +32,16 @@ struct PrimOp {
       : fun(fun), arity(arity), name(name) {}
 };
 
-struct Env {
+struct Env : public gc {
+  Env(unsigned short size) : size(size) {
+    values = std::vector<Value*, traceable_allocator<Value*>>(size);
+  }
+
   Env* up;
   unsigned short size;           // used by ‘valueSize’
   unsigned short prevWith : 14;  // nr of levels up to next `with' environment
   enum { Plain = 0, HasWithExpr, HasWithAttrs } type : 2;
-  Value* values[0];
+  std::vector<Value*, traceable_allocator<Value*>> values;
 };
 
 Value& mkString(Value& v, const std::string& s,