Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute tag_name a maximum of once per document owner #11318

Merged
merged 1 commit into from Aug 4, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Compute tag_name a maximum of once per document owner

  • Loading branch information
mitchhentges committed Aug 4, 2016
commit 1ca4a3e32f0b3377ef8acb95ce437233c10d96c8
@@ -103,6 +103,7 @@ use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage};
pub struct Element {
node: Node,
local_name: Atom,
tag_name: TagName,
namespace: Namespace,
prefix: Option<DOMString>,
attrs: DOMRefCell<Vec<JS<Attr>>>,
@@ -165,6 +166,7 @@ impl Element {
Element {
node: Node::new_inherited(document),
local_name: local_name,
tag_name: TagName::new(),
namespace: namespace,
prefix: prefix,
attrs: DOMRefCell::new(vec![]),
@@ -1367,17 +1369,20 @@ impl ElementMethods for Element {

// https://dom.spec.whatwg.org/#dom-element-tagname
fn TagName(&self) -> DOMString {
let qualified_name = match self.prefix {
Some(ref prefix) => {
Cow::Owned(format!("{}:{}", &**prefix, &*self.local_name))
},
None => Cow::Borrowed(&*self.local_name)
};
DOMString::from(if self.html_element_in_html_document() {
qualified_name.to_ascii_uppercase()
} else {
qualified_name.into_owned()
})
let name = self.tag_name.or_init(|| {
let qualified_name = match self.prefix {
Some(ref prefix) => {
Cow::Owned(format!("{}:{}", &**prefix, &*self.local_name))
},
None => Cow::Borrowed(&*self.local_name)
};
if self.html_element_in_html_document() {
Atom::from(qualified_name.to_ascii_uppercase())
} else {
Atom::from(qualified_name)
}
});
DOMString::from(&*name)
}

// https://dom.spec.whatwg.org/#dom-element-id
@@ -2219,6 +2224,14 @@ impl VirtualMethods for Element {
}
}
}

fn adopting_steps(&self, old_doc: &Document) {
self.super_type().unwrap().adopting_steps(old_doc);

if document_from_node(self).is_html_document() != old_doc.is_html_document() {
self.tag_name.clear();
}
}
}

impl<'a> ::selectors::MatchAttrGeneric for Root<Element> {
@@ -2691,3 +2704,38 @@ impl AtomicElementFlags {
self.0.fetch_or(flags.bits() as usize, Ordering::Relaxed);
}
}

/// A holder for an element's "tag name", which will be lazily
/// resolved and cached. Should be reset when the document
/// owner changes.
#[derive(JSTraceable, HeapSizeOf)]
struct TagName {
ptr: DOMRefCell<Option<Atom>>,
}

impl TagName {
fn new() -> TagName {
TagName { ptr: DOMRefCell::new(None) }
}

/// Retrieve a copy of the current inner value. If it is `None`, it is
/// initialized with the result of `cb` first.
fn or_init<F>(&self, cb: F) -> Atom
where F: FnOnce() -> Atom
{
match &mut *self.ptr.borrow_mut() {
&mut Some(ref name) => name.clone(),
ptr => {
let name = cb();
*ptr = Some(name.clone());
name
}
}
}

/// Clear the cached tag name, so that it will be re-calculated the
/// next time that `or_init()` is called.
fn clear(&self) {
*self.ptr.borrow_mut() = None;
}
}
@@ -40,10 +40,10 @@ macro_rules! sizeof_checker (
// Update the sizes here
sizeof_checker!(size_event_target, EventTarget, 40);
sizeof_checker!(size_node, Node, 160);
sizeof_checker!(size_element, Element, 312);
sizeof_checker!(size_htmlelement, HTMLElement, 328);
sizeof_checker!(size_div, HTMLDivElement, 328);
sizeof_checker!(size_span, HTMLSpanElement, 328);
sizeof_checker!(size_element, Element, 336);
sizeof_checker!(size_htmlelement, HTMLElement, 352);
sizeof_checker!(size_div, HTMLDivElement, 352);
sizeof_checker!(size_span, HTMLSpanElement, 352);
sizeof_checker!(size_text, Text, 192);
sizeof_checker!(size_characterdata, CharacterData, 192);
sizeof_checker!(size_servothreadsafelayoutnode, ServoThreadSafeLayoutNode, 16);
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.