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.
This commit is contained in:
committed by
Ariel Ben-Yehuda
parent
acd0e40b86
commit
ece6c8434b
@@ -16,7 +16,6 @@
|
||||
issue = "27700")]
|
||||
|
||||
use core::{isize, usize};
|
||||
#[cfg(not(test))]
|
||||
use core::intrinsics::{min_align_of_val, size_of_val};
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
@@ -158,10 +157,9 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[lang = "box_free"]
|
||||
#[cfg_attr(not(test), lang = "box_free")]
|
||||
#[inline]
|
||||
unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
|
||||
pub(crate) unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
|
||||
let size = size_of_val(&*ptr);
|
||||
let align = min_align_of_val(&*ptr);
|
||||
// We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
#![feature(needs_allocator)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(placement_in_syntax)]
|
||||
#![cfg_attr(stage0, feature(pub_restricted))]
|
||||
#![feature(shared)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user