From 5df565f3ef817bfd77830690f864efba113df598 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Mon, 10 Nov 2025 11:10:58 +0100 Subject: [PATCH] Move drop_fn of from_owner into vtable --- src/bytes.rs | 81 ++++++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 47 deletions(-) diff --git a/src/bytes.rs b/src/bytes.rs index b9264bd33..441ca80d7 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -267,10 +267,7 @@ impl Bytes { // and: https://github.com/tokio-rs/bytes/pull/742/#discussion_r1813316032 let owned = Box::into_raw(Box::new(Owned { - lifetime: OwnedLifetime { - ref_cnt: AtomicUsize::new(1), - drop: owned_box_and_drop::, - }, + ref_cnt: AtomicUsize::new(1), owner, })); @@ -278,7 +275,7 @@ impl Bytes { ptr: NonNull::dangling().as_ptr(), len: 0, data: AtomicPtr::new(owned.cast()), - vtable: &OWNED_VTABLE, + vtable: &Owned::::VTABLE, }; let buf = unsafe { &*owned }.owner.as_ref(); @@ -1107,85 +1104,75 @@ unsafe fn static_drop(_: &mut AtomicPtr<()>, _: *const u8, _: usize) { // ===== impl OwnedVtable ===== -#[repr(C)] -struct OwnedLifetime { - ref_cnt: AtomicUsize, - drop: unsafe fn(*mut ()), -} - #[repr(C)] struct Owned { - lifetime: OwnedLifetime, + ref_cnt: AtomicUsize, owner: T, } -unsafe fn owned_box_and_drop(ptr: *mut ()) { - let b: Box> = Box::from_raw(ptr as _); - drop(b); +impl Owned { + const VTABLE: Vtable = Vtable { + clone: owned_clone::, + into_vec: owned_to_vec::, + into_mut: owned_to_mut::, + is_unique: owned_is_unique, + drop: owned_drop::, + }; } -unsafe fn owned_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes { +unsafe fn owned_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes { let owned = data.load(Ordering::Relaxed); - let ref_cnt = &(*owned.cast::()).ref_cnt; - let old_cnt = ref_cnt.fetch_add(1, Ordering::Relaxed); + let old_cnt = (*owned.cast::()).fetch_add(1, Ordering::Relaxed); if old_cnt > usize::MAX >> 1 { - crate::abort() + crate::abort(); } Bytes { ptr, len, data: AtomicPtr::new(owned as _), - vtable: &OWNED_VTABLE, + vtable: &Owned::::VTABLE, } } -unsafe fn owned_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec { +unsafe fn owned_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec { let slice = slice::from_raw_parts(ptr, len); let vec = slice.to_vec(); - owned_drop_impl(data.load(Ordering::Relaxed)); + owned_drop_impl::(data.load(Ordering::Relaxed)); vec } -unsafe fn owned_to_mut(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> BytesMut { - BytesMut::from_vec(owned_to_vec(data, ptr, len)) +unsafe fn owned_to_mut(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> BytesMut { + BytesMut::from_vec(owned_to_vec::(data, ptr, len)) } unsafe fn owned_is_unique(_data: &AtomicPtr<()>) -> bool { false } -unsafe fn owned_drop_impl(owned: *mut ()) { - let lifetime = owned.cast::(); - let ref_cnt = &(*lifetime).ref_cnt; +unsafe fn owned_drop_impl(owned: *mut ()) { + { + let ref_cnt = &*owned.cast::(); - let old_cnt = ref_cnt.fetch_sub(1, Ordering::Release); - debug_assert!( - old_cnt > 0 && old_cnt <= usize::MAX >> 1, - "expected non-zero refcount and no underflow" - ); - if old_cnt != 1 { - return; + let old_cnt = ref_cnt.fetch_sub(1, Ordering::Release); + debug_assert!( + old_cnt > 0 && old_cnt <= usize::MAX >> 1, + "expected non-zero refcount and no underflow" + ); + if old_cnt != 1 { + return; + } + ref_cnt.load(Ordering::Acquire); } - ref_cnt.load(Ordering::Acquire); - let drop_fn = &(*lifetime).drop; - drop_fn(owned) + drop(Box::>::from_raw(owned.cast())); } -unsafe fn owned_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) { +unsafe fn owned_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) { let owned = data.load(Ordering::Relaxed); - owned_drop_impl(owned); + owned_drop_impl::(owned); } -static OWNED_VTABLE: Vtable = Vtable { - clone: owned_clone, - into_vec: owned_to_vec, - into_mut: owned_to_mut, - is_unique: owned_is_unique, - drop: owned_drop, -}; - // ===== impl PromotableVtable ===== static PROMOTABLE_EVEN_VTABLE: Vtable = Vtable {