Bug 1397614 part 2. Avoid array overallocation when parsing background shorthand. r=xidorn
MozReview-Commit-ID: CX0hjjsSKXs
--- a/servo/components/style/properties/shorthand/background.mako.rs
+++ b/servo/components/style/properties/shorthand/background.mako.rs
@@ -32,17 +32,21 @@
}
}
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Longhands, ParseError<'i>> {
let mut background_color = None;
% for name in "image position_x position_y repeat size attachment origin clip".split():
- let mut background_${name} = background_${name}::SpecifiedValue(Vec::new());
+ // Vec grows from 0 to 4 by default on first push(). So allocate
+ // with capacity 1, so in the common case of only one item we don't
+ // way overallocate. Note that we always push at least one item if
+ // parsing succeeds.
+ let mut background_${name} = background_${name}::SpecifiedValue(Vec::with_capacity(1));
% endfor
input.parse_comma_separated(|input| {
// background-color can only be in the last element, so if it
// is parsed anywhere before, the value is invalid.
if background_color.is_some() {
return Err(StyleParseError::UnspecifiedError.into());
}
@@ -192,18 +196,22 @@
sub_properties="background-position-x background-position-y"
spec="https://drafts.csswg.org/css-backgrounds-4/#the-background-position">
use properties::longhands::{background_position_x, background_position_y};
use values::specified::AllowQuirks;
use values::specified::position::Position;
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Longhands, ParseError<'i>> {
- let mut position_x = background_position_x::SpecifiedValue(Vec::new());
- let mut position_y = background_position_y::SpecifiedValue(Vec::new());
+ // Vec grows from 0 to 4 by default on first push(). So allocate with
+ // capacity 1, so in the common case of only one item we don't way
+ // overallocate. Note that we always push at least one item if parsing
+ // succeeds.
+ let mut position_x = background_position_x::SpecifiedValue(Vec::with_capacity(1));
+ let mut position_y = background_position_y::SpecifiedValue(Vec::with_capacity(1));
let mut any = false;
input.parse_comma_separated(|input| {
let value = Position::parse_quirky(context, input, AllowQuirks::Yes)?;
position_x.0.push(value.horizontal);
position_y.0.push(value.vertical);
any = true;
Ok(())
--- a/servo/components/style/properties/shorthand/mask.mako.rs
+++ b/servo/components/style/properties/shorthand/mask.mako.rs
@@ -33,17 +33,21 @@
% endif
}
}
}
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Longhands, ParseError<'i>> {
% for name in "image mode position_x position_y size repeat origin clip composite".split():
- let mut mask_${name} = mask_${name}::SpecifiedValue(Vec::new());
+ // Vec grows from 0 to 4 by default on first push(). So allocate
+ // with capacity 1, so in the common case of only one item we don't
+ // way overallocate. Note that we always push at least one item if
+ // parsing succeeds.
+ let mut mask_${name} = mask_${name}::SpecifiedValue(Vec::with_capacity(1));
% endfor
input.parse_comma_separated(|input| {
% for name in "image mode position size repeat origin clip composite".split():
let mut ${name} = None;
% endfor
loop {
if image.is_none() {
@@ -178,18 +182,22 @@
sub_properties="mask-position-x mask-position-y"
spec="https://drafts.csswg.org/css-masks-4/#the-mask-position">
use properties::longhands::{mask_position_x,mask_position_y};
use values::specified::position::Position;
use parser::Parse;
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Longhands, ParseError<'i>> {
- let mut position_x = mask_position_x::SpecifiedValue(Vec::new());
- let mut position_y = mask_position_y::SpecifiedValue(Vec::new());
+ // Vec grows from 0 to 4 by default on first push(). So allocate with
+ // capacity 1, so in the common case of only one item we don't way
+ // overallocate. Note that we always push at least one item if parsing
+ // succeeds.
+ let mut position_x = mask_position_x::SpecifiedValue(Vec::with_capacity(1));
+ let mut position_y = mask_position_y::SpecifiedValue(Vec::with_capacity(1));
let mut any = false;
input.parse_comma_separated(|input| {
let value = Position::parse(context, input)?;
position_x.0.push(value.horizontal);
position_y.0.push(value.vertical);
any = true;
Ok(())