about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/eval.cc24
-rw-r--r--src/libexpr/eval.hh9
2 files changed, 22 insertions, 11 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 5aee3f05eaa6..d0bdaf23822a 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -431,17 +431,19 @@ Value * EvalState::maybeThunk(Env & env, Expr * expr)
 
 void EvalState::evalFile(const Path & path, Value & v)
 {
-    startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
-
-    Expr * e = parseExprFromFile(path);
-    
-    try {
-        /* !!! Maybe we should cache the evaluation result. */
-        eval(e, v);
-    } catch (Error & e) {
-        addErrorPrefix(e, "while evaluating the file `%1%':\n", path);
-        throw;
-    }
+    FileEvalCache::iterator i = fileEvalCache.find(path);
+    if (i == fileEvalCache.end()) {
+        startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
+        Expr * e = parseExprFromFile(path);
+        try {
+            eval(e, v);
+        } catch (Error & e) {
+            addErrorPrefix(e, "while evaluating the file `%1%':\n", path);
+            throw;
+        }
+        fileEvalCache[path] = v;
+    } else
+        v = i->second;
 }
 
 
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 413234f2bf19..694d4407b847 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -211,8 +211,17 @@ private:
 
     bool allowUnsafeEquality;
 
+    /* A cache from path names to parse trees. */
     std::map<Path, Expr *> parseTrees;
 
+    /* A cache from path names to values. */
+#if HAVE_BOEHMGC
+    typedef std::map<Path, Value, std::less<Path>, gc_allocator<std::pair<const Path, Value> > > FileEvalCache;
+#else
+    typedef std::map<Path, Value> FileEvalCache;
+#endif
+    FileEvalCache fileEvalCache;
+
     typedef list<std::pair<string, Path> > SearchPath;
     SearchPath searchPath;
     SearchPath::iterator searchPathInsertionPoint;