[DOMJIT][JSC] Explore the way to embed nodeType into JSC::JSType in WebCore
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Oct 2016 20:47:51 +0000 (20:47 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Oct 2016 20:47:51 +0000 (20:47 +0000)
commitf7df8bcb56982c4410e6e357fb89285441a078bc
treee9b0d444edfdce4a3a083f3360ee8e116d5fd601
parentae830e62de6ce46aaabd6b87fb1905b62aa6f3d7
[DOMJIT][JSC] Explore the way to embed nodeType into JSC::JSType in WebCore
https://bugs.webkit.org/show_bug.cgi?id=163245

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

We reserve the highest bit of JSC::JSType for extensions outside JSC.
JSC does not use JSType bits so many: only 52 types are defined.

And we extend CallDOM patchpoint to claim that it does not require a global object.
This global object is used to generate a DOM wrapper. However, nodeType does not require
it since it just returns integer. In the future, we will extend CallDOM to claim
its result type. And we can decide this `requireGlobalObject` condition automatically
according to the result type.

* JavaScriptCore.xcodeproj/project.pbxproj:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleDOMJITGetter):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.h:
* dfg/DFGNode.h:
(JSC::DFG::Node::hasCheckDOMPatchpoint):
(JSC::DFG::Node::checkDOMPatchpoint):
(JSC::DFG::Node::hasCallDOMPatchpoint):
(JSC::DFG::Node::callDOMPatchpoint):
(JSC::DFG::Node::hasDOMJIT): Deleted.
(JSC::DFG::Node::domJIT): Deleted.
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCallDOM):
(JSC::DFG::SpeculativeJIT::compileCheckDOM):
* domjit/DOMJITCallDOMPatchpoint.h: Copied from Source/JavaScriptCore/domjit/DOMJITGetterSetter.h.
(JSC::DOMJIT::CallDOMPatchpoint::create):
* domjit/DOMJITGetterSetter.h:
* domjit/DOMJITPatchpoint.h:
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCheckDOM):
(JSC::FTL::DFG::LowerDFGToB3::compileCallDOM):
* jsc.cpp:
* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LowLevelInterpreter.asm:
* runtime/JSType.h:

Source/WebCore:

Node.nodeType accessor is so frequently called. For example, jQuery's $ function uses
this to distinguish DOM objects from the other JS objects. So every time you call `$(dom)`,
nodeType accessor is called. In addition to that, jQuery's prev, next, parent etc. also uses
this `nodeType`. And Ember.js also uses it. And ... So this function is super critical for DOM
performance.

The challenge is that there is no room for putting NodeType into C++ Node class. Node class
has a 32bit field to store some data. However, these bits are already exhausted. Extending
Node class is unacceptable since it significantly enlarges memory consumption of WebKit (Node
is everywhere!). Unfortunately, current Node::nodeType is implemented as a virtual function
even though this function is frequently called from JS world.

Interestingly, we already store some duplicate data in JSObject, JSC::JSType. WebCore already
extends it with JSElementType, JSNodeType, and JSDocumentWrapperType. And these types are
corresponding to specific NodeTypes. For example, JSElementType should have ELEMENT_NODE type.

This patch further extends this JSC::JSType in WebCore side safely. We embed NodeType bits into
JSC::JSType. This design offers significantly faster nodeType implementation. Furthermore, it
makes DOMJIT easy for nodeType accessor.

Even without the IC change[1], Dromaeo dom-query shows 8 - 10% improvement,
1452.96 runs/s vs 1578.56 runs/s. We can expect that this improvement will be applied to the
other benchmarks / real applications when the IC change is landed.

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

* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMWrapper.h:
* bindings/js/JSNodeCustom.h:
(WebCore::JSNode::nodeType):
* bindings/scripts/CodeGeneratorJS.pm:
(GetJSTypeForNode):
(GenerateHeader):
* dom/Node.idl:
* dom/NodeConstants.h: Copied from Source/JavaScriptCore/domjit/DOMJITGetterSetter.h.
* domjit/JSNodeDOMJIT.cpp:
(WebCore::createCallDOMForOffsetAccess):
(WebCore::NodeFirstChildDOMJIT::callDOM):
(WebCore::NodeLastChildDOMJIT::callDOM):
(WebCore::NodeNextSiblingDOMJIT::callDOM):
(WebCore::NodePreviousSiblingDOMJIT::callDOM):
(WebCore::NodeParentNodeDOMJIT::callDOM):
(WebCore::NodeNodeTypeDOMJIT::checkDOM):
(WebCore::NodeNodeTypeDOMJIT::callDOM):

LayoutTests:

* js/dom/domjit-accessor-node-type.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207239 268f45cc-cd09-0410-ab3c-d52691b4dbfc
25 files changed:
LayoutTests/ChangeLog
LayoutTests/js/dom/domjit-accessor-node-type.html [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGGraph.h
Source/JavaScriptCore/dfg/DFGNode.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/domjit/DOMJITCallDOMPatchpoint.h [new file with mode: 0644]
Source/JavaScriptCore/domjit/DOMJITGetterSetter.h
Source/JavaScriptCore/domjit/DOMJITPatchpoint.h
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/llint/LLIntData.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/runtime/JSType.h
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSDOMWrapper.h
Source/WebCore/bindings/js/JSNodeCustom.h
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/dom/Node.idl
Source/WebCore/dom/NodeConstants.h [new file with mode: 0644]
Source/WebCore/domjit/JSNodeDOMJIT.cpp