about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-04-16T14·28+0200
committertazjin <mail@tazj.in>2020-07-17T20·04+0000
commit80eaa1eaf9dde0caa4e983374fb1356aed67c8e1 (patch)
treeca4a33da8de115e888234252ecdd6629b3e8b9d3
parent014436eb4ad0c403647939a2461e1fe4a7967c89 (diff)
feat(3p/nix): Add function to allocate a Value in traceable memory r/1354
Backported from:
https://github.com/NixOS/nix/commit/b3e5eea4a91400fb2a12aba4b07a94d03ba54605
https://github.com/NixOS/nix/commit/fcd048a526bd239fa615457e77d61d69d679bf03

Intentionally skipped because we have not backported the JSON changes:
https://github.com/NixOS/nix/commit/9f46f54de4e55267df492456fc0393f74616366b

Did not apply changes ni primops.cc, because those look suspect and
are also based on something that we don't have in our tree.

Change-Id: I837787ce9f2c90267bc39fce15177980d209d4e9
Reviewed-on: https://cl.tvl.fyi/c/depot/+/1253
Tested-by: BuildkiteCI
Reviewed-by: isomer <isomer@tvl.fyi>
-rw-r--r--third_party/nix/src/libexpr/eval.cc7
-rw-r--r--third_party/nix/src/libexpr/nixexpr.hh1
-rw-r--r--third_party/nix/src/libexpr/value.hh2
-rw-r--r--third_party/nix/src/nix/command.hh3
-rw-r--r--third_party/nix/src/nix/installables.cc16
5 files changed, 19 insertions, 10 deletions
diff --git a/third_party/nix/src/libexpr/eval.cc b/third_party/nix/src/libexpr/eval.cc
index 2b825bfd2788..0f3b7fabe029 100644
--- a/third_party/nix/src/libexpr/eval.cc
+++ b/third_party/nix/src/libexpr/eval.cc
@@ -5,10 +5,13 @@
 #include <cstring>
 #include <fstream>
 #include <iostream>
+#include <memory>
 #include <new>
 #include <optional>
 #include <variant>
 
+#define GC_INCLUDE_NEW
+
 #include <absl/strings/match.h>
 #include <gc/gc.h>
 #include <gc/gc_cpp.h>
@@ -40,6 +43,10 @@ static char* dupString(const char* s) {
   return t;
 }
 
+std::shared_ptr<Value*> allocRootValue(Value* v) {
+  return std::allocate_shared<Value*>(traceable_allocator<Value*>(), v);
+}
+
 static void printValue(std::ostream& str, std::set<const Value*>& active,
                        const Value& v) {
   checkInterrupt();
diff --git a/third_party/nix/src/libexpr/nixexpr.hh b/third_party/nix/src/libexpr/nixexpr.hh
index 4b2bd86ef966..365235377f71 100644
--- a/third_party/nix/src/libexpr/nixexpr.hh
+++ b/third_party/nix/src/libexpr/nixexpr.hh
@@ -3,6 +3,7 @@
 #include <map>
 #include <optional>
 #include <variant>
+
 #include <absl/container/flat_hash_map.h>
 
 #include "libexpr/symbol-table.hh"
diff --git a/third_party/nix/src/libexpr/value.hh b/third_party/nix/src/libexpr/value.hh
index 7308dd31933a..cb1b8796cfe4 100644
--- a/third_party/nix/src/libexpr/value.hh
+++ b/third_party/nix/src/libexpr/value.hh
@@ -247,4 +247,6 @@ typedef std::map<Symbol, Value*, std::less<Symbol>,
                  traceable_allocator<std::pair<const Symbol, Value*>>>
     ValueMap;
 
+std::shared_ptr<Value*> allocRootValue(Value* v);
+
 }  // namespace nix
diff --git a/third_party/nix/src/nix/command.hh b/third_party/nix/src/nix/command.hh
index f7eaeb721620..01c1ed69d61d 100644
--- a/third_party/nix/src/nix/command.hh
+++ b/third_party/nix/src/nix/command.hh
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <memory>
+
 #include "libexpr/common-eval-args.hh"
 #include "libutil/args.hh"
 
@@ -81,7 +82,7 @@ struct SourceExprCommand : virtual Args, StoreCommand, MixEvalArgs {
 
  private:
   std::shared_ptr<EvalState> evalState;
-  std::shared_ptr<Value> vSourceExpr;
+  std::shared_ptr<Value*> vSourceExpr;
 };
 
 enum RealiseMode { Build, NoBuild, DryRun };
diff --git a/third_party/nix/src/nix/installables.cc b/third_party/nix/src/nix/installables.cc
index cc001d37f327..c6cfc4344f6d 100644
--- a/third_party/nix/src/nix/installables.cc
+++ b/third_party/nix/src/nix/installables.cc
@@ -1,8 +1,6 @@
 #include <regex>
 #include <utility>
 
-#include <gc/gc.h>
-
 #include "libexpr/attr-path.hh"
 #include "libexpr/common-eval-args.hh"
 #include "libexpr/eval-inline.hh"
@@ -26,7 +24,7 @@ SourceExprCommand::SourceExprCommand() {
 
 Value* SourceExprCommand::getSourceExpr(EvalState& state) {
   if (vSourceExpr != nullptr) {
-    return vSourceExpr.get();
+    return *vSourceExpr;
   }
 
   auto sToplevel = state.symbols.Create("_toplevel");
@@ -34,18 +32,18 @@ Value* SourceExprCommand::getSourceExpr(EvalState& state) {
   // Allocate the vSourceExpr Value as uncollectable. Boehm GC doesn't
   // consider the member variable "alive" during execution causing it to be
   // GC'ed in the middle of evaluation.
-  vSourceExpr = std::allocate_shared<Value>(traceable_allocator<Value>());
+  vSourceExpr = allocRootValue(state.allocValue());
 
   if (!file.empty()) {
-    state.evalFile(lookupFileArg(state, file), *vSourceExpr);
+    state.evalFile(lookupFileArg(state, file), **vSourceExpr);
   } else {
     /* Construct the installation source from $NIX_PATH. */
 
     auto searchPath = state.getSearchPath();
 
-    state.mkAttrs(*vSourceExpr, 1024);
+    state.mkAttrs(**vSourceExpr, 1024);
 
-    mkBool(*state.allocAttr(*vSourceExpr, sToplevel), true);
+    mkBool(*state.allocAttr(**vSourceExpr, sToplevel), true);
 
     std::unordered_set<std::string> seen;
 
@@ -61,7 +59,7 @@ Value* SourceExprCommand::getSourceExpr(EvalState& state) {
                   state.getBuiltin("nixPath"));
       Value* v2 = state.allocValue();
       mkApp(*v2, *v1, mkString(*state.allocValue(), name));
-      mkApp(*state.allocAttr(*vSourceExpr, state.symbols.Create(name)),
+      mkApp(*state.allocAttr(**vSourceExpr, state.symbols.Create(name)),
             state.getBuiltin("import"), *v2);
     };
 
@@ -79,7 +77,7 @@ Value* SourceExprCommand::getSourceExpr(EvalState& state) {
     }
   }
 
-  return vSourceExpr.get();
+  return *vSourceExpr;
 }
 
 ref<EvalState> SourceExprCommand::getEvalState() {