Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better default allocator handling #89

Merged
merged 2 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 36.1.1-rc8 (api=2.0.0, abi=2.0.0)
- Improve `DefaultAllocator` handling

# 36.1.1-rc7 (api=2.0.0, abi=2.0.0)
- BREAKING CHANGES:
- The in-place constructors for `Box` and `Arc` now require the initializer function to return a result, yielding the uninitialized allocation if allocation succeeded but initialization reported a failure.
Expand Down
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ license = " EPL-2.0 OR Apache-2.0"
categories = ["development-tools::ffi", "no-std::no-alloc"]
repository = "https://github.com/ZettaScaleLabs/stabby"
readme = "stabby/README.md"
version = "36.1.1-rc7" # Track
version = "36.1.1-rc8" # Track

[workspace.dependencies]
stabby-macros = { path = "./stabby-macros/", version = "36.1.1-rc7", default-features = false } # Track
stabby-abi = { path = "./stabby-abi/", version = "36.1.1-rc7", default-features = false } # Track
stabby = { path = "./stabby/", version = "36.1.1-rc7", default-features = false } # Track
stabby-macros = { path = "./stabby-macros/", version = "36.1.1-rc8", default-features = false } # Track
stabby-abi = { path = "./stabby-abi/", version = "36.1.1-rc8", default-features = false } # Track
stabby = { path = "./stabby/", version = "36.1.1-rc8", default-features = false } # Track

abi_stable = "0.11.0"
libc = "0.2"
Expand Down
11 changes: 10 additions & 1 deletion stabby-abi/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ fn main() {
tuples(max_tuple).unwrap();
println!("cargo:rustc-check-cfg=cfg(stabby_nightly, values(none()))");
println!(
r#"cargo:rustc-check-cfg=cfg(stabby_default_alloc, values(none(), "RustAlloc", "LibcAlloc"))"#
r#"cargo:rustc-check-cfg=cfg(stabby_default_alloc, values("RustAlloc", "LibcAlloc", "disabled"))"#
);
println!(
r#"cargo:rustc-check-cfg=cfg(stabby_check_unreachable, values(none(), "true", "false"))"#
Expand All @@ -123,6 +123,15 @@ fn main() {
println!(
r#"cargo:rustc-check-cfg=cfg(stabby_vtables, values(none(), "vec", "btree", "no_alloc"))"#
);
if std::env::var("CARGO_CFG_STABBY_DEFAULT_ALLOC").is_err() {
if std::env::var("CARGO_FEATURE_ALLOC_RS").is_ok() {
println!(r#"cargo:rustc-cfg=stabby_default_alloc="RustAlloc""#);
} else if std::env::var("CARGO_FEATURE_LIBC").is_ok() {
println!(r#"cargo:rustc-cfg=stabby_default_alloc="LibcAlloc""#);
} else {
println!(r#"cargo:rustc-cfg=stabby_default_alloc="disabled""#);
}
}
if let Ok(toolchain) = std::env::var("RUSTUP_TOOLCHAIN") {
if toolchain.starts_with("nightly") {
println!("cargo:rustc-cfg=stabby_nightly");
Expand Down
9 changes: 3 additions & 6 deletions stabby-abi/src/alloc/allocators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod rust_alloc;
#[cfg(feature = "alloc-rs")]
pub use rust_alloc::RustAlloc;

#[cfg(any(stabby_default_alloc = "RustAlloc", feature = "alloc-rs"))]
#[cfg(stabby_default_alloc = "RustAlloc")]
/// The default allocator, depending on which of the following is available:
/// - RustAlloc: Rust's `GlobalAlloc`, through a vtable that ensures FFI-safety.
/// - LibcAlloc: libc::malloc, which is 0-sized.
Expand All @@ -19,10 +19,7 @@ pub use rust_alloc::RustAlloc;
/// You can also use the `stabby_default_alloc` cfg to override the default allocator regardless of feature flags.
pub(crate) type DefaultAllocator = RustAlloc;

#[cfg(any(
stabby_default_alloc = "LibcAlloc",
all(feature = "libc", not(feature = "alloc-rs"))
))]
#[cfg(stabby_default_alloc = "LibcAlloc")]
/// The default allocator, depending on which of the following is available:
/// - RustAlloc: Rust's `GlobalAlloc`, through a vtable that ensures FFI-safety.
/// - LibcAlloc: libc::malloc, which is 0-sized.
Expand All @@ -31,7 +28,7 @@ pub(crate) type DefaultAllocator = RustAlloc;
/// You can also use the `stabby_default_alloc` cfg to override the default allocator regardless of feature flags.
pub(crate) type DefaultAllocator = LibcAlloc;

#[cfg(not(any(stabby_default_alloc, feature = "alloc-rs", feature = "libc")))]
#[cfg(stabby_default_alloc = "disabled")]
/// The default allocator, depending on which of the following is available:
/// - RustAlloc: Rust's `GlobalAlloc`, through a vtable that ensures FFI-safety.
/// - LibcAlloc: libc::malloc, which is 0-sized.
Expand Down
6 changes: 2 additions & 4 deletions stabby-abi/src/alloc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ unsafe impl<T: Send, Alloc: IAlloc + Send> Send for BoxedSlice<T, Alloc> {}
// SAFETY: Same constraints as `std::boxed::Box`
unsafe impl<T: Sync, Alloc: IAlloc> Sync for BoxedSlice<T, Alloc> {}

impl<T> Box<T>
where
super::DefaultAllocator: Default,
{
#[cfg(not(stabby_default_alloc = "disabled"))]
impl<T> Box<T> {
/// Attempts to allocate [`Self`], initializing it with `constructor`.
///
/// Note that the allocation may or may not be zeroed.
Expand Down
2 changes: 1 addition & 1 deletion stabby-abi/src/alloc/single_or_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ where
inner: crate::Result<Single<T, Alloc>, Vec<T, Alloc>>,
}

#[cfg(not(stabby_default_alloc = "disabled"))]
impl<T: IStable> SingleOrVec<T>
where
DefaultAllocator: Default,
Single<T, DefaultAllocator>: IDeterminantProvider<Vec<T, DefaultAllocator>>,
Vec<T, DefaultAllocator>: IStable,
crate::Result<Single<T, DefaultAllocator>, Vec<T, DefaultAllocator>>: IStable,
Expand Down
6 changes: 2 additions & 4 deletions stabby-abi/src/alloc/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ pub struct String<Alloc: IAlloc = super::DefaultAllocator> {
pub(crate) inner: Vec<u8, Alloc>,
}

impl String
where
super::DefaultAllocator: Default,
{
#[cfg(not(stabby_default_alloc = "disabled"))]
impl String {
/// Constructs a new string using the default allocator.
pub const fn new() -> Self {
Self { inner: Vec::new() }
Expand Down
1 change: 1 addition & 0 deletions stabby-abi/src/alloc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for Arc<T, Alloc>
unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for Arc<T, Alloc> {}
const USIZE_TOP_BIT: usize = 1 << (core::mem::size_of::<usize>() as i32 * 8 - 1);

#[cfg(not(stabby_default_alloc = "disabled"))]
impl<T> Arc<T> {
/// Attempts to allocate [`Self`], initializing it with `constructor`.
///
Expand Down
7 changes: 2 additions & 5 deletions stabby-abi/src/alloc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,13 @@ pub(crate) const fn ptr_add<T>(lhs: NonNull<T>, rhs: usize) -> NonNull<T> {
}
}

impl<T> Vec<T>
where
super::DefaultAllocator: Default,
{
#[cfg(not(stabby_default_alloc = "disabled"))]
impl<T> Vec<T> {
/// Constructs a new vector with the default allocator. This doesn't actually allocate.
pub const fn new() -> Self {
Self::new_in(super::DefaultAllocator::new())
}
}

impl<T, Alloc: IAlloc> Vec<T, Alloc> {
/// Constructs a new vector in `alloc`. This doesn't actually allocate.
pub const fn new_in(alloc: Alloc) -> Self {
Expand Down
21 changes: 18 additions & 3 deletions stabby-abi/src/vtable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ pub trait IConstConstructor<'a, Source>: 'a + Copy {
}
}

#[cfg(all(any(feature = "libc", feature = "alloc-rs"), feature = "test"))]
#[cfg(all(not(stabby_default_alloc = "disabled"), feature = "test"))]
pub use internal::{VTableRegistry, VtBtree, VtVec};

#[cfg(any(feature = "libc", feature = "alloc-rs"))]
#[cfg(not(stabby_default_alloc = "disabled"))]
pub(crate) mod internal {
use crate::alloc::{boxed::BoxedSlice, collections::arc_btree::AtomicArcBTreeSet};
use core::ptr::NonNull;
Expand Down Expand Up @@ -214,7 +214,7 @@ pub(crate) mod internal {
}

#[cfg(all(
any(feature = "libc", feature = "alloc-rs"),
not(stabby_default_alloc = "disabled"),
any(stabby_vtables = "vec", stabby_vtables = "btree", not(stabby_vtables))
))]
#[rustversion::all(not(nightly), since(1.78.0))]
Expand All @@ -229,6 +229,21 @@ pub trait IConstConstructor<'a, Source>: 'a + Copy {
internal::VTABLES.insert_typed(&Self::VTABLE)
}
}
#[cfg(not(all(
not(stabby_default_alloc = "disabled"),
any(stabby_vtables = "vec", stabby_vtables = "btree", not(stabby_vtables))
)))]
#[rustversion::all(not(nightly), since(1.78.0))]
/// Implementation detail for stabby's version of dyn traits.
/// Any type that implements a trait `ITrait` must implement `IConstConstructor<VtITrait>` for `stabby::dyn!(Ptr<ITrait>)::from(value)` to work.
pub trait IConstConstructor<'a, Source>: 'a + Copy {
/// The vtable.
const VTABLE: Self;
/// Returns the reference to the vtable
fn vtable() -> &'a Self {
core::compile_error!("stabby's dyn traits need an allocator for non-nightly versions of Rust starting `1.78.0` and until https://github.com/rust-lang/rfcs/pull/3633 lands in stable.")
}
}
/// Implementation detail for stabby's version of dyn traits.
pub trait TransitiveDeref<Head, N> {
/// Deref transitiverly.
Expand Down
3 changes: 3 additions & 0 deletions stabby/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@ impl Duration {
nanos: ((micros % 1000000) * 1000) as u32,
}
}

/// Construct a new [`Duration`].
///
/// # Panics
/// if `secs` is negative.
#[cfg(feature = "std")]
pub fn from_secs_f64(secs: f64) -> Self {
assert!(secs >= 0.);
Self {
Expand Down