diff --git a/Cargo.lock b/Cargo.lock index d33761f4af6..55260cddf49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3077,7 +3077,6 @@ dependencies = [ "nix 0.30.1", "num-complex", "num-traits", - "once_cell", "parking_lot", "radium", "rustpython-literal", @@ -3337,7 +3336,6 @@ dependencies = [ "num-traits", "num_cpus", "num_enum", - "once_cell", "optional", "parking_lot", "paste", diff --git a/Cargo.toml b/Cargo.toml index c6d4d732453..d0f30bd6307 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -184,7 +184,6 @@ num-integer = "0.1.46" num-traits = "0.2" num_enum = { version = "0.7", default-features = false } optional = "0.5" -once_cell = "1.20.3" parking_lot = "0.12.3" paste = "1.0.15" proc-macro2 = "1.0.105" diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 679c7cd4a7b..054e52ae81a 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -28,7 +28,6 @@ malachite-bigint = { workspace = true } malachite-q = { workspace = true } malachite-base = { workspace = true } num-traits = { workspace = true } -once_cell = { workspace = true } parking_lot = { workspace = true, optional = true } unicode_names2 = { workspace = true } radium = { workspace = true } diff --git a/crates/common/src/lock.rs b/crates/common/src/lock.rs index ca5ffe8de37..f8e7da3e0e3 100644 --- a/crates/common/src/lock.rs +++ b/crates/common/src/lock.rs @@ -10,12 +10,12 @@ cfg_if::cfg_if! { if #[cfg(feature = "threading")] { pub use parking_lot::{RawMutex, RawRwLock, RawThreadId}; - pub use once_cell::sync::{Lazy, OnceCell}; + pub use std::sync::{LazyLock as Lazy, OnceLock as OnceCell}; } else { mod cell_lock; pub use cell_lock::{RawCellMutex as RawMutex, RawCellRwLock as RawRwLock, SingleThreadId as RawThreadId}; - pub use once_cell::unsync::{Lazy, OnceCell}; + pub use core::cell::{LazyCell as Lazy, OnceCell}; } } diff --git a/crates/common/src/static_cell.rs b/crates/common/src/static_cell.rs index 61f97a97305..bf277e60ea7 100644 --- a/crates/common/src/static_cell.rs +++ b/crates/common/src/static_cell.rs @@ -31,7 +31,12 @@ mod threading { where F: FnOnce() -> Result, { - self.inner.get_or_try_init(f) + if let Some(val) = self.inner.get() { + return Ok(val); + } + let val = f()?; + let _ = self.inner.set(val); + Ok(self.inner.get().unwrap()) } } @@ -92,8 +97,15 @@ mod non_threading { where F: FnOnce() -> Result, { - self.inner - .with(|x| x.get_or_try_init(|| f().map(leak)).copied()) + self.inner.with(|x| { + if let Some(val) = x.get() { + Ok(*val) + } else { + let val = leak(f()?); + let _ = x.set(val); + Ok(val) + } + }) } } @@ -156,7 +168,12 @@ mod no_std { where F: FnOnce() -> Result, { - self.inner.0.get_or_try_init(f) + if let Some(val) = self.inner.0.get() { + return Ok(val); + } + let val = f()?; + let _ = self.inner.0.set(val); + Ok(self.inner.0.get().unwrap()) } } diff --git a/crates/vm/Cargo.toml b/crates/vm/Cargo.toml index ba9cc4a6719..b89cda4fdb5 100644 --- a/crates/vm/Cargo.toml +++ b/crates/vm/Cargo.toml @@ -63,7 +63,6 @@ num-complex = { workspace = true } num-integer = { workspace = true } num-traits = { workspace = true } num_enum = { workspace = true } -once_cell = { workspace = true } parking_lot = { workspace = true } paste = { workspace = true } scoped-tls = { workspace = true } diff --git a/crates/vm/src/builtins/function.rs b/crates/vm/src/builtins/function.rs index 9541e968ab6..5afde116a02 100644 --- a/crates/vm/src/builtins/function.rs +++ b/crates/vm/src/builtins/function.rs @@ -816,15 +816,16 @@ impl PyFunction { #[cfg(feature = "jit")] #[pymethod] fn __jit__(zelf: PyRef, vm: &VirtualMachine) -> PyResult<()> { - zelf.jitted_code - .get_or_try_init(|| { - let arg_types = jit::get_jit_arg_types(&zelf, vm)?; - let ret_type = jit::jit_ret_type(&zelf, vm)?; - let code = zelf.code.lock(); - rustpython_jit::compile(&code.code, &arg_types, ret_type) - .map_err(|err| jit::new_jit_error(err.to_string(), vm)) - }) - .map(drop) + if zelf.jitted_code.get().is_some() { + return Ok(()); + } + let arg_types = jit::get_jit_arg_types(&zelf, vm)?; + let ret_type = jit::jit_ret_type(&zelf, vm)?; + let code = zelf.code.lock(); + let compiled = rustpython_jit::compile(&code.code, &arg_types, ret_type) + .map_err(|err| jit::new_jit_error(err.to_string(), vm))?; + let _ = zelf.jitted_code.set(compiled); + Ok(()) } } diff --git a/crates/vm/src/builtins/memory.rs b/crates/vm/src/builtins/memory.rs index 469a536f9d4..db815fcba63 100644 --- a/crates/vm/src/builtins/memory.rs +++ b/crates/vm/src/builtins/memory.rs @@ -1095,15 +1095,16 @@ impl Comparable for PyMemoryView { impl Hashable for PyMemoryView { fn hash(zelf: &Py, vm: &VirtualMachine) -> PyResult { - zelf.hash - .get_or_try_init(|| { - zelf.try_not_released(vm)?; - if !zelf.desc.readonly { - return Err(vm.new_value_error("cannot hash writable memoryview object")); - } - Ok(zelf.contiguous_or_collect(|bytes| vm.state.hash_secret.hash_bytes(bytes))) - }) - .copied() + if let Some(val) = zelf.hash.get() { + return Ok(*val); + } + zelf.try_not_released(vm)?; + if !zelf.desc.readonly { + return Err(vm.new_value_error("cannot hash writable memoryview object")); + } + let val = zelf.contiguous_or_collect(|bytes| vm.state.hash_secret.hash_bytes(bytes)); + let _ = zelf.hash.set(val); + Ok(*zelf.hash.get().unwrap()) } } diff --git a/crates/vm/src/codecs.rs b/crates/vm/src/codecs.rs index cca33eba2e1..9cd75eee55c 100644 --- a/crates/vm/src/codecs.rs +++ b/crates/vm/src/codecs.rs @@ -8,6 +8,7 @@ use rustpython_common::{ wtf8::{CodePoint, Wtf8, Wtf8Buf}, }; +use crate::common::lock::OnceCell; use crate::{ AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, TryFromBorrowedObject, TryFromObject, VirtualMachine, @@ -18,7 +19,6 @@ use crate::{ }; use alloc::borrow::Cow; use core::ops::{self, Range}; -use once_cell::unsync::OnceCell; use std::collections::HashMap; pub struct CodecsRegistry { @@ -861,22 +861,25 @@ impl<'a> ErrorsHandler<'a> { }, None => Self { errors: identifier!(vm, strict).as_ref(), - resolved: OnceCell::with_value(ResolvedError::Standard(StandardError::Strict)), + resolved: OnceCell::from(ResolvedError::Standard(StandardError::Strict)), }, } } #[inline] fn resolve(&self, vm: &VirtualMachine) -> PyResult<&ResolvedError> { - self.resolved.get_or_try_init(|| { - if let Ok(standard) = self.errors.as_str().parse() { - Ok(ResolvedError::Standard(standard)) - } else { - vm.state - .codec_registry - .lookup_error(self.errors.as_str(), vm) - .map(ResolvedError::Handler) - } - }) + if let Some(val) = self.resolved.get() { + return Ok(val); + } + let val = if let Ok(standard) = self.errors.as_str().parse() { + ResolvedError::Standard(standard) + } else { + vm.state + .codec_registry + .lookup_error(self.errors.as_str(), vm) + .map(ResolvedError::Handler)? + }; + let _ = self.resolved.set(val); + Ok(self.resolved.get().unwrap()) } } impl StrBuffer for PyStrRef { @@ -998,7 +1001,7 @@ where encoding: s_encoding.as_str(), data: &s, pos: StrSize::default(), - exception: OnceCell::with_value(err.downcast().unwrap()), + exception: OnceCell::from(err.downcast().unwrap()), }; let mut iter = s.as_wtf8().code_point_indices(); let start = StrSize { @@ -1038,7 +1041,7 @@ where data: PyDecodeData::Original(s.borrow_buf()), orig_bytes: s.as_object().downcast_ref(), pos: 0, - exception: OnceCell::with_value(err.downcast().unwrap()), + exception: OnceCell::from(err.downcast().unwrap()), }; let (replace, restart) = handler.handle_decode_error(&mut ctx, range, None)?; Ok((replace.into(), restart)) @@ -1061,7 +1064,7 @@ where encoding: "", data: &s, pos: StrSize::default(), - exception: OnceCell::with_value(err.downcast().unwrap()), + exception: OnceCell::from(err.downcast().unwrap()), }; let mut iter = s.as_wtf8().code_point_indices(); let start = StrSize { diff --git a/crates/vm/src/stdlib/os.rs b/crates/vm/src/stdlib/os.rs index 6664bc7efb7..0f4eb0ce422 100644 --- a/crates/vm/src/stdlib/os.rs +++ b/crates/vm/src/stdlib/os.rs @@ -657,16 +657,28 @@ pub(super) mod _os { vm, ) }; - let lstat = || self.lstat.get_or_try_init(|| do_stat(false)); + let lstat = || match self.lstat.get() { + Some(val) => Ok(val), + None => { + let val = do_stat(false)?; + let _ = self.lstat.set(val); + Ok(self.lstat.get().unwrap()) + } + }; let stat = if follow_symlinks.0 { // if follow_symlinks == true and we aren't a symlink, cache both stat and lstat - self.stat.get_or_try_init(|| { - if self.is_symlink(vm)? { - do_stat(true) - } else { - lstat().cloned() + match self.stat.get() { + Some(val) => val, + None => { + let val = if self.is_symlink(vm)? { + do_stat(true)? + } else { + lstat()?.clone() + }; + let _ = self.stat.set(val); + self.stat.get().unwrap() } - })? + } } else { lstat()? };