servo: Merge #16369 - Store style system options in the global style data and shared style context (from bholley:style_system_options); r=SimonSapin

I wanted to add an environmental variable to disable the style sharing
cache for gecko, but the current pattern involves lazy_static!, which
involves an atomic operation on lookup, which is a bit hot to do each
time we try to share styles. This makes that work happen once per
process.

Source-Repo: https://github.com/servo/servo
Source-Revision: 54ecfb155dba40382764ee20186a31f067a507be

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 35cbfe0f6490eadf25d9de020f0d2ea851badaba
This commit is contained in:
Bobby Holley 2017-04-12 02:27:02 -05:00
Родитель 372552d50a
Коммит 9ab23a87f3
7 изменённых файлов: 66 добавлений и 50 удалений

Просмотреть файл

@ -107,7 +107,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::{Receiver, Sender, channel}; use std::sync::mpsc::{Receiver, Sender, channel};
use std::thread; use std::thread;
use style::animation::Animation; use style::animation::Animation;
use style::context::{QuirksMode, ReflowGoal, SharedStyleContext, ThreadLocalStyleContextCreationInfo}; use style::context::{QuirksMode, ReflowGoal, SharedStyleContext};
use style::context::{StyleSystemOptions, ThreadLocalStyleContextCreationInfo};
use style::data::StoredRestyleHint; use style::data::StoredRestyleHint;
use style::dom::{ShowSubtree, ShowSubtreeDataAndPrimaryValues, TElement, TNode}; use style::dom::{ShowSubtree, ShowSubtreeDataAndPrimaryValues, TElement, TNode};
use style::error_reporting::StdoutErrorReporter; use style::error_reporting::StdoutErrorReporter;
@ -516,6 +517,7 @@ impl LayoutThread {
LayoutContext { LayoutContext {
style_context: SharedStyleContext { style_context: SharedStyleContext {
stylist: rw_data.stylist.clone(), stylist: rw_data.stylist.clone(),
options: StyleSystemOptions::default(),
guards: guards, guards: guards,
running_animations: self.running_animations.clone(), running_animations: self.running_animations.clone(),
expired_animations: self.expired_animations.clone(), expired_animations: self.expired_animations.clone(),

Просмотреть файл

@ -61,6 +61,42 @@ pub enum QuirksMode {
NoQuirks, NoQuirks,
} }
/// A global options structure for the style system. We use this instead of
/// opts to abstract across Gecko and Servo.
#[derive(Clone)]
pub struct StyleSystemOptions {
/// Whether the style sharing cache is disabled.
pub disable_style_sharing_cache: bool,
/// Whether we should dump statistics about the style system.
pub dump_style_statistics: bool,
}
#[cfg(feature = "gecko")]
fn get_env(name: &str) -> bool {
match env::var(name) {
Ok(s) => !s.is_empty(),
Err(_) => false,
}
}
impl Default for StyleSystemOptions {
#[cfg(feature = "servo")]
fn default() -> Self {
StyleSystemOptions {
disable_style_sharing_cache: opts::get().disable_share_style_cache,
dump_style_statistics: opts::get().style_sharing_stats,
}
}
#[cfg(feature = "gecko")]
fn default() -> Self {
StyleSystemOptions {
disable_style_sharing_cache: get_env("DISABLE_STYLE_SHARING_CACHE"),
dump_style_statistics: get_env("DUMP_STYLE_STATISTICS"),
}
}
}
/// A shared style context. /// A shared style context.
/// ///
/// There's exactly one of these during a given restyle traversal, and it's /// There's exactly one of these during a given restyle traversal, and it's
@ -69,6 +105,9 @@ pub struct SharedStyleContext<'a> {
/// The CSS selector stylist. /// The CSS selector stylist.
pub stylist: Arc<Stylist>, pub stylist: Arc<Stylist>,
/// Configuration options.
pub options: StyleSystemOptions,
/// Guards for pre-acquired locks /// Guards for pre-acquired locks
pub guards: StylesheetGuards<'a>, pub guards: StylesheetGuards<'a>,
@ -175,35 +214,7 @@ impl fmt::Display for TraversalStatistics {
} }
} }
#[cfg(not(feature = "servo"))]
lazy_static! {
/// Whether to dump style statistics, computed statically. We use an environmental
/// variable so that this is easy to set for Gecko builds, and matches the
/// mechanism we use to dump statistics on the Gecko style system.
static ref DUMP_STYLE_STATISTICS: bool = {
match env::var("DUMP_STYLE_STATISTICS") {
Ok(s) => !s.is_empty(),
Err(_) => false,
}
};
}
#[cfg(feature = "servo")]
fn shall_stat_style_sharing() -> bool {
opts::get().style_sharing_stats
}
#[cfg(not(feature = "servo"))]
fn shall_stat_style_sharing() -> bool {
*DUMP_STYLE_STATISTICS
}
impl TraversalStatistics { impl TraversalStatistics {
/// Returns whether statistics dumping is enabled.
pub fn should_dump() -> bool {
shall_stat_style_sharing()
}
/// Computes the traversal time given the start time in seconds. /// Computes the traversal time given the start time in seconds.
pub fn finish<E, D>(&mut self, traversal: &D, start: f64) pub fn finish<E, D>(&mut self, traversal: &D, start: f64)
where E: TElement, where E: TElement,

Просмотреть файл

@ -4,6 +4,7 @@
//! Global style data //! Global style data
use context::StyleSystemOptions;
use num_cpus; use num_cpus;
use rayon; use rayon;
use shared_lock::SharedRwLock; use shared_lock::SharedRwLock;
@ -20,6 +21,9 @@ pub struct GlobalStyleData {
/// Shared RWLock for CSSOM objects /// Shared RWLock for CSSOM objects
pub shared_lock: SharedRwLock, pub shared_lock: SharedRwLock,
/// Global style system options determined by env vars.
pub options: StyleSystemOptions,
} }
lazy_static! { lazy_static! {
@ -45,6 +49,7 @@ lazy_static! {
num_threads: num_threads, num_threads: num_threads,
style_thread_pool: pool, style_thread_pool: pool,
shared_lock: SharedRwLock::new(), shared_lock: SharedRwLock::new(),
options: StyleSystemOptions::default(),
} }
}; };
} }

Просмотреть файл

@ -25,7 +25,6 @@ use selector_parser::{PseudoElement, RestyleDamage, SelectorImpl};
use selectors::bloom::BloomFilter; use selectors::bloom::BloomFilter;
use selectors::matching::{ElementSelectorFlags, StyleRelations}; use selectors::matching::{ElementSelectorFlags, StyleRelations};
use selectors::matching::AFFECTED_BY_PSEUDO_ELEMENTS; use selectors::matching::AFFECTED_BY_PSEUDO_ELEMENTS;
#[cfg(feature = "servo")] use servo_config::opts;
use sink::ForgetfulSink; use sink::ForgetfulSink;
use std::sync::Arc; use std::sync::Arc;
use stylist::ApplicableDeclarationBlock; use stylist::ApplicableDeclarationBlock;
@ -727,16 +726,6 @@ pub enum StyleSharingBehavior {
Disallow, Disallow,
} }
#[cfg(feature = "servo")]
fn is_share_style_cache_disabled() -> bool {
opts::get().disable_share_style_cache
}
#[cfg(not(feature = "servo"))]
fn is_share_style_cache_disabled() -> bool {
false
}
/// The public API that elements expose for selector matching. /// The public API that elements expose for selector matching.
pub trait MatchMethods : TElement { pub trait MatchMethods : TElement {
/// Performs selector matching and property cascading on an element and its eager pseudos. /// Performs selector matching and property cascading on an element and its eager pseudos.
@ -1033,7 +1022,7 @@ pub trait MatchMethods : TElement {
context: &mut StyleContext<Self>, context: &mut StyleContext<Self>,
data: &mut AtomicRefMut<ElementData>) data: &mut AtomicRefMut<ElementData>)
-> StyleSharingResult { -> StyleSharingResult {
if is_share_style_cache_disabled() { if context.shared.options.disable_style_sharing_cache {
debug!("{:?} Cannot share style: style sharing cache disabled", self); debug!("{:?} Cannot share style: style sharing cache disabled", self);
return StyleSharingResult::CannotShare return StyleSharingResult::CannotShare
} }

Просмотреть файл

@ -44,7 +44,7 @@ pub fn traverse_dom<E, D>(traversal: &D,
where E: TElement, where E: TElement,
D: DomTraversal<E>, D: DomTraversal<E>,
{ {
let dump_stats = TraversalStatistics::should_dump(); let dump_stats = traversal.shared_context().options.dump_style_statistics;
let start_time = if dump_stats { Some(time::precise_time_s()) } else { None }; let start_time = if dump_stats { Some(time::precise_time_s()) } else { None };
debug_assert!(traversal.is_parallel()); debug_assert!(traversal.is_parallel());

Просмотреть файл

@ -6,7 +6,6 @@
#![deny(missing_docs)] #![deny(missing_docs)]
use context::TraversalStatistics;
use dom::{TElement, TNode}; use dom::{TElement, TNode};
use std::borrow::BorrowMut; use std::borrow::BorrowMut;
use std::collections::VecDeque; use std::collections::VecDeque;
@ -22,7 +21,7 @@ pub fn traverse_dom<E, D>(traversal: &D,
where E: TElement, where E: TElement,
D: DomTraversal<E>, D: DomTraversal<E>,
{ {
let dump_stats = TraversalStatistics::should_dump(); let dump_stats = traversal.shared_context().options.dump_style_statistics;
let start_time = if dump_stats { Some(time::precise_time_s()) } else { None }; let start_time = if dump_stats { Some(time::precise_time_s()) } else { None };
debug_assert!(!traversal.is_parallel()); debug_assert!(!traversal.is_parallel());

Просмотреть файл

@ -22,7 +22,7 @@ use style::dom::{ShowSubtreeData, TElement, TNode};
use style::error_reporting::StdoutErrorReporter; use style::error_reporting::StdoutErrorReporter;
use style::font_metrics::get_metrics_provider_for_product; use style::font_metrics::get_metrics_provider_for_product;
use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl}; use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl};
use style::gecko::global_style_data::GLOBAL_STYLE_DATA; use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData};
use style::gecko::restyle_damage::GeckoRestyleDamage; use style::gecko::restyle_damage::GeckoRestyleDamage;
use style::gecko::selector_parser::{SelectorImpl, PseudoElement}; use style::gecko::selector_parser::{SelectorImpl, PseudoElement};
use style::gecko::traversal::RecalcStyleOnly; use style::gecko::traversal::RecalcStyleOnly;
@ -143,7 +143,8 @@ unsafe fn dummy_url_data() -> &'static RefPtr<URLExtraData> {
RefPtr::from_ptr_ref(&DUMMY_URL_DATA) RefPtr::from_ptr_ref(&DUMMY_URL_DATA)
} }
fn create_shared_context<'a>(guard: &'a SharedRwLockReadGuard, fn create_shared_context<'a>(global_style_data: &GlobalStyleData,
guard: &'a SharedRwLockReadGuard,
per_doc_data: &PerDocumentStyleDataImpl, per_doc_data: &PerDocumentStyleDataImpl,
traversal_flags: TraversalFlags) -> SharedStyleContext<'a> { traversal_flags: TraversalFlags) -> SharedStyleContext<'a> {
let local_context_data = let local_context_data =
@ -151,6 +152,7 @@ fn create_shared_context<'a>(guard: &'a SharedRwLockReadGuard,
SharedStyleContext { SharedStyleContext {
stylist: per_doc_data.stylist.clone(), stylist: per_doc_data.stylist.clone(),
options: global_style_data.options.clone(),
guards: StylesheetGuards::same(guard), guards: StylesheetGuards::same(guard),
running_animations: per_doc_data.running_animations.clone(), running_animations: per_doc_data.running_animations.clone(),
expired_animations: per_doc_data.expired_animations.clone(), expired_animations: per_doc_data.expired_animations.clone(),
@ -187,7 +189,10 @@ fn traverse_subtree(element: GeckoElement, raw_data: RawServoStyleSetBorrowed,
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
let shared_style_context = create_shared_context(&guard, &per_doc_data, traversal_flags); let shared_style_context = create_shared_context(&global_style_data,
&guard,
&per_doc_data,
traversal_flags);
let traversal_driver = if global_style_data.style_thread_pool.is_none() { let traversal_driver = if global_style_data.style_thread_pool.is_none() {
TraversalDriver::Sequential TraversalDriver::Sequential
@ -407,8 +412,10 @@ pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawSe
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow(); let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
let shared_context = &create_shared_context(&guard, &doc_data, TraversalFlags::empty()); let shared_context = &create_shared_context(&global_style_data,
&guard,
&doc_data,
TraversalFlags::empty());
let element = GeckoElement(element); let element = GeckoElement(element);
let element_data = element.borrow_data().unwrap(); let element_data = element.borrow_data().unwrap();
let styles = element_data.styles(); let styles = element_data.styles();
@ -1691,7 +1698,10 @@ pub extern "C" fn Servo_ResolveStyleLazily(element: RawGeckoElementBorrowed,
} }
// We don't have the style ready. Go ahead and compute it as necessary. // We don't have the style ready. Go ahead and compute it as necessary.
let shared = create_shared_context(&guard, &mut doc_data.borrow_mut(), TraversalFlags::empty()); let shared = create_shared_context(&global_style_data,
&guard,
&mut doc_data.borrow_mut(),
TraversalFlags::empty());
let mut tlc = ThreadLocalStyleContext::new(&shared); let mut tlc = ThreadLocalStyleContext::new(&shared);
let mut context = StyleContext { let mut context = StyleContext {
shared: &shared, shared: &shared,