Skip to content

Commit 7ce330f

Browse files
authored
Move drop_fn of from_owner into vtable (#801)
1 parent 4b53a29 commit 7ce330f

File tree

1 file changed

+34
-47
lines changed

1 file changed

+34
-47
lines changed

src/bytes.rs

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -267,18 +267,15 @@ impl Bytes {
267267
// and: https://github.com/tokio-rs/bytes/pull/742/#discussion_r1813316032
268268

269269
let owned = Box::into_raw(Box::new(Owned {
270-
lifetime: OwnedLifetime {
271-
ref_cnt: AtomicUsize::new(1),
272-
drop: owned_box_and_drop::<T>,
273-
},
270+
ref_cnt: AtomicUsize::new(1),
274271
owner,
275272
}));
276273

277274
let mut ret = Bytes {
278275
ptr: NonNull::dangling().as_ptr(),
279276
len: 0,
280277
data: AtomicPtr::new(owned.cast()),
281-
vtable: &OWNED_VTABLE,
278+
vtable: &Owned::<T>::VTABLE,
282279
};
283280

284281
let buf = unsafe { &*owned }.owner.as_ref();
@@ -1107,85 +1104,75 @@ unsafe fn static_drop(_: &mut AtomicPtr<()>, _: *const u8, _: usize) {
11071104

11081105
// ===== impl OwnedVtable =====
11091106

1110-
#[repr(C)]
1111-
struct OwnedLifetime {
1112-
ref_cnt: AtomicUsize,
1113-
drop: unsafe fn(*mut ()),
1114-
}
1115-
11161107
#[repr(C)]
11171108
struct Owned<T> {
1118-
lifetime: OwnedLifetime,
1109+
ref_cnt: AtomicUsize,
11191110
owner: T,
11201111
}
11211112

1122-
unsafe fn owned_box_and_drop<T>(ptr: *mut ()) {
1123-
let b: Box<Owned<T>> = Box::from_raw(ptr as _);
1124-
drop(b);
1113+
impl<T> Owned<T> {
1114+
const VTABLE: Vtable = Vtable {
1115+
clone: owned_clone::<T>,
1116+
into_vec: owned_to_vec::<T>,
1117+
into_mut: owned_to_mut::<T>,
1118+
is_unique: owned_is_unique,
1119+
drop: owned_drop::<T>,
1120+
};
11251121
}
11261122

1127-
unsafe fn owned_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1123+
unsafe fn owned_clone<T>(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
11281124
let owned = data.load(Ordering::Relaxed);
1129-
let ref_cnt = &(*owned.cast::<OwnedLifetime>()).ref_cnt;
1130-
let old_cnt = ref_cnt.fetch_add(1, Ordering::Relaxed);
1125+
let old_cnt = (*owned.cast::<AtomicUsize>()).fetch_add(1, Ordering::Relaxed);
11311126
if old_cnt > usize::MAX >> 1 {
1132-
crate::abort()
1127+
crate::abort();
11331128
}
11341129

11351130
Bytes {
11361131
ptr,
11371132
len,
11381133
data: AtomicPtr::new(owned as _),
1139-
vtable: &OWNED_VTABLE,
1134+
vtable: &Owned::<T>::VTABLE,
11401135
}
11411136
}
11421137

1143-
unsafe fn owned_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
1138+
unsafe fn owned_to_vec<T>(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
11441139
let slice = slice::from_raw_parts(ptr, len);
11451140
let vec = slice.to_vec();
1146-
owned_drop_impl(data.load(Ordering::Relaxed));
1141+
owned_drop_impl::<T>(data.load(Ordering::Relaxed));
11471142
vec
11481143
}
11491144

1150-
unsafe fn owned_to_mut(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> BytesMut {
1151-
BytesMut::from_vec(owned_to_vec(data, ptr, len))
1145+
unsafe fn owned_to_mut<T>(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> BytesMut {
1146+
BytesMut::from_vec(owned_to_vec::<T>(data, ptr, len))
11521147
}
11531148

11541149
unsafe fn owned_is_unique(_data: &AtomicPtr<()>) -> bool {
11551150
false
11561151
}
11571152

1158-
unsafe fn owned_drop_impl(owned: *mut ()) {
1159-
let lifetime = owned.cast::<OwnedLifetime>();
1160-
let ref_cnt = &(*lifetime).ref_cnt;
1153+
unsafe fn owned_drop_impl<T>(owned: *mut ()) {
1154+
{
1155+
let ref_cnt = &*owned.cast::<AtomicUsize>();
11611156

1162-
let old_cnt = ref_cnt.fetch_sub(1, Ordering::Release);
1163-
debug_assert!(
1164-
old_cnt > 0 && old_cnt <= usize::MAX >> 1,
1165-
"expected non-zero refcount and no underflow"
1166-
);
1167-
if old_cnt != 1 {
1168-
return;
1157+
let old_cnt = ref_cnt.fetch_sub(1, Ordering::Release);
1158+
debug_assert!(
1159+
old_cnt > 0 && old_cnt <= usize::MAX >> 1,
1160+
"expected non-zero refcount and no underflow"
1161+
);
1162+
if old_cnt != 1 {
1163+
return;
1164+
}
1165+
ref_cnt.load(Ordering::Acquire);
11691166
}
1170-
ref_cnt.load(Ordering::Acquire);
11711167

1172-
let drop_fn = &(*lifetime).drop;
1173-
drop_fn(owned)
1168+
drop(Box::<Owned<T>>::from_raw(owned.cast()));
11741169
}
11751170

1176-
unsafe fn owned_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) {
1171+
unsafe fn owned_drop<T>(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) {
11771172
let owned = data.load(Ordering::Relaxed);
1178-
owned_drop_impl(owned);
1173+
owned_drop_impl::<T>(owned);
11791174
}
11801175

1181-
static OWNED_VTABLE: Vtable = Vtable {
1182-
clone: owned_clone,
1183-
into_vec: owned_to_vec,
1184-
into_mut: owned_to_mut,
1185-
is_unique: owned_is_unique,
1186-
drop: owned_drop,
1187-
};
1188-
11891176
// ===== impl PromotableVtable =====
11901177

11911178
static PROMOTABLE_EVEN_VTABLE: Vtable = Vtable {

0 commit comments

Comments
 (0)