From 20c72c8ccb9cdb18237111119952f974a6e82689 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 23 May 2014 15:45:07 +0100 Subject: [PATCH] Remove CowArc and use the new Arc::make_unique() method instead. --- src/components/main/layout/floats.rs | 11 +-- src/components/style/properties.rs.mako | 49 +++++++----- src/components/util/cowarc.rs | 100 ------------------------ src/components/util/util.rs | 1 - 4 files changed, 37 insertions(+), 124 deletions(-) delete mode 100644 src/components/util/cowarc.rs diff --git a/src/components/main/layout/floats.rs b/src/components/main/layout/floats.rs index 4f58da33e33..e743498647c 100644 --- a/src/components/main/layout/floats.rs +++ b/src/components/main/layout/floats.rs @@ -5,10 +5,10 @@ use geom::point::Point2D; use geom::rect::Rect; use geom::size::Size2D; -use servo_util::cowarc::CowArc; use servo_util::geometry::{Au, max, min}; use std::i32; use style::computed_values::float; +use sync::Arc; /// The kind of float: left or right. #[deriving(Clone)] @@ -69,7 +69,7 @@ impl FloatList { /// FIXME(pcwalton): When we have fast `MutexArc`s, try removing `CowArc` and use a mutex instead. #[deriving(Clone)] struct FloatListRef { - list: Option>, + list: Option>, } impl FloatListRef { @@ -89,16 +89,17 @@ impl FloatListRef { fn get<'a>(&'a self) -> Option<&'a FloatList> { match self.list { None => None, - Some(ref list) => Some(list.get()), + Some(ref list) => Some(&**list), } } + #[allow(experimental)] #[inline] fn get_mut<'a>(&'a mut self) -> &'a mut FloatList { if self.list.is_none() { - self.list = Some(CowArc::new(FloatList::new())) + self.list = Some(Arc::new(FloatList::new())) } - self.list.as_mut().unwrap().get_mut() + self.list.as_mut().unwrap().make_unique() } } diff --git a/src/components/style/properties.rs.mako b/src/components/style/properties.rs.mako index 658d43089f3..0df1700ca6f 100644 --- a/src/components/style/properties.rs.mako +++ b/src/components/style/properties.rs.mako @@ -10,7 +10,6 @@ use serialize::{Encodable, Encoder}; pub use servo_util::url::parse_url; use sync::Arc; pub use url::Url; -use servo_util::cowarc::CowArc; pub use cssparser::*; pub use cssparser::ast::*; @@ -1577,10 +1576,10 @@ pub mod style_structs { % endfor } -#[deriving(Eq, Clone)] +#[deriving(Clone)] pub struct ComputedValues { % for style_struct in STYLE_STRUCTS: - ${style_struct.ident}: CowArc, + ${style_struct.ident}: Arc, % endfor shareable: bool, } @@ -1603,7 +1602,7 @@ impl ComputedValues { % for style_struct in STYLE_STRUCTS: pub fn get_${style_struct.name.lower()} <'a>(&'a self) -> &'a style_structs::${style_struct.name} { - self.${style_struct.ident}.get() + &*self.${style_struct.ident} } % endfor } @@ -1612,7 +1611,7 @@ impl ComputedValues { lazy_init! { static ref INITIAL_VALUES: ComputedValues = ComputedValues { % for style_struct in STYLE_STRUCTS: - ${style_struct.ident}: CowArc::new(style_structs::${style_struct.name} { + ${style_struct.ident}: Arc::new(style_structs::${style_struct.name} { % for longhand in style_struct.longhands: ${longhand.ident}: longhands::${longhand.ident}::get_initial_value(), % endfor @@ -1622,6 +1621,20 @@ lazy_init! { }; } + +/// This only exists to limit the scope of #[allow(experimental)] +/// FIXME: remove this when Arc::make_unique() is not experimental anymore. +trait ArcExperimental { + fn make_unique_experimental<'a>(&'a mut self) -> &'a mut T; +} +impl ArcExperimental for Arc { + #[inline] + #[allow(experimental)] + fn make_unique_experimental<'a>(&'a mut self) -> &'a mut T { + self.make_unique() + } +} + /// Fast path for the function below. Only computes new inherited styles. fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty], shareable: bool, @@ -1667,18 +1680,18 @@ fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty], // // FIXME: is it still? parent_style.${style_struct.ident} - .get() .${property.ident} .clone() } }; - style_${style_struct.ident}.get_mut().${property.ident} = - computed_value; + style_${style_struct.ident}.make_unique_experimental() + .${property.ident} = computed_value; % if property.name in DERIVED_LONGHANDS: % for derived in DERIVED_LONGHANDS[property.name]: - style_${derived.style_struct.ident}.get_mut() - .${derived.ident} = + style_${derived.style_struct.ident} + .make_unique_experimental() + .${derived.ident} = longhands::${derived.ident} ::derive_from_${property.ident}( computed_value, @@ -1870,18 +1883,18 @@ pub fn cascade(applicable_declarations: &[MatchedProperty], // FIXME: is it still? cacheable = false; inherited_style.${style_struct.ident} - .get() .${property.ident} .clone() } }; - style_${style_struct.ident}.get_mut().${property.ident} = - computed_value; + style_${style_struct.ident}.make_unique_experimental() + .${property.ident} = computed_value; % if property.name in DERIVED_LONGHANDS: % for derived in DERIVED_LONGHANDS[property.name]: - style_${derived.style_struct.ident}.get_mut() - .${derived.ident} = + style_${derived.style_struct.ident} + .make_unique_experimental() + .${derived.ident} = longhands::${derived.ident} ::derive_from_${property.ident}( computed_value, @@ -1902,7 +1915,7 @@ pub fn cascade(applicable_declarations: &[MatchedProperty], // The initial value of border-*-width may be changed at computed value time. { - let border = style_border.get_mut(); + let border = style_border.make_unique_experimental(); % for side in ["top", "right", "bottom", "left"]: // Like calling to_computed_value, which wouldn't type check. if !context.border_${side}_present { @@ -1913,7 +1926,7 @@ pub fn cascade(applicable_declarations: &[MatchedProperty], // The initial value of display may be changed at computed value time. if !seen.get_display() { - let box_ = style_box_.get_mut(); + let box_ = style_box_.make_unique_experimental(); box_.display = longhands::display::to_computed_value(box_.display, &context); } @@ -1945,7 +1958,7 @@ pub fn cascade_anonymous(parent_style: &ComputedValues) -> ComputedValues { shareable: false, }; { - let border = result.border.get_mut(); + let border = result.border.make_unique_experimental(); % for side in ["top", "right", "bottom", "left"]: // Like calling to_computed_value, which wouldn't type check. border.border_${side}_width = Au(0); diff --git a/src/components/util/cowarc.rs b/src/components/util/cowarc.rs deleted file mode 100644 index dbd6709cfcf..00000000000 --- a/src/components/util/cowarc.rs +++ /dev/null @@ -1,100 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -//! An atomically reference counted type that copies itself on mutation. - -use std::cast; -use std::ptr; -use std::sync::atomics::{AtomicUint, SeqCst}; - -struct CowArcAlloc { - ref_count: AtomicUint, - data: T, -} - -#[unsafe_no_drop_flag] -pub struct CowArc { - ptr: *mut CowArcAlloc, -} - -#[unsafe_destructor] -impl Drop for CowArc { - #[inline] - fn drop(&mut self) { - unsafe { - if self.ptr != ptr::mut_null() && (*self.ptr).ref_count.fetch_sub(1, SeqCst) == 1 { - let _kill_it: Box> = cast::transmute(self.ptr); - self.ptr = ptr::mut_null() - } - } - } -} - -impl Eq for CowArc { - fn eq(&self, other: &CowArc) -> bool { - self.get() == other.get() - } -} - -impl Clone for CowArc { - #[inline] - fn clone(&self) -> CowArc { - unsafe { - drop((*self.ptr).ref_count.fetch_add(1, SeqCst)); - } - CowArc { - ptr: self.ptr - } - } -} - -impl CowArc { - #[inline] - pub fn new(value: T) -> CowArc { - let alloc = box CowArcAlloc { - ref_count: AtomicUint::new(1), - data: value, - }; - unsafe { - CowArc { - ptr: cast::transmute(alloc), - } - } - } - - #[inline] - pub fn shared(&self) -> bool { - unsafe { - (*self.ptr).ref_count.load(SeqCst) != 1 - } - } - - #[inline] - pub fn get<'a>(&'a self) -> &'a T { - unsafe { - cast::transmute(&(*self.ptr).data) - } - } - - #[inline(always)] - pub fn get_mut<'a>(&'a mut self) -> &'a mut T { - unsafe { - if (*self.ptr).ref_count.load(SeqCst) == 1 { - return cast::transmute(&mut (*self.ptr).data) - } - - let copy = box CowArcAlloc { - ref_count: AtomicUint::new(1), - data: (*self.ptr).data.clone(), - }; - - *self = CowArc { - ptr: cast::transmute(copy), - }; - - cast::transmute(&mut (*self.ptr).data) - } - } -} - diff --git a/src/components/util/util.rs b/src/components/util/util.rs index 456bf91943f..c21e5efca74 100644 --- a/src/components/util/util.rs +++ b/src/components/util/util.rs @@ -26,7 +26,6 @@ extern crate std_url = "url"; pub mod cache; pub mod concurrentmap; -pub mod cowarc; pub mod debug; pub mod geometry; pub mod namespace;