Bug 106963

Summary: Move TreeScope pointer to ContainerNode
Product: WebKit Reporter: Antti Koivisto <koivisto>
Component: DOMAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Normal CC: darin, dglazkov, d-r, esprehn, fmalita, haraken, kling, ojan.autocc, pdr, peter+ews, philn, rniwa, schenney, webkit.review.bot, xan.lopez
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
possible patch webkit-ews: commit-queue-

Description Antti Koivisto 2013-01-15 17:28:05 PST
We can make non-ContainerNodes (Text mostly) smaller by moving the tree scope pointer from Node to ContainerNode. Non-containers can get it from the parent (and they don't need it much anyway). This should be a significant memory win.
Comment 1 Antti Koivisto 2013-01-15 17:29:50 PST
Created attachment 182882 [details]
possible patch
Comment 2 Early Warning System Bot 2013-01-15 17:37:06 PST
Comment on attachment 182882 [details]
possible patch

Attachment 182882 [details] did not pass qt-ews (qt):
Output: http://queues.webkit.org/results/15884795
Comment 3 Early Warning System Bot 2013-01-15 17:38:15 PST
Comment on attachment 182882 [details]
possible patch

Attachment 182882 [details] did not pass qt-wk2-ews (qt):
Output: http://queues.webkit.org/results/15901195
Comment 4 Ryosuke Niwa 2013-01-15 17:39:37 PST
Comment on attachment 182882 [details]
possible patch

View in context: https://bugs.webkit.org/attachment.cgi?id=182882&action=review

> Source/WebCore/dom/Node.h:810
> +    union {
> +        ContainerNode* m_parentOrHostNode;
> +        TreeScope* m_treeScopeForParentlessNonContainer;
> +    };

It's very unfortunate that we have to use union for such an edge case :(
Comment 5 WebKit Review Bot 2013-01-15 17:49:40 PST
Comment on attachment 182882 [details]
possible patch

Attachment 182882 [details] did not pass chromium-ews (chromium-xvfb):
Output: http://queues.webkit.org/results/15902183
Comment 6 Elliott Sprehn 2013-01-15 17:50:38 PST
Comment on attachment 182882 [details]
possible patch

View in context: https://bugs.webkit.org/attachment.cgi?id=182882&action=review

I object to this change, it puts a branch into all the methods that go through the document pointer in the render tree (see RenderObject.h) which we know is a perf regression from the last time moritta tried replacing the document pointer. This also seems like a lot of complexity.

> Source/WebCore/dom/ContainerNode.h:278
> +    return toContainerNode(this)->treeScope();

This is going to be a perf regression since you're inserting a branch into all node->document() access which means a branch into lots of methods in the render tree.
Comment 7 Elliott Sprehn 2013-01-15 18:02:06 PST
(In reply to comment #0)
> We can make non-ContainerNodes (Text mostly) smaller by moving the tree scope pointer from Node to ContainerNode. Non-containers can get it from the parent (and they don't need it much anyway).

Note also that "they don't need it much anyway" is not really true since document() goes through m_treeScope and CharacterData.cpp uses document() a bunch; Text.cpp also uses it in the critical path for recalcTextStyle and RenderText.cpp also uses document() in a bunch of performance sensitive places.
Comment 8 Peter Beverloo (cr-android ews) 2013-01-15 18:18:47 PST
Comment on attachment 182882 [details]
possible patch

Attachment 182882 [details] did not pass cr-android-ews (chromium-android):
Output: http://queues.webkit.org/results/15904205
Comment 9 EFL EWS Bot 2013-01-15 20:47:23 PST
Comment on attachment 182882 [details]
possible patch

Attachment 182882 [details] did not pass efl-ews (efl):
Output: http://queues.webkit.org/results/15910182
Comment 10 Antti Koivisto 2013-01-16 02:53:49 PST
(In reply to comment #4)
> (From update of attachment 182882 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=182882&action=review
> 
> > Source/WebCore/dom/Node.h:810
> > +    union {
> > +        ContainerNode* m_parentOrHostNode;
> > +        TreeScope* m_treeScopeForParentlessNonContainer;
> > +    };
> 
> It's very unfortunate that we have to use union for such an edge case :(

Yeah. It is double silly since both TreeScope types are actually ContainerNodes. 

Maybe the case is rare enough to shove the tree scope to a map. The case is easy enough to hit by by trying though

javascript:alert(document.createTextNode().ownerDocument)
Comment 11 Antti Koivisto 2013-01-16 03:32:48 PST
(In reply to comment #6)
> I object to this change, it puts a branch into all the methods that go through the document pointer in the render tree (see RenderObject.h) which we know is a perf regression from the last time moritta tried replacing the document pointer. This also seems like a lot of complexity.

There is no branch if you operate on ContainerNodes. Looks like the new branchiness in the render tree could be largely eliminated by simple tightening (non-RenderTexts always have Element as their node())

Note that significant memory reductions can be performance progressions too in by themselves due to improved locality. I don't know how this is going to be without testing.
Comment 12 Antti Koivisto 2013-01-16 06:19:28 PST
Actually I can probably do this cleaner by enuming with the renderer pointer. The edge case never has a renderer.
Comment 13 Darin Adler 2013-01-16 09:46:51 PST
(In reply to comment #12)
> Actually I can probably do this cleaner by enuming with the renderer pointer. The edge case never has a renderer.

Where you say "enuming" you mean "unioning", right?
Comment 14 Antti Koivisto 2013-01-16 11:03:10 PST
(In reply to comment #13)
> Where you say "enuming" you mean "unioning", right?

Yes!