Auto merge of #16369 - bholley:style_system_options, r=SimonSapin

Store style system options in the global style data and shared style context.

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.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16369)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-04-12 02:27:02 -05:00 committed by GitHub
commit 54ecfb155d
7 changed files with 66 additions and 50 deletions

View file

@ -107,7 +107,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::{Receiver, Sender, channel};
use std::thread;
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::dom::{ShowSubtree, ShowSubtreeDataAndPrimaryValues, TElement, TNode};
use style::error_reporting::StdoutErrorReporter;
@ -516,6 +517,7 @@ impl LayoutThread {
LayoutContext {
style_context: SharedStyleContext {
stylist: rw_data.stylist.clone(),
options: StyleSystemOptions::default(),
guards: guards,
running_animations: self.running_animations.clone(),
expired_animations: self.expired_animations.clone(),

View file

@ -61,6 +61,42 @@ pub enum QuirksMode {
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.
///
/// 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.
pub stylist: Arc<Stylist>,
/// Configuration options.
pub options: StyleSystemOptions,
/// Guards for pre-acquired locks
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 {
/// 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.
pub fn finish<E, D>(&mut self, traversal: &D, start: f64)
where E: TElement,

View file

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

View file

@ -25,7 +25,6 @@ use selector_parser::{PseudoElement, RestyleDamage, SelectorImpl};
use selectors::bloom::BloomFilter;
use selectors::matching::{ElementSelectorFlags, StyleRelations};
use selectors::matching::AFFECTED_BY_PSEUDO_ELEMENTS;
#[cfg(feature = "servo")] use servo_config::opts;
use sink::ForgetfulSink;
use std::sync::Arc;
use stylist::ApplicableDeclarationBlock;
@ -727,16 +726,6 @@ pub enum StyleSharingBehavior {
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.
pub trait MatchMethods : TElement {
/// 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>,
data: &mut AtomicRefMut<ElementData>)
-> StyleSharingResult {
if is_share_style_cache_disabled() {
if context.shared.options.disable_style_sharing_cache {
debug!("{:?} Cannot share style: style sharing cache disabled", self);
return StyleSharingResult::CannotShare
}

View file

@ -44,7 +44,7 @@ pub fn traverse_dom<E, D>(traversal: &D,
where E: TElement,
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 };
debug_assert!(traversal.is_parallel());

View file

@ -6,7 +6,6 @@
#![deny(missing_docs)]
use context::TraversalStatistics;
use dom::{TElement, TNode};
use std::borrow::BorrowMut;
use std::collections::VecDeque;
@ -22,7 +21,7 @@ pub fn traverse_dom<E, D>(traversal: &D,
where E: TElement,
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 };
debug_assert!(!traversal.is_parallel());