Optimize `Lua::create_registry_value` by reusing previously expired registry keys.

This commit is contained in:
Alex Orlenko 2022-02-14 21:20:57 +00:00
parent 6190427f37
commit 18c3255c90
No known key found for this signature in database
GPG Key ID: 4C150C250863B96D
1 changed files with 20 additions and 1 deletions

View File

@ -1721,14 +1721,29 @@ impl Lua {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 4)?;
let unref_list = (*self.extra.get()).registry_unref_list.clone();
self.push_value(t)?;
// Try to reuse previously allocated RegistryKey
let unref_list2 = unref_list.clone();
let mut unref_list2 = mlua_expect!(unref_list2.lock(), "unref list poisoned");
if let Some(registry_id) = unref_list2.as_mut().and_then(|x| x.pop()) {
// It must be safe to replace the value without triggering memory error
ffi::lua_rawseti(self.state, ffi::LUA_REGISTRYINDEX, registry_id as Integer);
return Ok(RegistryKey {
registry_id,
unref_list,
});
}
// Allocate a new RegistryKey
let registry_id = protect_lua!(self.state, 1, 0, |state| {
ffi::luaL_ref(state, ffi::LUA_REGISTRYINDEX)
})?;
Ok(RegistryKey {
registry_id,
unref_list: (*self.extra.get()).registry_unref_list.clone(),
unref_list,
})
}
}
@ -1787,6 +1802,10 @@ impl Lua {
key: &RegistryKey,
t: T,
) -> Result<()> {
if !self.owns_registry_value(key) {
return Err(Error::MismatchedRegistryKey);
}
let t = t.to_lua(self)?;
unsafe {
let _sg = StackGuard::new(self.state);