style: Optimize storage of ApplicableDeclaration again.

So that we don't regress perf.

Differential Revision: https://phabricator.services.mozilla.com/D52576
This commit is contained in:
Emilio Cobos Álvarez 2019-11-13 09:59:10 +00:00
parent 349492b5e2
commit 1f2c1f555c
No known key found for this signature in database
GPG key ID: E1152D0994E4BF8A
2 changed files with 85 additions and 11 deletions

View file

@ -19,27 +19,37 @@ use smallvec::SmallVec;
/// However, it may depend a lot on workload, and stack space is cheap.
pub type ApplicableDeclarationList = SmallVec<[ApplicableDeclarationBlock; 16]>;
/// Blink uses 18 bits to store source order, and does not check overflow [1].
/// That's a limit that could be reached in realistic webpages, so we use
/// 24 bits and enforce defined behavior in the overflow case.
///
/// [1] https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/css/
/// RuleSet.h?l=128&rcl=90140ab80b84d0f889abc253410f44ed54ae04f3
const SOURCE_ORDER_SHIFT: usize = 0;
const SOURCE_ORDER_BITS: usize = 24;
const SOURCE_ORDER_MAX: u32 = (1 << SOURCE_ORDER_BITS) - 1;
const SOURCE_ORDER_MASK: u32 = SOURCE_ORDER_MAX << SOURCE_ORDER_SHIFT;
/// We pack the cascade level in a single byte, see CascadeLevel::to_byte_lossy
/// for the different trade-offs there.
const CASCADE_LEVEL_SHIFT: usize = SOURCE_ORDER_BITS;
/// Stores the source order of a block, the cascade level it belongs to, and the
/// counter needed to handle Shadow DOM cascade order properly.
///
/// FIXME(emilio): Optimize storage.
#[derive(Clone, Copy, Eq, MallocSizeOf, PartialEq, Debug)]
struct ApplicableDeclarationBits {
source_order: u32,
cascade_level: CascadeLevel,
}
struct ApplicableDeclarationBits(u32);
impl ApplicableDeclarationBits {
fn new(source_order: u32, cascade_level: CascadeLevel) -> Self {
Self { source_order, cascade_level }
Self((source_order & SOURCE_ORDER_MASK) | ((cascade_level.to_byte_lossy() as u32) << CASCADE_LEVEL_SHIFT))
}
fn source_order(&self) -> u32 {
self.source_order
self.0 & SOURCE_ORDER_MASK
}
fn level(&self) -> CascadeLevel {
self.cascade_level
CascadeLevel::from_byte((self.0 >> CASCADE_LEVEL_SHIFT) as u8)
}
}