Skip to content

Commit

Permalink
Stop creating unnecessarily-large SmallVecs for specific tasks.
Browse files Browse the repository at this point in the history
MozReview-Commit-ID: IM9aAjSeJI9
  • Loading branch information
bholley committed Jun 20, 2017
1 parent db8f594 commit fac5aeb
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions components/selectors/parser.rs
Expand Up @@ -9,6 +9,7 @@ use cssparser::{ParseError, BasicParseError, CompactCowStr};
use cssparser::{Token, Parser as CssParser, parse_nth, ToCss, serialize_identifier, CssStringWriter};
use precomputed_hash::PrecomputedHash;
use servo_arc::{Arc, HeaderWithLength, ThinArc};
use sink::Push;
use smallvec::SmallVec;
use std::ascii::AsciiExt;
use std::borrow::{Borrow, Cow};
Expand Down Expand Up @@ -1120,41 +1121,42 @@ impl<Impl: SelectorImpl> Selector<Impl> {
/// * `Err(())`: Invalid selector, abort
/// * `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`)
fn parse_type_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParser<'i, 't>,
sequence: &mut ParseVec<Impl>)
-> Result<bool, ParseError<'i, SelectorParseError<'i, E>>>
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
fn parse_type_selector<'i, 't, P, E, Impl, S>(parser: &P, input: &mut CssParser<'i, 't>, sink: &mut S)
-> Result<bool, ParseError<'i, SelectorParseError<'i, E>>>
where P: Parser<'i, Impl=Impl, Error=E>,
Impl: SelectorImpl,
S: Push<Component<Impl>>,
{
match parse_qualified_name(parser, input, /* in_attr_selector = */ false)? {
None => Ok(false),
Some((namespace, local_name)) => {
match namespace {
QNamePrefix::ImplicitAnyNamespace => {}
QNamePrefix::ImplicitDefaultNamespace(url) => {
sequence.push(Component::DefaultNamespace(url))
sink.push(Component::DefaultNamespace(url))
}
QNamePrefix::ExplicitNamespace(prefix, url) => {
sequence.push(Component::Namespace(prefix, url))
sink.push(Component::Namespace(prefix, url))
}
QNamePrefix::ExplicitNoNamespace => {
sequence.push(Component::ExplicitNoNamespace)
sink.push(Component::ExplicitNoNamespace)
}
QNamePrefix::ExplicitAnyNamespace => {
sequence.push(Component::ExplicitAnyNamespace)
sink.push(Component::ExplicitAnyNamespace)
}
QNamePrefix::ImplicitNoNamespace => {
unreachable!() // Not returned with in_attr_selector = false
}
}
match local_name {
Some(name) => {
sequence.push(Component::LocalName(LocalName {
sink.push(Component::LocalName(LocalName {
lower_name: from_cow_str(to_ascii_lowercase(&name)),
name: from_cow_str(name.into()),
}))
}
None => {
sequence.push(Component::ExplicitUniversalType)
sink.push(Component::ExplicitUniversalType)
}
}
Ok(true)
Expand Down Expand Up @@ -1422,7 +1424,7 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P,
where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl
{
// 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.
loop {
Expand Down Expand Up @@ -1476,7 +1478,7 @@ fn parse_compound_selector<'i, 't, P, E, Impl>(
}
}
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 there was no explicit type selector, but there is a
// default namespace, there is an implicit "<defaultns>|*" type
Expand All @@ -1496,8 +1498,9 @@ fn parse_compound_selector<'i, 't, P, E, Impl>(
empty = false
}
Some(SimpleSelectorParseResult::PseudoElement(p)) => {
// Try to parse state to its right.
let mut state_selectors = ParseVec::new();
// Try to parse state to its right. There are only 3 allowable
// state selectors that can go on pseudo-elements.
let mut state_selectors = SmallVec::<[Component<Impl>; 3]>::new();

loop {
match input.next_including_whitespace() {
Expand Down

0 comments on commit fac5aeb

Please sign in to comment.