Title: [207932] trunk
Revision
207932
Author
[email protected]
Date
2016-10-26 20:42:13 -0700 (Wed, 26 Oct 2016)

Log Message

[DOMJIT] Implement Node::ownerDocument
https://bugs.webkit.org/show_bug.cgi?id=164004

Reviewed by Darin Adler.

Source/WebCore:

Test: js/dom/domjit-accessor-owner-document.html

Implement Node.ownerDocument DOMJIT accessor.
According to the result of the profiler, jQuery's prop()
function is frequently called in Ember.js SpeedoMeter.
And this function calls jQuery.isXMLDoc(). And this isXMLDoc()
function calls element.ownerDocument accessor. And our WebKit
inspector also uses ownerDocument accessor frequently.

Interesting thing is this ownerDocument functionality is used
in CSSJIT, so CSSJIT has similar helper function to look up the
owner document of the element. As a result, all the necessary
functionality is already implemented, DOMJIT just utilizes it.
For example, Node::treeScopeMemoryOffset() and
TreeScope::documentScopeMemoryOffset() is implemented before this
patch.

In the future, we will convert CSSJIT's Assembler& to CCallHelpers&
and share the code with DOMJIT[1].

[1]: https://bugs.webkit.org/show_bug.cgi?id=164006

* dom/Node.idl:
* domjit/DOMJITAbstractHeapRepository.h:
* domjit/JSNodeDOMJIT.cpp:
(WebCore::NodeOwnerDocumentDOMJIT::checkDOM):
(WebCore::NodeOwnerDocumentDOMJIT::callDOM):

LayoutTests:

* js/dom/domjit-accessor-owner-document-expected.txt: Added.
* js/dom/domjit-accessor-owner-document.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (207931 => 207932)


--- trunk/LayoutTests/ChangeLog	2016-10-27 03:13:21 UTC (rev 207931)
+++ trunk/LayoutTests/ChangeLog	2016-10-27 03:42:13 UTC (rev 207932)
@@ -1,3 +1,13 @@
+2016-10-26  Yusuke Suzuki  <[email protected]>
+
+        [DOMJIT] Implement Node::ownerDocument
+        https://bugs.webkit.org/show_bug.cgi?id=164004
+
+        Reviewed by Darin Adler.
+
+        * js/dom/domjit-accessor-owner-document-expected.txt: Added.
+        * js/dom/domjit-accessor-owner-document.html: Added.
+
 2016-10-26  Chris Dumez  <[email protected]>
 
         Replace IDBKeyPath with a WTF::Variant

Added: trunk/LayoutTests/js/dom/domjit-accessor-owner-document-expected.txt (0 => 207932)


--- trunk/LayoutTests/js/dom/domjit-accessor-owner-document-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/dom/domjit-accessor-owner-document-expected.txt	2016-10-27 03:42:13 UTC (rev 207932)
@@ -0,0 +1,109 @@
+Test DOMJIT nodeType accessor works.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS (
+            function testElement(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        )(target, result) is true
+PASS (
+            function testAttr(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        )(target, result) is true
+PASS (
+            function testText(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        )(target, result) is true
+PASS (
+            function testCDATA(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        )(target, result) is true
+PASS (
+            function testProcessingInstruction(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        )(target, result) is true
+PASS (
+            function testComment(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        )(target, result) is true
+PASS (
+            function testDocument(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        )(target, result) is true
+PASS (
+            function testXMLDocument(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        )(target, result) is true
+PASS (
+            function testDocumentType(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        )(target, result) is true
+PASS (
+            function testDocumentFragment(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        )(target, result) is true
+

Added: trunk/LayoutTests/js/dom/domjit-accessor-owner-document.html (0 => 207932)


--- trunk/LayoutTests/js/dom/domjit-accessor-owner-document.html	                        (rev 0)
+++ trunk/LayoutTests/js/dom/domjit-accessor-owner-document.html	2016-10-27 03:42:13 UTC (rev 207932)
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<iframe id="xmlframe" _onload_="frameLoaded()" style="height:0px" src="" version='1.0' encoding='UTF-8'?><body/>"></iframe>
+<script>
+description('Test DOMJIT nodeType accessor works.');
+
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+var target = null;
+var result = null;
+function runTest()
+{
+    var xmlDocument = document.getElementById('xmlframe').contentDocument;
+    var targets = [
+        ['Element', document.body, document],
+        ['Attr', document.createAttribute('Cocoa'), document],
+        ['Text', document.createTextNode('Cocoa'), document],
+        ['CDATA', xmlDocument.createCDATASection('test'), xmlDocument],
+        ['ProcessingInstruction', xmlDocument.createProcessingInstruction('target', 'test'), xmlDocument],
+        ['Comment', document.createComment('Cocoa'), document],
+        ['Document', document, null],
+        ['XMLDocument', xmlDocument, null],
+        ['DocumentType', document.doctype, document],
+        ['DocumentFragment', document.createDocumentFragment(), document],
+    ];
+
+    for ([name, target, result] of targets) {
+        var text = `
+            function test${name}(element, result)
+            {
+                for (var i = 0; i < 1e4; ++i) {
+                    if (element.ownerDocument !== result)
+                        return false;
+                }
+                return true;
+            }
+        `;
+        shouldBeTrue(`(${text})(target, result)`);
+    }
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+function frameLoaded()
+{
+    runTest();
+}
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (207931 => 207932)


--- trunk/Source/WebCore/ChangeLog	2016-10-27 03:13:21 UTC (rev 207931)
+++ trunk/Source/WebCore/ChangeLog	2016-10-27 03:42:13 UTC (rev 207932)
@@ -1,3 +1,38 @@
+2016-10-26  Yusuke Suzuki  <[email protected]>
+
+        [DOMJIT] Implement Node::ownerDocument
+        https://bugs.webkit.org/show_bug.cgi?id=164004
+
+        Reviewed by Darin Adler.
+
+        Test: js/dom/domjit-accessor-owner-document.html
+
+        Implement Node.ownerDocument DOMJIT accessor.
+        According to the result of the profiler, jQuery's prop()
+        function is frequently called in Ember.js SpeedoMeter.
+        And this function calls jQuery.isXMLDoc(). And this isXMLDoc()
+        function calls element.ownerDocument accessor. And our WebKit
+        inspector also uses ownerDocument accessor frequently.
+
+        Interesting thing is this ownerDocument functionality is used
+        in CSSJIT, so CSSJIT has similar helper function to look up the
+        owner document of the element. As a result, all the necessary
+        functionality is already implemented, DOMJIT just utilizes it.
+        For example, Node::treeScopeMemoryOffset() and
+        TreeScope::documentScopeMemoryOffset() is implemented before this
+        patch.
+
+        In the future, we will convert CSSJIT's Assembler& to CCallHelpers&
+        and share the code with DOMJIT[1].
+
+        [1]: https://bugs.webkit.org/show_bug.cgi?id=164006
+
+        * dom/Node.idl:
+        * domjit/DOMJITAbstractHeapRepository.h:
+        * domjit/JSNodeDOMJIT.cpp:
+        (WebCore::NodeOwnerDocumentDOMJIT::checkDOM):
+        (WebCore::NodeOwnerDocumentDOMJIT::callDOM):
+
 2016-10-26  Chris Dumez  <[email protected]>
 
         Replace IDBKeyPath with a WTF::Variant

Modified: trunk/Source/WebCore/dom/Node.idl (207931 => 207932)


--- trunk/Source/WebCore/dom/Node.idl	2016-10-27 03:13:21 UTC (rev 207931)
+++ trunk/Source/WebCore/dom/Node.idl	2016-10-27 03:42:13 UTC (rev 207932)
@@ -53,7 +53,7 @@
     [DOMJIT] readonly attribute Node? lastChild;
     [DOMJIT] readonly attribute Node? previousSibling;
     [DOMJIT] readonly attribute Node? nextSibling;
-    readonly attribute Document? ownerDocument;
+    [DOMJIT] readonly attribute Document? ownerDocument;
 
     [CEReactions, Custom, MayThrowLegacyException] Node insertBefore(Node newChild, Node? refChild);
     [CEReactions, Custom, MayThrowLegacyException] Node replaceChild(Node newChild, Node oldChild);

Modified: trunk/Source/WebCore/domjit/DOMJITAbstractHeapRepository.h (207931 => 207932)


--- trunk/Source/WebCore/domjit/DOMJITAbstractHeapRepository.h	2016-10-27 03:13:21 UTC (rev 207931)
+++ trunk/Source/WebCore/domjit/DOMJITAbstractHeapRepository.h	2016-10-27 03:42:13 UTC (rev 207932)
@@ -42,6 +42,7 @@
     V(Node_parentNode, Node) \
     V(Node_nextSibling, Node) \
     V(Node_previousSibling, Node) \
+    V(Node_ownerDocument, Node) \
 
 
 class AbstractHeapRepository {

Modified: trunk/Source/WebCore/domjit/JSNodeDOMJIT.cpp (207931 => 207932)


--- trunk/Source/WebCore/domjit/JSNodeDOMJIT.cpp	2016-10-27 03:13:21 UTC (rev 207931)
+++ trunk/Source/WebCore/domjit/JSNodeDOMJIT.cpp	2016-10-27 03:42:13 UTC (rev 207932)
@@ -96,7 +96,6 @@
     return patchpoint;
 }
 
-// Node#firstChild.
 Ref<JSC::DOMJIT::Patchpoint> NodeFirstChildDOMJIT::checkDOM()
 {
     return checkNode();
@@ -110,7 +109,6 @@
     return patchpoint;
 }
 
-// Node#lastChild.
 Ref<JSC::DOMJIT::Patchpoint> NodeLastChildDOMJIT::checkDOM()
 {
     return checkNode();
@@ -124,7 +122,6 @@
     return patchpoint;
 }
 
-// Node#nextSibling.
 Ref<JSC::DOMJIT::Patchpoint> NodeNextSiblingDOMJIT::checkDOM()
 {
     return checkNode();
@@ -138,7 +135,6 @@
     return patchpoint;
 }
 
-// Node#previousSibling.
 Ref<JSC::DOMJIT::Patchpoint> NodePreviousSiblingDOMJIT::checkDOM()
 {
     return checkNode();
@@ -152,7 +148,6 @@
     return patchpoint;
 }
 
-// Node#parentNode.
 Ref<JSC::DOMJIT::Patchpoint> NodeParentNodeDOMJIT::checkDOM()
 {
     return checkNode();
@@ -166,7 +161,6 @@
     return patchpoint;
 }
 
-// Node#nodeType.
 Ref<JSC::DOMJIT::Patchpoint> NodeNodeTypeDOMJIT::checkDOM()
 {
     return checkNode();
@@ -188,6 +182,41 @@
     return patchpoint;
 }
 
+Ref<JSC::DOMJIT::Patchpoint> NodeOwnerDocumentDOMJIT::checkDOM()
+{
+    return checkNode();
 }
 
+Ref<JSC::DOMJIT::CallDOMPatchpoint> NodeOwnerDocumentDOMJIT::callDOM()
+{
+    const auto& heap = DOMJIT::AbstractHeapRepository::shared();
+    Ref<JSC::DOMJIT::CallDOMPatchpoint> patchpoint = JSC::DOMJIT::CallDOMPatchpoint::create();
+    patchpoint->numGPScratchRegisters = 1;
+    patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) {
+        JSValueRegs result = params[0].jsValueRegs();
+        GPRReg node = params[1].gpr();
+        GPRReg globalObject = params[2].gpr();
+        JSValue globalObjectValue = params[2].value();
+        GPRReg scratch = params.gpScratch(0);
+
+        // If the given node is a Document, Node#ownerDocument returns null.
+        auto notDocument = DOMJIT::branchIfNotDocumentWrapper(jit, node);
+        jit.moveValue(jsNull(), result);
+        auto done = jit.jump();
+
+        notDocument.link(&jit);
+        jit.loadPtr(CCallHelpers::Address(node, JSNode::offsetOfWrapped()), scratch);
+        jit.loadPtr(CCallHelpers::Address(scratch, Node::treeScopeMemoryOffset()), scratch);
+        jit.loadPtr(CCallHelpers::Address(scratch, TreeScope::documentScopeMemoryOffset()), scratch);
+
+        DOMJIT::toWrapper<Document>(jit, params, scratch, globalObject, result, toWrapperSlow<Document>, globalObjectValue);
+        done.link(&jit);
+        return CCallHelpers::JumpList();
+    });
+    patchpoint->effect = JSC::DOMJIT::Effect::forDef(heap.Node_ownerDocument);
+    return patchpoint;
+}
+
+}
+
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to