feat(tvix/eval): crude caching builtins.import

Before this, tvix was spending most of its time furiously re-parsing
and re-compiling nixpkgs, each time hoping to get a different result...

Change-Id: I1c0cfbf9af622c276275b1f2fb8d4e976f1b5533
Signed-off-by: Adam Joseph <adam@westernsemico.com>
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7361
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Adam Joseph 2022-11-23 00:32:45 -08:00 committed by clbot
parent 7ffeb4f7f1
commit 8eb32fb2d7
2 changed files with 20 additions and 7 deletions

View file

@ -122,6 +122,12 @@ pub fn builtins_import(globals: &Weak<GlobalsMap>, source: SourceCode) -> Builti
path.push("default.nix");
}
let current_span = vm.current_span();
let entry = match vm.import_cache.entry(path.clone()) {
std::collections::btree_map::Entry::Occupied(oe) => return Ok(oe.get().clone()),
std::collections::btree_map::Entry::Vacant(ve) => ve,
};
let contents =
std::fs::read_to_string(&path).map_err(|err| ErrorKind::ReadFileError {
path: path.clone(),
@ -167,16 +173,20 @@ pub fn builtins_import(globals: &Weak<GlobalsMap>, source: SourceCode) -> Builti
});
}
// Compilation succeeded, we can construct a thunk from whatever it spat
// out and return that.
let res = entry
.insert(Value::Thunk(Thunk::new_suspended(
result.lambda,
current_span,
)))
.clone();
for warning in result.warnings {
vm.push_warning(warning);
}
// Compilation succeeded, we can construct a thunk from whatever it spat
// out and return that.
Ok(Value::Thunk(Thunk::new_suspended(
result.lambda,
vm.current_span(),
)))
Ok(res)
},
)
}

View file

@ -2,7 +2,7 @@
//! Tvix bytecode.
use serde_json::json;
use std::{cmp::Ordering, ops::DerefMut, path::PathBuf, rc::Rc};
use std::{cmp::Ordering, collections::BTreeMap, ops::DerefMut, path::PathBuf, rc::Rc};
use crate::{
chunk::Chunk,
@ -60,6 +60,8 @@ pub struct VM<'o> {
/// Runtime warnings collected during evaluation.
warnings: Vec<EvalWarning>,
pub import_cache: Box<BTreeMap<PathBuf, Value>>,
nix_search_path: NixSearchPath,
observer: &'o mut dyn RuntimeObserver,
@ -164,6 +166,7 @@ impl<'o> VM<'o> {
stack: vec![],
with_stack: vec![],
warnings: vec![],
import_cache: Default::default(),
}
}