diff options
| author | Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> | 2017-04-20 15:08:41 +0300 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2017-04-22 21:00:50 +0300 |
| commit | ece6c8434bc4eba1d3addfa4d5900264e55395fc (patch) | |
| tree | 5fe4185c3ba908c2eb5c9660111eb18f9d4918f1 /src/liballoc/rc.rs | |
| parent | acd0e40b86d718d339b13f594242575c28e966f7 (diff) | |
| download | rust-ece6c8434bc4eba1d3addfa4d5900264e55395fc.tar.gz rust-ece6c8434bc4eba1d3addfa4d5900264e55395fc.zip | |
cache attributes of items from foreign crates
this avoids parsing item attributes on each call to `item_attrs`, which takes off 33% (!) of translation time and 50% (!) of trans-item collection time.
Diffstat (limited to 'src/liballoc/rc.rs')
| -rw-r--r-- | src/liballoc/rc.rs | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index fed718e9be4..69e5351cad5 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -239,7 +239,7 @@ use core::ops::CoerceUnsized; use core::ptr::{self, Shared}; use core::convert::From; -use heap::deallocate; +use heap::{allocate, deallocate, box_free}; use raw_vec::RawVec; struct RcBox<T: ?Sized> { @@ -248,7 +248,6 @@ struct RcBox<T: ?Sized> { value: T, } - /// A single-threaded reference-counting pointer. /// /// See the [module-level documentation](./index.html) for more details. @@ -438,6 +437,38 @@ impl Rc<str> { } } +impl<T> Rc<[T]> { + /// Constructs a new `Rc<[T]>` from a `Box<[T]>`. + #[doc(hidden)] + #[unstable(feature = "rustc_private", + reason = "for internal use in rustc", + issue = "0")] + pub fn __from_array(value: Box<[T]>) -> Rc<[T]> { + unsafe { + let ptr: *mut RcBox<[T]> = + mem::transmute([mem::align_of::<RcBox<[T; 1]>>(), value.len()]); + // FIXME(custom-DST): creating this invalid &[T] is dubiously defined, + // we should have a better way of getting the size/align + // of a DST from its unsized part. + let ptr = allocate(size_of_val(&*ptr), align_of_val(&*ptr)); + let ptr: *mut RcBox<[T]> = mem::transmute([ptr as usize, value.len()]); + + // Initialize the new RcBox. + ptr::write(&mut (*ptr).strong, Cell::new(1)); + ptr::write(&mut (*ptr).weak, Cell::new(1)); + ptr::copy_nonoverlapping( + value.as_ptr(), + &mut (*ptr).value as *mut [T] as *mut T, + value.len()); + + // Free the original allocation without freeing its (moved) contents. + box_free(Box::into_raw(value)); + + Rc { ptr: Shared::new(ptr as *const _) } + } + } +} + impl<T: ?Sized> Rc<T> { /// Creates a new [`Weak`][weak] pointer to this value. /// |
