style: Use atoms for grid line names.

The style system already atomizes all CustomIdent values, which means that we're
just wasting memory and CPU by doing string copies all over the place.

This patch fixes it. This also simplifies further changes to use as much of the
rust data structures as possible.

I had to switch from nsTHashtable to mozilla::HashTable because the former
doesn't handle well non-default-constructible structs (like NamedLine, which
now has a StyleAtom, which is not default-constructible).

Differential Revision: https://phabricator.services.mozilla.com/D35119
This commit is contained in:
Emilio Cobos Álvarez 2019-06-19 05:58:11 +00:00
parent 6cb588d2b5
commit c87da27bca
No known key found for this signature in database
GPG key ID: E1152D0994E4BF8A
2 changed files with 34 additions and 29 deletions

View file

@ -1137,11 +1137,12 @@ fn static_assert() {
use crate::gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine}; use crate::gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine};
let line = &mut self.gecko.${value.gecko}; let line = &mut self.gecko.${value.gecko};
let line_name = &mut line.mLineName; line.mLineName.set_move(unsafe {
match v.ident.as_ref() { RefPtr::from_addrefed(match v.ident {
Some(i) => i.0.with_str(|s| line_name.assign(s)), Some(i) => i.0,
None => line_name.assign(""), None => atom!(""),
}; }.into_addrefed())
});
line.mHasSpan = v.is_span; line.mHasSpan = v.is_span;
if let Some(integer) = v.line_num { if let Some(integer) = v.line_num {
// clamping the integer between a range // clamping the integer between a range
@ -1155,7 +1156,9 @@ fn static_assert() {
pub fn copy_${value.name}_from(&mut self, other: &Self) { pub fn copy_${value.name}_from(&mut self, other: &Self) {
self.gecko.${value.gecko}.mHasSpan = other.gecko.${value.gecko}.mHasSpan; self.gecko.${value.gecko}.mHasSpan = other.gecko.${value.gecko}.mHasSpan;
self.gecko.${value.gecko}.mInteger = other.gecko.${value.gecko}.mInteger; self.gecko.${value.gecko}.mInteger = other.gecko.${value.gecko}.mInteger;
self.gecko.${value.gecko}.mLineName.assign(&*other.gecko.${value.gecko}.mLineName); unsafe {
self.gecko.${value.gecko}.mLineName.set(&other.gecko.${value.gecko}.mLineName);
}
} }
pub fn reset_${value.name}(&mut self, other: &Self) { pub fn reset_${value.name}(&mut self, other: &Self) {
@ -1168,11 +1171,11 @@ fn static_assert() {
longhands::${value.name}::computed_value::T { longhands::${value.name}::computed_value::T {
is_span: self.gecko.${value.gecko}.mHasSpan, is_span: self.gecko.${value.gecko}.mHasSpan,
ident: { ident: {
let name = self.gecko.${value.gecko}.mLineName.to_string(); let name = unsafe { Atom::from_raw(self.gecko.${value.gecko}.mLineName.mRawPtr) };
if name.len() == 0 { if name == atom!("") {
None None
} else { } else {
Some(CustomIdent(Atom::from(name))) Some(CustomIdent(name))
} }
}, },
line_num: line_num:
@ -1211,20 +1214,21 @@ fn static_assert() {
pub fn set_grid_template_${kind}(&mut self, v: longhands::grid_template_${kind}::computed_value::T) { pub fn set_grid_template_${kind}(&mut self, v: longhands::grid_template_${kind}::computed_value::T) {
<% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %> <% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
use crate::gecko_bindings::structs::{nsTArray, nsStyleGridLine_kMaxLine}; use crate::gecko_bindings::structs::{nsTArray, nsStyleGridLine_kMaxLine};
use nsstring::nsCString;
use std::usize; use std::usize;
use crate::values::CustomIdent; use crate::values::CustomIdent;
use crate::values::generics::grid::TrackListType::Auto; use crate::values::generics::grid::TrackListType::Auto;
use crate::values::generics::grid::{GridTemplateComponent, RepeatCount}; use crate::values::generics::grid::{GridTemplateComponent, RepeatCount};
#[inline] #[inline]
fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<nsCString>) { fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<structs::RefPtr<structs::nsAtom>>) {
unsafe { unsafe {
bindings::Gecko_ResizeTArrayForCStrings(gecko_names, servo_names.len() as u32); bindings::Gecko_ResizeAtomArray(gecko_names, servo_names.len() as u32);
} }
for (servo_name, gecko_name) in servo_names.iter().zip(gecko_names.iter_mut()) { for (servo_name, gecko_name) in servo_names.iter().zip(gecko_names.iter_mut()) {
servo_name.0.with_str(|s| gecko_name.assign(s)) gecko_name.set_move(unsafe {
RefPtr::from_addrefed(servo_name.0.clone().into_addrefed())
});
} }
} }
@ -1262,9 +1266,9 @@ fn static_assert() {
auto_track_size = Some(auto_repeat.track_sizes.get(0).unwrap().clone()); auto_track_size = Some(auto_repeat.track_sizes.get(0).unwrap().clone());
} else { } else {
unsafe { unsafe {
bindings::Gecko_ResizeTArrayForCStrings( bindings::Gecko_ResizeAtomArray(
&mut value.mRepeatAutoLineNameListBefore, 0); &mut value.mRepeatAutoLineNameListBefore, 0);
bindings::Gecko_ResizeTArrayForCStrings( bindings::Gecko_ResizeAtomArray(
&mut value.mRepeatAutoLineNameListAfter, 0); &mut value.mRepeatAutoLineNameListAfter, 0);
} }
} }
@ -1338,7 +1342,6 @@ fn static_assert() {
pub fn clone_grid_template_${kind}(&self) -> longhands::grid_template_${kind}::computed_value::T { pub fn clone_grid_template_${kind}(&self) -> longhands::grid_template_${kind}::computed_value::T {
<% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %> <% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
use crate::gecko_bindings::structs::nsTArray; use crate::gecko_bindings::structs::nsTArray;
use nsstring::nsCString;
use crate::values::CustomIdent; use crate::values::CustomIdent;
use crate::values::generics::grid::{GridTemplateComponent, LineNameList, RepeatCount}; use crate::values::generics::grid::{GridTemplateComponent, LineNameList, RepeatCount};
use crate::values::generics::grid::{TrackList, TrackListType, TrackListValue, TrackRepeat, TrackSize}; use crate::values::generics::grid::{TrackList, TrackListType, TrackListValue, TrackRepeat, TrackSize};
@ -1349,16 +1352,17 @@ fn static_assert() {
}; };
#[inline] #[inline]
fn to_boxed_customident_slice(gecko_names: &nsTArray<nsCString>) -> Box<[CustomIdent]> { fn to_boxed_customident_slice(gecko_names: &nsTArray<structs::RefPtr<structs::nsAtom>>) -> Box<[CustomIdent]> {
let idents: Vec<CustomIdent> = gecko_names.iter().map(|gecko_name| { let idents: Vec<CustomIdent> = gecko_names.iter().map(|gecko_name| {
CustomIdent(Atom::from(unsafe { gecko_name.as_str_unchecked() })) CustomIdent(unsafe { Atom::from_raw(gecko_name.mRawPtr) })
}).collect(); }).collect();
idents.into_boxed_slice() idents.into_boxed_slice()
} }
#[inline] #[inline]
fn to_line_names_vec(gecko_line_names: &nsTArray<nsTArray<nsCString>>) fn to_line_names_vec(
-> Vec<Box<[CustomIdent]>> { gecko_line_names: &nsTArray<nsTArray<structs::RefPtr<structs::nsAtom>>>,
) -> Vec<Box<[CustomIdent]>> {
gecko_line_names.iter().map(|gecko_names| { gecko_line_names.iter().map(|gecko_names| {
to_boxed_customident_slice(gecko_names) to_boxed_customident_slice(gecko_names)
}).collect() }).collect()

View file

@ -7,7 +7,8 @@
//! //!
//! [position]: https://drafts.csswg.org/css-backgrounds-3/#position //! [position]: https://drafts.csswg.org/css-backgrounds-3/#position
use crate::hash::FxHashMap; use crate::Atom;
use crate::selector_map::PrecomputedHashMap;
use crate::parser::{Parse, ParserContext}; use crate::parser::{Parse, ParserContext};
use crate::str::HTML_SPACE_CHARACTERS; use crate::str::HTML_SPACE_CHARACTERS;
use crate::values::computed::LengthPercentage as ComputedLengthPercentage; use crate::values::computed::LengthPercentage as ComputedLengthPercentage;
@ -500,15 +501,15 @@ impl TemplateAreas {
let mut width = 0; let mut width = 0;
{ {
let mut row = 0u32; let mut row = 0u32;
let mut area_indices = FxHashMap::<&str, usize>::default(); let mut area_indices = PrecomputedHashMap::<Atom, usize>::default();
for string in &strings { for string in &strings {
let mut current_area_index: Option<usize> = None; let mut current_area_index: Option<usize> = None;
row += 1; row += 1;
let mut column = 0u32; let mut column = 0u32;
for token in TemplateAreasTokenizer(string) { for token in TemplateAreasTokenizer(string) {
column += 1; column += 1;
let token = if let Some(token) = token? { let name = if let Some(token) = token? {
token Atom::from(token)
} else { } else {
if let Some(index) = current_area_index.take() { if let Some(index) = current_area_index.take() {
if areas[index].columns.end != column { if areas[index].columns.end != column {
@ -518,7 +519,7 @@ impl TemplateAreas {
continue; continue;
}; };
if let Some(index) = current_area_index { if let Some(index) = current_area_index {
if &*areas[index].name == token { if areas[index].name == name {
if areas[index].rows.start == row { if areas[index].rows.start == row {
areas[index].columns.end += 1; areas[index].columns.end += 1;
} }
@ -528,7 +529,7 @@ impl TemplateAreas {
return Err(()); return Err(());
} }
} }
if let Some(index) = area_indices.get(token).cloned() { if let Some(index) = area_indices.get(&name).cloned() {
if areas[index].columns.start != column || areas[index].rows.end != row { if areas[index].columns.start != column || areas[index].rows.end != row {
return Err(()); return Err(());
} }
@ -537,8 +538,9 @@ impl TemplateAreas {
continue; continue;
} }
let index = areas.len(); let index = areas.len();
assert!(area_indices.insert(name.clone(), index).is_none());
areas.push(NamedArea { areas.push(NamedArea {
name: token.to_owned().into(), name,
columns: UnsignedRange { columns: UnsignedRange {
start: column, start: column,
end: column + 1, end: column + 1,
@ -548,7 +550,6 @@ impl TemplateAreas {
end: row + 1, end: row + 1,
}, },
}); });
assert!(area_indices.insert(token, index).is_none());
current_area_index = Some(index); current_area_index = Some(index);
} }
if let Some(index) = current_area_index { if let Some(index) = current_area_index {
@ -629,7 +630,7 @@ pub struct UnsignedRange {
/// grid-placement properties. /// grid-placement properties.
pub struct NamedArea { pub struct NamedArea {
/// Name of the `named area` /// Name of the `named area`
pub name: crate::OwnedStr, pub name: Atom,
/// Rows of the `named area` /// Rows of the `named area`
pub rows: UnsignedRange, pub rows: UnsignedRange,
/// Columns of the `named area` /// Columns of the `named area`