@@ -12,6 +12,7 @@ use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
12
12
use core:: borrow;
13
13
use core:: fmt;
14
14
use core:: cmp:: { self , Ordering } ;
15
+ use core:: iter;
15
16
use core:: intrinsics:: abort;
16
17
use core:: mem:: { self , align_of, align_of_val, size_of_val} ;
17
18
use core:: ops:: { Deref , Receiver , CoerceUnsized , DispatchFromDyn } ;
@@ -21,7 +22,7 @@ use core::marker::{Unpin, Unsize, PhantomData};
21
22
use core:: hash:: { Hash , Hasher } ;
22
23
use core:: { isize, usize} ;
23
24
use core:: convert:: From ;
24
- use core:: slice:: from_raw_parts_mut;
25
+ use core:: slice:: { self , from_raw_parts_mut} ;
25
26
26
27
use crate :: alloc:: { Global , Alloc , Layout , box_free, handle_alloc_error} ;
27
28
use crate :: boxed:: Box ;
@@ -587,21 +588,28 @@ impl<T: ?Sized> Arc<T> {
587
588
}
588
589
589
590
impl < T : ?Sized > Arc < T > {
590
- // Allocates an `ArcInner<T>` with sufficient space for an unsized value
591
- unsafe fn allocate_for_ptr ( ptr : * const T ) -> * mut ArcInner < T > {
592
- // Calculate layout using the given value.
591
+ // Allocates an `ArcInner<T>` with sufficient space for
592
+ // an unsized value where the value has the layout provided.
593
+ //
594
+ // The function `mem_to_arcinner` is called with the data pointer
595
+ // and must return back a (potentially fat)-pointer for the `ArcInner<T>`.
596
+ unsafe fn allocate_for_unsized (
597
+ value_layout : Layout ,
598
+ mem_to_arcinner : impl FnOnce ( * mut u8 ) -> * mut ArcInner < T >
599
+ ) -> * mut ArcInner < T > {
600
+ // Calculate layout using the given value layout.
593
601
// Previously, layout was calculated on the expression
594
602
// `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
595
603
// reference (see #54908).
596
604
let layout = Layout :: new :: < ArcInner < ( ) > > ( )
597
- . extend ( Layout :: for_value ( & * ptr ) ) . unwrap ( ) . 0
605
+ . extend ( value_layout ) . unwrap ( ) . 0
598
606
. pad_to_align ( ) . unwrap ( ) ;
599
607
600
608
let mem = Global . alloc ( layout)
601
609
. unwrap_or_else ( |_| handle_alloc_error ( layout) ) ;
602
610
603
611
// Initialize the ArcInner
604
- let inner = set_data_ptr ( ptr as * mut T , mem. as_ptr ( ) as * mut u8 ) as * mut ArcInner < T > ;
612
+ let inner = mem_to_arcinner ( mem. as_ptr ( ) ) ;
605
613
debug_assert_eq ! ( Layout :: for_value( & * inner) , layout) ;
606
614
607
615
ptr:: write ( & mut ( * inner) . strong , atomic:: AtomicUsize :: new ( 1 ) ) ;
@@ -610,6 +618,15 @@ impl<T: ?Sized> Arc<T> {
610
618
inner
611
619
}
612
620
621
+ // Allocates an `ArcInner<T>` with sufficient space for an unsized value
622
+ unsafe fn allocate_for_ptr ( ptr : * const T ) -> * mut ArcInner < T > {
623
+ // Allocate for the `ArcInner<T>` using the given value.
624
+ Self :: allocate_for_unsized (
625
+ Layout :: for_value ( & * ptr) ,
626
+ |mem| set_data_ptr ( ptr as * mut T , mem) as * mut ArcInner < T > ,
627
+ )
628
+ }
629
+
613
630
fn from_box ( v : Box < T > ) -> Arc < T > {
614
631
unsafe {
615
632
let box_unique = Box :: into_unique ( v) ;
@@ -632,6 +649,32 @@ impl<T: ?Sized> Arc<T> {
632
649
}
633
650
}
634
651
652
+ impl < T > Arc < [ T ] > {
653
+ // Allocates an `ArcInner<[T]>` with the given length.
654
+ unsafe fn allocate_for_slice ( len : usize ) -> * mut ArcInner < [ T ] > {
655
+ // FIXME(#60667): Deduplicate.
656
+ fn slice_from_raw_parts_mut < T > ( data : * mut T , len : usize ) -> * mut [ T ] {
657
+ #[ repr( C ) ]
658
+ union Repr < T > {
659
+ rust_mut : * mut [ T ] ,
660
+ raw : FatPtr < T > ,
661
+ }
662
+
663
+ #[ repr( C ) ]
664
+ struct FatPtr < T > {
665
+ data : * const T ,
666
+ len : usize ,
667
+ }
668
+ unsafe { Repr { raw : FatPtr { data, len } } . rust_mut }
669
+ }
670
+
671
+ Self :: allocate_for_unsized (
672
+ Layout :: array :: < T > ( len) . unwrap ( ) ,
673
+ |mem| slice_from_raw_parts_mut ( mem as * mut T , len) as * mut ArcInner < [ T ] > ,
674
+ )
675
+ }
676
+ }
677
+
635
678
// Sets the data pointer of a `?Sized` raw pointer.
636
679
//
637
680
// For a slice/trait object, this sets the `data` field and leaves the rest
@@ -646,8 +689,7 @@ impl<T> Arc<[T]> {
646
689
//
647
690
// Unsafe because the caller must either take ownership or bind `T: Copy`
648
691
unsafe fn copy_from_slice ( v : & [ T ] ) -> Arc < [ T ] > {
649
- let v_ptr = v as * const [ T ] ;
650
- let ptr = Self :: allocate_for_ptr ( v_ptr) ;
692
+ let ptr = Self :: allocate_for_slice ( v. len ( ) ) ;
651
693
652
694
ptr:: copy_nonoverlapping (
653
695
v. as_ptr ( ) ,
@@ -656,16 +698,11 @@ impl<T> Arc<[T]> {
656
698
657
699
Self :: from_ptr ( ptr)
658
700
}
659
- }
660
701
661
- // Specialization trait used for From<&[T]>
662
- trait ArcFromSlice < T > {
663
- fn from_slice ( slice : & [ T ] ) -> Self ;
664
- }
665
-
666
- impl < T : Clone > ArcFromSlice < T > for Arc < [ T ] > {
667
- #[ inline]
668
- default fn from_slice ( v : & [ T ] ) -> Self {
702
+ /// Constructs an `Arc<[T]>` from an iterator known to be of a certain size.
703
+ ///
704
+ /// Behavior is undefined should the size be wrong.
705
+ unsafe fn from_iter_exact ( iter : impl iter:: Iterator < Item = T > , len : usize ) -> Arc < [ T ] > {
669
706
// Panic guard while cloning T elements.
670
707
// In the event of a panic, elements that have been written
671
708
// into the new ArcInner will be dropped, then the memory freed.
@@ -687,32 +724,43 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
687
724
}
688
725
}
689
726
690
- unsafe {
691
- let v_ptr = v as * const [ T ] ;
692
- let ptr = Self :: allocate_for_ptr ( v_ptr) ;
727
+ let ptr = Self :: allocate_for_slice ( len) ;
728
+
729
+ let mem = ptr as * mut _ as * mut u8 ;
730
+ let layout = Layout :: for_value ( & * ptr) ;
693
731
694
- let mem = ptr as * mut _ as * mut u8 ;
695
- let layout = Layout :: for_value ( & * ptr) ;
732
+ // Pointer to first element
733
+ let elems = & mut ( * ptr) . data as * mut [ T ] as * mut T ;
696
734
697
- // Pointer to first element
698
- let elems = & mut ( * ptr) . data as * mut [ T ] as * mut T ;
735
+ let mut guard = Guard {
736
+ mem : NonNull :: new_unchecked ( mem) ,
737
+ elems,
738
+ layout,
739
+ n_elems : 0 ,
740
+ } ;
699
741
700
- let mut guard = Guard {
701
- mem : NonNull :: new_unchecked ( mem) ,
702
- elems : elems,
703
- layout : layout,
704
- n_elems : 0 ,
705
- } ;
742
+ for ( i, item) in iter. enumerate ( ) {
743
+ ptr:: write ( elems. add ( i) , item) ;
744
+ guard. n_elems += 1 ;
745
+ }
706
746
707
- for ( i, item) in v. iter ( ) . enumerate ( ) {
708
- ptr:: write ( elems. add ( i) , item. clone ( ) ) ;
709
- guard. n_elems += 1 ;
710
- }
747
+ // All clear. Forget the guard so it doesn't free the new ArcInner.
748
+ mem:: forget ( guard) ;
711
749
712
- // All clear. Forget the guard so it doesn't free the new ArcInner.
713
- mem:: forget ( guard) ;
750
+ Self :: from_ptr ( ptr)
751
+ }
752
+ }
714
753
715
- Self :: from_ptr ( ptr)
754
+ // Specialization trait used for From<&[T]>
755
+ trait ArcFromSlice < T > {
756
+ fn from_slice ( slice : & [ T ] ) -> Self ;
757
+ }
758
+
759
+ impl < T : Clone > ArcFromSlice < T > for Arc < [ T ] > {
760
+ #[ inline]
761
+ default fn from_slice ( v : & [ T ] ) -> Self {
762
+ unsafe {
763
+ Self :: from_iter_exact ( v. iter ( ) . cloned ( ) , v. len ( ) )
716
764
}
717
765
}
718
766
}
@@ -1792,9 +1840,88 @@ impl<T> From<Vec<T>> for Arc<[T]> {
1792
1840
}
1793
1841
1794
1842
#[ stable( feature = "shared_from_iter" , since = "1.37.0" ) ]
1795
- impl < T > core:: iter:: FromIterator < T > for Arc < [ T ] > {
1796
- fn from_iter < I : IntoIterator < Item = T > > ( iter : I ) -> Self {
1797
- iter. into_iter ( ) . collect :: < Vec < T > > ( ) . into ( )
1843
+ impl < T > iter:: FromIterator < T > for Arc < [ T ] > {
1844
+ /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`.
1845
+ ///
1846
+ /// # Performance characteristics
1847
+ ///
1848
+ /// ## The general case
1849
+ ///
1850
+ /// In the general case, collecting into `Arc<[T]>` is done by first
1851
+ /// collecting into a `Vec<T>`. That is, when writing the following:
1852
+ ///
1853
+ /// ```rust
1854
+ /// # use std::sync::Arc;
1855
+ /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect();
1856
+ /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
1857
+ /// ```
1858
+ ///
1859
+ /// this behaves as if we wrote:
1860
+ ///
1861
+ /// ```rust
1862
+ /// # use std::sync::Arc;
1863
+ /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0)
1864
+ /// .collect::<Vec<_>>() // The first set of allocations happens here.
1865
+ /// .into(); // A second allocation for `Arc<[T]>` happens here.
1866
+ /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
1867
+ /// ```
1868
+ ///
1869
+ /// This will allocate as many times as needed for constructing the `Vec<T>`
1870
+ /// and then it will allocate once for turning the `Vec<T>` into the `Arc<[T]>`.
1871
+ ///
1872
+ /// ## Iterators of known length
1873
+ ///
1874
+ /// When your `Iterator` implements `TrustedLen` and is of an exact size,
1875
+ /// a single allocation will be made for the `Arc<[T]>`. For example:
1876
+ ///
1877
+ /// ```rust
1878
+ /// # use std::sync::Arc;
1879
+ /// let evens: Arc<[u8]> = (0..10).collect(); // Just a single allocation happens here.
1880
+ /// # assert_eq!(&*evens, &*(0..10).collect::<Vec<_>>());
1881
+ /// ```
1882
+ fn from_iter < I : iter:: IntoIterator < Item = T > > ( iter : I ) -> Self {
1883
+ ArcFromIter :: from_iter ( iter. into_iter ( ) )
1884
+ }
1885
+ }
1886
+
1887
+ /// Specialization trait used for collecting into `Arc<[T]>`.
1888
+ trait ArcFromIter < T , I > {
1889
+ fn from_iter ( iter : I ) -> Self ;
1890
+ }
1891
+
1892
+ impl < T , I : Iterator < Item = T > > ArcFromIter < T , I > for Arc < [ T ] > {
1893
+ default fn from_iter ( iter : I ) -> Self {
1894
+ iter. collect :: < Vec < T > > ( ) . into ( )
1895
+ }
1896
+ }
1897
+
1898
+ impl < T , I : iter:: TrustedLen < Item = T > > ArcFromIter < T , I > for Arc < [ T ] > {
1899
+ default fn from_iter ( iter : I ) -> Self {
1900
+ // This is the case for a `TrustedLen` iterator.
1901
+ let ( low, high) = iter. size_hint ( ) ;
1902
+ if let Some ( high) = high {
1903
+ debug_assert_eq ! (
1904
+ low, high,
1905
+ "TrustedLen iterator's size hint is not exact: {:?}" ,
1906
+ ( low, high)
1907
+ ) ;
1908
+
1909
+ unsafe {
1910
+ // SAFETY: We need to ensure that the iterator has an exact length and we have.
1911
+ Arc :: from_iter_exact ( iter, low)
1912
+ }
1913
+ } else {
1914
+ // Fall back to normal implementation.
1915
+ iter. collect :: < Vec < T > > ( ) . into ( )
1916
+ }
1917
+ }
1918
+ }
1919
+
1920
+ impl < ' a , T : ' a + Clone > ArcFromIter < & ' a T , slice:: Iter < ' a , T > > for Arc < [ T ] > {
1921
+ fn from_iter ( iter : slice:: Iter < ' a , T > ) -> Self {
1922
+ // Delegate to `impl<T: Clone> From<&[T]> for Arc<[T]>`
1923
+ // which will use `ptr::copy_nonoverlapping`.
1924
+ iter. as_slice ( ) . into ( )
1798
1925
}
1799
1926
}
1800
1927
0 commit comments