diff options
-rw-r--r-- | src/libexpr/eval.cc | 24 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 9 |
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; |