diff options
author | bors-servo <release+servo@mozilla.com> | 2014-01-30 16:28:18 -0800 |
---|---|---|
committer | bors-servo <release+servo@mozilla.com> | 2014-01-30 16:28:18 -0800 |
commit | e2e848c6adae74b564d6696da5a7f9b346347a08 (patch) | |
tree | c675d22c92fe79bac727d0a7cadf7825435deb20 | |
parent | 31442fe8561a91bf82818550ae5e3b4c03d2cf27 (diff) | |
parent | a8e35fbeacf3cc2b8b689a402b04b70439a8d851 (diff) | |
download | servo-e2e848c6adae74b564d6696da5a7f9b346347a08.tar.gz servo-e2e848c6adae74b564d6696da5a7f9b346347a08.zip |
auto merge of #1600 : pcwalton/servo/use-concurrent-hash-map, r=larsbergstrom
64% improvement in style recalc.
r? @larsbergstrom
-rw-r--r-- | src/components/main/layout/box_.rs | 2 | ||||
-rw-r--r-- | src/components/main/layout/construct.rs | 20 | ||||
-rw-r--r-- | src/components/main/layout/context.rs | 6 | ||||
-rw-r--r-- | src/components/main/layout/flow.rs | 29 | ||||
-rw-r--r-- | src/components/main/layout/layout_task.rs | 10 | ||||
-rw-r--r-- | src/components/main/layout/parallel.rs | 20 | ||||
-rw-r--r-- | src/components/main/layout/wrapper.rs | 12 |
7 files changed, 47 insertions, 52 deletions
diff --git a/src/components/main/layout/box_.rs b/src/components/main/layout/box_.rs index c801f7c8e53..807f950faf9 100644 --- a/src/components/main/layout/box_.rs +++ b/src/components/main/layout/box_.rs @@ -27,7 +27,7 @@ use std::cast; use std::cell::RefCell; use std::cmp::ApproxEq; use std::num::Zero; -use style::{ComputedValues, TElement, TNode, cascade}; +use style::{ComputedValues, TElement, TNode}; use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto, overflow, LPA_Auto}; use style::computed_values::{border_style, clear, font_family, line_height}; use style::computed_values::{text_align, text_decoration, vertical_align, visibility, white_space}; diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs index cbd03bb50c2..1cb7b419c3d 100644 --- a/src/components/main/layout/construct.rs +++ b/src/components/main/layout/construct.rs @@ -58,7 +58,7 @@ pub enum ConstructionResult { } impl ConstructionResult { - fn destroy(&mut self, leaf_set: &mut FlowLeafSet) { + fn destroy(&mut self, leaf_set: &FlowLeafSet) { match *self { NoConstructionResult => {} FlowConstructionResult(ref mut flow) => flow.destroy(leaf_set), @@ -76,7 +76,7 @@ enum ConstructionItem { } impl ConstructionItem { - fn destroy(&mut self, leaf_set: &mut FlowLeafSet) { + fn destroy(&mut self, leaf_set: &FlowLeafSet) { match *self { InlineBoxesConstructionItem(ref mut result) => { for splits in result.splits.mut_iter() { @@ -133,7 +133,7 @@ struct InlineBlockSplit { } impl InlineBlockSplit { - fn destroy(&mut self, leaf_set: &mut FlowLeafSet) { + fn destroy(&mut self, leaf_set: &FlowLeafSet) { self.flow.destroy(leaf_set) } } @@ -274,7 +274,7 @@ impl<'fc> FlowConstructor<'fc> { let inline_base = BaseFlow::new(self.next_flow_id(), node); let mut inline_flow = ~InlineFlow::from_boxes(inline_base, boxes) as ~Flow; - self.layout_context.flow_leaf_set.access(|leaf_set| inline_flow.mark_as_leaf(leaf_set)); + inline_flow.mark_as_leaf(self.layout_context.flow_leaf_set.get()); TextRunScanner::new().scan_for_runs(self.font_context, inline_flow); flow.add_new_child(inline_flow) @@ -380,7 +380,7 @@ impl<'fc> FlowConstructor<'fc> { // The flow is done. If it ended up with no kids, add the flow to the leaf set. if flow.child_count() == 0 { - self.layout_context.flow_leaf_set.access(|leaf_set| flow.mark_as_leaf(leaf_set)) + flow.mark_as_leaf(self.layout_context.flow_leaf_set.get()) } else { flow.mark_as_nonleaf() } @@ -619,12 +619,10 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { // `display: none` contributes no flow construction result. Nuke the flow construction // results of children. (display::none, _, _) => { - self.layout_context.flow_leaf_set.access(|leaf_set| { - for child in node.children() { - let mut old_result = child.swap_out_construction_result(); - old_result.destroy(leaf_set) - } - }) + for child in node.children() { + let mut old_result = child.swap_out_construction_result(); + old_result.destroy(self.layout_context.flow_leaf_set.get()) + } } // Inline items contribute inline box construction results. diff --git a/src/components/main/layout/context.rs b/src/components/main/layout/context.rs index 9a405dad147..5385e2bcb99 100644 --- a/src/components/main/layout/context.rs +++ b/src/components/main/layout/context.rs @@ -4,7 +4,7 @@ //! Data needed by the layout task. -use extra::arc::MutexArc; +use extra::arc::{Arc, MutexArc}; use green::task::GreenTask; use layout::flow::FlowLeafSet; use layout::util::OpaqueNode; @@ -39,13 +39,13 @@ pub struct LayoutContext { constellation_chan: ConstellationChan, /// The set of leaf DOM nodes. - dom_leaf_set: MutexArc<DomLeafSet>, + dom_leaf_set: Arc<DomLeafSet>, /// A channel up to the layout task. layout_chan: LayoutChan, /// The set of leaf flows. - flow_leaf_set: MutexArc<FlowLeafSet>, + flow_leaf_set: Arc<FlowLeafSet>, /// Information needed to construct a font context. font_context_info: FontContextInfo, diff --git a/src/components/main/layout/flow.rs b/src/components/main/layout/flow.rs index 95281f8b17f..2373a47df87 100644 --- a/src/components/main/layout/flow.rs +++ b/src/components/main/layout/flow.rs @@ -44,10 +44,10 @@ use geom::rect::Rect; use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection, DisplayList}; use layout::display_list_builder::ToGfxColor; use gfx::color::Color; +use servo_util::concurrentmap::{ConcurrentHashMap, ConcurrentHashMapIterator}; use servo_util::geometry::Au; use std::cast; use std::cell::RefCell; -use std::hashmap::{HashSet, HashSetIterator}; use std::sync::atomics::Relaxed; use style::ComputedValues; use style::computed_values::text_align; @@ -217,13 +217,13 @@ pub trait MutableOwnedFlowUtils { /// Marks the flow as a leaf. The flow must not have children and must not be marked as a /// nonleaf. - fn mark_as_leaf(&mut self, leaf_set: &mut FlowLeafSet); + fn mark_as_leaf(&mut self, leaf_set: &FlowLeafSet); /// Marks the flow as a nonleaf. The flow must not be marked as a leaf. fn mark_as_nonleaf(&mut self); /// Destroys the flow. - fn destroy(&mut self, leaf_set: &mut FlowLeafSet); + fn destroy(&mut self, leaf_set: &FlowLeafSet); } pub enum FlowClass { @@ -762,7 +762,7 @@ impl MutableOwnedFlowUtils for ~Flow { /// Marks the flow as a leaf. The flow must not have children and must not be marked as a /// nonleaf. - fn mark_as_leaf(&mut self, leaf_set: &mut FlowLeafSet) { + fn mark_as_leaf(&mut self, leaf_set: &FlowLeafSet) { { let base = mut_base(*self); if base.flags_info.flags.is_nonleaf() { @@ -787,7 +787,7 @@ impl MutableOwnedFlowUtils for ~Flow { } /// Destroys the flow. - fn destroy(&mut self, leaf_set: &mut FlowLeafSet) { + fn destroy(&mut self, leaf_set: &FlowLeafSet) { let is_leaf = { let base = mut_base(*self); base.children.len() == 0 @@ -808,27 +808,26 @@ impl MutableOwnedFlowUtils for ~Flow { /// Keeps track of the leaves of the flow tree. This is used to efficiently start bottom-up /// parallel traversals. -#[deriving(Clone)] pub struct FlowLeafSet { - priv set: HashSet<UnsafeFlow>, + priv set: ConcurrentHashMap<UnsafeFlow,()>, } impl FlowLeafSet { /// Creates a new flow leaf set. pub fn new() -> FlowLeafSet { FlowLeafSet { - set: HashSet::new(), + set: ConcurrentHashMap::with_locks_and_buckets(64, 256), } } /// Inserts a newly-created flow into the leaf set. - fn insert(&mut self, flow: &~Flow) { - self.set.insert(parallel::owned_flow_to_unsafe_flow(flow)); + fn insert(&self, flow: &~Flow) { + self.set.insert(parallel::owned_flow_to_unsafe_flow(flow), ()); } /// Removes a flow from the leaf set. Asserts that the flow was indeed in the leaf set. (This /// invariant is needed for memory safety, as there must always be exactly one leaf set.) - fn remove(&mut self, flow: &~Flow) { + fn remove(&self, flow: &~Flow) { if !self.contains(flow) { fail!("attempted to remove a flow from the leaf set that wasn't in the set!") } @@ -836,16 +835,16 @@ impl FlowLeafSet { self.set.remove(&flow); } - pub fn contains(&mut self, flow: &~Flow) -> bool { + pub fn contains(&self, flow: &~Flow) -> bool { let flow = parallel::owned_flow_to_unsafe_flow(flow); - self.set.contains(&flow) + self.set.contains_key(&flow) } - pub fn clear(&mut self) { + pub fn clear(&self) { self.set.clear() } - pub fn iter<'a>(&'a self) -> HashSetIterator<'a,UnsafeFlow> { + pub fn iter<'a>(&'a self) -> ConcurrentHashMapIterator<'a,UnsafeFlow,()> { self.set.iter() } } diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index a52ded755a8..468ef2297b1 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -83,10 +83,10 @@ pub struct LayoutTask { local_image_cache: MutexArc<LocalImageCache>, /// The set of leaves in the DOM tree. - dom_leaf_set: MutexArc<DomLeafSet>, + dom_leaf_set: Arc<DomLeafSet>, /// The set of leaves in the flow tree. - flow_leaf_set: MutexArc<FlowLeafSet>, + flow_leaf_set: Arc<FlowLeafSet>, /// The size of the viewport. screen_size: Size2D<Au>, @@ -292,8 +292,8 @@ impl LayoutTask { image_cache_task: image_cache_task.clone(), local_image_cache: local_image_cache, screen_size: screen_size, - dom_leaf_set: MutexArc::new(DomLeafSet::new()), - flow_leaf_set: MutexArc::new(FlowLeafSet::new()), + dom_leaf_set: Arc::new(DomLeafSet::new()), + flow_leaf_set: Arc::new(FlowLeafSet::new()), display_list_collection: None, stylist: ~new_stylist(), @@ -655,7 +655,7 @@ impl LayoutTask { }); } - self.flow_leaf_set.access(|leaf_set| layout_root.destroy(leaf_set)); + layout_root.destroy(self.flow_leaf_set.get()); // Tell script that we're done. // diff --git a/src/components/main/layout/parallel.rs b/src/components/main/layout/parallel.rs index ebbed1ac1b0..74c4a5c0073 100644 --- a/src/components/main/layout/parallel.rs +++ b/src/components/main/layout/parallel.rs @@ -15,7 +15,7 @@ use layout::layout_task::{AssignHeightsAndStoreOverflowTraversal, BubbleWidthsTr use layout::util::{LayoutDataAccess, OpaqueNode}; use layout::wrapper::{layout_node_to_unsafe_layout_node, LayoutNode, UnsafeLayoutNode}; -use extra::arc::MutexArc; +use extra::arc::Arc; use servo_util::time::{ProfilerChan, profile}; use servo_util::time; use servo_util::workqueue::{WorkQueue, WorkUnit, WorkerProxy}; @@ -167,7 +167,7 @@ fn match_and_cascade_node(unsafe_layout_node: UnsafeLayoutNode, if child_count == 0 { // We don't need set the `child_count` field here since that's only used by kids during // bottom-up traversals, and since this node is a leaf it has no kids. - layout_context.dom_leaf_set.access(|dom_leaf_set| dom_leaf_set.insert(&node)); + layout_context.dom_leaf_set.get().insert(&node); } else { let mut layout_data_ref = node.mutate_layout_data(); match *layout_data_ref.get() { @@ -220,7 +220,7 @@ pub fn match_and_cascade_subtree(root_node: &LayoutNode, } pub fn traverse_flow_tree(kind: TraversalKind, - leaf_set: &MutexArc<FlowLeafSet>, + leaf_set: &Arc<FlowLeafSet>, profiler_chan: ProfilerChan, layout_context: &mut LayoutContext, queue: &mut WorkQueue<*mut LayoutContext,UnsafeFlow>) { @@ -234,14 +234,12 @@ pub fn traverse_flow_tree(kind: TraversalKind, }; profile(time::LayoutParallelWarmupCategory, profiler_chan, || { - leaf_set.access(|leaf_set| { - for &flow in leaf_set.iter() { - queue.push(WorkUnit { - fun: fun, - data: flow, - }) - } - }) + for (flow, _) in leaf_set.get().iter() { + queue.push(WorkUnit { + fun: fun, + data: *flow, + }) + } }); queue.run(); diff --git a/src/components/main/layout/wrapper.rs b/src/components/main/layout/wrapper.rs index f6ebb1b2898..b9863b3db5f 100644 --- a/src/components/main/layout/wrapper.rs +++ b/src/components/main/layout/wrapper.rs @@ -22,10 +22,10 @@ use script::dom::htmlimageelement::HTMLImageElement; use script::dom::node::{AbstractNode, DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId}; use script::dom::text::Text; use servo_msg::constellation_msg::{PipelineId, SubpageId}; +use servo_util::concurrentmap::{ConcurrentHashMap, ConcurrentHashMapIterator}; use servo_util::namespace; use servo_util::namespace::Namespace; use std::cast; -use std::hashmap::{HashMap, HashMapIterator}; use style::{PropertyDeclarationBlock, TElement, TNode, AttrSelector}; /// A wrapper so that layout can access only the methods that it should have access to. Layout must @@ -439,29 +439,29 @@ pub fn layout_node_to_unsafe_layout_node(node: &LayoutNode) -> UnsafeLayoutNode /// Keeps track of the leaves of the DOM. This is used to efficiently start bottom-up traversals. pub struct DomLeafSet { - priv set: HashMap<UnsafeLayoutNode,()>, + priv set: ConcurrentHashMap<UnsafeLayoutNode,()>, } impl DomLeafSet { /// Creates a new DOM leaf set. pub fn new() -> DomLeafSet { DomLeafSet { - set: HashMap::new(), + set: ConcurrentHashMap::with_locks_and_buckets(64, 256), } } /// Inserts a DOM node into the leaf set. - pub fn insert(&mut self, node: &LayoutNode) { + pub fn insert(&self, node: &LayoutNode) { self.set.insert(layout_node_to_unsafe_layout_node(node), ()); } /// Removes all DOM nodes from the set. - pub fn clear(&mut self) { + pub fn clear(&self) { self.set.clear() } /// Iterates over the DOM nodes in the leaf set. - pub fn iter<'a>(&'a self) -> HashMapIterator<'a,UnsafeLayoutNode,()> { + pub fn iter<'a>(&'a self) -> ConcurrentHashMapIterator<'a,UnsafeLayoutNode,()> { self.set.iter() } } |