diff --git a/components/servo_arc/lib.rs b/components/servo_arc/lib.rs index 53c7d7aaa31..089aa60f031 100644 --- a/components/servo_arc/lib.rs +++ b/components/servo_arc/lib.rs @@ -34,7 +34,7 @@ use nodrop::NoDrop; #[cfg(feature = "servo")] use serde::{Deserialize, Serialize}; use stable_deref_trait::{CloneStableDeref, StableDeref}; -use std::alloc::Layout; +use std::alloc::{self, Layout}; use std::borrow; use std::cmp::Ordering; use std::convert::From; @@ -134,6 +134,23 @@ impl UniqueArc { UniqueArc(Arc::new(data)) } + /// Construct an uninitialized arc + #[inline] + pub fn new_uninit() -> UniqueArc> { + unsafe { + let layout = Layout::new::>>(); + let ptr = alloc::alloc(layout); + let mut p = ptr::NonNull::new(ptr) + .unwrap_or_else(|| alloc::handle_alloc_error(layout)) + .cast::>>(); + ptr::write(&mut p.as_mut().count, atomic::AtomicUsize::new(1)); + UniqueArc(Arc { + p, + phantom: PhantomData, + }) + } + } + #[inline] /// Convert to a shareable Arc once we're done mutating it pub fn shareable(self) -> Arc { @@ -141,6 +158,17 @@ impl UniqueArc { } } +impl UniqueArc> { + /// Convert to an initialized Arc. + #[inline] + pub unsafe fn assume_init(this: Self) -> UniqueArc { + UniqueArc(Arc { + p: this.0.p.cast(), + phantom: PhantomData, + }) + } +} + impl Deref for UniqueArc { type Target = T; fn deref(&self) -> &T {