Use pool for MultiValue container

This commit is contained in:
Alex Orlenko
2024-08-05 21:34:51 +01:00
parent ac6a391426
commit aa47324ee9
6 changed files with 45 additions and 73 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
name = "mlua"
version = "0.10.0-beta.1" # remember to update mlua_derive
authors = ["Aleksandr Orlenko <zxteam@pm.me>", "kyren <catherine@kyju.org>"]
rust-version = "1.71"
rust-version = "1.79.0"
edition = "2021"
repository = "https://github.com/khvzak/mlua"
documentation = "https://docs.rs/mlua"
+4 -4
View File
@@ -49,7 +49,7 @@ impl<E: IntoLua> IntoLuaMulti for StdResult<(), E> {
impl<T: IntoLua> IntoLuaMulti for T {
#[inline]
fn into_lua_multi(self, lua: &Lua) -> Result<MultiValue> {
let mut v = MultiValue::with_lua_and_capacity(lua, 1);
let mut v = MultiValue::with_capacity(1);
v.push_back(self.into_lua(lua)?);
Ok(v)
}
@@ -177,7 +177,7 @@ impl<T> DerefMut for Variadic<T> {
impl<T: IntoLua> IntoLuaMulti for Variadic<T> {
#[inline]
fn into_lua_multi(self, lua: &Lua) -> Result<MultiValue> {
let mut values = MultiValue::with_lua_and_capacity(lua, self.0.len());
let mut values = MultiValue::with_capacity(self.0.len());
values.extend_from_values(self.0.into_iter().map(|val| val.into_lua(lua)))?;
Ok(values)
}
@@ -198,8 +198,8 @@ macro_rules! impl_tuple {
() => (
impl IntoLuaMulti for () {
#[inline]
fn into_lua_multi(self, lua: &Lua) -> Result<MultiValue> {
Ok(MultiValue::with_lua_and_capacity(lua, 0))
fn into_lua_multi(self, _: &Lua) -> Result<MultiValue> {
Ok(MultiValue::new())
}
#[inline]
+1 -6
View File
@@ -1,10 +1,9 @@
use std::any::TypeId;
use std::cell::UnsafeCell;
use std::rc::Rc;
// use std::collections::VecDeque;
use std::mem::{self, MaybeUninit};
use std::os::raw::{c_int, c_void};
use std::ptr;
use std::rc::Rc;
use std::sync::Arc;
use parking_lot::Mutex;
@@ -28,7 +27,6 @@ use super::{Lua, WeakLua};
static EXTRA_REGISTRY_KEY: u8 = 0;
const WRAPPED_FAILURE_POOL_SIZE: usize = 64;
// const MULTIVALUE_POOL_SIZE: usize = 64;
const REF_STACK_RESERVE: c_int = 1;
/// Data associated with the Lua state.
@@ -61,8 +59,6 @@ pub(crate) struct ExtraData {
// Pool of `WrappedFailure` enums in the ref thread (as userdata)
pub(super) wrapped_failure_pool: Vec<c_int>,
// Pool of `MultiValue` containers
// multivalue_pool: Vec<VecDeque<Value>>,
// Pool of `Thread`s (coroutines) for async execution
#[cfg(feature = "async")]
pub(super) thread_pool: Vec<c_int>,
@@ -162,7 +158,6 @@ impl ExtraData {
ref_stack_top: ffi::lua_gettop(ref_thread),
ref_free: Vec::new(),
wrapped_failure_pool: Vec::with_capacity(WRAPPED_FAILURE_POOL_SIZE),
// multivalue_pool: Vec::with_capacity(MULTIVALUE_POOL_SIZE),
#[cfg(feature = "async")]
thread_pool: Vec::new(),
wrapped_failure_mt_ptr,
-19
View File
@@ -496,25 +496,6 @@ impl RawLua {
false
}
// FIXME
// #[inline]
// pub(crate) fn pop_multivalue_from_pool(&self) -> Option<VecDeque<Value>> {
// let extra = unsafe { &mut *self.extra.get() };
// extra.multivalue_pool.pop()
// }
// FIXME
// #[inline]
// pub(crate) fn push_multivalue_to_pool(&self, mut multivalue: VecDeque<Value>) {
// let extra = unsafe { &mut *self.extra.get() };
// if extra.multivalue_pool.len() < MULTIVALUE_POOL_SIZE {
// multivalue.clear();
// extra
// .multivalue_pool
// .push(unsafe { mem::transmute(multivalue) });
// }
// }
/// Pushes a value that implements `IntoLua` onto the Lua stack.
///
/// Uses 2 stack spaces, does not call checkstack.
-1
View File
@@ -8,7 +8,6 @@ use crate::state::{ExtraData, RawLua};
use crate::util::{self, get_internal_metatable, WrappedFailure};
const WRAPPED_FAILURE_POOL_SIZE: usize = 64;
// const MULTIVALUE_POOL_SIZE: usize = 64;
pub(super) struct StateGuard<'a>(&'a RawLua, *mut ffi::lua_State);
+39 -42
View File
@@ -1,3 +1,4 @@
use std::cell::RefCell;
use std::cmp::Ordering;
use std::collections::{vec_deque, HashSet, VecDeque};
use std::ops::{Deref, DerefMut};
@@ -23,7 +24,7 @@ use {
crate::table::SerializableTable,
rustc_hash::FxHashSet,
serde::ser::{self, Serialize, Serializer},
std::{cell::RefCell, rc::Rc, result::Result as StdResult},
std::{rc::Rc, result::Result as StdResult},
};
/// A dynamically typed Lua value. The `String`, `Table`, `Function`, `Thread`, and `UserData`
@@ -744,21 +745,25 @@ pub trait FromLua: Sized {
}
}
// Per-thread size of the VecDeque pool for MultiValue container.
const MULTIVALUE_POOL_SIZE: usize = 32;
thread_local! {
static MULTIVALUE_POOL: RefCell<Vec<VecDeque<Value>>> = const { RefCell::new(Vec::new()) };
}
/// Multiple Lua values used for both argument passing and also for multiple return values.
#[derive(Debug, Clone)]
pub struct MultiValue {
deque: VecDeque<Value>,
// FIXME
// lua: Option<&'static Lua>,
}
pub struct MultiValue(VecDeque<Value>);
impl Drop for MultiValue {
fn drop(&mut self) {
// FIXME
// if let Some(lua) = self.lua {
// let vec = mem::take(&mut self.deque);
// lua.push_multivalue_to_pool(vec);
// }
MULTIVALUE_POOL.with_borrow_mut(|pool| {
if pool.len() < MULTIVALUE_POOL_SIZE {
self.0.clear();
pool.push(mem::take(&mut self.0));
}
});
}
}
@@ -774,44 +779,38 @@ impl Deref for MultiValue {
#[inline]
fn deref(&self) -> &Self::Target {
&self.deque
&self.0
}
}
impl DerefMut for MultiValue {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.deque
&mut self.0
}
}
impl MultiValue {
/// Creates an empty `MultiValue` containing no values.
pub const fn new() -> MultiValue {
MultiValue {
deque: VecDeque::new(),
// lua: None,
}
pub fn new() -> MultiValue {
Self::with_capacity(0)
}
/// Similar to `new` but can reuse previously used container with allocated capacity.
#[inline]
pub(crate) fn with_lua_and_capacity(_lua: &Lua, capacity: usize) -> MultiValue {
// FIXME
// let deque = lua
// .pop_multivalue_from_pool()
// .map(|mut deque| {
// if capacity > 0 {
// deque.reserve(capacity);
// }
// deque
// })
// .unwrap_or_else(|| VecDeque::with_capacity(capacity));
let deque = VecDeque::with_capacity(capacity);
MultiValue {
deque,
// lua: Some(lua),
}
pub(crate) fn with_capacity(capacity: usize) -> MultiValue {
let deque = MULTIVALUE_POOL.with_borrow_mut(|pool| {
pool.pop().map_or_else(
|| VecDeque::with_capacity(capacity),
|mut deque| {
if capacity > 0 {
deque.reserve(capacity);
}
deque
},
)
});
MultiValue(deque)
}
#[inline]
@@ -826,11 +825,9 @@ impl MultiValue {
impl FromIterator<Value> for MultiValue {
#[inline]
fn from_iter<I: IntoIterator<Item = Value>>(iter: I) -> Self {
let deque = VecDeque::from_iter(iter);
MultiValue {
deque,
// lua: None,
}
let mut multi_value = MultiValue::new();
multi_value.extend(iter);
multi_value
}
}
@@ -840,7 +837,7 @@ impl IntoIterator for MultiValue {
#[inline]
fn into_iter(mut self) -> Self::IntoIter {
let deque = mem::take(&mut self.deque);
let deque = mem::take(&mut self.0);
mem::forget(self);
deque.into_iter()
}
@@ -852,7 +849,7 @@ impl<'a> IntoIterator for &'a MultiValue {
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.deque.iter()
self.0.iter()
}
}
@@ -910,7 +907,7 @@ pub trait FromLuaMulti: Sized {
#[doc(hidden)]
#[inline]
unsafe fn from_stack_multi(nvals: c_int, lua: &RawLua) -> Result<Self> {
let mut values = MultiValue::with_lua_and_capacity(lua.lua(), nvals as usize);
let mut values = MultiValue::with_capacity(nvals as usize);
for idx in 0..nvals {
values.push_back(lua.stack_value(-nvals + idx));
}