diff options
-rw-r--r-- | components/layout/construct.rs | 6 | ||||
-rw-r--r-- | components/layout/data.rs | 16 | ||||
-rw-r--r-- | components/layout/wrapper.rs | 55 | ||||
-rw-r--r-- | components/layout_thread/lib.rs | 6 | ||||
-rw-r--r-- | components/script/layout_wrapper.rs | 44 | ||||
-rw-r--r-- | components/script_layout_interface/lib.rs | 10 | ||||
-rw-r--r-- | components/script_layout_interface/wrapper_traits.rs | 36 | ||||
-rw-r--r-- | components/style/data.rs | 6 | ||||
-rw-r--r-- | components/style/dom.rs | 17 | ||||
-rw-r--r-- | components/style/gecko/wrapper.rs | 18 | ||||
-rw-r--r-- | components/style/matching.rs | 20 | ||||
-rw-r--r-- | components/style/parallel.rs | 4 |
12 files changed, 96 insertions, 142 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 225456956df..8a463ded66a 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -16,7 +16,7 @@ use app_units::Au; use block::BlockFlow; use context::LayoutContext; -use data::{HAS_NEWLY_CONSTRUCTED_FLOW, PrivateLayoutData}; +use data::{HAS_NEWLY_CONSTRUCTED_FLOW, PersistentLayoutData}; use flex::FlexFlow; use floats::FloatKind; use flow::{self, AbsoluteDescendants, IS_ABSOLUTELY_POSITIONED, ImmutableFlowUtils}; @@ -1679,7 +1679,7 @@ trait NodeUtils { /// Returns true if this node doesn't render its kids and false otherwise. fn is_replaced_content(&self) -> bool; - fn construction_result_mut(self, layout_data: &mut PrivateLayoutData) -> &mut ConstructionResult; + fn construction_result_mut(self, layout_data: &mut PersistentLayoutData) -> &mut ConstructionResult; /// Sets the construction result of a flow. fn set_flow_construction_result(self, result: ConstructionResult); @@ -1708,7 +1708,7 @@ impl<ConcreteThreadSafeLayoutNode> NodeUtils for ConcreteThreadSafeLayoutNode } } - fn construction_result_mut(self, data: &mut PrivateLayoutData) -> &mut ConstructionResult { + fn construction_result_mut(self, data: &mut PersistentLayoutData) -> &mut ConstructionResult { match self.get_pseudo_element_type() { PseudoElementType::Before(_) => &mut data.before_flow_construction_result, PseudoElementType::After (_) => &mut data.after_flow_construction_result, diff --git a/components/layout/data.rs b/components/layout/data.rs index 167b87e6f1a..69f8488e2e6 100644 --- a/components/layout/data.rs +++ b/components/layout/data.rs @@ -4,15 +4,15 @@ use construct::ConstructionResult; use script_layout_interface::restyle_damage::RestyleDamage; -use style::data::PrivateStyleData; +use style::data::PersistentStyleData; /// Data that layout associates with a node. -pub struct PrivateLayoutData { +pub struct PersistentLayoutData { /// Data that the style system associates with a node. When the /// style system is being used standalone, this is all that hangs /// off the node. This must be first to permit the various - /// transmuations between PrivateStyleData PrivateLayoutData. - pub style_data: PrivateStyleData, + /// transmutations between PersistentStyleData and PersistentLayoutData. + pub style_data: PersistentStyleData, /// Description of how to account for recent style changes. pub restyle_damage: RestyleDamage, @@ -34,11 +34,11 @@ pub struct PrivateLayoutData { pub flags: LayoutDataFlags, } -impl PrivateLayoutData { +impl PersistentLayoutData { /// Creates new layout data. - pub fn new() -> PrivateLayoutData { - PrivateLayoutData { - style_data: PrivateStyleData::new(), + pub fn new() -> PersistentLayoutData { + PersistentLayoutData { + style_data: PersistentStyleData::new(), restyle_damage: RestyleDamage::empty(), flow_construction_result: ConstructionResult::None, before_flow_construction_result: ConstructionResult::None, diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index bc90055387e..28d1196221b 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -31,33 +31,25 @@ #![allow(unsafe_code)] use core::nonzero::NonZero; -use data::{LayoutDataFlags, PrivateLayoutData}; -use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData}; +use data::{LayoutDataFlags, PersistentLayoutData}; +use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData}; use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode}; +use style::atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; use style::computed_values::content::{self, ContentItem}; -use style::refcell::{Ref, RefCell, RefMut}; -pub type NonOpaqueStyleAndLayoutData = *mut RefCell<PrivateLayoutData>; +pub type NonOpaqueStyleAndLayoutData = *mut AtomicRefCell<PersistentLayoutData>; pub trait LayoutNodeLayoutData { - /// Similar to borrow_data*, but returns the full PrivateLayoutData rather - /// than only the PrivateStyleData. - unsafe fn borrow_layout_data_unchecked(&self) -> Option<*const PrivateLayoutData>; - fn borrow_layout_data(&self) -> Option<Ref<PrivateLayoutData>>; - fn mutate_layout_data(&self) -> Option<RefMut<PrivateLayoutData>>; + /// Similar to borrow_data*, but returns the full PersistentLayoutData rather + /// than only the PersistentStyleData. + fn borrow_layout_data(&self) -> Option<AtomicRef<PersistentLayoutData>>; + fn mutate_layout_data(&self) -> Option<AtomicRefMut<PersistentLayoutData>>; fn initialize_data(self); fn flow_debug_id(self) -> usize; } impl<T: LayoutNode> LayoutNodeLayoutData for T { - unsafe fn borrow_layout_data_unchecked(&self) -> Option<*const PrivateLayoutData> { - self.get_style_and_layout_data().map(|opaque| { - let container = *opaque.ptr as NonOpaqueStyleAndLayoutData; - &(*(*container).as_unsafe_cell().get()) as *const PrivateLayoutData - }) - } - - fn borrow_layout_data(&self) -> Option<Ref<PrivateLayoutData>> { + fn borrow_layout_data(&self) -> Option<AtomicRef<PersistentLayoutData>> { unsafe { self.get_style_and_layout_data().map(|opaque| { let container = *opaque.ptr as NonOpaqueStyleAndLayoutData; @@ -66,7 +58,7 @@ impl<T: LayoutNode> LayoutNodeLayoutData for T { } } - fn mutate_layout_data(&self) -> Option<RefMut<PrivateLayoutData>> { + fn mutate_layout_data(&self) -> Option<AtomicRefMut<PersistentLayoutData>> { unsafe { self.get_style_and_layout_data().map(|opaque| { let container = *opaque.ptr as NonOpaqueStyleAndLayoutData; @@ -76,11 +68,11 @@ impl<T: LayoutNode> LayoutNodeLayoutData for T { } fn initialize_data(self) { - if unsafe { self.borrow_data_unchecked() }.is_none() { + if self.borrow_data().is_none() { let ptr: NonOpaqueStyleAndLayoutData = - Box::into_raw(box RefCell::new(PrivateLayoutData::new())); + Box::into_raw(box AtomicRefCell::new(PersistentLayoutData::new())); let opaque = OpaqueStyleAndLayoutData { - ptr: unsafe { NonZero::new(ptr as *mut RefCell<PartialStyleAndLayoutData>) } + ptr: unsafe { NonZero::new(ptr as *mut AtomicRefCell<PartialPersistentLayoutData>) } }; self.init_style_and_layout_data(opaque); } @@ -94,19 +86,17 @@ impl<T: LayoutNode> LayoutNodeLayoutData for T { pub trait ThreadSafeLayoutNodeHelpers { fn flow_debug_id(self) -> usize; - unsafe fn borrow_layout_data_unchecked(&self) -> Option<*const PrivateLayoutData>; - /// Borrows the layout data immutably. Fails on a conflicting borrow. /// /// TODO(pcwalton): Make this private. It will let us avoid borrow flag checks in some cases. #[inline(always)] - fn borrow_layout_data(&self) -> Option<Ref<PrivateLayoutData>>; + fn borrow_layout_data(&self) -> Option<AtomicRef<PersistentLayoutData>>; /// Borrows the layout data mutably. Fails on a conflicting borrow. /// /// TODO(pcwalton): Make this private. It will let us avoid borrow flag checks in some cases. #[inline(always)] - fn mutate_layout_data(&self) -> Option<RefMut<PrivateLayoutData>>; + fn mutate_layout_data(&self) -> Option<AtomicRefMut<PersistentLayoutData>>; /// Returns the layout data flags for this node. fn flags(self) -> LayoutDataFlags; @@ -129,14 +119,7 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T { self.borrow_layout_data().map_or(0, |d| d.flow_construction_result.debug_id()) } - unsafe fn borrow_layout_data_unchecked(&self) -> Option<*const PrivateLayoutData> { - self.get_style_and_layout_data().map(|opaque| { - let container = *opaque.ptr as NonOpaqueStyleAndLayoutData; - &(*(*container).as_unsafe_cell().get()) as *const PrivateLayoutData - }) - } - - fn borrow_layout_data(&self) -> Option<Ref<PrivateLayoutData>> { + fn borrow_layout_data(&self) -> Option<AtomicRef<PersistentLayoutData>> { unsafe { self.get_style_and_layout_data().map(|opaque| { let container = *opaque.ptr as NonOpaqueStyleAndLayoutData; @@ -145,7 +128,7 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T { } } - fn mutate_layout_data(&self) -> Option<RefMut<PrivateLayoutData>> { + fn mutate_layout_data(&self) -> Option<AtomicRefMut<PersistentLayoutData>> { unsafe { self.get_style_and_layout_data().map(|opaque| { let container = *opaque.ptr as NonOpaqueStyleAndLayoutData; @@ -155,9 +138,7 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T { } fn flags(self) -> LayoutDataFlags { - unsafe { - (*self.borrow_layout_data_unchecked().unwrap()).flags - } + self.borrow_layout_data().as_ref().unwrap().flags } fn insert_flags(self, new_flags: LayoutDataFlags) { diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 6e8b32a2687..4797b8814aa 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -86,7 +86,7 @@ use profile_traits::mem::{self, Report, ReportKind, ReportsChan}; use profile_traits::time::{self, TimerMetadata, profile}; use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType}; use script::layout_wrapper::{ServoLayoutDocument, ServoLayoutNode}; -use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData}; +use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData}; use script_layout_interface::message::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow}; use script_layout_interface::reporter::CSSErrorReporter; use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION}; @@ -104,6 +104,7 @@ use std::sync::{Arc, Mutex, MutexGuard, RwLock}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::mpsc::{Receiver, Sender, channel}; use style::animation::Animation; +use style::atomic_refcell::AtomicRefCell; use style::computed_values::{filter, mix_blend_mode}; use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext}; use style::dom::{TDocument, TElement, TNode}; @@ -112,7 +113,6 @@ use style::logical_geometry::LogicalPoint; use style::media_queries::{Device, MediaType}; use style::parallel::WorkQueueData; use style::parser::ParserContextExtraData; -use style::refcell::RefCell; use style::selector_matching::Stylist; use style::stylesheets::{CSSRuleIteratorExt, Origin, Stylesheet, UserAgentStylesheets}; use style::thread_state; @@ -1594,7 +1594,7 @@ impl LayoutThread { /// Handles a message to destroy layout data. Layout data must be destroyed on *this* thread /// because the struct type is transmuted to a different type on the script side. unsafe fn handle_reap_style_and_layout_data(&self, data: OpaqueStyleAndLayoutData) { - let ptr: *mut RefCell<PartialStyleAndLayoutData> = *data.ptr; + let ptr: *mut AtomicRefCell<PartialPersistentLayoutData> = *data.ptr; let non_opaque: NonOpaqueStyleAndLayoutData = ptr as *mut _; let _ = Box::from_raw(non_opaque); } diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index 19e6c7c4e79..b609a545277 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -43,7 +43,7 @@ use gfx_traits::ByteIndex; use msg::constellation_msg::PipelineId; use range::Range; use script_layout_interface::{HTMLCanvasData, LayoutNodeType, TrustedNodeAddress}; -use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData}; +use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData}; use script_layout_interface::restyle_damage::RestyleDamage; use script_layout_interface::wrapper_traits::{DangerousThreadSafeLayoutNode, LayoutNode, PseudoElementType}; use script_layout_interface::wrapper_traits::{ThreadSafeLayoutElement, ThreadSafeLayoutNode}; @@ -54,15 +54,15 @@ use std::marker::PhantomData; use std::mem::transmute; use std::sync::Arc; use string_cache::{Atom, Namespace}; +use style::atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; use style::attr::AttrValue; use style::computed_values::display; use style::context::SharedStyleContext; -use style::data::PrivateStyleData; +use style::data::PersistentStyleData; use style::dom::{LayoutIterator, NodeInfo, OpaqueNode, PresentationalHintsSynthetizer, TDocument, TElement, TNode}; use style::dom::UnsafeNode; use style::element_state::*; use style::properties::{ComputedValues, PropertyDeclarationBlock}; -use style::refcell::{Ref, RefCell, RefMut}; use style::selector_impl::{ElementSnapshot, NonTSPseudoClass, PseudoElement, ServoSelectorImpl}; use style::selector_matching::ApplicableDeclarationBlock; use style::sink::Push; @@ -220,30 +220,20 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { self.node.set_flag(CAN_BE_FRAGMENTED, value) } - unsafe fn borrow_data_unchecked(&self) -> Option<*const PrivateStyleData> { - self.get_style_data().map(|d| { - &(*d.as_unsafe_cell().get()).style_data as *const _ - }) + fn borrow_data(&self) -> Option<AtomicRef<PersistentStyleData>> { + self.get_style_data().map(|d| d.borrow()) } - fn borrow_data(&self) -> Option<Ref<PrivateStyleData>> { - self.get_style_data().map(|d| { - Ref::map(d.borrow(), |d| &d.style_data) - }) - } - - fn mutate_data(&self) -> Option<RefMut<PrivateStyleData>> { - self.get_style_data().map(|d| { - RefMut::map(d.borrow_mut(), |d| &mut d.style_data) - }) + fn mutate_data(&self) -> Option<AtomicRefMut<PersistentStyleData>> { + self.get_style_data().map(|d| d.borrow_mut()) } fn restyle_damage(self) -> RestyleDamage { - self.get_style_data().unwrap().borrow().restyle_damage + self.get_partial_layout_data().unwrap().borrow().restyle_damage } fn set_restyle_damage(self, damage: RestyleDamage) { - self.get_style_data().unwrap().borrow_mut().restyle_damage = damage; + self.get_partial_layout_data().unwrap().borrow_mut().restyle_damage = damage; } fn parent_node(&self) -> Option<ServoLayoutNode<'ln>> { @@ -309,10 +299,12 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> { self.script_type_id().into() } - fn get_style_data(&self) -> Option<&RefCell<PartialStyleAndLayoutData>> { + fn get_style_data(&self) -> Option<&AtomicRefCell<PersistentStyleData>> { unsafe { self.get_jsmanaged().get_style_and_layout_data().map(|d| { - &**d.ptr + let ppld: &AtomicRefCell<PartialPersistentLayoutData> = &**d.ptr; + let psd: &AtomicRefCell<PersistentStyleData> = transmute(ppld); + psd }) } } @@ -331,6 +323,14 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> { } impl<'ln> ServoLayoutNode<'ln> { + fn get_partial_layout_data(&self) -> Option<&AtomicRefCell<PartialPersistentLayoutData>> { + unsafe { + self.get_jsmanaged().get_style_and_layout_data().map(|d| { + &**d.ptr + }) + } + } + fn dump_indent(self, indent: u32) { let mut s = String::new(); for _ in 0..indent { @@ -871,7 +871,7 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { } } - fn get_style_data(&self) -> Option<&RefCell<PartialStyleAndLayoutData>> { + fn get_style_data(&self) -> Option<&AtomicRefCell<PersistentStyleData>> { self.node.get_style_data() } } diff --git a/components/script_layout_interface/lib.rs b/components/script_layout_interface/lib.rs index d3554422dd7..cad2e012c7c 100644 --- a/components/script_layout_interface/lib.rs +++ b/components/script_layout_interface/lib.rs @@ -52,11 +52,11 @@ use core::nonzero::NonZero; use ipc_channel::ipc::IpcSender; use libc::c_void; use restyle_damage::RestyleDamage; -use style::data::PrivateStyleData; -use style::refcell::RefCell; +use style::atomic_refcell::AtomicRefCell; +use style::data::PersistentStyleData; -pub struct PartialStyleAndLayoutData { - pub style_data: PrivateStyleData, +pub struct PartialPersistentLayoutData { + pub style_data: PersistentStyleData, pub restyle_damage: RestyleDamage, } @@ -64,7 +64,7 @@ pub struct PartialStyleAndLayoutData { pub struct OpaqueStyleAndLayoutData { #[ignore_heap_size_of = "TODO(#6910) Box value that should be counted but \ the type lives in layout"] - pub ptr: NonZero<*mut RefCell<PartialStyleAndLayoutData>> + pub ptr: NonZero<*mut AtomicRefCell<PartialPersistentLayoutData>> } #[allow(unsafe_code)] diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs index bd0f2068271..c02d76a2f4e 100644 --- a/components/script_layout_interface/wrapper_traits.rs +++ b/components/script_layout_interface/wrapper_traits.rs @@ -5,7 +5,6 @@ use HTMLCanvasData; use LayoutNodeType; use OpaqueStyleAndLayoutData; -use PartialStyleAndLayoutData; use gfx_traits::{ByteIndex, LayerId, LayerType}; use msg::constellation_msg::PipelineId; use range::Range; @@ -13,12 +12,13 @@ use restyle_damage::RestyleDamage; use std::fmt::Debug; use std::sync::Arc; use string_cache::{Atom, Namespace}; +use style::atomic_refcell::AtomicRefCell; use style::computed_values::display; use style::context::SharedStyleContext; +use style::data::PersistentStyleData; use style::dom::{LayoutIterator, NodeInfo, PresentationalHintsSynthetizer, TNode}; use style::dom::OpaqueNode; use style::properties::ServoComputedValues; -use style::refcell::RefCell; use style::selector_impl::{PseudoElement, PseudoElementCascadeType, ServoSelectorImpl}; use url::Url; @@ -76,7 +76,7 @@ pub trait LayoutNode: TNode { /// Returns the type ID of this node. fn type_id(&self) -> LayoutNodeType; - fn get_style_data(&self) -> Option<&RefCell<PartialStyleAndLayoutData>>; + fn get_style_data(&self) -> Option<&AtomicRefCell<PersistentStyleData>>; fn init_style_and_layout_data(&self, data: OpaqueStyleAndLayoutData); fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData>; @@ -183,7 +183,6 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { if self.get_style_data() .unwrap() .borrow() - .style_data .per_pseudo .contains_key(&PseudoElement::Before) { Some(self.with_pseudo(PseudoElementType::Before(None))) @@ -197,7 +196,6 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { if self.get_style_data() .unwrap() .borrow() - .style_data .per_pseudo .contains_key(&PseudoElement::After) { Some(self.with_pseudo(PseudoElementType::After(None))) @@ -244,7 +242,7 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { match self.get_pseudo_element_type() { PseudoElementType::Normal => { self.get_style_data().unwrap().borrow() - .style_data.style.as_ref().unwrap().clone() + .style.as_ref().unwrap().clone() }, other => { // Precompute non-eagerly-cascaded pseudo-element styles if not @@ -257,14 +255,13 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { if !self.get_style_data() .unwrap() .borrow() - .style_data .per_pseudo.contains_key(&style_pseudo) { let mut data = self.get_style_data().unwrap().borrow_mut(); let new_style = context.stylist .precomputed_values_for_pseudo(&style_pseudo, - data.style_data.style.as_ref()); - data.style_data.per_pseudo + data.style.as_ref()); + data.per_pseudo .insert(style_pseudo.clone(), new_style.unwrap()); } } @@ -273,7 +270,6 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { if !self.get_style_data() .unwrap() .borrow() - .style_data .per_pseudo.contains_key(&style_pseudo) { let mut data = self.get_style_data().unwrap().borrow_mut(); let new_style = @@ -281,15 +277,15 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { .lazily_compute_pseudo_element_style( &self.as_element(), &style_pseudo, - data.style_data.style.as_ref().unwrap()); - data.style_data.per_pseudo + data.style.as_ref().unwrap()); + data.per_pseudo .insert(style_pseudo.clone(), new_style.unwrap()); } } } self.get_style_data().unwrap().borrow() - .style_data.per_pseudo.get(&style_pseudo) + .per_pseudo.get(&style_pseudo) .unwrap().clone() } } @@ -307,18 +303,18 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { let data = self.get_style_data().unwrap().borrow(); match self.get_pseudo_element_type() { PseudoElementType::Normal - => data.style_data.style.as_ref().unwrap().clone(), + => data.style.as_ref().unwrap().clone(), other - => data.style_data.per_pseudo.get(&other.style_pseudo_element()).unwrap().clone(), + => data.per_pseudo.get(&other.style_pseudo_element()).unwrap().clone(), } } #[inline] fn selected_style(&self, _context: &SharedStyleContext) -> Arc<ServoComputedValues> { let data = self.get_style_data().unwrap().borrow(); - data.style_data.per_pseudo + data.per_pseudo .get(&PseudoElement::Selection) - .unwrap_or(data.style_data.style.as_ref().unwrap()).clone() + .unwrap_or(data.style.as_ref().unwrap()).clone() } /// Removes the style from this node. @@ -329,10 +325,10 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { match self.get_pseudo_element_type() { PseudoElementType::Normal => { - data.style_data.style = None; + data.style = None; } other => { - data.style_data.per_pseudo.remove(&other.style_pseudo_element()); + data.per_pseudo.remove(&other.style_pseudo_element()); } }; } @@ -387,7 +383,7 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized { LayerId::new_of_type(LayerType::OverflowScroll, self.opaque().id() as usize) } - fn get_style_data(&self) -> Option<&RefCell<PartialStyleAndLayoutData>>; + fn get_style_data(&self) -> Option<&AtomicRefCell<PersistentStyleData>>; } // This trait is only public so that it can be implemented by the gecko wrapper. diff --git a/components/style/data.rs b/components/style/data.rs index 44920c72c98..c1c87d5f96e 100644 --- a/components/style/data.rs +++ b/components/style/data.rs @@ -11,7 +11,7 @@ use std::hash::BuildHasherDefault; use std::sync::Arc; use std::sync::atomic::AtomicIsize; -pub struct PrivateStyleData { +pub struct PersistentStyleData { /// The results of CSS styling for this node. pub style: Option<Arc<ComputedValues>>, @@ -23,9 +23,9 @@ pub struct PrivateStyleData { pub parallel: DomParallelInfo, } -impl PrivateStyleData { +impl PersistentStyleData { pub fn new() -> Self { - PrivateStyleData { + PersistentStyleData { style: None, per_pseudo: HashMap::with_hasher(Default::default()), parallel: DomParallelInfo::new(), diff --git a/components/style/dom.rs b/components/style/dom.rs index 8d0e98c8c53..a8da0d72fc3 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -6,11 +6,10 @@ #![allow(unsafe_code)] -use context::SharedStyleContext; -use data::PrivateStyleData; +use atomic_refcell::{AtomicRef, AtomicRefMut}; +use data::PersistentStyleData; use element_state::ElementState; use properties::{ComputedValues, PropertyDeclarationBlock}; -use refcell::{Ref, RefMut}; use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint}; use selector_impl::{ElementExt, PseudoElement}; use selector_matching::ApplicableDeclarationBlock; @@ -139,17 +138,13 @@ pub trait TNode : Sized + Copy + Clone + NodeInfo { unsafe fn set_can_be_fragmented(&self, value: bool); - /// Borrows the PrivateStyleData without checks. + /// Borrows the style data immutably. Fails on a conflicting borrow. #[inline(always)] - unsafe fn borrow_data_unchecked(&self) -> Option<*const PrivateStyleData>; + fn borrow_data(&self) -> Option<AtomicRef<PersistentStyleData>>; - /// Borrows the PrivateStyleData immutably. Fails on a conflicting borrow. + /// Borrows the style data mutably. Fails on a conflicting borrow. #[inline(always)] - fn borrow_data(&self) -> Option<Ref<PrivateStyleData>>; - - /// Borrows the PrivateStyleData mutably. Fails on a conflicting borrow. - #[inline(always)] - fn mutate_data(&self) -> Option<RefMut<PrivateStyleData>>; + fn mutate_data(&self) -> Option<AtomicRefMut<PersistentStyleData>>; /// Get the description of how to account for recent style changes. fn restyle_damage(self) -> Self::ConcreteRestyleDamage; diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 864e8fc8d22..6212e0da05f 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -5,7 +5,8 @@ #![allow(unsafe_code)] -use data::PrivateStyleData; +use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; +use data::PersistentStyleData; use dom::{LayoutIterator, NodeInfo, TDocument, TElement, TNode, TRestyleDamage, UnsafeNode}; use dom::{OpaqueNode, PresentationalHintsSynthetizer}; use element_state::ElementState; @@ -34,7 +35,6 @@ use libc::uintptr_t; use parser::ParserContextExtraData; use properties::{ComputedValues, parse_style_attribute}; use properties::PropertyDeclarationBlock; -use refcell::{Ref, RefCell, RefMut}; use selector_impl::ElementExt; use selector_matching::ApplicableDeclarationBlock; use selectors::Element; @@ -48,11 +48,11 @@ use std::sync::atomic::{AtomicBool, AtomicPtr}; use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; use url::Url; -pub struct NonOpaqueStyleData(RefCell<PrivateStyleData>); +pub struct NonOpaqueStyleData(AtomicRefCell<PersistentStyleData>); impl NonOpaqueStyleData { pub fn new() -> Self { - NonOpaqueStyleData(RefCell::new(PrivateStyleData::new())) + NonOpaqueStyleData(AtomicRefCell::new(PersistentStyleData::new())) } } @@ -302,18 +302,12 @@ impl<'ln> TNode for GeckoNode<'ln> { } #[inline(always)] - unsafe fn borrow_data_unchecked(&self) -> Option<*const PrivateStyleData> { - self.get_node_data().as_ref().map(|d| d.0.as_unsafe_cell().get() - as *const PrivateStyleData) - } - - #[inline(always)] - fn borrow_data(&self) -> Option<Ref<PrivateStyleData>> { + fn borrow_data(&self) -> Option<AtomicRef<PersistentStyleData>> { self.get_node_data().as_ref().map(|d| d.0.borrow()) } #[inline(always)] - fn mutate_data(&self) -> Option<RefMut<PrivateStyleData>> { + fn mutate_data(&self) -> Option<AtomicRefMut<PersistentStyleData>> { self.get_node_data().as_ref().map(|d| d.0.borrow_mut()) } diff --git a/components/style/matching.rs b/components/style/matching.rs index 8a9a12eaa72..24e67352fbe 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -11,7 +11,7 @@ use arc_ptr_eq; use cache::{LRUCache, SimpleHashCache}; use cascade_info::CascadeInfo; use context::{SharedStyleContext, StyleContext}; -use data::PrivateStyleData; +use data::PersistentStyleData; use dom::{NodeInfo, TElement, TNode, TRestyleDamage, UnsafeNode}; use properties::{ComputedValues, PropertyDeclarationBlock, cascade}; use properties::longhands::display::computed_value as display; @@ -874,19 +874,9 @@ pub trait MatchMethods : TNode { -> RestyleResult where Ctx: StyleContext<'a> { - // Get our parent's style. This must be unsafe so that we don't touch the parent's - // borrow flags. - // - // FIXME(pcwalton): Isolate this unsafety into the `wrapper` module to allow - // enforced safe, race-free access to the parent style. - let parent_style = match parent { - Some(parent_node) => { - let parent_style = (*parent_node.borrow_data_unchecked().unwrap()).style.as_ref().unwrap(); - Some(parent_style) - } - None => None, - }; - + // Get our parent's style. + let parent_node_data = parent.as_ref().and_then(|x| x.borrow_data()); + let parent_style = parent_node_data.as_ref().map(|x| x.style.as_ref().unwrap()); // In the case we're styling a text node, we don't need to compute the // restyle damage, since it's a subset of the restyle damage of the @@ -945,7 +935,7 @@ pub trait MatchMethods : TNode { fn compute_damage_and_cascade_pseudos<'a, Ctx>(&self, final_style: Arc<ComputedValues>, - data: &mut PrivateStyleData, + data: &mut PersistentStyleData, context: &Ctx, applicable_declarations: &ApplicableDeclarations, mut applicable_declarations_cache: &mut ApplicableDeclarationsCache) diff --git a/components/style/parallel.rs b/components/style/parallel.rs index ba904866710..b6ae6d49d66 100644 --- a/components/style/parallel.rs +++ b/components/style/parallel.rs @@ -161,9 +161,7 @@ fn bottom_up_dom<N, C>(root: OpaqueNode, Some(parent) => parent, }; - let parent_data = unsafe { - &*parent.borrow_data_unchecked().unwrap() - }; + let parent_data = parent.borrow_data().unwrap(); if parent_data .parallel |