aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-03-19 20:02:37 +0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2015-03-19 20:02:37 +0100
commit726f7f7fc92f4914bca450a37b8b85b1018afc01 (patch)
tree7e484a7a0249b9ae3fda87347568a0b77505335b /src
parentda6b704b197f19c386f0e53f5553252a226650bb (diff)
Fix Boehm API violation
We were calling GC_INIT() after doing an allocation (in the baseEnv construction), which is not allowed.
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval.cc80
-rw-r--r--src/libexpr/eval.hh4
-rw-r--r--src/nix-env/nix-env.cc1
-rw-r--r--src/nix-instantiate/nix-instantiate.cc1
4 files changed, 48 insertions, 38 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 4ae3005bb..a3e2a0add 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -191,6 +191,47 @@ static Symbol getName(const AttrName & name, EvalState & state, Env & env)
}
+static bool gcInitialised = false;
+
+void initGC()
+{
+ if (gcInitialised) return;
+
+#if HAVE_BOEHMGC
+ /* Initialise the Boehm garbage collector. */
+ GC_INIT();
+
+ GC_oom_fn = oomHandler;
+
+ /* Set the initial heap size to something fairly big (25% of
+ physical RAM, up to a maximum of 384 MiB) so that in most cases
+ we don't need to garbage collect at all. (Collection has a
+ fairly significant overhead.) The heap size can be overridden
+ through libgc's GC_INITIAL_HEAP_SIZE environment variable. We
+ should probably also provide a nix.conf setting for this. Note
+ that GC_expand_hp() causes a lot of virtual, but not physical
+ (resident) memory to be allocated. This might be a problem on
+ systems that don't overcommit. */
+ if (!getenv("GC_INITIAL_HEAP_SIZE")) {
+ size_t size = 32 * 1024 * 1024;
+#if HAVE_SYSCONF && defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
+ size_t maxSize = 384 * 1024 * 1024;
+ long pageSize = sysconf(_SC_PAGESIZE);
+ long pages = sysconf(_SC_PHYS_PAGES);
+ if (pageSize != -1)
+ size = (pageSize * pages) / 4; // 25% of RAM
+ if (size > maxSize) size = maxSize;
+#endif
+ debug(format("setting initial heap size to %1% bytes") % size);
+ GC_expand_hp(size);
+ }
+
+#endif
+
+ gcInitialised = true;
+}
+
+
EvalState::EvalState(const Strings & _searchPath)
: sWith(symbols.create("<with>"))
, sOutPath(symbols.create("outPath"))
@@ -220,44 +261,7 @@ EvalState::EvalState(const Strings & _searchPath)
restricted = settings.get("restrict-eval", false);
-#if HAVE_BOEHMGC
- static bool gcInitialised = false;
- if (!gcInitialised) {
-
- /* Initialise the Boehm garbage collector. This isn't
- necessary on most platforms, but for portability we do it
- anyway. */
- GC_INIT();
-
- GC_oom_fn = oomHandler;
-
- /* Set the initial heap size to something fairly big (25% of
- physical RAM, up to a maximum of 384 MiB) so that in most
- cases we don't need to garbage collect at all. (Collection
- has a fairly significant overhead.) The heap size can be
- overridden through libgc's GC_INITIAL_HEAP_SIZE environment
- variable. We should probably also provide a nix.conf
- setting for this. Note that GC_expand_hp() causes a lot of
- virtual, but not physical (resident) memory to be
- allocated. This might be a problem on systems that don't
- overcommit. */
- if (!getenv("GC_INITIAL_HEAP_SIZE")) {
- size_t size = 32 * 1024 * 1024;
-#if HAVE_SYSCONF && defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
- size_t maxSize = 384 * 1024 * 1024;
- long pageSize = sysconf(_SC_PAGESIZE);
- long pages = sysconf(_SC_PHYS_PAGES);
- if (pageSize != -1)
- size = (pageSize * pages) / 4; // 25% of RAM
- if (size > maxSize) size = maxSize;
-#endif
- debug(format("setting initial heap size to %1% bytes") % size);
- GC_expand_hp(size);
- }
-
- gcInitialised = true;
- }
-#endif
+ assert(gcInitialised);
/* Initialise the Nix expression search path. */
Strings paths = tokenizeString<Strings>(getEnv("NIX_PATH", ""), ":");
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index bfaa4081d..627fae3ff 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -121,6 +121,10 @@ std::ostream & operator << (std::ostream & str, const Value & v);
typedef list<std::pair<string, Path> > SearchPath;
+/* Initialise the Boehm GC, if applicable. */
+void initGC();
+
+
class EvalState
{
public:
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index f3c8d3ba8..10b95dad1 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -1337,6 +1337,7 @@ int main(int argc, char * * argv)
{
return handleExceptions(argv[0], [&]() {
initNix();
+ initGC();
Strings opFlags, opArgs, searchPath;
std::map<string, string> autoArgs_;
diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc
index e7214e657..5abaa617d 100644
--- a/src/nix-instantiate/nix-instantiate.cc
+++ b/src/nix-instantiate/nix-instantiate.cc
@@ -93,6 +93,7 @@ int main(int argc, char * * argv)
{
return handleExceptions(argv[0], [&]() {
initNix();
+ initGC();
Strings files, searchPath;
bool readStdin = false;