diff options
author | Bobby Holley <bobbyholley@gmail.com> | 2017-05-15 18:15:27 +0200 |
---|---|---|
committer | Bobby Holley <bobbyholley@gmail.com> | 2017-05-15 18:36:38 +0200 |
commit | bf242088c72b56286131582d69bc4b5866b12072 (patch) | |
tree | 40e563520a28c49f56f9f3af138042a605788d47 | |
parent | f3c8f7e0d0fb42f32e3699d07fc0f8002bf564c8 (diff) | |
download | servo-bf242088c72b56286131582d69bc4b5866b12072.tar.gz servo-bf242088c72b56286131582d69bc4b5866b12072.zip |
Use a SmallVec when gathering applicable declarations.
-rw-r--r-- | components/style/matching.rs | 12 | ||||
-rw-r--r-- | components/style/stylist.rs | 13 |
2 files changed, 16 insertions, 9 deletions
diff --git a/components/style/matching.rs b/components/style/matching.rs index 530b3c1f591..d82ede92f39 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -28,7 +28,7 @@ use selectors::matching::AFFECTED_BY_PSEUDO_ELEMENTS; use shared_lock::StylesheetGuards; use sink::ForgetfulSink; use stylearc::Arc; -use stylist::ApplicableDeclarationBlock; +use stylist::ApplicableDeclarationList; /// The way a style should be inherited. enum InheritMode { @@ -865,11 +865,11 @@ trait PrivateMatchMethods: TElement { } fn compute_rule_node<E: TElement>(rule_tree: &RuleTree, - applicable_declarations: &mut Vec<ApplicableDeclarationBlock>, + applicable_declarations: &mut ApplicableDeclarationList, guards: &StylesheetGuards) -> StrongRuleNode { - let rules = applicable_declarations.drain(..).map(|d| (d.source, d.level)); + let rules = applicable_declarations.drain().map(|d| (d.source, d.level)); let rule_node = rule_tree.insert_ordered_rules_with_important(rules, guards); rule_node } @@ -994,8 +994,7 @@ pub trait MatchMethods : TElement { } } - let mut applicable_declarations = - Vec::<ApplicableDeclarationBlock>::with_capacity(16); + let mut applicable_declarations = ApplicableDeclarationList::new(); let stylist = &context.shared.stylist; let style_attribute = self.style_attribute(); @@ -1049,8 +1048,7 @@ pub trait MatchMethods : TElement { return false; } - let mut applicable_declarations = - Vec::<ApplicableDeclarationBlock>::with_capacity(16); + let mut applicable_declarations = ApplicableDeclarationList::new(); let map = &mut context.thread_local.selector_flags; let mut set_selector_flags = |element: &Self, flags: ElementSelectorFlags| { diff --git a/components/style/stylist.rs b/components/style/stylist.rs index b929777bd2f..ce5761e3f2e 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -33,7 +33,7 @@ use selectors::parser::{SelectorMethods, LocalName as LocalNameSelector}; use selectors::visitor::SelectorVisitor; use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards}; use sink::Push; -use smallvec::VecLike; +use smallvec::{SmallVec, VecLike}; use std::borrow::Borrow; use std::collections::HashMap; use std::hash::Hash; @@ -49,6 +49,15 @@ use viewport::{self, MaybeNew, ViewportRule}; pub use ::fnv::FnvHashMap; +/// List of applicable declaration. This is a transient structure that shuttles +/// declarations between selector matching and inserting into the rule tree, and +/// therefore we want to avoid heap-allocation where possible. +/// +/// In measurements on wikipedia, we pretty much never have more than 8 applicable +/// declarations, so we could consider making this 8 entries instead of 16. +/// However, it may depend a lot on workload, and stack space is cheap. +pub type ApplicableDeclarationList = SmallVec<[ApplicableDeclarationBlock; 16]>; + /// This structure holds all the selectors and device characteristics /// for a given document. The selectors are converted into `Rule`s /// (defined in rust-selectors), and introduced in a `SelectorMap` @@ -673,7 +682,7 @@ impl Stylist { }; - let mut declarations = vec![]; + let mut declarations = ApplicableDeclarationList::new(); self.push_applicable_declarations(element, None, None, |