mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Use a bitmap to optimize adding to a PropertyDeclarationBlock.
This commit is contained in:
parent
f70a49974a
commit
60f454d7c4
3 changed files with 61 additions and 18 deletions
|
@ -41,7 +41,7 @@ impl Importance {
|
|||
}
|
||||
|
||||
/// Overridden declarations are skipped.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct PropertyDeclarationBlock {
|
||||
/// The group of declarations, along with their importance.
|
||||
///
|
||||
|
@ -50,6 +50,14 @@ pub struct PropertyDeclarationBlock {
|
|||
|
||||
/// The number of entries in `self.declaration` with `Importance::Important`
|
||||
important_count: usize,
|
||||
|
||||
longhands: LonghandIdSet,
|
||||
}
|
||||
|
||||
impl fmt::Debug for PropertyDeclarationBlock {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.declarations.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl PropertyDeclarationBlock {
|
||||
|
@ -58,14 +66,20 @@ impl PropertyDeclarationBlock {
|
|||
PropertyDeclarationBlock {
|
||||
declarations: Vec::new(),
|
||||
important_count: 0,
|
||||
longhands: LonghandIdSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a block with a single declaration
|
||||
pub fn with_one(declaration: PropertyDeclaration, importance: Importance) -> Self {
|
||||
let mut longhands = LonghandIdSet::new();
|
||||
if let PropertyDeclarationId::Longhand(id) = declaration.id() {
|
||||
longhands.insert(id);
|
||||
}
|
||||
PropertyDeclarationBlock {
|
||||
declarations: vec![(declaration, importance)],
|
||||
important_count: if importance.important() { 1 } else { 0 },
|
||||
longhands: longhands,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,28 +212,39 @@ impl PropertyDeclarationBlock {
|
|||
|
||||
fn push_common(&mut self, declaration: PropertyDeclaration, importance: Importance,
|
||||
overwrite_more_important: bool) -> bool {
|
||||
for slot in &mut *self.declarations {
|
||||
if slot.0.id() == declaration.id() {
|
||||
match (slot.1, importance) {
|
||||
(Importance::Normal, Importance::Important) => {
|
||||
self.important_count += 1;
|
||||
}
|
||||
(Importance::Important, Importance::Normal) => {
|
||||
if overwrite_more_important {
|
||||
self.important_count -= 1;
|
||||
} else {
|
||||
return false
|
||||
let definitely_new = if let PropertyDeclarationId::Longhand(id) = declaration.id() {
|
||||
!self.longhands.contains(id)
|
||||
} else {
|
||||
false // For custom properties, always scan
|
||||
};
|
||||
|
||||
if !definitely_new {
|
||||
for slot in &mut *self.declarations {
|
||||
if slot.0.id() == declaration.id() {
|
||||
match (slot.1, importance) {
|
||||
(Importance::Normal, Importance::Important) => {
|
||||
self.important_count += 1;
|
||||
}
|
||||
(Importance::Important, Importance::Normal) => {
|
||||
if overwrite_more_important {
|
||||
self.important_count -= 1;
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
_ => if slot.0 == declaration {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_ => if slot.0 == declaration {
|
||||
return false;
|
||||
}
|
||||
*slot = (declaration, importance);
|
||||
return true
|
||||
}
|
||||
*slot = (declaration, importance);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if let PropertyDeclarationId::Longhand(id) = declaration.id() {
|
||||
self.longhands.insert(id);
|
||||
}
|
||||
self.declarations.push((declaration, importance));
|
||||
if importance.important() {
|
||||
self.important_count += 1;
|
||||
|
@ -256,6 +281,11 @@ impl PropertyDeclarationBlock {
|
|||
///
|
||||
/// Returns whether any declaration was actually removed.
|
||||
pub fn remove_property(&mut self, property: &PropertyId) -> bool {
|
||||
if let PropertyId::Longhand(id) = *property {
|
||||
if !self.longhands.contains(id) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
let important_count = &mut self.important_count;
|
||||
let mut removed_at_least_one = false;
|
||||
self.declarations.retain(|&(ref declaration, importance)| {
|
||||
|
@ -269,6 +299,10 @@ impl PropertyDeclarationBlock {
|
|||
!remove
|
||||
});
|
||||
|
||||
if let PropertyId::Longhand(id) = *property {
|
||||
debug_assert!(removed_at_least_one);
|
||||
self.longhands.remove(id);
|
||||
}
|
||||
removed_at_least_one
|
||||
}
|
||||
|
||||
|
|
|
@ -177,6 +177,7 @@ pub mod animated_properties {
|
|||
}
|
||||
|
||||
/// A set of longhand properties
|
||||
#[derive(Clone)]
|
||||
pub struct LonghandIdSet {
|
||||
storage: [u32; (${len(data.longhands)} - 1 + 32) / 32]
|
||||
}
|
||||
|
@ -202,6 +203,13 @@ impl LonghandIdSet {
|
|||
self.storage[bit / 32] |= 1 << (bit % 32);
|
||||
}
|
||||
|
||||
/// Remove the given property from the set
|
||||
#[inline]
|
||||
pub fn remove(&mut self, id: LonghandId) {
|
||||
let bit = id as usize;
|
||||
self.storage[bit / 32] &= !(1 << (bit % 32));
|
||||
}
|
||||
|
||||
/// Set the corresponding bit of TransitionProperty.
|
||||
/// This function will panic if TransitionProperty::All is given.
|
||||
pub fn set_transition_property_bit(&mut self, property: &TransitionProperty) {
|
||||
|
|
|
@ -738,7 +738,8 @@ pub extern "C" fn Servo_DeclarationBlock_Clone(declarations: RawServoDeclaration
|
|||
pub extern "C" fn Servo_DeclarationBlock_Equals(a: RawServoDeclarationBlockBorrowed,
|
||||
b: RawServoDeclarationBlockBorrowed)
|
||||
-> bool {
|
||||
*RwLock::<PropertyDeclarationBlock>::as_arc(&a).read() == *RwLock::<PropertyDeclarationBlock>::as_arc(&b).read()
|
||||
*RwLock::<PropertyDeclarationBlock>::as_arc(&a).read().declarations() ==
|
||||
*RwLock::<PropertyDeclarationBlock>::as_arc(&b).read().declarations()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue