mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Do not lazy initialize RareData on its getters
This commit is contained in:
parent
d0b2e826ef
commit
9b2eb77530
4 changed files with 101 additions and 109 deletions
|
@ -332,75 +332,60 @@ impl Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_custom_element_state(&self, state: CustomElementState) {
|
pub fn set_custom_element_state(&self, state: CustomElementState) {
|
||||||
self.rare_data_mut().as_mut().unwrap().custom_element_state = state;
|
self.ensure_rare_data().custom_element_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_custom_element_state(&self) -> CustomElementState {
|
pub fn get_custom_element_state(&self) -> CustomElementState {
|
||||||
self.rare_data().as_ref().unwrap().custom_element_state
|
if let Some(rare_data) = self.rare_data().as_ref() {
|
||||||
|
return rare_data.custom_element_state;
|
||||||
|
}
|
||||||
|
CustomElementState::Undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_custom_element_definition(&self, definition: Rc<CustomElementDefinition>) {
|
pub fn set_custom_element_definition(&self, definition: Rc<CustomElementDefinition>) {
|
||||||
self.rare_data_mut()
|
self.ensure_rare_data().custom_element_definition = Some(definition);
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.custom_element_definition = Some(definition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_custom_element_definition(&self) -> Option<Rc<CustomElementDefinition>> {
|
pub fn get_custom_element_definition(&self) -> Option<Rc<CustomElementDefinition>> {
|
||||||
self.rare_data()
|
if let Some(rare_data) = self.rare_data().as_ref() {
|
||||||
.as_ref()
|
return rare_data.custom_element_definition.clone();
|
||||||
.unwrap()
|
}
|
||||||
.custom_element_definition
|
None
|
||||||
.clone()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_callback_reaction(&self, function: Rc<Function>, args: Box<[Heap<JSVal>]>) {
|
pub fn push_callback_reaction(&self, function: Rc<Function>, args: Box<[Heap<JSVal>]>) {
|
||||||
self.rare_data_mut()
|
self.ensure_rare_data()
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.custom_element_reaction_queue
|
.custom_element_reaction_queue
|
||||||
.push(CustomElementReaction::Callback(function, args));
|
.push(CustomElementReaction::Callback(function, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_upgrade_reaction(&self, definition: Rc<CustomElementDefinition>) {
|
pub fn push_upgrade_reaction(&self, definition: Rc<CustomElementDefinition>) {
|
||||||
self.rare_data_mut()
|
self.ensure_rare_data()
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.custom_element_reaction_queue
|
.custom_element_reaction_queue
|
||||||
.push(CustomElementReaction::Upgrade(definition));
|
.push(CustomElementReaction::Upgrade(definition));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_reaction_queue(&self) {
|
pub fn clear_reaction_queue(&self) {
|
||||||
self.rare_data_mut()
|
self.ensure_rare_data()
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.custom_element_reaction_queue
|
.custom_element_reaction_queue
|
||||||
.clear();
|
.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invoke_reactions(&self) {
|
pub fn invoke_reactions(&self) {
|
||||||
// TODO: This is not spec compliant, as this will allow some reactions to be processed
|
if let Some(rare_data) = self.rare_data().as_ref() {
|
||||||
// after clear_reaction_queue has been called.
|
// TODO: This is not spec compliant, as this will allow some reactions to be processed
|
||||||
rooted_vec!(let mut reactions);
|
// after clear_reaction_queue has been called.
|
||||||
while !self
|
rooted_vec!(let mut reactions);
|
||||||
.rare_data()
|
while !rare_data.custom_element_reaction_queue.is_empty() {
|
||||||
.as_ref()
|
mem::swap(
|
||||||
.unwrap()
|
&mut *reactions,
|
||||||
.custom_element_reaction_queue
|
&mut self.ensure_rare_data().custom_element_reaction_queue,
|
||||||
.is_empty()
|
);
|
||||||
{
|
for reaction in reactions.iter() {
|
||||||
mem::swap(
|
reaction.invoke(self);
|
||||||
&mut *reactions,
|
}
|
||||||
&mut self
|
reactions.clear();
|
||||||
.rare_data_mut()
|
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.custom_element_reaction_queue,
|
|
||||||
);
|
|
||||||
for reaction in reactions.iter() {
|
|
||||||
reaction.invoke(self);
|
|
||||||
}
|
}
|
||||||
reactions.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,7 +443,10 @@ impl Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_shadow_host(&self) -> bool {
|
pub fn is_shadow_host(&self) -> bool {
|
||||||
self.rare_data().as_ref().unwrap().shadow_root.is_some()
|
if let Some(rare_data) = self.rare_data().as_ref() {
|
||||||
|
return rare_data.shadow_root.is_some();
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://dom.spec.whatwg.org/#dom-element-attachshadow
|
/// https://dom.spec.whatwg.org/#dom-element-attachshadow
|
||||||
|
@ -502,7 +490,7 @@ impl Element {
|
||||||
|
|
||||||
// Steps 4, 5 and 6.
|
// Steps 4, 5 and 6.
|
||||||
let shadow_root = ShadowRoot::new(self, &*self.node.owner_doc());
|
let shadow_root = ShadowRoot::new(self, &*self.node.owner_doc());
|
||||||
self.rare_data_mut().as_mut().unwrap().shadow_root = Some(Dom::from_ref(&*shadow_root));
|
self.ensure_rare_data().shadow_root = Some(Dom::from_ref(&*shadow_root));
|
||||||
|
|
||||||
if self.is_connected() {
|
if self.is_connected() {
|
||||||
self.node.owner_doc().register_shadow_root(&*shadow_root);
|
self.node.owner_doc().register_shadow_root(&*shadow_root);
|
||||||
|
@ -1077,13 +1065,10 @@ impl LayoutElementHelpers for LayoutDom<Element> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn get_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> {
|
unsafe fn get_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> {
|
||||||
(*self.unsafe_get())
|
if let Some(rare_data) = (*self.unsafe_get()).rare_data_for_layout().as_ref() {
|
||||||
.rare_data_for_layout()
|
return rare_data.shadow_root.as_ref().map(|sr| sr.to_layout());
|
||||||
.as_ref()
|
}
|
||||||
.unwrap()
|
None
|
||||||
.shadow_root
|
|
||||||
.as_ref()
|
|
||||||
.map(|sr| sr.to_layout())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2827,13 +2812,15 @@ impl VirtualMethods for Element {
|
||||||
|
|
||||||
let doc = document_from_node(self);
|
let doc = document_from_node(self);
|
||||||
|
|
||||||
if let Some(ref shadow_root) = self.rare_data().as_ref().unwrap().shadow_root {
|
if let Some(rare_data) = self.rare_data().as_ref() {
|
||||||
doc.register_shadow_root(&shadow_root);
|
if let Some(ref shadow_root) = rare_data.shadow_root {
|
||||||
let shadow_root = shadow_root.upcast::<Node>();
|
doc.register_shadow_root(&shadow_root);
|
||||||
shadow_root.set_flag(NodeFlags::IS_CONNECTED, context.tree_connected);
|
let shadow_root = shadow_root.upcast::<Node>();
|
||||||
for node in shadow_root.children() {
|
shadow_root.set_flag(NodeFlags::IS_CONNECTED, context.tree_connected);
|
||||||
node.set_flag(NodeFlags::IS_CONNECTED, context.tree_connected);
|
for node in shadow_root.children() {
|
||||||
node.bind_to_tree(context);
|
node.set_flag(NodeFlags::IS_CONNECTED, context.tree_connected);
|
||||||
|
node.bind_to_tree(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2865,13 +2852,15 @@ impl VirtualMethods for Element {
|
||||||
|
|
||||||
let doc = document_from_node(self);
|
let doc = document_from_node(self);
|
||||||
|
|
||||||
if let Some(ref shadow_root) = self.rare_data().as_ref().unwrap().shadow_root {
|
if let Some(rare_data) = self.rare_data().as_ref() {
|
||||||
doc.unregister_shadow_root(&shadow_root);
|
if let Some(ref shadow_root) = rare_data.shadow_root {
|
||||||
let shadow_root = shadow_root.upcast::<Node>();
|
doc.unregister_shadow_root(&shadow_root);
|
||||||
shadow_root.set_flag(NodeFlags::IS_CONNECTED, false);
|
let shadow_root = shadow_root.upcast::<Node>();
|
||||||
for node in shadow_root.children() {
|
shadow_root.set_flag(NodeFlags::IS_CONNECTED, false);
|
||||||
node.set_flag(NodeFlags::IS_CONNECTED, false);
|
for node in shadow_root.children() {
|
||||||
node.unbind_from_tree(context);
|
node.set_flag(NodeFlags::IS_CONNECTED, false);
|
||||||
|
node.unbind_from_tree(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -635,29 +635,22 @@ macro_rules! handle_potential_webgl_error {
|
||||||
|
|
||||||
macro_rules! impl_rare_data (
|
macro_rules! impl_rare_data (
|
||||||
($type:ty) => (
|
($type:ty) => (
|
||||||
fn init_rare_data(&self) {
|
fn rare_data(&self) -> Ref<Option<Box<$type>>> {
|
||||||
|
self.rare_data.borrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ensure_rare_data(&self) -> RefMut<Box<$type>> {
|
||||||
let mut rare_data = self.rare_data.borrow_mut();
|
let mut rare_data = self.rare_data.borrow_mut();
|
||||||
if rare_data.is_none() {
|
if rare_data.is_none() {
|
||||||
*rare_data = Some(Default::default());
|
*rare_data = Some(Default::default());
|
||||||
}
|
}
|
||||||
}
|
RefMut::map(rare_data, |rare_data| {
|
||||||
|
rare_data.as_mut().unwrap()
|
||||||
fn rare_data(&self) -> Ref<Option<Box<$type>>> {
|
})
|
||||||
self.init_rare_data();
|
|
||||||
self.rare_data.borrow()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rare_data_mut(&self) -> RefMut<Option<Box<$type>>> {
|
|
||||||
self.init_rare_data();
|
|
||||||
self.rare_data.borrow_mut()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn rare_data_for_layout(&self) -> &Option<Box<$type>> {
|
fn rare_data_for_layout(&self) -> &Option<Box<$type>> {
|
||||||
let mut rare_data = self.rare_data.borrow_mut_for_layout();
|
|
||||||
if rare_data.is_none() {
|
|
||||||
*rare_data = Some(Default::default());
|
|
||||||
}
|
|
||||||
unsafe { self.rare_data.borrow_for_layout() }
|
unsafe { self.rare_data.borrow_for_layout() }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -452,26 +452,25 @@ impl Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return all registered mutation observers for this node.
|
/// Return all registered mutation observers for this node.
|
||||||
|
/// XXX(ferjm) This should probably be split into two functions,
|
||||||
|
/// `registered_mutation_observers`, which returns an Option or
|
||||||
|
/// an empty slice or something, and doesn't create the rare data,
|
||||||
|
/// and `registered_mutation_observers_mut`, which does lazily
|
||||||
|
/// initialize the raredata.
|
||||||
pub fn registered_mutation_observers(&self) -> RefMut<Vec<RegisteredObserver>> {
|
pub fn registered_mutation_observers(&self) -> RefMut<Vec<RegisteredObserver>> {
|
||||||
RefMut::map(self.rare_data_mut(), |rare_data| {
|
RefMut::map(self.ensure_rare_data(), |rare_data| {
|
||||||
&mut rare_data.as_mut().unwrap().mutation_observers
|
&mut rare_data.mutation_observers
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a new mutation observer for a given node.
|
/// Add a new mutation observer for a given node.
|
||||||
pub fn add_mutation_observer(&self, observer: RegisteredObserver) {
|
pub fn add_mutation_observer(&self, observer: RegisteredObserver) {
|
||||||
self.rare_data_mut()
|
self.ensure_rare_data().mutation_observers.push(observer);
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.mutation_observers
|
|
||||||
.push(observer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes the mutation observer for a given node.
|
/// Removes the mutation observer for a given node.
|
||||||
pub fn remove_mutation_observer(&self, observer: &MutationObserver) {
|
pub fn remove_mutation_observer(&self, observer: &MutationObserver) {
|
||||||
self.rare_data_mut()
|
self.ensure_rare_data()
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.mutation_observers
|
.mutation_observers
|
||||||
.retain(|reg_obs| &*reg_obs.observer != observer)
|
.retain(|reg_obs| &*reg_obs.observer != observer)
|
||||||
}
|
}
|
||||||
|
@ -951,16 +950,17 @@ impl Node {
|
||||||
if let Some(ref shadow_root) = self.downcast::<ShadowRoot>() {
|
if let Some(ref shadow_root) = self.downcast::<ShadowRoot>() {
|
||||||
return Some(DomRoot::from_ref(shadow_root));
|
return Some(DomRoot::from_ref(shadow_root));
|
||||||
}
|
}
|
||||||
self.rare_data()
|
if let Some(rare_data) = self.rare_data().as_ref() {
|
||||||
.as_ref()
|
return rare_data
|
||||||
.unwrap()
|
.owner_shadow_root
|
||||||
.owner_shadow_root
|
.as_ref()
|
||||||
.as_ref()
|
.map(|sr| DomRoot::from_ref(&**sr));
|
||||||
.map(|sr| DomRoot::from_ref(&**sr))
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_owner_shadow_root(&self, shadow_root: &ShadowRoot) {
|
pub fn set_owner_shadow_root(&self, shadow_root: &ShadowRoot) {
|
||||||
self.rare_data_mut().as_mut().unwrap().owner_shadow_root = Some(Dom::from_ref(shadow_root));
|
self.ensure_rare_data().owner_shadow_root = Some(Dom::from_ref(shadow_root));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_in_html_doc(&self) -> bool {
|
pub fn is_in_html_doc(&self) -> bool {
|
||||||
|
@ -1281,13 +1281,13 @@ impl LayoutNodeHelpers for LayoutDom<Node> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn owner_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> {
|
unsafe fn owner_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> {
|
||||||
(*self.unsafe_get())
|
if let Some(rare_data) = (*self.unsafe_get()).rare_data_for_layout().as_ref() {
|
||||||
.rare_data_for_layout()
|
return rare_data
|
||||||
.as_ref()
|
.owner_shadow_root
|
||||||
.unwrap()
|
.as_ref()
|
||||||
.owner_shadow_root
|
.map(|sr| sr.to_layout());
|
||||||
.as_ref()
|
}
|
||||||
.map(|sr| sr.to_layout())
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2293,14 +2293,21 @@ impl NodeMethods for Node {
|
||||||
// https://dom.spec.whatwg.org/#dom-node-getrootnode
|
// https://dom.spec.whatwg.org/#dom-node-getrootnode
|
||||||
fn GetRootNode(&self, options: &GetRootNodeOptions) -> DomRoot<Node> {
|
fn GetRootNode(&self, options: &GetRootNodeOptions) -> DomRoot<Node> {
|
||||||
if options.composed {
|
if options.composed {
|
||||||
if let Some(ref shadow_root) = self.rare_data().as_ref().unwrap().owner_shadow_root {
|
if let Some(rare_data) = self.rare_data().as_ref() {
|
||||||
// shadow-including root.
|
if let Some(ref shadow_root) = rare_data.owner_shadow_root {
|
||||||
return shadow_root.Host().upcast::<Node>().GetRootNode(options);
|
// shadow-including root.
|
||||||
|
return shadow_root.Host().upcast::<Node>().GetRootNode(options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(ref shadow_root) = self.rare_data().as_ref().unwrap().owner_shadow_root {
|
|
||||||
DomRoot::from_ref(shadow_root.upcast::<Node>())
|
if let Some(rare_data) = self.rare_data().as_ref() {
|
||||||
} else if self.is_in_doc() {
|
if let Some(ref shadow_root) = rare_data.owner_shadow_root {
|
||||||
|
return DomRoot::from_ref(shadow_root.upcast::<Node>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.is_in_doc() {
|
||||||
DomRoot::from_ref(self.owner_doc().upcast::<Node>())
|
DomRoot::from_ref(self.owner_doc().upcast::<Node>())
|
||||||
} else {
|
} else {
|
||||||
self.inclusive_ancestors(ShadowIncluding::No)
|
self.inclusive_ancestors(ShadowIncluding::No)
|
||||||
|
|
|
@ -10,6 +10,9 @@ use crate::dom::mutationobserver::RegisteredObserver;
|
||||||
use crate::dom::shadowroot::ShadowRoot;
|
use crate::dom::shadowroot::ShadowRoot;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
//XXX(ferjm) Ideally merge NodeRareData and ElementRareData so they share
|
||||||
|
// storage.
|
||||||
|
|
||||||
#[derive(Default, JSTraceable, MallocSizeOf)]
|
#[derive(Default, JSTraceable, MallocSizeOf)]
|
||||||
#[must_root]
|
#[must_root]
|
||||||
pub struct NodeRareData {
|
pub struct NodeRareData {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue