aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/node.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/node.rs')
-rw-r--r--components/script/dom/node.rs111
1 files changed, 28 insertions, 83 deletions
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index a2a39979ad2..ee82a25733f 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -57,14 +57,12 @@ use selectors::matching::matches;
use selectors::parser::Selector;
use selectors::parser::parse_author_origin_selector_list_from_str;
use std::borrow::ToOwned;
-use std::cell::{Cell, Ref, RefCell, RefMut};
+use std::cell::Cell;
use std::cmp::max;
use std::default::Default;
use std::iter::{self, FilterMap, Peekable};
use std::mem;
-use std::sync::Arc;
use string_cache::{Atom, Namespace, QualName};
-use style::properties::ComputedValues;
use util::str::DOMString;
use util::task_state;
use uuid::Uuid;
@@ -115,11 +113,11 @@ pub struct Node {
/// are this node.
ranges: WeakRangeVec,
- /// Layout information. Only the layout task may touch this data.
+ /// Style+Layout information. Only the layout task may touch this data.
///
/// Must be sent back to the layout task to be destroyed when this
/// node is finalized.
- layout_data: LayoutDataRef,
+ style_and_layout_data: Cell<Option<OpaqueStyleAndLayoutData>>,
unique_id: DOMRefCell<Option<Box<Uuid>>>,
}
@@ -164,7 +162,7 @@ impl NodeFlags {
impl Drop for Node {
#[allow(unsafe_code)]
fn drop(&mut self) {
- self.layout_data.dispose(self);
+ self.style_and_layout_data.get().map(|d| d.dispose(self));
}
}
@@ -177,74 +175,27 @@ enum SuppressObserver {
Unsuppressed
}
-/// Layout data that is shared between the script and layout tasks.
-#[derive(HeapSizeOf)]
-pub struct SharedLayoutData {
- /// The results of CSS styling for this node.
- pub style: Option<Arc<ComputedValues>>,
-}
-
-/// Encapsulates the abstract layout data.
-#[derive(HeapSizeOf)]
-pub struct LayoutData {
- _shared_data: SharedLayoutData,
- #[ignore_heap_size_of = "TODO(#6910) Box value that should be counted but the type lives in layout"]
- _data: NonZero<*const ()>,
+#[derive(Copy, Clone, HeapSizeOf)]
+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 ()>
}
#[allow(unsafe_code)]
-unsafe impl Send for LayoutData {}
+unsafe impl Send for OpaqueStyleAndLayoutData {}
-#[derive(HeapSizeOf)]
-pub struct LayoutDataRef {
- data_cell: RefCell<Option<LayoutData>>,
-}
-
-no_jsmanaged_fields!(LayoutDataRef);
+no_jsmanaged_fields!(OpaqueStyleAndLayoutData);
-impl LayoutDataRef {
- pub fn new() -> LayoutDataRef {
- LayoutDataRef {
- data_cell: RefCell::new(None),
- }
- }
- /// Sends layout data, if any, back to the layout task to be destroyed.
- pub fn dispose(&self, node: &Node) {
+impl OpaqueStyleAndLayoutData {
+ /// Sends the style and layout data, if any, back to the layout task to be destroyed.
+ pub fn dispose(self, node: &Node) {
debug_assert!(task_state::get().is_script());
- if let Some(layout_data) = mem::replace(&mut *self.data_cell.borrow_mut(), None) {
- let win = window_from_node(node);
- let LayoutChan(chan) = win.layout_chan();
- chan.send(Msg::ReapLayoutData(layout_data)).unwrap()
- }
- }
-
- /// Borrows the layout data immutably, *assuming that there are no mutators*. Bad things will
- /// happen if you try to mutate the layout data while this is held. This is the only thread-
- /// safe layout data accessor.
- #[inline]
- #[allow(unsafe_code)]
- pub unsafe fn borrow_unchecked(&self) -> *const Option<LayoutData> {
- debug_assert!(task_state::get().is_layout());
- self.data_cell.as_unsafe_cell().get() as *const _
- }
-
- /// Borrows the layout data immutably. This function is *not* thread-safe.
- #[inline]
- pub fn borrow(&self) -> Ref<Option<LayoutData>> {
- debug_assert!(task_state::get().is_layout());
- self.data_cell.borrow()
- }
-
- /// Borrows the layout data mutably. This function is *not* thread-safe.
- ///
- /// FIXME(pcwalton): We should really put this behind a `MutLayoutView` phantom type, to
- /// prevent CSS selector matching from mutably accessing nodes it's not supposed to and racing
- /// on it. This has already resulted in one bug!
- #[inline]
- pub fn borrow_mut(&self) -> RefMut<Option<LayoutData>> {
- debug_assert!(task_state::get().is_layout());
- self.data_cell.borrow_mut()
+ let win = window_from_node(node);
+ let LayoutChan(chan) = win.layout_chan();
+ node.style_and_layout_data.set(None);
+ chan.send(Msg::ReapStyleAndLayoutData(self)).unwrap();
}
}
@@ -334,7 +285,7 @@ impl Node {
for node in child.traverse_preorder() {
node.set_flag(IS_IN_DOC, false);
vtable_for(&&*node).unbind_from_tree(&context);
- node.layout_data.dispose(&node);
+ node.style_and_layout_data.get().map(|d| d.dispose(&node));
}
self.owner_doc().content_and_heritage_changed(self, NodeDamage::OtherNodeDamage);
@@ -378,7 +329,7 @@ impl<'a> Iterator for QuerySelectorIterator {
impl Node {
pub fn teardown(&self) {
- self.layout_data.dispose(self);
+ self.style_and_layout_data.get().map(|d| d.dispose(self));
for kid in self.children() {
kid.teardown();
}
@@ -966,9 +917,8 @@ pub trait LayoutNodeHelpers {
unsafe fn children_count(&self) -> u32;
- unsafe fn layout_data(&self) -> Ref<Option<LayoutData>>;
- unsafe fn layout_data_mut(&self) -> RefMut<Option<LayoutData>>;
- unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData>;
+ unsafe fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData>;
+ unsafe fn init_style_and_layout_data(&self, OpaqueStyleAndLayoutData);
}
impl LayoutNodeHelpers for LayoutJS<Node> {
@@ -1049,20 +999,15 @@ impl LayoutNodeHelpers for LayoutJS<Node> {
#[inline]
#[allow(unsafe_code)]
- unsafe fn layout_data(&self) -> Ref<Option<LayoutData>> {
- (*self.unsafe_get()).layout_data.borrow()
- }
-
- #[inline]
- #[allow(unsafe_code)]
- unsafe fn layout_data_mut(&self) -> RefMut<Option<LayoutData>> {
- (*self.unsafe_get()).layout_data.borrow_mut()
+ unsafe fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData> {
+ (*self.unsafe_get()).style_and_layout_data.get()
}
#[inline]
#[allow(unsafe_code)]
- unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData> {
- (*self.unsafe_get()).layout_data.borrow_unchecked()
+ unsafe fn init_style_and_layout_data(&self, val: OpaqueStyleAndLayoutData) {
+ debug_assert!((*self.unsafe_get()).style_and_layout_data.get().is_none());
+ (*self.unsafe_get()).style_and_layout_data.set(Some(val));
}
}
@@ -1322,7 +1267,7 @@ impl Node {
inclusive_descendants_version: Cell::new(0),
ranges: WeakRangeVec::new(),
- layout_data: LayoutDataRef::new(),
+ style_and_layout_data: Cell::new(None),
unique_id: DOMRefCell::new(None),
}