1use core::mem::{self, ManuallyDrop};
2use core::ops::{Deref, RangeBounds};
3use core::ptr::NonNull;
4use core::{cmp, fmt, hash, ptr, slice};
5
6use alloc::{
7 alloc::{dealloc, Layout},
8 borrow::Borrow,
9 boxed::Box,
10 string::String,
11 vec::Vec,
12};
13
14use crate::buf::IntoIter;
15#[allow(unused)]
16use crate::loom::sync::atomic::AtomicMut;
17use crate::loom::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
18use crate::{Buf, BytesMut};
19
20pub struct Bytes {
102 ptr: *const u8,
103 len: usize,
104 data: AtomicPtr<()>,
106 vtable: &'static Vtable,
107}
108
109pub(crate) struct Vtable {
114 pub clone: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Bytes,
116 pub into_vec: unsafe fn(*mut (), *const u8, usize) -> Vec<u8>,
120 pub into_mut: unsafe fn(*mut (), *const u8, usize) -> BytesMut,
121 pub is_unique: unsafe fn(&AtomicPtr<()>) -> bool,
123 pub drop: unsafe fn(*mut (), *const u8, usize),
125}
126
127impl Bytes {
128 #[inline]
141 #[cfg(not(all(loom, test)))]
142 pub const fn new() -> Self {
143 const EMPTY: &[u8] = &[];
146 Bytes::from_static(EMPTY)
147 }
148
149 #[cfg(all(loom, test))]
151 pub fn new() -> Self {
152 const EMPTY: &[u8] = &[];
153 Bytes::from_static(EMPTY)
154 }
155
156 #[inline]
170 #[cfg(not(all(loom, test)))]
171 pub const fn from_static(bytes: &'static [u8]) -> Self {
172 Bytes {
173 ptr: bytes.as_ptr(),
174 len: bytes.len(),
175 data: AtomicPtr::new(ptr::null_mut()),
176 vtable: &STATIC_VTABLE,
177 }
178 }
179
180 #[cfg(all(loom, test))]
182 pub fn from_static(bytes: &'static [u8]) -> Self {
183 Bytes {
184 ptr: bytes.as_ptr(),
185 len: bytes.len(),
186 data: AtomicPtr::new(ptr::null_mut()),
187 vtable: &STATIC_VTABLE,
188 }
189 }
190
191 fn new_empty_with_ptr(ptr: *const u8) -> Self {
193 debug_assert!(!ptr.is_null());
194
195 let ptr = without_provenance(ptr as usize);
198
199 Bytes {
200 ptr,
201 len: 0,
202 data: AtomicPtr::new(ptr::null_mut()),
203 vtable: &STATIC_VTABLE,
204 }
205 }
206
207 pub fn from_owner<T>(owner: T) -> Self
255 where
256 T: AsRef<[u8]> + Send + 'static,
257 {
258 let owned = Box::into_raw(Box::new(Owned {
274 ref_cnt: AtomicUsize::new(1),
275 owner,
276 }));
277
278 let mut ret = Bytes {
279 ptr: NonNull::dangling().as_ptr(),
280 len: 0,
281 data: AtomicPtr::new(owned.cast()),
282 vtable: &Owned::<T>::VTABLE,
283 };
284
285 let buf = unsafe { &*owned }.owner.as_ref();
286 ret.ptr = buf.as_ptr();
287 ret.len = buf.len();
288
289 ret
290 }
291
292 #[inline]
303 pub const fn len(&self) -> usize {
304 self.len
305 }
306
307 #[inline]
318 pub const fn is_empty(&self) -> bool {
319 self.len == 0
320 }
321
322 pub fn is_unique(&self) -> bool {
343 unsafe { (self.vtable.is_unique)(&self.data) }
344 }
345
346 pub fn copy_from_slice(data: &[u8]) -> Self {
348 data.to_vec().into()
349 }
350
351 pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
374 let (begin, end) = crate::range(range, self.len());
375
376 if end == begin {
377 return Bytes::new_empty_with_ptr(self.ptr.wrapping_add(begin));
378 }
379
380 let mut ret = self.clone();
381
382 ret.len = end - begin;
383 ret.ptr = unsafe { ret.ptr.add(begin) };
384
385 ret
386 }
387
388 pub fn slice_ref(&self, subset: &[u8]) -> Self {
414 if subset.is_empty() {
417 return Bytes::new();
418 }
419
420 let bytes_p = self.as_ptr() as usize;
421 let bytes_len = self.len();
422
423 let sub_p = subset.as_ptr() as usize;
424 let sub_len = subset.len();
425
426 assert!(
427 sub_p >= bytes_p,
428 "subset pointer ({:p}) is smaller than self pointer ({:p})",
429 subset.as_ptr(),
430 self.as_ptr(),
431 );
432 assert!(
433 sub_p + sub_len <= bytes_p + bytes_len,
434 "subset is out of bounds: self = ({:p}, {}), subset = ({:p}, {})",
435 self.as_ptr(),
436 bytes_len,
437 subset.as_ptr(),
438 sub_len,
439 );
440
441 let sub_offset = sub_p - bytes_p;
442
443 self.slice(sub_offset..(sub_offset + sub_len))
444 }
445
446 #[must_use = "consider Bytes::truncate if you don't need the other half"]
472 pub fn split_off(&mut self, at: usize) -> Self {
473 if at == self.len() {
474 return Bytes::new_empty_with_ptr(self.ptr.wrapping_add(at));
475 }
476
477 if at == 0 {
478 return mem::replace(self, Bytes::new_empty_with_ptr(self.ptr));
479 }
480
481 assert!(
482 at <= self.len(),
483 "split_off out of bounds: {:?} <= {:?}",
484 at,
485 self.len(),
486 );
487
488 let mut ret = self.clone();
489
490 self.len = at;
491
492 unsafe { ret.inc_start(at) };
495
496 ret
497 }
498
499 #[must_use = "consider Bytes::advance if you don't need the other half"]
523 pub fn split_to(&mut self, at: usize) -> Self {
524 if at == self.len() {
525 let end_ptr = self.ptr.wrapping_add(at);
526 return mem::replace(self, Bytes::new_empty_with_ptr(end_ptr));
527 }
528
529 if at == 0 {
530 return Bytes::new_empty_with_ptr(self.ptr);
531 }
532
533 assert!(
534 at <= self.len(),
535 "split_to out of bounds: {:?} <= {:?}",
536 at,
537 self.len(),
538 );
539
540 let mut ret = self.clone();
541
542 unsafe { self.inc_start(at) };
545
546 ret.len = at;
547 ret
548 }
549
550 #[inline]
569 pub fn truncate(&mut self, len: usize) {
570 if len < self.len {
571 if self.vtable as *const Vtable == &PROMOTABLE_EVEN_VTABLE
575 || self.vtable as *const Vtable == &PROMOTABLE_ODD_VTABLE
576 {
577 drop(self.split_off(len));
578 } else {
579 self.len = len;
580 }
581 }
582 }
583
584 #[inline]
596 pub fn clear(&mut self) {
597 self.truncate(0);
598 }
599
600 pub fn try_into_mut(self) -> Result<BytesMut, Bytes> {
619 if self.is_unique() {
620 Ok(self.into())
621 } else {
622 Err(self)
623 }
624 }
625
626 #[inline]
627 pub(crate) unsafe fn with_vtable(
628 ptr: *const u8,
629 len: usize,
630 data: AtomicPtr<()>,
631 vtable: &'static Vtable,
632 ) -> Bytes {
633 Bytes {
634 ptr,
635 len,
636 data,
637 vtable,
638 }
639 }
640
641 #[inline]
644 fn as_slice(&self) -> &[u8] {
645 unsafe { slice::from_raw_parts(self.ptr, self.len) }
646 }
647
648 #[inline]
649 unsafe fn inc_start(&mut self, by: usize) {
650 debug_assert!(self.len >= by, "internal: inc_start out of bounds");
652 self.len -= by;
653 self.ptr = self.ptr.add(by);
654 }
655
656 #[inline]
657 fn data_mut(&mut self) -> *mut () {
658 self.data.with_mut(|p| *p)
659 }
660}
661
662unsafe impl Send for Bytes {}
664unsafe impl Sync for Bytes {}
665
666impl Drop for Bytes {
667 #[inline]
668 fn drop(&mut self) {
669 let data = self.data_mut();
670 unsafe { (self.vtable.drop)(data, self.ptr, self.len) }
671 }
672}
673
674impl Clone for Bytes {
675 #[inline]
676 fn clone(&self) -> Bytes {
677 unsafe { (self.vtable.clone)(&self.data, self.ptr, self.len) }
678 }
679}
680
681impl Buf for Bytes {
682 #[inline]
683 fn remaining(&self) -> usize {
684 self.len()
685 }
686
687 #[inline]
688 fn chunk(&self) -> &[u8] {
689 self.as_slice()
690 }
691
692 #[inline]
693 fn advance(&mut self, cnt: usize) {
694 assert!(
695 cnt <= self.len(),
696 "cannot advance past `remaining`: {:?} <= {:?}",
697 cnt,
698 self.len(),
699 );
700
701 unsafe {
702 self.inc_start(cnt);
703 }
704 }
705
706 fn copy_to_bytes(&mut self, len: usize) -> Self {
707 self.split_to(len)
708 }
709}
710
711impl Deref for Bytes {
712 type Target = [u8];
713
714 #[inline]
715 fn deref(&self) -> &[u8] {
716 self.as_slice()
717 }
718}
719
720impl AsRef<[u8]> for Bytes {
721 #[inline]
722 fn as_ref(&self) -> &[u8] {
723 self.as_slice()
724 }
725}
726
727impl hash::Hash for Bytes {
728 fn hash<H>(&self, state: &mut H)
729 where
730 H: hash::Hasher,
731 {
732 self.as_slice().hash(state);
733 }
734}
735
736impl Borrow<[u8]> for Bytes {
737 fn borrow(&self) -> &[u8] {
738 self.as_slice()
739 }
740}
741
742impl IntoIterator for Bytes {
743 type Item = u8;
744 type IntoIter = IntoIter<Bytes>;
745
746 fn into_iter(self) -> Self::IntoIter {
747 IntoIter::new(self)
748 }
749}
750
751impl<'a> IntoIterator for &'a Bytes {
752 type Item = &'a u8;
753 type IntoIter = core::slice::Iter<'a, u8>;
754
755 fn into_iter(self) -> Self::IntoIter {
756 self.as_slice().iter()
757 }
758}
759
760impl FromIterator<u8> for Bytes {
761 fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
762 Vec::from_iter(into_iter).into()
763 }
764}
765
766impl PartialEq for Bytes {
769 fn eq(&self, other: &Bytes) -> bool {
770 self.as_slice() == other.as_slice()
771 }
772}
773
774impl PartialOrd for Bytes {
775 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
776 Some(self.cmp(other))
777 }
778}
779
780impl Ord for Bytes {
781 fn cmp(&self, other: &Bytes) -> cmp::Ordering {
782 self.as_slice().cmp(other.as_slice())
783 }
784}
785
786impl Eq for Bytes {}
787
788impl PartialEq<[u8]> for Bytes {
789 fn eq(&self, other: &[u8]) -> bool {
790 self.as_slice() == other
791 }
792}
793
794impl PartialOrd<[u8]> for Bytes {
795 fn partial_cmp(&self, other: &[u8]) -> Option<cmp::Ordering> {
796 self.as_slice().partial_cmp(other)
797 }
798}
799
800impl PartialEq<Bytes> for [u8] {
801 fn eq(&self, other: &Bytes) -> bool {
802 *other == *self
803 }
804}
805
806impl PartialOrd<Bytes> for [u8] {
807 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
808 <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
809 }
810}
811
812impl PartialEq<str> for Bytes {
813 fn eq(&self, other: &str) -> bool {
814 self.as_slice() == other.as_bytes()
815 }
816}
817
818impl PartialOrd<str> for Bytes {
819 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
820 self.as_slice().partial_cmp(other.as_bytes())
821 }
822}
823
824impl PartialEq<Bytes> for str {
825 fn eq(&self, other: &Bytes) -> bool {
826 *other == *self
827 }
828}
829
830impl PartialOrd<Bytes> for str {
831 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
832 <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
833 }
834}
835
836impl PartialEq<Vec<u8>> for Bytes {
837 fn eq(&self, other: &Vec<u8>) -> bool {
838 *self == other[..]
839 }
840}
841
842impl PartialOrd<Vec<u8>> for Bytes {
843 fn partial_cmp(&self, other: &Vec<u8>) -> Option<cmp::Ordering> {
844 self.as_slice().partial_cmp(&other[..])
845 }
846}
847
848impl PartialEq<Bytes> for Vec<u8> {
849 fn eq(&self, other: &Bytes) -> bool {
850 *other == *self
851 }
852}
853
854impl PartialOrd<Bytes> for Vec<u8> {
855 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
856 <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
857 }
858}
859
860impl PartialEq<String> for Bytes {
861 fn eq(&self, other: &String) -> bool {
862 *self == other[..]
863 }
864}
865
866impl PartialOrd<String> for Bytes {
867 fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
868 self.as_slice().partial_cmp(other.as_bytes())
869 }
870}
871
872impl PartialEq<Bytes> for String {
873 fn eq(&self, other: &Bytes) -> bool {
874 *other == *self
875 }
876}
877
878impl PartialOrd<Bytes> for String {
879 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
880 <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
881 }
882}
883
884impl PartialEq<Bytes> for &[u8] {
885 fn eq(&self, other: &Bytes) -> bool {
886 *other == *self
887 }
888}
889
890impl PartialOrd<Bytes> for &[u8] {
891 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
892 <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
893 }
894}
895
896impl PartialEq<Bytes> for &str {
897 fn eq(&self, other: &Bytes) -> bool {
898 *other == *self
899 }
900}
901
902impl PartialOrd<Bytes> for &str {
903 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
904 <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
905 }
906}
907
908impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
909where
910 Bytes: PartialEq<T>,
911{
912 fn eq(&self, other: &&'a T) -> bool {
913 *self == **other
914 }
915}
916
917impl<'a, T: ?Sized> PartialOrd<&'a T> for Bytes
918where
919 Bytes: PartialOrd<T>,
920{
921 fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
922 self.partial_cmp(&**other)
923 }
924}
925
926impl Default for Bytes {
929 #[inline]
930 fn default() -> Bytes {
931 Bytes::new()
932 }
933}
934
935impl From<&'static [u8]> for Bytes {
936 fn from(slice: &'static [u8]) -> Bytes {
937 Bytes::from_static(slice)
938 }
939}
940
941impl From<&'static str> for Bytes {
942 fn from(slice: &'static str) -> Bytes {
943 Bytes::from_static(slice.as_bytes())
944 }
945}
946
947impl From<Vec<u8>> for Bytes {
948 fn from(vec: Vec<u8>) -> Bytes {
949 let mut vec = ManuallyDrop::new(vec);
950 let ptr = vec.as_mut_ptr();
951 let len = vec.len();
952 let cap = vec.capacity();
953
954 if len == cap {
956 let vec = ManuallyDrop::into_inner(vec);
957 return Bytes::from(vec.into_boxed_slice());
958 }
959
960 let shared = Box::new(Shared {
961 buf: ptr,
962 cap,
963 ref_cnt: AtomicUsize::new(1),
964 });
965
966 let shared = Box::into_raw(shared);
967 debug_assert!(
970 0 == (shared as usize & KIND_MASK),
971 "internal: Box<Shared> should have an aligned pointer",
972 );
973 Bytes {
974 ptr,
975 len,
976 data: AtomicPtr::new(shared as _),
977 vtable: &SHARED_VTABLE,
978 }
979 }
980}
981
982impl From<Box<[u8]>> for Bytes {
983 fn from(slice: Box<[u8]>) -> Bytes {
984 if slice.is_empty() {
988 return Bytes::new();
989 }
990
991 let len = slice.len();
992 let ptr = Box::into_raw(slice) as *mut u8;
993
994 if ptr as usize & 0x1 == 0 {
995 let data = ptr_map(ptr, |addr| addr | KIND_VEC);
996 Bytes {
997 ptr,
998 len,
999 data: AtomicPtr::new(data.cast()),
1000 vtable: &PROMOTABLE_EVEN_VTABLE,
1001 }
1002 } else {
1003 Bytes {
1004 ptr,
1005 len,
1006 data: AtomicPtr::new(ptr.cast()),
1007 vtable: &PROMOTABLE_ODD_VTABLE,
1008 }
1009 }
1010 }
1011}
1012
1013impl From<Bytes> for BytesMut {
1014 fn from(bytes: Bytes) -> Self {
1030 let mut bytes = ManuallyDrop::new(bytes);
1031 let data = bytes.data_mut();
1032 unsafe { (bytes.vtable.into_mut)(data, bytes.ptr, bytes.len) }
1033 }
1034}
1035
1036impl From<String> for Bytes {
1037 fn from(s: String) -> Bytes {
1038 Bytes::from(s.into_bytes())
1039 }
1040}
1041
1042impl From<Bytes> for Vec<u8> {
1043 fn from(bytes: Bytes) -> Vec<u8> {
1044 let mut bytes = ManuallyDrop::new(bytes);
1045 let data = bytes.data_mut();
1046 unsafe { (bytes.vtable.into_vec)(data, bytes.ptr, bytes.len) }
1047 }
1048}
1049
1050impl fmt::Debug for Vtable {
1053 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1054 f.debug_struct("Vtable")
1055 .field("clone", &(self.clone as *const ()))
1056 .field("drop", &(self.drop as *const ()))
1057 .finish()
1058 }
1059}
1060
1061const STATIC_VTABLE: Vtable = Vtable {
1064 clone: static_clone,
1065 into_vec: static_to_vec,
1066 into_mut: static_to_mut,
1067 is_unique: static_is_unique,
1068 drop: static_drop,
1069};
1070
1071unsafe fn static_clone(_: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1072 let slice = slice::from_raw_parts(ptr, len);
1073 Bytes::from_static(slice)
1074}
1075
1076unsafe fn static_to_vec(_: *mut (), ptr: *const u8, len: usize) -> Vec<u8> {
1077 let slice = slice::from_raw_parts(ptr, len);
1078 slice.to_vec()
1079}
1080
1081unsafe fn static_to_mut(_: *mut (), ptr: *const u8, len: usize) -> BytesMut {
1082 let slice = slice::from_raw_parts(ptr, len);
1083 BytesMut::from(slice)
1084}
1085
1086fn static_is_unique(_: &AtomicPtr<()>) -> bool {
1087 false
1088}
1089
1090unsafe fn static_drop(_: *mut (), _: *const u8, _: usize) {
1091 }
1093
1094#[repr(C)]
1097struct Owned<T> {
1098 ref_cnt: AtomicUsize,
1099 owner: T,
1100}
1101
1102impl<T> Owned<T> {
1103 const VTABLE: Vtable = Vtable {
1104 clone: owned_clone::<T>,
1105 into_vec: owned_to_vec::<T>,
1106 into_mut: owned_to_mut::<T>,
1107 is_unique: owned_is_unique,
1108 drop: owned_drop::<T>,
1109 };
1110}
1111
1112unsafe fn owned_clone<T>(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1113 let owned = data.load(Ordering::Relaxed);
1114 let old_cnt = (*owned.cast::<AtomicUsize>()).fetch_add(1, Ordering::Relaxed);
1115 if old_cnt > usize::MAX >> 1 {
1116 crate::abort();
1117 }
1118
1119 Bytes {
1120 ptr,
1121 len,
1122 data: AtomicPtr::new(owned as _),
1123 vtable: &Owned::<T>::VTABLE,
1124 }
1125}
1126
1127unsafe fn owned_to_vec<T>(owned: *mut (), ptr: *const u8, len: usize) -> Vec<u8> {
1128 let slice = slice::from_raw_parts(ptr, len);
1129 let vec = slice.to_vec();
1130 owned_drop_impl::<T>(owned);
1131 vec
1132}
1133
1134unsafe fn owned_to_mut<T>(owned: *mut (), ptr: *const u8, len: usize) -> BytesMut {
1135 BytesMut::from_vec(owned_to_vec::<T>(owned, ptr, len))
1136}
1137
1138unsafe fn owned_is_unique(_data: &AtomicPtr<()>) -> bool {
1139 false
1140}
1141
1142unsafe fn owned_drop_impl<T>(owned: *mut ()) {
1143 {
1144 let ref_cnt = &*owned.cast::<AtomicUsize>();
1145
1146 let old_cnt = ref_cnt.fetch_sub(1, Ordering::Release);
1147 debug_assert!(
1148 old_cnt > 0 && old_cnt <= usize::MAX >> 1,
1149 "expected non-zero refcount and no underflow"
1150 );
1151 if old_cnt != 1 {
1152 return;
1153 }
1154 ref_cnt.load(Ordering::Acquire);
1155 }
1156
1157 drop(Box::<Owned<T>>::from_raw(owned.cast()));
1158}
1159
1160unsafe fn owned_drop<T>(data: *mut (), _ptr: *const u8, _len: usize) {
1161 owned_drop_impl::<T>(data);
1162}
1163
1164static PROMOTABLE_EVEN_VTABLE: Vtable = Vtable {
1167 clone: promotable_even_clone,
1168 into_vec: promotable_even_to_vec,
1169 into_mut: promotable_even_to_mut,
1170 is_unique: promotable_is_unique,
1171 drop: promotable_even_drop,
1172};
1173
1174static PROMOTABLE_ODD_VTABLE: Vtable = Vtable {
1175 clone: promotable_odd_clone,
1176 into_vec: promotable_odd_to_vec,
1177 into_mut: promotable_odd_to_mut,
1178 is_unique: promotable_is_unique,
1179 drop: promotable_odd_drop,
1180};
1181
1182unsafe fn promotable_even_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1183 let shared = data.load(Ordering::Acquire);
1184 let kind = shared as usize & KIND_MASK;
1185
1186 if kind == KIND_ARC {
1187 shallow_clone_arc(shared.cast(), ptr, len)
1188 } else {
1189 debug_assert_eq!(kind, KIND_VEC);
1190 let buf = ptr_map(shared.cast(), |addr| addr & !KIND_MASK);
1191 shallow_clone_vec(data, shared, buf, ptr, len)
1192 }
1193}
1194
1195unsafe fn promotable_to_vec(
1196 shared: *mut (),
1197 ptr: *const u8,
1198 len: usize,
1199 f: fn(*mut ()) -> *mut u8,
1200) -> Vec<u8> {
1201 let kind = shared as usize & KIND_MASK;
1202
1203 if kind == KIND_ARC {
1204 shared_to_vec_impl(shared.cast(), ptr, len)
1205 } else {
1206 debug_assert_eq!(kind, KIND_VEC);
1208
1209 let buf = f(shared);
1210
1211 let cap = ptr.offset_from(buf) as usize + len;
1212
1213 ptr::copy(ptr, buf, len);
1215
1216 Vec::from_raw_parts(buf, len, cap)
1217 }
1218}
1219
1220unsafe fn promotable_to_mut(
1221 shared: *mut (),
1222 ptr: *const u8,
1223 len: usize,
1224 f: fn(*mut ()) -> *mut u8,
1225) -> BytesMut {
1226 let kind = shared as usize & KIND_MASK;
1227
1228 if kind == KIND_ARC {
1229 shared_to_mut_impl(shared.cast(), ptr, len)
1230 } else {
1231 debug_assert_eq!(kind, KIND_VEC);
1236
1237 let buf = f(shared);
1238 let off = ptr.offset_from(buf) as usize;
1239 let cap = off + len;
1240 let v = Vec::from_raw_parts(buf, cap, cap);
1241
1242 let mut b = BytesMut::from_vec(v);
1243 b.advance_unchecked(off);
1244 b
1245 }
1246}
1247
1248unsafe fn promotable_even_to_vec(shared: *mut (), ptr: *const u8, len: usize) -> Vec<u8> {
1249 promotable_to_vec(shared, ptr, len, |shared| {
1250 ptr_map(shared.cast(), |addr| addr & !KIND_MASK)
1251 })
1252}
1253
1254unsafe fn promotable_even_to_mut(shared: *mut (), ptr: *const u8, len: usize) -> BytesMut {
1255 promotable_to_mut(shared, ptr, len, |shared| {
1256 ptr_map(shared.cast(), |addr| addr & !KIND_MASK)
1257 })
1258}
1259
1260unsafe fn promotable_even_drop(shared: *mut (), ptr: *const u8, len: usize) {
1261 let kind = shared as usize & KIND_MASK;
1262
1263 if kind == KIND_ARC {
1264 release_shared(shared.cast());
1265 } else {
1266 debug_assert_eq!(kind, KIND_VEC);
1267 let buf = ptr_map(shared.cast(), |addr| addr & !KIND_MASK);
1268 free_boxed_slice(buf, ptr, len);
1269 }
1270}
1271
1272unsafe fn promotable_odd_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1273 let shared = data.load(Ordering::Acquire);
1274 let kind = shared as usize & KIND_MASK;
1275
1276 if kind == KIND_ARC {
1277 shallow_clone_arc(shared as _, ptr, len)
1278 } else {
1279 debug_assert_eq!(kind, KIND_VEC);
1280 shallow_clone_vec(data, shared, shared.cast(), ptr, len)
1281 }
1282}
1283
1284unsafe fn promotable_odd_to_vec(shared: *mut (), ptr: *const u8, len: usize) -> Vec<u8> {
1285 promotable_to_vec(shared, ptr, len, |shared| shared.cast())
1286}
1287
1288unsafe fn promotable_odd_to_mut(shared: *mut (), ptr: *const u8, len: usize) -> BytesMut {
1289 promotable_to_mut(shared, ptr, len, |shared| shared.cast())
1290}
1291
1292unsafe fn promotable_odd_drop(shared: *mut (), ptr: *const u8, len: usize) {
1293 let kind = shared as usize & KIND_MASK;
1294
1295 if kind == KIND_ARC {
1296 release_shared(shared.cast());
1297 } else {
1298 debug_assert_eq!(kind, KIND_VEC);
1299
1300 free_boxed_slice(shared.cast(), ptr, len);
1301 }
1302}
1303
1304unsafe fn promotable_is_unique(data: &AtomicPtr<()>) -> bool {
1305 let shared = data.load(Ordering::Acquire);
1306 let kind = shared as usize & KIND_MASK;
1307
1308 if kind == KIND_ARC {
1309 let ref_cnt = (*shared.cast::<Shared>()).ref_cnt.load(Ordering::Relaxed);
1310 ref_cnt == 1
1311 } else {
1312 true
1313 }
1314}
1315
1316unsafe fn free_boxed_slice(buf: *mut u8, offset: *const u8, len: usize) {
1317 let cap = offset.offset_from(buf) as usize + len;
1318 dealloc(buf, Layout::from_size_align(cap, 1).unwrap())
1319}
1320
1321struct Shared {
1324 buf: *mut u8,
1326 cap: usize,
1327 ref_cnt: AtomicUsize,
1328}
1329
1330impl Drop for Shared {
1331 fn drop(&mut self) {
1332 unsafe { dealloc(self.buf, Layout::from_size_align(self.cap, 1).unwrap()) }
1333 }
1334}
1335
1336const _: [(); 0 - mem::align_of::<Shared>() % 2] = []; static SHARED_VTABLE: Vtable = Vtable {
1343 clone: shared_clone,
1344 into_vec: shared_to_vec,
1345 into_mut: shared_to_mut,
1346 is_unique: shared_is_unique,
1347 drop: shared_drop,
1348};
1349
1350const KIND_ARC: usize = 0b0;
1351const KIND_VEC: usize = 0b1;
1352const KIND_MASK: usize = 0b1;
1353
1354unsafe fn shared_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1355 let shared = data.load(Ordering::Relaxed);
1356 shallow_clone_arc(shared as _, ptr, len)
1357}
1358
1359unsafe fn shared_to_vec_impl(shared: *mut Shared, ptr: *const u8, len: usize) -> Vec<u8> {
1360 if (*shared)
1367 .ref_cnt
1368 .compare_exchange(1, 0, Ordering::AcqRel, Ordering::Relaxed)
1369 .is_ok()
1370 {
1371 let shared = *Box::from_raw(shared);
1373 let shared = ManuallyDrop::new(shared);
1374 let buf = shared.buf;
1375 let cap = shared.cap;
1376
1377 ptr::copy(ptr, buf, len);
1379
1380 Vec::from_raw_parts(buf, len, cap)
1381 } else {
1382 let v = slice::from_raw_parts(ptr, len).to_vec();
1383 release_shared(shared);
1384 v
1385 }
1386}
1387
1388unsafe fn shared_to_vec(shared: *mut (), ptr: *const u8, len: usize) -> Vec<u8> {
1389 shared_to_vec_impl(shared.cast(), ptr, len)
1390}
1391
1392unsafe fn shared_to_mut_impl(shared: *mut Shared, ptr: *const u8, len: usize) -> BytesMut {
1393 if (*shared).ref_cnt.load(Ordering::Acquire) == 1 {
1406 let shared = *Box::from_raw(shared);
1408 let shared = ManuallyDrop::new(shared);
1409 let buf = shared.buf;
1410 let cap = shared.cap;
1411
1412 let off = ptr.offset_from(buf) as usize;
1414 let v = Vec::from_raw_parts(buf, len + off, cap);
1415
1416 let mut b = BytesMut::from_vec(v);
1417 b.advance_unchecked(off);
1418 b
1419 } else {
1420 let v = slice::from_raw_parts(ptr, len).to_vec();
1422 release_shared(shared);
1423 BytesMut::from_vec(v)
1424 }
1425}
1426
1427unsafe fn shared_to_mut(shared: *mut (), ptr: *const u8, len: usize) -> BytesMut {
1428 shared_to_mut_impl(shared.cast(), ptr, len)
1429}
1430
1431pub(crate) unsafe fn shared_is_unique(data: &AtomicPtr<()>) -> bool {
1432 let shared = data.load(Ordering::Acquire);
1433 let ref_cnt = (*shared.cast::<Shared>()).ref_cnt.load(Ordering::Relaxed);
1434 ref_cnt == 1
1435}
1436
1437unsafe fn shared_drop(shared: *mut (), _ptr: *const u8, _len: usize) {
1438 release_shared(shared.cast());
1439}
1440
1441unsafe fn shallow_clone_arc(shared: *mut Shared, ptr: *const u8, len: usize) -> Bytes {
1442 let old_size = (*shared).ref_cnt.fetch_add(1, Ordering::Relaxed);
1443
1444 if old_size > usize::MAX >> 1 {
1445 crate::abort();
1446 }
1447
1448 Bytes {
1449 ptr,
1450 len,
1451 data: AtomicPtr::new(shared as _),
1452 vtable: &SHARED_VTABLE,
1453 }
1454}
1455
1456#[cold]
1457unsafe fn shallow_clone_vec(
1458 atom: &AtomicPtr<()>,
1459 ptr: *const (),
1460 buf: *mut u8,
1461 offset: *const u8,
1462 len: usize,
1463) -> Bytes {
1464 let shared = Box::new(Shared {
1476 buf,
1477 cap: offset.offset_from(buf) as usize + len,
1478 ref_cnt: AtomicUsize::new(2),
1482 });
1483
1484 let shared = Box::into_raw(shared);
1485
1486 debug_assert!(
1489 0 == (shared as usize & KIND_MASK),
1490 "internal: Box<Shared> should have an aligned pointer",
1491 );
1492
1493 match atom.compare_exchange(ptr as _, shared as _, Ordering::AcqRel, Ordering::Acquire) {
1503 Ok(actual) => {
1504 debug_assert!(core::ptr::eq(actual, ptr));
1505 Bytes {
1508 ptr: offset,
1509 len,
1510 data: AtomicPtr::new(shared as _),
1511 vtable: &SHARED_VTABLE,
1512 }
1513 }
1514 Err(actual) => {
1515 let shared = Box::from_raw(shared);
1519 mem::forget(*shared);
1520
1521 shallow_clone_arc(actual as _, offset, len)
1524 }
1525 }
1526}
1527
1528unsafe fn release_shared(ptr: *mut Shared) {
1529 if (*ptr).ref_cnt.fetch_sub(1, Ordering::Release) != 1 {
1531 return;
1532 }
1533
1534 (*ptr).ref_cnt.load(Ordering::Acquire);
1555
1556 drop(Box::from_raw(ptr));
1558}
1559
1560#[cfg(miri)]
1567fn ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8
1568where
1569 F: FnOnce(usize) -> usize,
1570{
1571 let old_addr = ptr as usize;
1572 let new_addr = f(old_addr);
1573 let diff = new_addr.wrapping_sub(old_addr);
1574 ptr.wrapping_add(diff)
1575}
1576
1577#[cfg(not(miri))]
1578fn ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8
1579where
1580 F: FnOnce(usize) -> usize,
1581{
1582 let old_addr = ptr as usize;
1583 let new_addr = f(old_addr);
1584 new_addr as *mut u8
1585}
1586
1587fn without_provenance(ptr: usize) -> *const u8 {
1588 core::ptr::null::<u8>().wrapping_add(ptr)
1589}
1590
1591fn _split_to_must_use() {}
1602
1603fn _split_off_must_use() {}
1612
1613#[cfg(all(test, loom))]
1615mod fuzz {
1616 use loom::sync::Arc;
1617 use loom::thread;
1618
1619 use super::Bytes;
1620 #[test]
1621 fn bytes_cloning_vec() {
1622 loom::model(|| {
1623 let a = Bytes::from(b"abcdefgh".to_vec());
1624 let addr = a.as_ptr() as usize;
1625
1626 let a1 = Arc::new(a);
1628 let a2 = a1.clone();
1629
1630 let t1 = thread::spawn(move || {
1631 let b: Bytes = (*a1).clone();
1632 assert_eq!(b.as_ptr() as usize, addr);
1633 });
1634
1635 let t2 = thread::spawn(move || {
1636 let b: Bytes = (*a2).clone();
1637 assert_eq!(b.as_ptr() as usize, addr);
1638 });
1639
1640 t1.join().unwrap();
1641 t2.join().unwrap();
1642 });
1643 }
1644}