Implement cache for not found symbols

This commit is contained in:
hyd-dev 2021-06-08 20:36:57 +08:00
parent ce7040075a
commit c822ec59aa
No known key found for this signature in database
GPG key ID: 74FA7FD5B8DA14B8
3 changed files with 11 additions and 8 deletions

View file

@ -297,7 +297,8 @@ pub struct Evaluator<'mir, 'tcx> {
string_cache: FxHashMap<String, measureme::StringId>,
/// Cache of `Instance` exported under the given `Symbol` name.
pub(crate) exported_symbols_cache: FxHashMap<Symbol, Instance<'tcx>>,
/// `None` means no `Instance` exported under the given name is found.
pub(crate) exported_symbols_cache: FxHashMap<Symbol, Option<Instance<'tcx>>>,
/// Whether to raise a panic in the context of the evaluated process when unsupported
/// functionality is encountered. If `false`, an error is propagated in the Miri application context

View file

@ -135,7 +135,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// If the result was cached, just return it.
if let Some(instance) = this.machine.exported_symbols_cache.get(&link_name) {
return Ok(Some(this.load_mir(instance.def, None)?));
return instance.map(|instance| this.load_mir(instance.def, None)).transpose();
}
// Find it if it was not cached.
@ -187,13 +187,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
}
let instance = instance_and_crate.map(|ic| ic.0);
// Cache it and load its MIR, if found.
instance_and_crate
.map(|(instance, _)| {
this.machine.exported_symbols_cache.insert(link_name, instance);
this.load_mir(instance.def, None)
})
.transpose()
this.machine.exported_symbols_cache.insert(link_name, instance);
instance.map(|instance| this.load_mir(instance.def, None)).transpose()
}
/// Emulates calling a foreign item, failing if the item is not supported.

View file

@ -20,10 +20,15 @@ fn main() {
for _ in 0..3 {
extern "C" {
fn foo() -> i32;
fn free(_: *mut std::ffi::c_void);
}
assert_eq!(unsafe { foo() }, -1);
// `free()` is a built-in shim, so calling it will add ("free", None) to the cache.
// Test that the cache is not broken with ("free", None).
unsafe { free(std::ptr::null_mut()) }
extern "Rust" {
fn bar() -> i32;
fn baz() -> i32;