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