Stop creating unnecessarily-large SmallVecs for specific tasks.

MozReview-Commit-ID: IM9aAjSeJI9
This commit is contained in:
Bobby Holley 2017-06-17 20:20:19 -07:00
parent db8f59407f
commit fac5aeb092

View file

@ -9,6 +9,7 @@ use cssparser::{ParseError, BasicParseError, CompactCowStr};
use cssparser::{Token, Parser as CssParser, parse_nth, ToCss, serialize_identifier, CssStringWriter}; use cssparser::{Token, Parser as CssParser, parse_nth, ToCss, serialize_identifier, CssStringWriter};
use precomputed_hash::PrecomputedHash; use precomputed_hash::PrecomputedHash;
use servo_arc::{Arc, HeaderWithLength, ThinArc}; use servo_arc::{Arc, HeaderWithLength, ThinArc};
use sink::Push;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::borrow::{Borrow, Cow}; use std::borrow::{Borrow, Cow};
@ -1120,10 +1121,11 @@ impl<Impl: SelectorImpl> Selector<Impl> {
/// * `Err(())`: Invalid selector, abort /// * `Err(())`: Invalid selector, abort
/// * `Ok(false)`: Not a type selector, could be something else. `input` was not consumed. /// * `Ok(false)`: Not a type selector, could be something else. `input` was not consumed.
/// * `Ok(true)`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`) /// * `Ok(true)`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`)
fn parse_type_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParser<'i, 't>, fn parse_type_selector<'i, 't, P, E, Impl, S>(parser: &P, input: &mut CssParser<'i, 't>, sink: &mut S)
sequence: &mut ParseVec<Impl>)
-> Result<bool, ParseError<'i, SelectorParseError<'i, E>>> -> Result<bool, ParseError<'i, SelectorParseError<'i, E>>>
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl where P: Parser<'i, Impl=Impl, Error=E>,
Impl: SelectorImpl,
S: Push<Component<Impl>>,
{ {
match parse_qualified_name(parser, input, /* in_attr_selector = */ false)? { match parse_qualified_name(parser, input, /* in_attr_selector = */ false)? {
None => Ok(false), None => Ok(false),
@ -1131,16 +1133,16 @@ fn parse_type_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParser<'i,
match namespace { match namespace {
QNamePrefix::ImplicitAnyNamespace => {} QNamePrefix::ImplicitAnyNamespace => {}
QNamePrefix::ImplicitDefaultNamespace(url) => { QNamePrefix::ImplicitDefaultNamespace(url) => {
sequence.push(Component::DefaultNamespace(url)) sink.push(Component::DefaultNamespace(url))
} }
QNamePrefix::ExplicitNamespace(prefix, url) => { QNamePrefix::ExplicitNamespace(prefix, url) => {
sequence.push(Component::Namespace(prefix, url)) sink.push(Component::Namespace(prefix, url))
} }
QNamePrefix::ExplicitNoNamespace => { QNamePrefix::ExplicitNoNamespace => {
sequence.push(Component::ExplicitNoNamespace) sink.push(Component::ExplicitNoNamespace)
} }
QNamePrefix::ExplicitAnyNamespace => { QNamePrefix::ExplicitAnyNamespace => {
sequence.push(Component::ExplicitAnyNamespace) sink.push(Component::ExplicitAnyNamespace)
} }
QNamePrefix::ImplicitNoNamespace => { QNamePrefix::ImplicitNoNamespace => {
unreachable!() // Not returned with in_attr_selector = false unreachable!() // Not returned with in_attr_selector = false
@ -1148,13 +1150,13 @@ fn parse_type_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParser<'i,
} }
match local_name { match local_name {
Some(name) => { Some(name) => {
sequence.push(Component::LocalName(LocalName { sink.push(Component::LocalName(LocalName {
lower_name: from_cow_str(to_ascii_lowercase(&name)), lower_name: from_cow_str(to_ascii_lowercase(&name)),
name: from_cow_str(name.into()), name: from_cow_str(name.into()),
})) }))
} }
None => { None => {
sequence.push(Component::ExplicitUniversalType) sink.push(Component::ExplicitUniversalType)
} }
} }
Ok(true) Ok(true)
@ -1422,7 +1424,7 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P,
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
{ {
// We use a sequence because a type selector may be represented as two Components. // We use a sequence because a type selector may be represented as two Components.
let mut sequence = ParseVec::new(); let mut sequence = SmallVec::<[Component<Impl>; 2]>::new();
// Consume any leading whitespace. // Consume any leading whitespace.
loop { loop {
@ -1476,7 +1478,7 @@ fn parse_compound_selector<'i, 't, P, E, Impl>(
} }
} }
let mut empty = true; let mut empty = true;
if !parse_type_selector(parser, input, &mut sequence)? { if !parse_type_selector(parser, input, sequence)? {
if let Some(url) = parser.default_namespace() { if let Some(url) = parser.default_namespace() {
// If there was no explicit type selector, but there is a // If there was no explicit type selector, but there is a
// default namespace, there is an implicit "<defaultns>|*" type // default namespace, there is an implicit "<defaultns>|*" type
@ -1496,8 +1498,9 @@ fn parse_compound_selector<'i, 't, P, E, Impl>(
empty = false empty = false
} }
Some(SimpleSelectorParseResult::PseudoElement(p)) => { Some(SimpleSelectorParseResult::PseudoElement(p)) => {
// Try to parse state to its right. // Try to parse state to its right. There are only 3 allowable
let mut state_selectors = ParseVec::new(); // state selectors that can go on pseudo-elements.
let mut state_selectors = SmallVec::<[Component<Impl>; 3]>::new();
loop { loop {
match input.next_including_whitespace() { match input.next_including_whitespace() {