mirror of
https://github.com/servo/servo.git
synced 2025-06-20 07:08:59 +01:00
Servo currently uses `heapsize`, but Stylo/Gecko use `malloc_size_of`. `malloc_size_of` is better -- it handles various cases that `heapsize` does not -- so this patch changes Servo to use `malloc_size_of`. This patch makes the following changes to the `malloc_size_of` crate. - Adds `MallocSizeOf` trait implementations for numerous types, some built-in (e.g. `VecDeque`), some external and Servo-only (e.g. `string_cache`). - Makes `enclosing_size_of_op` optional, because vanilla jemalloc doesn't support that operation. - For `HashSet`/`HashMap`, falls back to a computed estimate when `enclosing_size_of_op` isn't available. - Adds an extern "C" `malloc_size_of` function that does the actual heap measurement; this is based on the same functions from the `heapsize` crate. This patch makes the following changes elsewhere. - Converts all the uses of `heapsize` to instead use `malloc_size_of`. - Disables the "heapsize"/"heap_size" feature for the external crates that provide it. - Removes the `HeapSizeOf` implementation from `hashglobe`. - Adds `ignore` annotations to a few `Rc`/`Arc`, because `malloc_size_of` doesn't derive those types, unlike `heapsize`.
139 lines
4.2 KiB
Rust
139 lines
4.2 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
//! Code related to the invalidation of media-query-affected rules.
|
|
|
|
use context::QuirksMode;
|
|
use fnv::FnvHashSet;
|
|
use media_queries::Device;
|
|
use shared_lock::SharedRwLockReadGuard;
|
|
use stylesheets::{DocumentRule, ImportRule, MediaRule};
|
|
use stylesheets::{NestedRuleIterationCondition, Stylesheet, SupportsRule};
|
|
|
|
/// A key for a given media query result.
|
|
///
|
|
/// NOTE: It happens to be the case that all the media lists we care about
|
|
/// happen to have a stable address, so we can just use an opaque pointer to
|
|
/// represent them.
|
|
///
|
|
/// Also, note that right now when a rule or stylesheet is removed, we do a full
|
|
/// style flush, so there's no need to worry about other item created with the
|
|
/// same pointer address.
|
|
///
|
|
/// If this changes, though, we may need to remove the item from the cache if
|
|
/// present before it goes away.
|
|
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
|
|
pub struct MediaListKey(usize);
|
|
|
|
impl MediaListKey {
|
|
/// Create a MediaListKey from a raw usize.
|
|
pub fn from_raw(k: usize) -> Self {
|
|
MediaListKey(k)
|
|
}
|
|
}
|
|
|
|
/// A trait to get a given `MediaListKey` for a given item that can hold a
|
|
/// `MediaList`.
|
|
pub trait ToMediaListKey : Sized {
|
|
/// Get a `MediaListKey` for this item. This key needs to uniquely identify
|
|
/// the item.
|
|
#[allow(unsafe_code)]
|
|
fn to_media_list_key(&self) -> MediaListKey {
|
|
use std::mem;
|
|
MediaListKey(unsafe { mem::transmute(self as *const Self) })
|
|
}
|
|
}
|
|
|
|
impl ToMediaListKey for Stylesheet {}
|
|
impl ToMediaListKey for ImportRule {}
|
|
impl ToMediaListKey for MediaRule {}
|
|
|
|
/// A struct that holds the result of a media query evaluation pass for the
|
|
/// media queries that evaluated successfully.
|
|
#[derive(Debug, MallocSizeOf, PartialEq)]
|
|
pub struct EffectiveMediaQueryResults {
|
|
/// The set of media lists that matched last time.
|
|
set: FnvHashSet<MediaListKey>,
|
|
}
|
|
|
|
impl EffectiveMediaQueryResults {
|
|
/// Trivially constructs an empty `EffectiveMediaQueryResults`.
|
|
pub fn new() -> Self {
|
|
Self {
|
|
set: FnvHashSet::default(),
|
|
}
|
|
}
|
|
|
|
/// Resets the results, using an empty key.
|
|
pub fn clear(&mut self) {
|
|
self.set.clear()
|
|
}
|
|
|
|
/// Returns whether a given item was known to be effective when the results
|
|
/// were cached.
|
|
pub fn was_effective<T>(&self, item: &T) -> bool
|
|
where T: ToMediaListKey,
|
|
{
|
|
self.set.contains(&item.to_media_list_key())
|
|
}
|
|
|
|
/// Notices that an effective item has been seen, and caches it as matching.
|
|
pub fn saw_effective<T>(&mut self, item: &T)
|
|
where T: ToMediaListKey,
|
|
{
|
|
// NOTE(emilio): We can't assert that we don't cache the same item twice
|
|
// because of stylesheet reusing... shrug.
|
|
self.set.insert(item.to_media_list_key());
|
|
}
|
|
}
|
|
|
|
/// A filter that filters over effective rules, but allowing all potentially
|
|
/// effective `@media` rules.
|
|
pub struct PotentiallyEffectiveMediaRules;
|
|
|
|
impl NestedRuleIterationCondition for PotentiallyEffectiveMediaRules {
|
|
fn process_import(
|
|
_: &SharedRwLockReadGuard,
|
|
_: &Device,
|
|
_: QuirksMode,
|
|
_: &ImportRule)
|
|
-> bool
|
|
{
|
|
true
|
|
}
|
|
|
|
fn process_media(
|
|
_: &SharedRwLockReadGuard,
|
|
_: &Device,
|
|
_: QuirksMode,
|
|
_: &MediaRule)
|
|
-> bool
|
|
{
|
|
true
|
|
}
|
|
|
|
/// Whether we should process the nested rules in a given `@-moz-document` rule.
|
|
fn process_document(
|
|
guard: &SharedRwLockReadGuard,
|
|
device: &Device,
|
|
quirks_mode: QuirksMode,
|
|
rule: &DocumentRule)
|
|
-> bool
|
|
{
|
|
use stylesheets::EffectiveRules;
|
|
EffectiveRules::process_document(guard, device, quirks_mode, rule)
|
|
}
|
|
|
|
/// Whether we should process the nested rules in a given `@supports` rule.
|
|
fn process_supports(
|
|
guard: &SharedRwLockReadGuard,
|
|
device: &Device,
|
|
quirks_mode: QuirksMode,
|
|
rule: &SupportsRule)
|
|
-> bool
|
|
{
|
|
use stylesheets::EffectiveRules;
|
|
EffectiveRules::process_supports(guard, device, quirks_mode, rule)
|
|
}
|
|
}
|