diff --git a/Makefile.am b/Makefile.am
index 2f39f90d6..cb1a321dd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,6 +2,8 @@ SUBDIRS = externals src scripts corepkgs doc misc tests
EXTRA_DIST = substitute.mk nix.spec nix.spec.in bootstrap.sh \
nix.conf.example NEWS version
+pkginclude_HEADERS = config.h
+
include ./substitute.mk
nix.spec: nix.spec.in
diff --git a/configure.ac b/configure.ac
index 81c008a84..c2599a75f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -132,11 +132,18 @@ AC_LANG_POP(C++)
AC_CHECK_HEADER([err.h], [], [bsddiff_compat_include="-Icompat-include"])
AC_SUBST([bsddiff_compat_include])
+
# Check whether we have the personality() syscall, which allows us to
# do i686-linux builds on x86_64-linux machines.
AC_CHECK_HEADERS([sys/personality.h])
+# Check for tr1/unordered_set.
+AC_LANG_PUSH(C++)
+AC_CHECK_HEADERS([tr1/unordered_set], [], [], [])
+AC_LANG_POP(C++)
+
+
AC_DEFUN([NEED_PROG],
[
AC_PATH_PROG($1, $2)
@@ -255,6 +262,18 @@ AC_SUBST(sqlite_lib)
AC_SUBST(sqlite_include)
AC_SUBST(sqlite_bin)
+# Whether to use the Boehm garbage collector.
+AC_ARG_ENABLE(gc, AC_HELP_STRING([--enable-gc],
+ [enable garbage collection in the Nix expression evaluator (requires Boehm GC)]),
+ gc=$enableval, gc=)
+if test -n "$gc"; then
+ PKG_CHECK_MODULES([BDW_GC], [bdw-gc])
+ boehmgc_lib="-L$boehmgc/lib -lgc"
+ CXXFLAGS="$BDW_GC_CFLAGS $CXXFLAGS"
+ AC_DEFINE(HAVE_BOEHMGC, 1, [Whether to use the Boehm garbage collector.])
+fi
+AC_SUBST(boehmgc_lib)
+
AC_ARG_ENABLE(init-state, AC_HELP_STRING([--disable-init-state],
[do not initialise DB etc. in `make install']),
diff --git a/doc/manual/env-common.xml b/doc/manual/env-common.xml
index d67ef714d..99acc5949 100644
--- a/doc/manual/env-common.xml
+++ b/doc/manual/env-common.xml
@@ -271,6 +271,17 @@ $ mount -o bind /mnt/otherdisk/nix /nix
+
+GC_INITIAL_HEAP_SIZE
+
+ If Nix has been configured to use the Boehm garbage
+ collector, this variable sets the initial size of the heap in bytes.
+ It defaults to 384 MiB. Setting it to a low value reduces memory
+ consumption, but will increase runtime due to the overhead of
+ garbage collection.
+
+
+
diff --git a/doc/manual/installation.xml b/doc/manual/installation.xml
index bc5e21f0d..87a6c446a 100644
--- a/doc/manual/installation.xml
+++ b/doc/manual/installation.xml
@@ -105,6 +105,13 @@ this packages. Alternatively, if you already have it installed, you
can use configure's
options to point to their respective locations.
+Nix can optionally use the Boehm
+garbage collector to reduce the evaluator’s memory consumption.
+To enable it, install pkgconfig and the Boehm
+garbage collector, and pass the flag to
+configure.
+
diff --git a/doc/manual/introduction.xml b/doc/manual/introduction.xml
index 0cf57fd85..bdd71e5c3 100644
--- a/doc/manual/introduction.xml
+++ b/doc/manual/introduction.xml
@@ -113,7 +113,7 @@ $ nix-env --rollback
Garbage collection
-When you install a package like this…
+When you uninstall a package like this…
$ nix-env --uninstall firefox
diff --git a/doc/manual/release-notes.xml b/doc/manual/release-notes.xml
index 5b1c30bf8..1e579a37b 100644
--- a/doc/manual/release-notes.xml
+++ b/doc/manual/release-notes.xml
@@ -6,6 +6,27 @@
+
+
+Release 1.0 (TBA)
+
+This release has the following improvements:
+
+
+
+
+ Nix can now optionally use the Boehm garbage collector.
+ This significantly reduces the Nix evaluator’s memory footprint,
+ especially when evaluating large NixOS system configurations. It
+ can be enabled using the configure
+ option.
+
+
+
+
+
+
+
Release 0.16 (August 17, 2010)
diff --git a/release.nix b/release.nix
index 589d0f035..1fc9405bd 100644
--- a/release.nix
+++ b/release.nix
@@ -18,8 +18,8 @@ let
inherit officialRelease;
buildInputs =
- [ curl bison flex2533 perl libxml2 libxslt w3m bzip2
- tetex dblatex nukeReferences
+ [ curl bison24 flex2535 perl libxml2 libxslt w3m bzip2
+ tetex dblatex nukeReferences pkgconfig
];
configureFlags = ''
@@ -70,11 +70,12 @@ let
name = "nix";
src = tarball;
- buildInputs = [ curl perl bzip2 openssl ];
+ buildInputs = [ curl perl bzip2 openssl pkgconfig boehmgc ];
configureFlags = ''
--disable-init-state
--with-bzip2=${bzip2} --with-sqlite=${sqlite}
+ --enable-gc
'';
};
diff --git a/src/libexpr/Makefile.am b/src/libexpr/Makefile.am
index e7228e183..6c38ecdd5 100644
--- a/src/libexpr/Makefile.am
+++ b/src/libexpr/Makefile.am
@@ -11,7 +11,7 @@ pkginclude_HEADERS = \
names.hh symbol-table.hh
libexpr_la_LIBADD = ../libutil/libutil.la ../libstore/libstore.la \
- ../boost/format/libformat.la
+ ../boost/format/libformat.la @boehmgc_lib@
BUILT_SOURCES = \
parser-tab.hh lexer-tab.hh parser-tab.cc lexer-tab.cc
diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc
index 0660ba1c1..49c08339a 100644
--- a/src/libexpr/attr-path.cc
+++ b/src/libexpr/attr-path.cc
@@ -5,8 +5,9 @@
namespace nix {
+// !!! Shouldn't we return a pointer to a Value?
void findAlongAttrPath(EvalState & state, const string & attrPath,
- const Bindings & autoArgs, Expr * e, Value & v)
+ Bindings & autoArgs, Expr * e, Value & v)
{
Strings tokens = tokenizeString(attrPath, ".");
@@ -48,7 +49,7 @@ void findAlongAttrPath(EvalState & state, const string & attrPath,
Bindings::iterator a = v.attrs->find(state.symbols.create(attr));
if (a == v.attrs->end())
throw Error(format("attribute `%1%' in selection path `%2%' not found") % attr % curPath);
- v = a->second.value;
+ v = *a->value;
}
else if (apType == apIndex) {
diff --git a/src/libexpr/attr-path.hh b/src/libexpr/attr-path.hh
index 33587e5ed..b106da5ef 100644
--- a/src/libexpr/attr-path.hh
+++ b/src/libexpr/attr-path.hh
@@ -1,17 +1,17 @@
#ifndef __ATTR_PATH_H
#define __ATTR_PATH_H
+#include "eval.hh"
+
#include
#include