Skip to content

Commit

Permalink
refactor!: allow any Default allocator for unallocated Bumps via …
Browse files Browse the repository at this point in the history
…the `BaseAllocator` trait
  • Loading branch information
bluurryy committed May 20, 2024
1 parent 1d277a4 commit 97fc797
Show file tree
Hide file tree
Showing 19 changed files with 207 additions and 230 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased
- **breaking:** `BumpPool::new` is now no longer const, you can the same const constructor with `BumpPool::new_in(Global)`.
- **added:** any allocator that implements `Default` can now be used as a base allocator (before it was just `Global`)

## 0.4.0 (2024-05-19)
- **breaking:** renamed `Stats::to_stats` to `to_guaranteed_stats`
- **breaking:** removed deprecated `BumpBox::into_fixed_vec` and `into_fixed_string`.
Expand Down
3 changes: 1 addition & 2 deletions benches/benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ trait Bumper {
fn try_alloc_try_with<T, E>(&self, f: impl FnOnce() -> Result<T, E>) -> Result<Result<&mut T, E>, AllocError>;
}

impl<const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool> Bumper
for Bump<Global, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
impl<const MIN_ALIGN: usize, const UP: bool> Bumper for Bump<Global, MIN_ALIGN, UP>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
{
Expand Down
7 changes: 5 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ all:
just fmt
just clippy
just doc
cargo semver-checks
just check-msrv
just check-nooom
cargo test --all-features
Expand Down Expand Up @@ -59,4 +58,8 @@ test-fallibility:
@ just crates/test-fallibility/test

inspect-asm *args:
just crates/inspect-asm/inspect {{args}}
just crates/inspect-asm/inspect {{args}}

publish:
cargo semver-checks
cargo publish
17 changes: 9 additions & 8 deletions src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ use allocator_api2::alloc::{AllocError, Allocator};
use core::{alloc::Layout, num::NonZeroUsize, ptr::NonNull};

use crate::{
bump_down, polyfill::nonnull, up_align_usize_unchecked, Bump, BumpScope, MinimumAlignment, SupportedMinimumAlignment,
bump_down, polyfill::nonnull, up_align_usize_unchecked, BaseAllocator, Bump, BumpScope, MinimumAlignment,
SupportedMinimumAlignment,
};

unsafe impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool> Allocator
for BumpScope<'_, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
#[inline(always)]
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
Expand Down Expand Up @@ -49,7 +50,7 @@ unsafe impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATE
for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
#[inline(always)]
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
Expand Down Expand Up @@ -89,7 +90,7 @@ fn allocate<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATE
) -> Result<NonNull<[u8]>, AllocError>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
Ok(nonnull::slice_from_raw_parts(bump.try_alloc_layout(layout)?, layout.size()))
}
Expand Down Expand Up @@ -155,7 +156,7 @@ unsafe fn grow<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOC
) -> Result<NonNull<[u8]>, AllocError>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
debug_assert!(
new_layout.size() >= old_layout.size(),
Expand Down Expand Up @@ -243,7 +244,7 @@ unsafe fn grow_zeroed<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEE
) -> Result<NonNull<[u8]>, AllocError>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
let new_ptr = grow(bump, old_ptr, old_layout, new_layout)?;

Expand All @@ -262,7 +263,7 @@ unsafe fn shrink<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALL
) -> Result<NonNull<[u8]>, AllocError>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
/// Called when `new_layout` doesn't fit alignment.
/// Does ANY consumer cause this?
Expand All @@ -277,7 +278,7 @@ where
) -> Result<NonNull<[u8]>, AllocError>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
if is_last(bump, old_ptr, old_layout) {
let old_pos = bump.chunk.get().pos();
Expand Down
12 changes: 5 additions & 7 deletions src/any_bump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ use core::{alloc::Layout, mem::MaybeUninit, ptr::NonNull};
#[cfg(feature = "alloc")]
use core::fmt;

use allocator_api2::alloc::Allocator;

use crate::{Bump, BumpBox, BumpScope, ErrorBehavior, MinimumAlignment, SupportedMinimumAlignment};
use crate::{BaseAllocator, Bump, BumpBox, BumpScope, ErrorBehavior, MinimumAlignment, SupportedMinimumAlignment};

pub(crate) trait Sealed {
fn alloc_uninit<B: ErrorBehavior, T>(&self) -> Result<BumpBox<MaybeUninit<T>>, B>;
Expand Down Expand Up @@ -152,7 +150,7 @@ impl<'a, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED:
for BumpScope<'a, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
#[inline(always)]
fn alloc_uninit<B: ErrorBehavior, T>(&self) -> Result<BumpBox<MaybeUninit<T>>, B> {
Expand Down Expand Up @@ -218,7 +216,7 @@ impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool
for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
#[inline(always)]
fn alloc_uninit<B: ErrorBehavior, T>(&self) -> Result<BumpBox<MaybeUninit<T>>, B> {
Expand Down Expand Up @@ -296,14 +294,14 @@ impl<'a, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED:
for BumpScope<'a, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
}

impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool> AnyBump
for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
}
60 changes: 29 additions & 31 deletions src/bump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,21 @@ use core::{
ptr::NonNull,
};

use allocator_api2::alloc::{AllocError, Allocator};

#[cfg(feature = "alloc")]
use allocator_api2::alloc::Global;
use allocator_api2::alloc::AllocError;

use crate::{
bump_common_methods, bump_scope_methods, chunk_size::ChunkSize, doc_align_cant_decrease,
error_behavior_generic_methods_allocation_failure, polyfill::pointer, BumpScope, BumpScopeGuardRoot, Checkpoint,
ErrorBehavior, GuaranteedAllocatedStats, MinimumAlignment, RawChunk, Stats, SupportedMinimumAlignment, WithoutDealloc,
WithoutShrink, DEFAULT_START_CHUNK_SIZE,
bump_common_methods, bump_scope_methods,
chunk_size::ChunkSize,
doc_align_cant_decrease, error_behavior_generic_methods_allocation_failure,
polyfill::{cfg_const, pointer},
unallocated_chunk_header, BaseAllocator, BumpScope, BumpScopeGuardRoot, Checkpoint, ErrorBehavior,
GuaranteedAllocatedStats, MinimumAlignment, RawChunk, Stats, SupportedMinimumAlignment, WithoutDealloc, WithoutShrink,
DEFAULT_START_CHUNK_SIZE,
};

#[cfg(not(no_global_oom_handling))]
use crate::infallible;

#[cfg(feature = "alloc")]
use crate::{polyfill::cfg_const, unallocated_chunk_header};

#[cfg(test)]
use crate::WithDrop;

Expand Down Expand Up @@ -63,13 +60,14 @@ use crate::WithDrop;
/// ```
#[repr(transparent)]
pub struct Bump<
#[cfg(feature = "alloc")] A: Allocator + Clone = Global,
#[cfg(not(feature = "alloc"))] A: Allocator + Clone,
#[cfg(feature = "alloc")] A = allocator_api2::alloc::Global,
#[cfg(not(feature = "alloc"))] A,
const MIN_ALIGN: usize = 1,
const UP: bool = true,
const GUARANTEED_ALLOCATED: bool = true,
> where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
pub(crate) chunk: Cell<RawChunk<UP, A>>,
}
Expand All @@ -80,31 +78,31 @@ unsafe impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATE
for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
}

impl<const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, A> UnwindSafe
for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone + UnwindSafe,
A: BaseAllocator<GUARANTEED_ALLOCATED> + UnwindSafe,
{
}

impl<const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, A> RefUnwindSafe
for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone + UnwindSafe,
A: BaseAllocator<GUARANTEED_ALLOCATED> + UnwindSafe,
{
}

impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool> Drop
for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
fn drop(&mut self) {
if self.is_unallocated() {
Expand All @@ -124,7 +122,7 @@ impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool
for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.stats().debug_format("Bump", f)
Expand All @@ -136,18 +134,18 @@ impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool
for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone + Default,
A: BaseAllocator<GUARANTEED_ALLOCATED> + Default,
{
#[inline(always)]
fn default() -> Self {
Self::new_in(Default::default())
}
}

#[cfg(feature = "alloc")]
impl<const MIN_ALIGN: usize, const UP: bool> Bump<Global, MIN_ALIGN, UP, false>
impl<A, const MIN_ALIGN: usize, const UP: bool> Bump<A, MIN_ALIGN, UP, false>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: BaseAllocator<false>,
{
cfg_const! {
#[cfg_const(feature = "nightly-const-refs-to-static")]
Expand All @@ -161,11 +159,11 @@ where
}
}

#[cfg(feature = "alloc")]
impl<const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool>
Bump<Global, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool>
Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: BaseAllocator<GUARANTEED_ALLOCATED> + Default,
{
error_behavior_generic_methods_allocation_failure! {
impl
Expand All @@ -175,7 +173,7 @@ where
/// This is equivalent to `Bump::try_with_capacity(512)`.
for pub fn try_new
fn generic_new() -> Self {
Self::generic_new_in(Global)
Self::generic_new_in(Default::default())
}

/// Constructs a new `Bump` with a chunk of at least `size` bytes.
Expand All @@ -184,7 +182,7 @@ where
for pub fn with_size
for pub fn try_with_size
fn generic_with_size(size: usize) -> Self {
Self::generic_with_size_in(size, Global)
Self::generic_with_size_in(size, Default::default())
}

/// Constructs a new `Bump` with at least enough space for `layout`.
Expand All @@ -193,7 +191,7 @@ where
for pub fn with_capacity
for pub fn try_with_capacity
fn generic_with_capacity(layout: Layout) -> Self {
Self::generic_with_capacity_in(layout, Global)
Self::generic_with_capacity_in(layout, Default::default())
}
}
}
Expand All @@ -202,7 +200,7 @@ where
impl<A, const MIN_ALIGN: usize, const UP: bool> Bump<A, MIN_ALIGN, UP>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator,
{
bump_scope_methods!(BumpScopeGuardRoot, false);
}
Expand All @@ -211,7 +209,7 @@ impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool
Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
error_behavior_generic_methods_allocation_failure! {
impl
Expand Down Expand Up @@ -425,7 +423,7 @@ impl<'b, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED:
From<&'b Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>> for &'b BumpScope<'b, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
#[inline(always)]
fn from(value: &'b Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>) -> Self {
Expand All @@ -438,7 +436,7 @@ impl<'b, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED:
for &'b mut BumpScope<'b, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
#[inline(always)]
fn from(value: &'b mut Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>) -> Self {
Expand Down
10 changes: 4 additions & 6 deletions src/bump_align_guard.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use allocator_api2::alloc::Allocator;

use crate::{BumpScope, MinimumAlignment, SupportedMinimumAlignment};
use crate::{BaseAllocator, BumpScope, MinimumAlignment, SupportedMinimumAlignment};

/// Aligns the bump pointer on drop.
///
Expand All @@ -10,7 +8,7 @@ use crate::{BumpScope, MinimumAlignment, SupportedMinimumAlignment};
pub(crate) struct BumpAlignGuard<'b, 'a, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
pub(crate) scope: &'b mut BumpScope<'a, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>,
}
Expand All @@ -19,7 +17,7 @@ impl<'b, 'a, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCAT
for BumpAlignGuard<'b, 'a, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
#[inline(always)]
fn drop(&mut self) {
Expand All @@ -31,7 +29,7 @@ impl<'b, 'a, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCAT
BumpAlignGuard<'b, 'a, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
A: Allocator + Clone,
A: BaseAllocator<GUARANTEED_ALLOCATED>,
{
#[inline(always)]
pub fn new(scope: &'b mut BumpScope<'a, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED>) -> Self {
Expand Down

0 comments on commit 97fc797

Please sign in to comment.