mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Remove CowArc and use the new Arc::make_unique() method instead.
This commit is contained in:
parent
f01bfc7db9
commit
20c72c8ccb
4 changed files with 37 additions and 124 deletions
|
@ -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<CowArc<FloatList>>,
|
||||
list: Option<Arc<FloatList>>,
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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_structs::${style_struct.name}>,
|
||||
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
|
||||
% 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<T> {
|
||||
fn make_unique_experimental<'a>(&'a mut self) -> &'a mut T;
|
||||
}
|
||||
impl<T: Send + Share + Clone> ArcExperimental<T> for Arc<T> {
|
||||
#[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);
|
||||
|
|
|
@ -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<T> {
|
||||
ref_count: AtomicUint,
|
||||
data: T,
|
||||
}
|
||||
|
||||
#[unsafe_no_drop_flag]
|
||||
pub struct CowArc<T> {
|
||||
ptr: *mut CowArcAlloc<T>,
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<T> Drop for CowArc<T> {
|
||||
#[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<CowArcAlloc<T>> = cast::transmute(self.ptr);
|
||||
self.ptr = ptr::mut_null()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Eq + Clone> Eq for CowArc<T> {
|
||||
fn eq(&self, other: &CowArc<T>) -> bool {
|
||||
self.get() == other.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Clone> Clone for CowArc<T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> CowArc<T> {
|
||||
unsafe {
|
||||
drop((*self.ptr).ref_count.fetch_add(1, SeqCst));
|
||||
}
|
||||
CowArc {
|
||||
ptr: self.ptr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Clone> CowArc<T> {
|
||||
#[inline]
|
||||
pub fn new(value: T) -> CowArc<T> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue