aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <release+servo@mozilla.com>2014-01-30 16:28:18 -0800
committerbors-servo <release+servo@mozilla.com>2014-01-30 16:28:18 -0800
commite2e848c6adae74b564d6696da5a7f9b346347a08 (patch)
treec675d22c92fe79bac727d0a7cadf7825435deb20
parent31442fe8561a91bf82818550ae5e3b4c03d2cf27 (diff)
parenta8e35fbeacf3cc2b8b689a402b04b70439a8d851 (diff)
downloadservo-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_.rs2
-rw-r--r--src/components/main/layout/construct.rs20
-rw-r--r--src/components/main/layout/context.rs6
-rw-r--r--src/components/main/layout/flow.rs29
-rw-r--r--src/components/main/layout/layout_task.rs10
-rw-r--r--src/components/main/layout/parallel.rs20
-rw-r--r--src/components/main/layout/wrapper.rs12
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()
}
}