servo: Merge #20017 - Optimise more AnimationValue methods 🐉🐲 (from servo:derive-all-the-things); r=emilio

Optimise more AnimationValue methods 🐉🐲

```
__TEXT	__DATA	__OBJC	others	dec	hex
87101440	5226496	0	64122880	156450816	9534000	XUL.old
87072768	5226496	0	64122880	156422144	952d000	XUL.new
```

Source-Repo: https://github.com/servo/servo
Source-Revision: 9c94fe427942fd73cc641e28c13ec9fa9305a01d

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 392398e22c97bfe97e5fbace1c77d5cdd9f4d2b0
This commit is contained in:
Anthony Ramine 2018-02-11 18:43:17 -05:00
parent e878eeef74
commit 7af0ffd626
2 changed files with 126 additions and 22 deletions

View File

@ -24,11 +24,11 @@ use properties::longhands::visibility::computed_value::T as Visibility;
#[cfg(feature = "gecko")]
use properties::PropertyId;
use properties::{LonghandId, ShorthandId};
use selectors::parser::SelectorParseErrorKind;
use servo_arc::Arc;
use smallvec::SmallVec;
use std::{cmp, mem, ptr};
use std::{cmp, ptr};
use std::fmt::{self, Write};
use std::mem::{self, ManuallyDrop};
#[cfg(feature = "gecko")] use hash::FnvHashMap;
use style_traits::{CssWriter, ParseError, ToCss};
use super::ComputedValues;
@ -141,21 +141,42 @@ impl TransitionProperty {
/// Parse a transition-property value.
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
// FIXME(https://github.com/rust-lang/rust/issues/33156): remove this
// enum and use PropertyId when stable Rust allows destructors in
// statics.
//
// FIXME: This should handle aliases too.
pub enum StaticId {
All,
Longhand(LonghandId),
Shorthand(ShorthandId),
}
ascii_case_insensitive_phf_map! {
static_id -> StaticId = {
"all" => StaticId::All,
% for prop in data.shorthands_except_all():
"${prop.name}" => StaticId::Shorthand(ShorthandId::${prop.camel_case}),
% endfor
% for prop in data.longhands:
"${prop.name}" => StaticId::Longhand(LonghandId::${prop.camel_case}),
% endfor
}
}
let location = input.current_source_location();
let ident = input.expect_ident()?;
match_ignore_ascii_case! { &ident,
"all" => Ok(TransitionProperty::All),
% for prop in data.shorthands_except_all():
"${prop.name}" => Ok(TransitionProperty::Shorthand(ShorthandId::${prop.camel_case})),
% endfor
% for prop in data.longhands:
"${prop.name}" => Ok(TransitionProperty::Longhand(LonghandId::${prop.camel_case})),
% endfor
"none" => Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))),
_ => CustomIdent::from_ident(location, ident, &[]).map(TransitionProperty::Unsupported),
}
}
Ok(match static_id(&ident) {
Some(&StaticId::All) => TransitionProperty::All,
Some(&StaticId::Longhand(id)) => TransitionProperty::Longhand(id),
Some(&StaticId::Shorthand(id)) => TransitionProperty::Shorthand(id),
None => {
TransitionProperty::Unsupported(
CustomIdent::from_ident(location, ident, &["none"])?,
)
},
})
}
/// Convert TransitionProperty to nsCSSPropertyID.
#[cfg(feature = "gecko")]
@ -345,8 +366,8 @@ unsafe impl HasSimpleFFI for AnimationValueMap {}
///
/// FIXME: We need to add a path for custom properties, but that's trivial after
/// this (is a similar path to that of PropertyDeclaration).
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
#[derive(Debug)]
#[repr(u16)]
pub enum AnimationValue {
% for prop in data.longhands:
@ -370,6 +391,95 @@ pub enum AnimationValue {
unanimated.append(prop)
%>
#[repr(C)]
struct AnimationValueVariantRepr<T> {
tag: u16,
value: T
}
impl Clone for AnimationValue {
#[inline]
fn clone(&self) -> Self {
use self::AnimationValue::*;
<%
[copy, others] = [list(g) for _, g in groupby(animated, key=lambda x: not x.specified_is_copy())]
%>
let self_tag = unsafe { *(self as *const _ as *const u16) };
if self_tag <= LonghandId::${copy[-1].camel_case} as u16 {
#[derive(Clone, Copy)]
#[repr(u16)]
enum CopyVariants {
% for prop in copy:
_${prop.camel_case}(${prop.animated_type()}),
% endfor
}
unsafe {
let mut out = mem::uninitialized();
ptr::write(
&mut out as *mut _ as *mut CopyVariants,
*(self as *const _ as *const CopyVariants),
);
return out;
}
}
match *self {
% for ty, props in groupby(others, key=lambda x: x.animated_type()):
<% props = list(props) %>
${" |\n".join("{}(ref value)".format(prop.camel_case) for prop in props)} => {
% if len(props) == 1:
${props[0].camel_case}(value.clone())
% else:
unsafe {
let mut out = ManuallyDrop::new(mem::uninitialized());
ptr::write(
&mut out as *mut _ as *mut AnimationValueVariantRepr<${ty}>,
AnimationValueVariantRepr {
tag: *(self as *const _ as *const u16),
value: value.clone(),
},
);
ManuallyDrop::into_inner(out)
}
% endif
}
% endfor
_ => unsafe { debug_unreachable!() }
}
}
}
impl PartialEq for AnimationValue {
#[inline]
fn eq(&self, other: &Self) -> bool {
use self::AnimationValue::*;
unsafe {
let this_tag = *(self as *const _ as *const u16);
let other_tag = *(other as *const _ as *const u16);
if this_tag != other_tag {
return false;
}
match *self {
% for ty, props in groupby(animated, key=lambda x: x.animated_type()):
${" |\n".join("{}(ref this)".format(prop.camel_case) for prop in props)} => {
let other_repr =
&*(other as *const _ as *const AnimationValueVariantRepr<${ty}>);
*this == other_repr.value
}
% endfor
${" |\n".join("{}(void)".format(prop.camel_case) for prop in unanimated)} => {
void::unreachable(void)
}
}
}
}
}
impl AnimationValue {
/// Returns the longhand id this animated value corresponds to.
#[inline]
@ -564,12 +674,6 @@ fn animate_discrete<T: Clone>(this: &T, other: &T, procedure: Procedure) -> Resu
}
}
#[repr(C)]
struct AnimationValueVariantRepr<T> {
tag: u16,
value: T
}
impl Animate for AnimationValue {
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
Ok(unsafe {

View File

@ -88,7 +88,7 @@ impl ToAnimatedZero for BorderCornerRadius {
/// The computed value of the `border-image-repeat` property:
///
/// https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
pub struct BorderImageRepeat(pub BorderImageRepeatKeyword, pub BorderImageRepeatKeyword);
impl BorderImageRepeat {