File: mod.rs

package info (click to toggle)
thunderbird 1%3A143.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 4,703,968 kB
  • sloc: cpp: 7,770,492; javascript: 5,943,842; ansic: 3,918,754; python: 1,418,263; xml: 653,354; asm: 474,045; java: 183,079; sh: 111,238; makefile: 20,410; perl: 14,359; objc: 13,059; yacc: 4,583; pascal: 3,405; lex: 1,720; ruby: 999; exp: 762; sql: 715; awk: 580; php: 436; lisp: 430; sed: 69; csh: 10
file content (139 lines) | stat: -rw-r--r-- 4,505 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* 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 https://mozilla.org/MPL/2.0/. */

//! Various stuff for CSS property use counters.

use crate::properties::{property_counts, CountedUnknownProperty, NonCustomPropertyId};
use std::sync::atomic::{AtomicUsize, Ordering};

#[cfg(target_pointer_width = "64")]
const BITS_PER_ENTRY: usize = 64;

#[cfg(target_pointer_width = "32")]
const BITS_PER_ENTRY: usize = 32;

/// One bit per each non-custom CSS property.
#[derive(Debug, Default)]
pub struct CountedUnknownPropertyUseCounters {
    storage:
        [AtomicUsize; (property_counts::COUNTED_UNKNOWN + BITS_PER_ENTRY - 1) / BITS_PER_ENTRY],
}

/// One bit per each non-custom CSS property.
#[derive(Debug, Default)]
pub struct NonCustomPropertyUseCounters {
    storage: [AtomicUsize; (property_counts::NON_CUSTOM + BITS_PER_ENTRY - 1) / BITS_PER_ENTRY],
}

/// A custom style use counter that we may want to record.
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum CustomUseCounter {
    /// Whether we reference a non-local uri at all.
    HasNonLocalUriDependency = 0,
    /// Whether we are likely to be using relative URIs that depend on our path depth.
    MaybeHasPathBaseUriDependency,
    /// Whether we are likely to be using relative URIs that depend on our full URI.
    MaybeHasFullBaseUriDependency,
    /// Dummy value, used for indexing purposes.
    Last,
}

impl CustomUseCounter {
    #[inline]
    fn bit(self) -> usize {
        self as usize
    }
}

/// One bit for each custom use counter.
#[derive(Debug, Default)]
pub struct CustomUseCounters {
    storage:
        [AtomicUsize; ((CustomUseCounter::Last as usize) + BITS_PER_ENTRY - 1) / BITS_PER_ENTRY],
}

macro_rules! use_counters_methods {
    ($id: ident) => {
        /// Returns the bucket a given property belongs in, and the bitmask for that
        /// property.
        #[inline(always)]
        fn bucket_and_pattern(id: $id) -> (usize, usize) {
            let bit = id.bit();
            let bucket = bit / BITS_PER_ENTRY;
            let bit_in_bucket = bit % BITS_PER_ENTRY;
            (bucket, 1 << bit_in_bucket)
        }

        /// Record that a given property ID has been parsed.
        #[inline]
        pub fn record(&self, id: $id) {
            let (bucket, pattern) = Self::bucket_and_pattern(id);
            let bucket = &self.storage[bucket];
            bucket.fetch_or(pattern, Ordering::Relaxed);
        }

        /// Returns whether a given property ID has been recorded
        /// earlier.
        #[inline]
        pub fn recorded(&self, id: $id) -> bool {
            let (bucket, pattern) = Self::bucket_and_pattern(id);
            self.storage[bucket].load(Ordering::Relaxed) & pattern != 0
        }

        /// Merge `other` into `self`.
        #[inline]
        fn merge(&self, other: &Self) {
            for (bucket, other_bucket) in self.storage.iter().zip(other.storage.iter()) {
                bucket.fetch_or(other_bucket.load(Ordering::Relaxed), Ordering::Relaxed);
            }
        }
    };
}

impl CountedUnknownPropertyUseCounters {
    use_counters_methods!(CountedUnknownProperty);
}

impl NonCustomPropertyUseCounters {
    use_counters_methods!(NonCustomPropertyId);
}

impl CustomUseCounters {
    use_counters_methods!(CustomUseCounter);
}

/// The use-counter data related to a given document we want to store.
#[derive(Debug, Default)]
pub struct UseCounters {
    /// The counters for non-custom properties that have been parsed in the
    /// document's stylesheets.
    pub non_custom_properties: NonCustomPropertyUseCounters,
    /// The counters for css properties which we haven't implemented yet.
    pub counted_unknown_properties: CountedUnknownPropertyUseCounters,
    /// Custom counters for virtually everything else.
    pub custom: CustomUseCounters,
}

impl UseCounters {
    /// Merge the use counters.
    ///
    /// Used for parallel parsing, where we parse off-main-thread.
    #[inline]
    pub fn merge(&self, other: &Self) {
        self.non_custom_properties
            .merge(&other.non_custom_properties);
        self.counted_unknown_properties
            .merge(&other.counted_unknown_properties);
        self.custom.merge(&other.custom);
    }
}

impl Clone for UseCounters {
    fn clone(&self) -> Self {
        let result = Self::default();
        result.merge(self);
        result
    }
}