1use core::mem::{self, ManuallyDrop, MaybeUninit};
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 if vec.len() == vec.capacity() {
951 return Bytes::from(vec.into_boxed_slice());
952 }
953
954 let shared = Box::new(MaybeUninit::<Shared>::uninit());
955 let mut vec = ManuallyDrop::new(vec);
956 let ptr = vec.as_mut_ptr();
957 let len = vec.len();
958 let cap = vec.capacity();
959
960 let shared = Shared::init_to_raw(
961 shared,
962 Shared {
963 buf: ptr,
964 cap,
965 ref_cnt: AtomicUsize::new(1),
966 },
967 );
968
969 debug_assert!(
972 0 == (shared as usize & KIND_MASK),
973 "internal: Box<Shared> should have an aligned pointer",
974 );
975 Bytes {
976 ptr,
977 len,
978 data: AtomicPtr::new(shared as _),
979 vtable: &SHARED_VTABLE,
980 }
981 }
982}
983
984impl From<Box<[u8]>> for Bytes {
985 fn from(slice: Box<[u8]>) -> Bytes {
986 if slice.is_empty() {
990 return Bytes::new();
991 }
992
993 let len = slice.len();
994 let ptr = Box::into_raw(slice) as *mut u8;
995
996 if ptr as usize & 0x1 == 0 {
997 let data = ptr_map(ptr, |addr| addr | KIND_VEC);
998 Bytes {
999 ptr,
1000 len,
1001 data: AtomicPtr::new(data.cast()),
1002 vtable: &PROMOTABLE_EVEN_VTABLE,
1003 }
1004 } else {
1005 Bytes {
1006 ptr,
1007 len,
1008 data: AtomicPtr::new(ptr.cast()),
1009 vtable: &PROMOTABLE_ODD_VTABLE,
1010 }
1011 }
1012 }
1013}
1014
1015impl From<Bytes> for BytesMut {
1016 fn from(bytes: Bytes) -> Self {
1032 let mut bytes = ManuallyDrop::new(bytes);
1033 let data = bytes.data_mut();
1034 unsafe { (bytes.vtable.into_mut)(data, bytes.ptr, bytes.len) }
1035 }
1036}
1037
1038impl From<String> for Bytes {
1039 fn from(s: String) -> Bytes {
1040 Bytes::from(s.into_bytes())
1041 }
1042}
1043
1044impl From<Bytes> for Vec<u8> {
1045 fn from(bytes: Bytes) -> Vec<u8> {
1046 let mut bytes = ManuallyDrop::new(bytes);
1047 let data = bytes.data_mut();
1048 unsafe { (bytes.vtable.into_vec)(data, bytes.ptr, bytes.len) }
1049 }
1050}
1051
1052impl fmt::Debug for Vtable {
1055 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1056 f.debug_struct("Vtable")
1057 .field("clone", &(self.clone as *const ()))
1058 .field("drop", &(self.drop as *const ()))
1059 .finish()
1060 }
1061}
1062
1063const STATIC_VTABLE: Vtable = Vtable {
1066 clone: static_clone,
1067 into_vec: static_to_vec,
1068 into_mut: static_to_mut,
1069 is_unique: static_is_unique,
1070 drop: static_drop,
1071};
1072
1073unsafe fn static_clone(_: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1074 let slice = slice::from_raw_parts(ptr, len);
1075 Bytes::from_static(slice)
1076}
1077
1078unsafe fn static_to_vec(_: *mut (), ptr: *const u8, len: usize) -> Vec<u8> {
1079 let slice = slice::from_raw_parts(ptr, len);
1080 slice.to_vec()
1081}
1082
1083unsafe fn static_to_mut(_: *mut (), ptr: *const u8, len: usize) -> BytesMut {
1084 let slice = slice::from_raw_parts(ptr, len);
1085 BytesMut::from(slice)
1086}
1087
1088fn static_is_unique(_: &AtomicPtr<()>) -> bool {
1089 false
1090}
1091
1092unsafe fn static_drop(_: *mut (), _: *const u8, _: usize) {
1093 }
1095
1096#[repr(C)]
1099struct Owned<T> {
1100 ref_cnt: AtomicUsize,
1101 owner: T,
1102}
1103
1104impl<T> Owned<T> {
1105 const VTABLE: Vtable = Vtable {
1106 clone: owned_clone::<T>,
1107 into_vec: owned_to_vec::<T>,
1108 into_mut: owned_to_mut::<T>,
1109 is_unique: owned_is_unique,
1110 drop: owned_drop::<T>,
1111 };
1112}
1113
1114unsafe fn owned_clone<T>(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1115 let owned = data.load(Ordering::Relaxed);
1116 let old_cnt = (*owned.cast::<AtomicUsize>()).fetch_add(1, Ordering::Relaxed);
1117 if old_cnt > usize::MAX >> 1 {
1118 crate::abort();
1119 }
1120
1121 Bytes {
1122 ptr,
1123 len,
1124 data: AtomicPtr::new(owned as _),
1125 vtable: &Owned::<T>::VTABLE,
1126 }
1127}
1128
1129unsafe fn owned_to_vec<T>(owned: *mut (), ptr: *const u8, len: usize) -> Vec<u8> {
1130 let slice = slice::from_raw_parts(ptr, len);
1131 let vec = slice.to_vec();
1132 owned_drop_impl::<T>(owned);
1133 vec
1134}
1135
1136unsafe fn owned_to_mut<T>(owned: *mut (), ptr: *const u8, len: usize) -> BytesMut {
1137 BytesMut::from_vec(owned_to_vec::<T>(owned, ptr, len))
1138}
1139
1140unsafe fn owned_is_unique(_data: &AtomicPtr<()>) -> bool {
1141 false
1142}
1143
1144unsafe fn owned_drop_impl<T>(owned: *mut ()) {
1145 {
1146 let ref_cnt = &*owned.cast::<AtomicUsize>();
1147
1148 let old_cnt = ref_cnt.fetch_sub(1, Ordering::Release);
1149 debug_assert!(
1150 old_cnt > 0 && old_cnt <= usize::MAX >> 1,
1151 "expected non-zero refcount and no underflow"
1152 );
1153 if old_cnt != 1 {
1154 return;
1155 }
1156 ref_cnt.load(Ordering::Acquire);
1157 }
1158
1159 drop(Box::<Owned<T>>::from_raw(owned.cast()));
1160}
1161
1162unsafe fn owned_drop<T>(data: *mut (), _ptr: *const u8, _len: usize) {
1163 owned_drop_impl::<T>(data);
1164}
1165
1166static PROMOTABLE_EVEN_VTABLE: Vtable = Vtable {
1169 clone: promotable_even_clone,
1170 into_vec: promotable_even_to_vec,
1171 into_mut: promotable_even_to_mut,
1172 is_unique: promotable_is_unique,
1173 drop: promotable_even_drop,
1174};
1175
1176static PROMOTABLE_ODD_VTABLE: Vtable = Vtable {
1177 clone: promotable_odd_clone,
1178 into_vec: promotable_odd_to_vec,
1179 into_mut: promotable_odd_to_mut,
1180 is_unique: promotable_is_unique,
1181 drop: promotable_odd_drop,
1182};
1183
1184unsafe fn promotable_even_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1185 let shared = data.load(Ordering::Acquire);
1186 let kind = shared as usize & KIND_MASK;
1187
1188 if kind == KIND_ARC {
1189 shallow_clone_arc(shared.cast(), ptr, len)
1190 } else {
1191 debug_assert_eq!(kind, KIND_VEC);
1192 let buf = ptr_map(shared.cast(), |addr| addr & !KIND_MASK);
1193 shallow_clone_vec(data, shared, buf, ptr, len)
1194 }
1195}
1196
1197unsafe fn promotable_to_vec(
1198 shared: *mut (),
1199 ptr: *const u8,
1200 len: usize,
1201 f: fn(*mut ()) -> *mut u8,
1202) -> Vec<u8> {
1203 let kind = shared as usize & KIND_MASK;
1204
1205 if kind == KIND_ARC {
1206 shared_to_vec_impl(shared.cast(), ptr, len)
1207 } else {
1208 debug_assert_eq!(kind, KIND_VEC);
1210
1211 let buf = f(shared);
1212
1213 let cap = ptr.offset_from(buf) as usize + len;
1214
1215 ptr::copy(ptr, buf, len);
1217
1218 Vec::from_raw_parts(buf, len, cap)
1219 }
1220}
1221
1222unsafe fn promotable_to_mut(
1223 shared: *mut (),
1224 ptr: *const u8,
1225 len: usize,
1226 f: fn(*mut ()) -> *mut u8,
1227) -> BytesMut {
1228 let kind = shared as usize & KIND_MASK;
1229
1230 if kind == KIND_ARC {
1231 shared_to_mut_impl(shared.cast(), ptr, len)
1232 } else {
1233 debug_assert_eq!(kind, KIND_VEC);
1238
1239 let buf = f(shared);
1240 let off = ptr.offset_from(buf) as usize;
1241 let cap = off + len;
1242 let v = Vec::from_raw_parts(buf, cap, cap);
1243
1244 let mut b = BytesMut::from_vec(v);
1245 b.advance_unchecked(off);
1246 b
1247 }
1248}
1249
1250unsafe fn promotable_even_to_vec(shared: *mut (), ptr: *const u8, len: usize) -> Vec<u8> {
1251 promotable_to_vec(shared, ptr, len, |shared| {
1252 ptr_map(shared.cast(), |addr| addr & !KIND_MASK)
1253 })
1254}
1255
1256unsafe fn promotable_even_to_mut(shared: *mut (), ptr: *const u8, len: usize) -> BytesMut {
1257 promotable_to_mut(shared, ptr, len, |shared| {
1258 ptr_map(shared.cast(), |addr| addr & !KIND_MASK)
1259 })
1260}
1261
1262unsafe fn promotable_even_drop(shared: *mut (), ptr: *const u8, len: usize) {
1263 let kind = shared as usize & KIND_MASK;
1264
1265 if kind == KIND_ARC {
1266 release_shared(shared.cast());
1267 } else {
1268 debug_assert_eq!(kind, KIND_VEC);
1269 let buf = ptr_map(shared.cast(), |addr| addr & !KIND_MASK);
1270 free_boxed_slice(buf, ptr, len);
1271 }
1272}
1273
1274unsafe fn promotable_odd_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1275 let shared = data.load(Ordering::Acquire);
1276 let kind = shared as usize & KIND_MASK;
1277
1278 if kind == KIND_ARC {
1279 shallow_clone_arc(shared as _, ptr, len)
1280 } else {
1281 debug_assert_eq!(kind, KIND_VEC);
1282 shallow_clone_vec(data, shared, shared.cast(), ptr, len)
1283 }
1284}
1285
1286unsafe fn promotable_odd_to_vec(shared: *mut (), ptr: *const u8, len: usize) -> Vec<u8> {
1287 promotable_to_vec(shared, ptr, len, |shared| shared.cast())
1288}
1289
1290unsafe fn promotable_odd_to_mut(shared: *mut (), ptr: *const u8, len: usize) -> BytesMut {
1291 promotable_to_mut(shared, ptr, len, |shared| shared.cast())
1292}
1293
1294unsafe fn promotable_odd_drop(shared: *mut (), ptr: *const u8, len: usize) {
1295 let kind = shared as usize & KIND_MASK;
1296
1297 if kind == KIND_ARC {
1298 release_shared(shared.cast());
1299 } else {
1300 debug_assert_eq!(kind, KIND_VEC);
1301
1302 free_boxed_slice(shared.cast(), ptr, len);
1303 }
1304}
1305
1306unsafe fn promotable_is_unique(data: &AtomicPtr<()>) -> bool {
1307 let shared = data.load(Ordering::Acquire);
1308 let kind = shared as usize & KIND_MASK;
1309
1310 if kind == KIND_ARC {
1311 let ref_cnt = (*shared.cast::<Shared>()).ref_cnt.load(Ordering::Relaxed);
1312 ref_cnt == 1
1313 } else {
1314 true
1315 }
1316}
1317
1318unsafe fn free_boxed_slice(buf: *mut u8, offset: *const u8, len: usize) {
1319 let cap = offset.offset_from(buf) as usize + len;
1320 dealloc(buf, Layout::from_size_align(cap, 1).unwrap())
1321}
1322
1323struct Shared {
1326 buf: *mut u8,
1328 cap: usize,
1329 ref_cnt: AtomicUsize,
1330}
1331
1332impl Shared {
1333 fn init_to_raw(b: Box<MaybeUninit<Self>>, v: Self) -> *mut Self {
1334 let shared = Box::into_raw(b).cast::<Self>();
1335 unsafe { shared.write(v) };
1337 shared
1338 }
1339}
1340
1341impl Drop for Shared {
1342 fn drop(&mut self) {
1343 unsafe { dealloc(self.buf, Layout::from_size_align(self.cap, 1).unwrap()) }
1344 }
1345}
1346
1347const _: [(); 0 - mem::align_of::<Shared>() % 2] = []; static SHARED_VTABLE: Vtable = Vtable {
1354 clone: shared_clone,
1355 into_vec: shared_to_vec,
1356 into_mut: shared_to_mut,
1357 is_unique: shared_is_unique,
1358 drop: shared_drop,
1359};
1360
1361const KIND_ARC: usize = 0b0;
1362const KIND_VEC: usize = 0b1;
1363const KIND_MASK: usize = 0b1;
1364
1365unsafe fn shared_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
1366 let shared = data.load(Ordering::Relaxed);
1367 shallow_clone_arc(shared as _, ptr, len)
1368}
1369
1370unsafe fn shared_to_vec_impl(shared: *mut Shared, ptr: *const u8, len: usize) -> Vec<u8> {
1371 if (*shared)
1378 .ref_cnt
1379 .compare_exchange(1, 0, Ordering::AcqRel, Ordering::Relaxed)
1380 .is_ok()
1381 {
1382 let shared = *Box::from_raw(shared);
1384 let shared = ManuallyDrop::new(shared);
1385 let buf = shared.buf;
1386 let cap = shared.cap;
1387
1388 ptr::copy(ptr, buf, len);
1390
1391 Vec::from_raw_parts(buf, len, cap)
1392 } else {
1393 let v = slice::from_raw_parts(ptr, len).to_vec();
1394 release_shared(shared);
1395 v
1396 }
1397}
1398
1399unsafe fn shared_to_vec(shared: *mut (), ptr: *const u8, len: usize) -> Vec<u8> {
1400 shared_to_vec_impl(shared.cast(), ptr, len)
1401}
1402
1403unsafe fn shared_to_mut_impl(shared: *mut Shared, ptr: *const u8, len: usize) -> BytesMut {
1404 if (*shared).ref_cnt.load(Ordering::Acquire) == 1 {
1417 let shared = *Box::from_raw(shared);
1419 let shared = ManuallyDrop::new(shared);
1420 let buf = shared.buf;
1421 let cap = shared.cap;
1422
1423 let off = ptr.offset_from(buf) as usize;
1425 let v = Vec::from_raw_parts(buf, len + off, cap);
1426
1427 let mut b = BytesMut::from_vec(v);
1428 b.advance_unchecked(off);
1429 b
1430 } else {
1431 let v = slice::from_raw_parts(ptr, len).to_vec();
1433 release_shared(shared);
1434 BytesMut::from_vec(v)
1435 }
1436}
1437
1438unsafe fn shared_to_mut(shared: *mut (), ptr: *const u8, len: usize) -> BytesMut {
1439 shared_to_mut_impl(shared.cast(), ptr, len)
1440}
1441
1442pub(crate) unsafe fn shared_is_unique(data: &AtomicPtr<()>) -> bool {
1443 let shared = data.load(Ordering::Acquire);
1444 let ref_cnt = (*shared.cast::<Shared>()).ref_cnt.load(Ordering::Relaxed);
1445 ref_cnt == 1
1446}
1447
1448unsafe fn shared_drop(shared: *mut (), _ptr: *const u8, _len: usize) {
1449 release_shared(shared.cast());
1450}
1451
1452unsafe fn shallow_clone_arc(shared: *mut Shared, ptr: *const u8, len: usize) -> Bytes {
1453 let old_size = (*shared).ref_cnt.fetch_add(1, Ordering::Relaxed);
1454
1455 if old_size > usize::MAX >> 1 {
1456 crate::abort();
1457 }
1458
1459 Bytes {
1460 ptr,
1461 len,
1462 data: AtomicPtr::new(shared as _),
1463 vtable: &SHARED_VTABLE,
1464 }
1465}
1466
1467#[cold]
1468unsafe fn shallow_clone_vec(
1469 atom: &AtomicPtr<()>,
1470 ptr: *const (),
1471 buf: *mut u8,
1472 offset: *const u8,
1473 len: usize,
1474) -> Bytes {
1475 let shared = Box::new(MaybeUninit::<Shared>::uninit());
1487 let shared = Shared::init_to_raw(
1488 shared,
1489 Shared {
1490 buf,
1491 cap: offset.offset_from(buf) as usize + len,
1492 ref_cnt: AtomicUsize::new(2),
1496 },
1497 );
1498
1499 debug_assert!(
1502 0 == (shared as usize & KIND_MASK),
1503 "internal: Box<Shared> should have an aligned pointer",
1504 );
1505
1506 match atom.compare_exchange(ptr as _, shared as _, Ordering::AcqRel, Ordering::Acquire) {
1516 Ok(actual) => {
1517 debug_assert!(core::ptr::eq(actual, ptr));
1518 Bytes {
1521 ptr: offset,
1522 len,
1523 data: AtomicPtr::new(shared as _),
1524 vtable: &SHARED_VTABLE,
1525 }
1526 }
1527 Err(actual) => {
1528 let shared = Box::from_raw(shared);
1532 mem::forget(*shared);
1533
1534 shallow_clone_arc(actual as _, offset, len)
1537 }
1538 }
1539}
1540
1541unsafe fn release_shared(ptr: *mut Shared) {
1542 if (*ptr).ref_cnt.fetch_sub(1, Ordering::Release) != 1 {
1544 return;
1545 }
1546
1547 (*ptr).ref_cnt.load(Ordering::Acquire);
1568
1569 drop(Box::from_raw(ptr));
1571}
1572
1573#[cfg(miri)]
1580fn ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8
1581where
1582 F: FnOnce(usize) -> usize,
1583{
1584 let old_addr = ptr as usize;
1585 let new_addr = f(old_addr);
1586 let diff = new_addr.wrapping_sub(old_addr);
1587 ptr.wrapping_add(diff)
1588}
1589
1590#[cfg(not(miri))]
1591fn ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8
1592where
1593 F: FnOnce(usize) -> usize,
1594{
1595 let old_addr = ptr as usize;
1596 let new_addr = f(old_addr);
1597 new_addr as *mut u8
1598}
1599
1600fn without_provenance(ptr: usize) -> *const u8 {
1601 core::ptr::null::<u8>().wrapping_add(ptr)
1602}
1603
1604fn _split_to_must_use() {}
1615
1616fn _split_off_must_use() {}
1625
1626#[cfg(all(test, loom))]
1628mod fuzz {
1629 use loom::sync::Arc;
1630 use loom::thread;
1631
1632 use super::Bytes;
1633 #[test]
1634 fn bytes_cloning_vec() {
1635 loom::model(|| {
1636 let a = Bytes::from(b"abcdefgh".to_vec());
1637 let addr = a.as_ptr() as usize;
1638
1639 let a1 = Arc::new(a);
1641 let a2 = a1.clone();
1642
1643 let t1 = thread::spawn(move || {
1644 let b: Bytes = (*a1).clone();
1645 assert_eq!(b.as_ptr() as usize, addr);
1646 });
1647
1648 let t2 = thread::spawn(move || {
1649 let b: Bytes = (*a2).clone();
1650 assert_eq!(b.as_ptr() as usize, addr);
1651 });
1652
1653 t1.join().unwrap();
1654 t2.join().unwrap();
1655 });
1656 }
1657}