<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[207239] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/207239">207239</a></dd>
<dt>Author</dt> <dd>utatane.tea@gmail.com</dd>
<dt>Date</dt> <dd>2016-10-12 13:47:51 -0700 (Wed, 12 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredomjitDOMJITGetterSetterh">trunk/Source/JavaScriptCore/domjit/DOMJITGetterSetter.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredomjitDOMJITPatchpointh">trunk/Source/JavaScriptCore/domjit/DOMJITPatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntDatacpp">trunk/Source/JavaScriptCore/llint/LLIntData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTypeh">trunk/Source/JavaScriptCore/runtime/JSType.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMWrapperh">trunk/Source/WebCore/bindings/js/JSDOMWrapper.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSNodeCustomh">trunk/Source/WebCore/bindings/js/JSNodeCustom.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm">trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
<li><a href="#trunkSourceWebCoredomNodeidl">trunk/Source/WebCore/dom/Node.idl</a></li>
<li><a href="#trunkSourceWebCoredomjitJSNodeDOMJITcpp">trunk/Source/WebCore/domjit/JSNodeDOMJIT.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsdomdomjitaccessornodetypehtml">trunk/LayoutTests/js/dom/domjit-accessor-node-type.html</a></li>
<li><a href="#trunkSourceJavaScriptCoredomjitDOMJITCallDOMPatchpointh">trunk/Source/JavaScriptCore/domjit/DOMJITCallDOMPatchpoint.h</a></li>
<li><a href="#trunkSourceWebCoredomNodeConstantsh">trunk/Source/WebCore/dom/NodeConstants.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/LayoutTests/ChangeLog        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2016-10-12  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [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.
+
+        * js/dom/domjit-accessor-node-type.html: Added.
+
</ins><span class="cx"> 2016-10-12  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Update more events to stop using legacy [ConstructorTemplate=Event]
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomdomjitaccessornodetypehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/dom/domjit-accessor-node-type.html (0 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/domjit-accessor-node-type.html                                (rev 0)
+++ trunk/LayoutTests/js/dom/domjit-accessor-node-type.html        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;iframe id=&quot;xmlframe&quot; onload=&quot;frameLoaded()&quot; style=&quot;height:0px&quot; src=&quot;data:application/xhtml+xml,&lt;?xml version='1.0' encoding='UTF-8'?&gt;&lt;body/&gt;&quot;&gt;&lt;/iframe&gt;
+&lt;script&gt;
+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 = [
+        [document.body, Node.ELEMENT_NODE],
+        [document.createAttribute('Cocoa'), Node.ATTRIBUTE_NODE],
+        [document.createTextNode('Cocoa'), Node.TEXT_NODE],
+        [xmlDocument.createCDATASection('test'), Node.CDATA_SECTION_NODE],
+        [xmlDocument.createProcessingInstruction('target', 'test'), Node.PROCESSING_INSTRUCTION_NODE],
+        [document.createComment('Cocoa'), Node.COMMENT_NODE],
+        [document, Node.DOCUMENT_NODE],
+        [document.doctype, Node.DOCUMENT_TYPE_NODE],
+        [document.createDocumentFragment(), Node.DOCUMENT_FRAGMENT_NODE],
+    ];
+
+    for ([target, result] of targets) {
+        var text = `
+            function test${result}(element, result)
+            {
+                for (var i = 0; i &lt; 1e4; ++i) {
+                    if (element.nodeType !== result)
+                        return false;
+                }
+                return true;
+            }
+        `;
+        shouldBeTrue(`(${text})(target, ${result})`);
+    }
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+function frameLoaded()
+{
+    runTest();
+}
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2016-10-12  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [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.
+
+        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:
+
</ins><span class="cx"> 2016-10-12  Keith Miller  &lt;keith_miller@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Handle non-function, non-undefined comparator in Array.prototype.sort
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -2096,6 +2096,7 @@
</span><span class="cx">                 E33F50851B8437A000413856 /* JSInternalPromiseDeferred.h in Headers */ = {isa = PBXBuildFile; fileRef = E33F50831B8437A000413856 /* JSInternalPromiseDeferred.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 E33F50871B8449EF00413856 /* JSInternalPromiseConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E33F50861B8449EF00413856 /* JSInternalPromiseConstructor.lut.h */; };
</span><span class="cx">                 E354622B1B6065D100545386 /* ConstructAbility.h in Headers */ = {isa = PBXBuildFile; fileRef = E354622A1B6065D100545386 /* ConstructAbility.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                E3555B8A1DAE03A500F36921 /* DOMJITCallDOMPatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = E3555B891DAE03A200F36921 /* DOMJITCallDOMPatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 E355F3521B7DC85300C50DC5 /* ModuleLoaderPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E355F3501B7DC85300C50DC5 /* ModuleLoaderPrototype.cpp */; };
</span><span class="cx">                 E355F3531B7DC85300C50DC5 /* ModuleLoaderPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = E355F3511B7DC85300C50DC5 /* ModuleLoaderPrototype.h */; };
</span><span class="cx">                 E35E035F1B7AB43E0073AD2A /* InspectorInstrumentationObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35E035D1B7AB43E0073AD2A /* InspectorInstrumentationObject.cpp */; };
</span><span class="lines">@@ -4399,6 +4400,7 @@
</span><span class="cx">                 E33F50861B8449EF00413856 /* JSInternalPromiseConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInternalPromiseConstructor.lut.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E33F50881B844A1A00413856 /* InternalPromiseConstructor.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = InternalPromiseConstructor.js; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E354622A1B6065D100545386 /* ConstructAbility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstructAbility.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                E3555B891DAE03A200F36921 /* DOMJITCallDOMPatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITCallDOMPatchpoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 E355F3501B7DC85300C50DC5 /* ModuleLoaderPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModuleLoaderPrototype.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E355F3511B7DC85300C50DC5 /* ModuleLoaderPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleLoaderPrototype.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E35E035D1B7AB43E0073AD2A /* InspectorInstrumentationObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorInstrumentationObject.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -7195,6 +7197,7 @@
</span><span class="cx">                 E3FF752D1D9CE9EA00C7E16D /* domjit */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                E3555B891DAE03A200F36921 /* DOMJITCallDOMPatchpoint.h */,
</ins><span class="cx">                                 E3FF752F1D9CEA1200C7E16D /* DOMJITGetterSetter.h */,
</span><span class="cx">                                 E3C08E3B1DA41B7B0039478F /* DOMJITPatchpoint.h */,
</span><span class="cx">                                 E37AD83A1DA4928000F3D412 /* DOMJITPatchpointParams.h */,
</span><span class="lines">@@ -8072,6 +8075,7 @@
</span><span class="cx">                                 A7C1EAF017987AB600299DB2 /* CLoopStackInlines.h in Headers */,
</span><span class="cx">                                 BC18C4270E16F5CD00B34460 /* JSString.h in Headers */,
</span><span class="cx">                                 86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */,
</span><ins>+                                E3555B8A1DAE03A500F36921 /* DOMJITCallDOMPatchpoint.h in Headers */,
</ins><span class="cx">                                 70EC0EC31AA0D7DA00B6AAFA /* JSStringIterator.h in Headers */,
</span><span class="cx">                                 0F070A471D543A8B006E7232 /* CellContainer.h in Headers */,
</span><span class="cx">                                 2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -2687,12 +2687,19 @@
</span><span class="cx">         return false;
</span><span class="cx">     addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structureSet())), thisNode);
</span><span class="cx"> 
</span><ins>+    Ref&lt;DOMJIT::Patchpoint&gt; checkDOMPatchpoint = domJIT-&gt;checkDOM();
+    m_graph.m_domJITPatchpoints.append(checkDOMPatchpoint.ptr());
</ins><span class="cx">     // We do not need to emit CheckCell thingy here. When the custom accessor is replaced to different one, Structure transition occurs.
</span><del>-    addToGraph(CheckDOM, OpInfo(domJIT), OpInfo(domJIT-&gt;thisClassInfo()), thisNode);
-    Node* globalObject = addToGraph(GetGlobalObject, thisNode);
-    addVarArgChild(globalObject); // GlobalObject of thisNode is always used to create a DOMWrapper.
</del><ins>+    addToGraph(CheckDOM, OpInfo(checkDOMPatchpoint.ptr()), OpInfo(domJIT-&gt;thisClassInfo()), thisNode);
+
+    Ref&lt;DOMJIT::CallDOMPatchpoint&gt; callDOMPatchpoint = domJIT-&gt;callDOM();
+    m_graph.m_domJITPatchpoints.append(callDOMPatchpoint.ptr());
+    if (callDOMPatchpoint-&gt;requireGlobalObject) {
+        Node* globalObject = addToGraph(GetGlobalObject, thisNode);
+        addVarArgChild(globalObject); // GlobalObject of thisNode is always used to create a DOMWrapper.
+    }
</ins><span class="cx">     addVarArgChild(thisNode);
</span><del>-    set(VirtualRegister(resultOperand), addToGraph(Node::VarArg, CallDOM, OpInfo(domJIT), OpInfo(prediction)));
</del><ins>+    set(VirtualRegister(resultOperand), addToGraph(Node::VarArg, CallDOM, OpInfo(callDOMPatchpoint.ptr()), OpInfo(prediction)));
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -1703,10 +1703,14 @@
</span><span class="cx">             fixEdge&lt;CellUse&gt;(node-&gt;child1());
</span><span class="cx">             break;
</span><span class="cx"> 
</span><del>-        case CallDOM:
-            fixEdge&lt;KnownCellUse&gt;(m_graph.varArgChild(node, 0)); // GlobalObject.
-            fixEdge&lt;CellUse&gt;(m_graph.varArgChild(node, 1)); // DOM.
</del><ins>+        case CallDOM: {
+            int childIndex = 0;
+            DOMJIT::CallDOMPatchpoint* patchpoint = node-&gt;callDOMPatchpoint();
+            if (patchpoint-&gt;requireGlobalObject)
+                fixEdge&lt;KnownCellUse&gt;(m_graph.varArgChild(node, childIndex++)); // GlobalObject.
+            fixEdge&lt;CellUse&gt;(m_graph.varArgChild(node, childIndex++)); // DOM.
</ins><span class="cx">             break;
</span><ins>+        }
</ins><span class="cx"> 
</span><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -904,6 +904,7 @@
</span><span class="cx">     HashMap&lt;CodeBlock*, std::unique_ptr&lt;BytecodeKills&gt;&gt; m_bytecodeKills;
</span><span class="cx">     HashSet&lt;std::pair&lt;JSObject*, PropertyOffset&gt;&gt; m_safeToLoad;
</span><span class="cx">     HashMap&lt;PropertyTypeKey, InferredType::Descriptor&gt; m_inferredTypes;
</span><ins>+    Vector&lt;RefPtr&lt;DOMJIT::Patchpoint&gt;&gt; m_domJITPatchpoints;
</ins><span class="cx">     std::unique_ptr&lt;Dominators&gt; m_dominators;
</span><span class="cx">     std::unique_ptr&lt;PrePostNumbering&gt; m_prePostNumbering;
</span><span class="cx">     std::unique_ptr&lt;NaturalLoops&gt; m_naturalLoops;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -59,7 +59,8 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> namespace DOMJIT {
</span><del>-class GetterSetter;
</del><ins>+class Patchpoint;
+class CallDOMPatchpoint;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> namespace Profiler {
</span><span class="lines">@@ -2314,17 +2315,28 @@
</span><span class="cx">         return m_opInfo.as&lt;BasicBlockLocation*&gt;();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool hasDOMJIT() const
</del><ins>+    bool hasCheckDOMPatchpoint() const
</ins><span class="cx">     {
</span><del>-        return op() == CheckDOM || op() == CallDOM;
</del><ins>+        return op() == CheckDOM;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    DOMJIT::GetterSetter* domJIT()
</del><ins>+    DOMJIT::Patchpoint* checkDOMPatchpoint()
</ins><span class="cx">     {
</span><del>-        ASSERT(hasDOMJIT());
-        return m_opInfo.as&lt;DOMJIT::GetterSetter*&gt;();
</del><ins>+        ASSERT(hasCheckDOMPatchpoint());
+        return m_opInfo.as&lt;DOMJIT::Patchpoint*&gt;();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    bool hasCallDOMPatchpoint() const
+    {
+        return op() == CallDOM;
+    }
+
+    DOMJIT::CallDOMPatchpoint* callDOMPatchpoint()
+    {
+        ASSERT(hasCallDOMPatchpoint());
+        return m_opInfo.as&lt;DOMJIT::CallDOMPatchpoint*&gt;();
+    }
+
</ins><span class="cx">     bool hasClassInfo() const
</span><span class="cx">     {
</span><span class="cx">         return op() == CheckDOM;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -7130,29 +7130,31 @@
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compileCallDOM(Node* node)
</span><span class="cx"> {
</span><del>-    Ref&lt;DOMJIT::Patchpoint&gt; patchpoint = node-&gt;domJIT()-&gt;callDOM();
</del><ins>+    DOMJIT::CallDOMPatchpoint* patchpoint = node-&gt;callDOMPatchpoint();
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;GPRReg&gt; gpScratch;
</span><span class="cx">     Vector&lt;FPRReg&gt; fpScratch;
</span><span class="cx">     Vector&lt;DOMJIT::Value&gt; regs;
</span><span class="cx"> 
</span><del>-    // FIXME: patchpoint should have a way to tell this can reuse &quot;base&quot; register.
-    // Teaching DFG about DOMJIT::Patchpoint clobber information is nice.
-    SpeculateCellOperand globalObject(this, m_jit.graph().varArgChild(node, 0));
-    SpeculateCellOperand base(this, m_jit.graph().varArgChild(node, 1));
</del><span class="cx">     JSValueRegsTemporary result(this);
</span><del>-
</del><span class="cx">     regs.append(result.regs());
</span><del>-    regs.append(DOMJIT::Value(globalObject.gpr(), m_state.forNode(m_jit.graph().varArgChild(node, 0)).value()));
-    regs.append(DOMJIT::Value(base.gpr(), m_state.forNode(m_jit.graph().varArgChild(node, 1)).value()));
-#if USE(JSVALUE64)
-    regs.append(static_cast&lt;GPRReg&gt;(GPRInfo::tagMaskRegister));
-    regs.append(static_cast&lt;GPRReg&gt;(GPRInfo::tagTypeNumberRegister));
-#endif
</del><span class="cx"> 
</span><ins>+    int childIndex = 0;
+
+    Optional&lt;SpeculateCellOperand&gt; globalObject;
+    if (patchpoint-&gt;requireGlobalObject) {
+        Edge&amp; globalObjectEdge = m_jit.graph().varArgChild(node, childIndex++);
+        globalObject = SpeculateCellOperand(this, globalObjectEdge);
+        regs.append(DOMJIT::Value(globalObject-&gt;gpr(), m_state.forNode(globalObjectEdge).value()));
+    }
+
+    Edge&amp; baseEdge = m_jit.graph().varArgChild(node, childIndex++);
+    SpeculateCellOperand base(this, baseEdge);
+    regs.append(DOMJIT::Value(base.gpr(), m_state.forNode(baseEdge).value()));
+
</ins><span class="cx">     Vector&lt;GPRTemporary&gt; gpTempraries;
</span><span class="cx">     Vector&lt;FPRTemporary&gt; fpTempraries;
</span><del>-    allocateTemporaryRegistersForPatchpoint(this, gpTempraries, fpTempraries, gpScratch, fpScratch, patchpoint.get());
</del><ins>+    allocateTemporaryRegistersForPatchpoint(this, gpTempraries, fpTempraries, gpScratch, fpScratch, *patchpoint);
</ins><span class="cx">     DOMJITPatchpointParams params(this, WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch));
</span><span class="cx">     patchpoint-&gt;generator()-&gt;run(m_jit, params);
</span><span class="cx">     jsValueResult(result.regs(), node);
</span><span class="lines">@@ -7161,7 +7163,7 @@
</span><span class="cx"> void SpeculativeJIT::compileCheckDOM(Node* node)
</span><span class="cx"> {
</span><span class="cx">     // FIXME: We can add the fallback implementation that inlines jsDynamicCast things here.
</span><del>-    Ref&lt;DOMJIT::Patchpoint&gt; patchpoint = node-&gt;domJIT()-&gt;checkDOM();
</del><ins>+    DOMJIT::Patchpoint* patchpoint = node-&gt;checkDOMPatchpoint();
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;GPRReg&gt; gpScratch;
</span><span class="cx">     Vector&lt;FPRReg&gt; fpScratch;
</span><span class="lines">@@ -7173,7 +7175,7 @@
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;GPRTemporary&gt; gpTempraries;
</span><span class="cx">     Vector&lt;FPRTemporary&gt; fpTempraries;
</span><del>-    allocateTemporaryRegistersForPatchpoint(this, gpTempraries, fpTempraries, gpScratch, fpScratch, patchpoint.get());
</del><ins>+    allocateTemporaryRegistersForPatchpoint(this, gpTempraries, fpTempraries, gpScratch, fpScratch, *patchpoint);
</ins><span class="cx"> 
</span><span class="cx">     DOMJITPatchpointParams params(this, WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch));
</span><span class="cx">     CCallHelpers::JumpList failureCases = patchpoint-&gt;generator()-&gt;run(m_jit, params);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredomjitDOMJITCallDOMPatchpointhfromrev207238trunkSourceJavaScriptCoredomjitDOMJITGetterSetterh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/domjit/DOMJITCallDOMPatchpoint.h (from rev 207238, trunk/Source/JavaScriptCore/domjit/DOMJITGetterSetter.h) (0 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/domjit/DOMJITCallDOMPatchpoint.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/domjit/DOMJITCallDOMPatchpoint.h        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(JIT)
+
+#include &quot;DOMJITPatchpoint.h&quot;
+#include &quot;RegisterSet.h&quot;
+
+namespace JSC { namespace DOMJIT {
+
+class CallDOMPatchpoint : public Patchpoint {
+public:
+    static Ref&lt;CallDOMPatchpoint&gt; create()
+    {
+        return adoptRef(*new CallDOMPatchpoint());
+    }
+
+    // To look up DOMWrapper cache, GlobalObject is required.
+    // FIXME: Later, we will extend this patchpoint to represent the result type by DOMJIT::Signature.
+    // And after that, we will automatically pass a global object when the result type includes a DOM wrapper thing.
+    // https://bugs.webkit.org/show_bug.cgi?id=162980
+    bool requireGlobalObject { true };
+
+private:
+    CallDOMPatchpoint() = default;
+};
+
+} }
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredomjitDOMJITGetterSetterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/domjit/DOMJITGetterSetter.h (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/domjit/DOMJITGetterSetter.h        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/domjit/DOMJITGetterSetter.h        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><del>-#include &quot;DOMJITPatchpoint.h&quot;
</del><ins>+#include &quot;DOMJITCallDOMPatchpoint.h&quot;
</ins><span class="cx"> #include &quot;PropertySlot.h&quot;
</span><span class="cx"> #include &quot;PutPropertySlot.h&quot;
</span><span class="cx"> #include &quot;SpeculatedType.h&quot;
</span><span class="lines">@@ -51,7 +51,7 @@
</span><span class="cx">     const ClassInfo* thisClassInfo() const { return m_thisClassInfo; }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-    virtual Ref&lt;DOMJIT::Patchpoint&gt; callDOM() = 0;
</del><ins>+    virtual Ref&lt;DOMJIT::CallDOMPatchpoint&gt; callDOM() = 0;
</ins><span class="cx">     virtual Ref&lt;DOMJIT::Patchpoint&gt; checkDOM() = 0;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredomjitDOMJITPatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/domjit/DOMJITPatchpoint.h (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/domjit/DOMJITPatchpoint.h        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/domjit/DOMJITPatchpoint.h        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -62,9 +62,10 @@
</span><span class="cx">     uint8_t numGPScratchRegisters { 0 };
</span><span class="cx">     uint8_t numFPScratchRegisters { 0 };
</span><span class="cx"> 
</span><del>-private:
</del><ins>+protected:
</ins><span class="cx">     Patchpoint() = default;
</span><span class="cx"> 
</span><ins>+private:
</ins><span class="cx">     RefPtr&lt;PatchpointGenerator&gt; m_generator;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -8724,7 +8724,7 @@
</span><span class="cx">     {
</span><span class="cx">         LValue cell = lowCell(m_node-&gt;child1());
</span><span class="cx"> 
</span><del>-        RefPtr&lt;DOMJIT::Patchpoint&gt; domJIT = m_node-&gt;domJIT()-&gt;checkDOM();
</del><ins>+        DOMJIT::Patchpoint* domJIT = m_node-&gt;checkDOMPatchpoint();
</ins><span class="cx"> 
</span><span class="cx">         PatchpointValue* patchpoint = m_out.patchpoint(Void);
</span><span class="cx">         patchpoint-&gt;appendSomeRegister(cell);
</span><span class="lines">@@ -8769,13 +8769,25 @@
</span><span class="cx"> 
</span><span class="cx">     void compileCallDOM()
</span><span class="cx">     {
</span><del>-        LValue globalObject = lowCell(m_graph.varArgChild(m_node, 0));
-        LValue cell = lowCell(m_graph.varArgChild(m_node, 1));
</del><ins>+        DOMJIT::CallDOMPatchpoint* domJIT = m_node-&gt;callDOMPatchpoint();
+        int childIndex = 0;
</ins><span class="cx"> 
</span><del>-        RefPtr&lt;DOMJIT::Patchpoint&gt; domJIT = m_node-&gt;domJIT()-&gt;callDOM();
</del><ins>+        LValue globalObject;
+        JSValue globalObjectConstant;
+        if (domJIT-&gt;requireGlobalObject) {
+            Edge&amp; globalObjectEdge = m_graph.varArgChild(m_node, childIndex++);
+            globalObject = lowCell(globalObjectEdge);
+            globalObjectConstant = m_state.forNode(globalObjectEdge).value();
+        }
+
+        Edge&amp; baseEdge = m_graph.varArgChild(m_node, childIndex++);
+        LValue base = lowCell(baseEdge);
+        JSValue baseConstant = m_state.forNode(baseEdge).value();
+
</ins><span class="cx">         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
</span><del>-        patchpoint-&gt;appendSomeRegister(globalObject);
-        patchpoint-&gt;appendSomeRegister(cell);
</del><ins>+        if (domJIT-&gt;requireGlobalObject)
+            patchpoint-&gt;appendSomeRegister(globalObject);
+        patchpoint-&gt;appendSomeRegister(base);
</ins><span class="cx">         patchpoint-&gt;append(m_tagMask, ValueRep::reg(GPRInfo::tagMaskRegister));
</span><span class="cx">         patchpoint-&gt;append(m_tagTypeNumber, ValueRep::reg(GPRInfo::tagTypeNumberRegister));
</span><span class="cx">         RefPtr&lt;PatchpointExceptionHandle&gt; exceptionHandle = preparePatchpointForExceptions(patchpoint);
</span><span class="lines">@@ -8786,8 +8798,6 @@
</span><span class="cx"> 
</span><span class="cx">         State* state = &amp;m_ftlState;
</span><span class="cx">         Node* node = m_node;
</span><del>-        JSValue child1Constant = m_state.forNode(m_graph.varArgChild(m_node, 0)).value();
-        JSValue child2Constant = m_state.forNode(m_graph.varArgChild(m_node, 1)).value();
</del><span class="cx">         patchpoint-&gt;setGenerator(
</span><span class="cx">             [=] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
</span><span class="cx">                 AllowMacroScratchRegisterUsage allowScratch(jit);
</span><span class="lines">@@ -8796,11 +8806,11 @@
</span><span class="cx">                 Vector&lt;FPRReg&gt; fpScratch;
</span><span class="cx">                 Vector&lt;DOMJIT::Value&gt; regs;
</span><span class="cx"> 
</span><del>-                // FIXME: patchpoint should have a way to tell this can reuse &quot;base&quot; register.
-                // Teaching DFG about DOMJIT::Patchpoint clobber information is nice.
</del><ins>+                int childIndex = 1;
</ins><span class="cx">                 regs.append(JSValueRegs(params[0].gpr()));
</span><del>-                regs.append(DOMJIT::Value(params[1].gpr(), child1Constant));
-                regs.append(DOMJIT::Value(params[2].gpr(), child2Constant));
</del><ins>+                if (domJIT-&gt;requireGlobalObject)
+                    regs.append(DOMJIT::Value(params[childIndex++].gpr(), globalObjectConstant));
+                regs.append(DOMJIT::Value(params[childIndex++].gpr(), baseConstant));
</ins><span class="cx"> 
</span><span class="cx">                 for (unsigned i = 0; i &lt; domJIT-&gt;numGPScratchRegisters; ++i)
</span><span class="cx">                     gpScratch.append(params.gpScratch(i));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -620,12 +620,13 @@
</span><span class="cx">             return patchpoint;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        Ref&lt;DOMJIT::Patchpoint&gt; callDOM() override
</del><ins>+        Ref&lt;DOMJIT::CallDOMPatchpoint&gt; callDOM() override
</ins><span class="cx">         {
</span><del>-            Ref&lt;DOMJIT::Patchpoint&gt; patchpoint = DOMJIT::Patchpoint::create();
</del><ins>+            Ref&lt;DOMJIT::CallDOMPatchpoint&gt; patchpoint = DOMJIT::CallDOMPatchpoint::create();
+            patchpoint-&gt;requireGlobalObject = false;
</ins><span class="cx">             patchpoint-&gt;setGenerator([=](CCallHelpers&amp; jit, const DOMJIT::PatchpointParams&amp; params) {
</span><span class="cx">                 JSValueRegs results = params[0].jsValueRegs();
</span><del>-                GPRReg dom = params[2].gpr();
</del><ins>+                GPRReg dom = params[1].gpr();
</ins><span class="cx"> 
</span><span class="cx">                 params.addSlowPathCall(jit.jump(), jit, static_cast&lt;EncodedJSValue(*)(ExecState*, void*)&gt;([](ExecState*, void* pointer) {
</span><span class="cx">                     return JSValue::encode(jsNumber(static_cast&lt;DOMJITGetter*&gt;(pointer)-&gt;value()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntData.cpp (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/llint/LLIntData.cpp        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -161,16 +161,16 @@
</span><span class="cx">     STATIC_ASSERT(JSFunctionType == 23);
</span><span class="cx">     STATIC_ASSERT(ArrayType == 31);
</span><span class="cx">     STATIC_ASSERT(DerivedArrayType == 32);
</span><del>-    STATIC_ASSERT(ProxyObjectType == 116);
-    STATIC_ASSERT(Int8ArrayType == 100);
-    STATIC_ASSERT(Int16ArrayType == 101);
-    STATIC_ASSERT(Int32ArrayType == 102);
-    STATIC_ASSERT(Uint8ArrayType == 103);
-    STATIC_ASSERT(Uint8ClampedArrayType == 104);
-    STATIC_ASSERT(Uint16ArrayType == 105);
-    STATIC_ASSERT(Uint32ArrayType == 106);
-    STATIC_ASSERT(Float32ArrayType == 107);
-    STATIC_ASSERT(Float64ArrayType == 108);
</del><ins>+    STATIC_ASSERT(ProxyObjectType == 49);
+    STATIC_ASSERT(Int8ArrayType == 33);
+    STATIC_ASSERT(Int16ArrayType == 34);
+    STATIC_ASSERT(Int32ArrayType == 35);
+    STATIC_ASSERT(Uint8ArrayType == 36);
+    STATIC_ASSERT(Uint8ClampedArrayType == 37);
+    STATIC_ASSERT(Uint16ArrayType == 38);
+    STATIC_ASSERT(Uint32ArrayType == 39);
+    STATIC_ASSERT(Float32ArrayType == 40);
+    STATIC_ASSERT(Float64ArrayType == 41);
</ins><span class="cx">     STATIC_ASSERT(MasqueradesAsUndefined == 1);
</span><span class="cx">     STATIC_ASSERT(ImplementsDefaultHasInstance == 2);
</span><span class="cx">     STATIC_ASSERT(FirstConstantRegisterIndex == 0x40000000);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -350,19 +350,19 @@
</span><span class="cx"> const JSFunctionType = 23
</span><span class="cx"> const ArrayType = 31
</span><span class="cx"> const DerivedArrayType = 32
</span><del>-const ProxyObjectType = 116
</del><ins>+const ProxyObjectType = 49
</ins><span class="cx"> 
</span><span class="cx"> # The typed array types need to be numbered in a particular order because of the manually written
</span><span class="cx"> # switch statement in get_by_val and put_by_val.
</span><del>-const Int8ArrayType = 100
-const Int16ArrayType = 101
-const Int32ArrayType = 102
-const Uint8ArrayType = 103
-const Uint8ClampedArrayType = 104
-const Uint16ArrayType = 105
-const Uint32ArrayType = 106
-const Float32ArrayType = 107
-const Float64ArrayType = 108
</del><ins>+const Int8ArrayType = 33
+const Int16ArrayType = 34
+const Int32ArrayType = 35
+const Uint8ArrayType = 36
+const Uint8ClampedArrayType = 37
+const Uint16ArrayType = 38
+const Uint32ArrayType = 39
+const Float32ArrayType = 40
+const Float64ArrayType = 41
</ins><span class="cx"> 
</span><span class="cx"> const FirstArrayType = Int8ArrayType
</span><span class="cx"> const LastArrayType = Float64ArrayType
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSType.h (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSType.h        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/JavaScriptCore/runtime/JSType.h        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -65,7 +65,7 @@
</span><span class="cx">     ArrayType,
</span><span class="cx">     DerivedArrayType,
</span><span class="cx"> 
</span><del>-    Int8ArrayType = 100,
</del><ins>+    Int8ArrayType,
</ins><span class="cx">     Int16ArrayType,
</span><span class="cx">     Int32ArrayType,
</span><span class="cx">     Uint8ArrayType,
</span><span class="lines">@@ -87,8 +87,10 @@
</span><span class="cx">     JSSetType,
</span><span class="cx"> 
</span><span class="cx">     LastJSCObjectType = JSSetType,
</span><ins>+    MaxJSType = 0b11111111,
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-COMPILE_ASSERT(sizeof(JSType) == sizeof(uint8_t), sizeof_jstype_is_one_byte);
</del><ins>+static_assert(sizeof(JSType) == sizeof(uint8_t), &quot;sizeof(JSType) is one byte.&quot;);
+static_assert(LastJSCObjectType &lt; 128, &quot;The highest bit is reserved for embedder's extension.&quot;);
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/WebCore/ChangeLog        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -1,3 +1,55 @@
</span><ins>+2016-10-12  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [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.
+
+        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):
+
</ins><span class="cx"> 2016-10-12  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Update more events to stop using legacy [ConstructorTemplate=Event]
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -6143,6 +6143,7 @@
</span><span class="cx">                 E1FF8F6D180DB5BE00132674 /* CryptoAlgorithmRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = E1FF8F6B180DB5BE00132674 /* CryptoAlgorithmRegistry.h */; };
</span><span class="cx">                 E3150EA61DA7219000194012 /* JSNodeDOMJIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3AFA9641DA6E908002861BD /* JSNodeDOMJIT.cpp */; };
</span><span class="cx">                 E3150EA71DA7219300194012 /* DOMJITHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E3150EA51DA7218D00194012 /* DOMJITHelpers.h */; };
</span><ins>+                E377FE4D1DADE16500CDD025 /* NodeConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D049931DADC04500718F3C /* NodeConstants.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 E38838981BAD145F00D62EE3 /* ScriptModuleLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38838941BAD145F00D62EE3 /* ScriptModuleLoader.cpp */; };
</span><span class="cx">                 E38838991BAD145F00D62EE3 /* ScriptModuleLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = E38838951BAD145F00D62EE3 /* ScriptModuleLoader.h */; };
</span><span class="cx">                 E3B2F0EB1D7F4C9D00B0C9D1 /* LoadableClassicScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3B2F0E31D7F35EC00B0C9D1 /* LoadableClassicScript.cpp */; };
</span><span class="lines">@@ -13784,6 +13785,7 @@
</span><span class="cx">                 E3B2F0E71D7F35EC00B0C9D1 /* LoadableScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableScript.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E3B2F0E81D7F35EC00B0C9D1 /* LoadableScriptClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableScriptClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E3B2F0E91D7F3D3C00B0C9D1 /* LoadableScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadableScript.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                E3D049931DADC04500718F3C /* NodeConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NodeConstants.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 E3FA38611D716E7600AA5950 /* PendingScriptClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PendingScriptClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E401C27417CE53EC00C41A35 /* ElementIteratorAssertions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementIteratorAssertions.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E401E0A31C3C0B8300F34D10 /* StyleChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleChange.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -23275,6 +23277,7 @@
</span><span class="cx">                                 63D7B32C0E78CD3F00F7617C /* NodeRenderStyle.h */,
</span><span class="cx">                                 E43105B716750F0C00DB2FB8 /* NodeTraversal.cpp */,
</span><span class="cx">                                 E43105BA16750F1600DB2FB8 /* NodeTraversal.h */,
</span><ins>+                                E3D049931DADC04500718F3C /* NodeConstants.h */,
</ins><span class="cx">                                 9382AAB10D8C386100F357A6 /* NodeWithIndex.h */,
</span><span class="cx">                                 E46B41F81CB24E70008F11DE /* NoEventDispatchAssertion.h */,
</span><span class="cx">                                 8369E58F1AFDD0300087DF68 /* NonDocumentTypeChildNode.idl */,
</span><span class="lines">@@ -25847,6 +25850,7 @@
</span><span class="cx">                                 51058AE21D67C229009A538C /* MockGamepadProvider.h in Headers */,
</span><span class="cx">                                 5EA3D6DF1C859D7F00300BBB /* MockMediaEndpoint.h in Headers */,
</span><span class="cx">                                 CDF2B0131820540600F2B424 /* MockMediaPlayerMediaSource.h in Headers */,
</span><ins>+                                E377FE4D1DADE16500CDD025 /* NodeConstants.h in Headers */,
</ins><span class="cx">                                 CDF2B0151820540600F2B424 /* MockMediaSourcePrivate.h in Headers */,
</span><span class="cx">                                 07D6A4F41BED5F8800174146 /* MockRealtimeAudioSource.h in Headers */,
</span><span class="cx">                                 07D6A4F01BECF2D200174146 /* MockRealtimeMediaSource.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMWrapperh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMWrapper.h (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMWrapper.h        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/WebCore/bindings/js/JSDOMWrapper.h        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -22,6 +22,7 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSDOMGlobalObject.h&quot;
</span><ins>+#include &quot;NodeConstants.h&quot;
</ins><span class="cx"> #include &lt;runtime/JSDestructibleObject.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -29,11 +30,26 @@
</span><span class="cx"> class JSDOMWindow;
</span><span class="cx"> class ScriptExecutionContext;
</span><span class="cx"> 
</span><del>-static const uint8_t JSDOMWrapperType = JSC::LastJSCObjectType + 1;
-static const uint8_t JSNodeType = JSC::LastJSCObjectType + 2;
-static const uint8_t JSDocumentWrapperType = JSC::LastJSCObjectType + 3;
-static const uint8_t JSElementType = JSC::LastJSCObjectType + 4;
</del><ins>+// We encode Node type into JSType. The format is the following.
+// offset | 7 | 6 5 4 | 3 2 1 0  |
+// value  | 1 | Kind  | NodeType |
+static const uint8_t JSNodeTypeMask                  = 0b00001111;
</ins><span class="cx"> 
</span><ins>+static const uint8_t JSDOMWrapperType                = 0b10000000;
+static const uint8_t JSNodeType                      = 0b10010000;
+static const uint8_t JSTextNodeType                  = JSNodeType | NodeConstants::TEXT_NODE;
+static const uint8_t JSProcessingInstructionNodeType = JSNodeType | NodeConstants::PROCESSING_INSTRUCTION_NODE;
+static const uint8_t JSDocumentTypeNodeType          = JSNodeType | NodeConstants::DOCUMENT_TYPE_NODE;
+static const uint8_t JSDocumentFragmentNodeType      = JSNodeType | NodeConstants::DOCUMENT_FRAGMENT_NODE;
+static const uint8_t JSDocumentWrapperType           = JSNodeType | NodeConstants::DOCUMENT_NODE;
+static const uint8_t JSCommentNodeType               = JSNodeType | NodeConstants::COMMENT_NODE;
+static const uint8_t JSCDATASectionNodeType          = JSNodeType | NodeConstants::CDATA_SECTION_NODE;
+static const uint8_t JSAttrNodeType                  = JSNodeType | NodeConstants::ATTRIBUTE_NODE;
+static const uint8_t JSElementType                   = 0b10100000 | NodeConstants::ELEMENT_NODE;
+
+static_assert(JSDOMWrapperType &gt; JSC::LastJSCObjectType, &quot;JSC::JSType offers the highest bit.&quot;);
+static_assert(NodeConstants::LastNodeType &lt;= JSNodeTypeMask, &quot;NodeType should be represented in 4bit.&quot;);
+
</ins><span class="cx"> class JSDOMObject : public JSC::JSDestructibleObject {
</span><span class="cx"> public:
</span><span class="cx">     typedef JSC::JSDestructibleObject Base;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSNodeCustomh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSNodeCustom.h (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSNodeCustom.h        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/WebCore/bindings/js/JSNodeCustom.h        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -85,4 +85,9 @@
</span><span class="cx">     return value.asCell()-&gt;type() &gt;= JSNodeType ? JSC::jsCast&lt;JSNode*&gt;(value) : nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ALWAYS_INLINE JSC::JSValue JSNode::nodeType(JSC::ExecState&amp;) const
+{
+    return JSC::jsNumber(static_cast&lt;uint8_t&gt;(type()) &amp; JSNodeTypeMask);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -1170,6 +1170,40 @@
</span><span class="cx">     return $result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+sub GetJSTypeForNode
+{
+    my ($codeGenerator, $interface) = @_;
+
+    if ($codeGenerator-&gt;InheritsInterface($interface, &quot;Document&quot;)) {
+        return &quot;JSDocumentWrapperType&quot;;
+    }
+    if ($codeGenerator-&gt;InheritsInterface($interface, &quot;DocumentFragment&quot;)) {
+        return &quot;JSDocumentFragmentNodeType&quot;;
+    }
+    if ($codeGenerator-&gt;InheritsInterface($interface, &quot;DocumentType&quot;)) {
+        return &quot;JSDocumentTypeNodeType&quot;;
+    }
+    if ($codeGenerator-&gt;InheritsInterface($interface, &quot;ProcessingInstruction&quot;)) {
+        return &quot;JSProcessingInstructionNodeType&quot;;
+    }
+    if ($codeGenerator-&gt;InheritsInterface($interface, &quot;CDATASection&quot;)) {
+        return &quot;JSCDATASectionNodeType&quot;;
+    }
+    if ($codeGenerator-&gt;InheritsInterface($interface, &quot;Attr&quot;)) {
+        return &quot;JSAttrNodeType&quot;;
+    }
+    if ($codeGenerator-&gt;InheritsInterface($interface, &quot;Comment&quot;)) {
+        return &quot;JSCommentNodeType&quot;;
+    }
+    if ($codeGenerator-&gt;InheritsInterface($interface, &quot;Text&quot;)) {
+        return &quot;JSTextNodeType&quot;;
+    }
+    if ($codeGenerator-&gt;InheritsInterface($interface, &quot;Element&quot;)) {
+        return &quot;JSElementType&quot;;
+    }
+    return &quot;JSNodeType&quot;;
+}
+
</ins><span class="cx"> sub GenerateHeader
</span><span class="cx"> {
</span><span class="cx">     my ($object, $interface, $enumerations, $dictionaries) = @_;
</span><span class="lines">@@ -1368,12 +1402,9 @@
</span><span class="cx">     push(@headerContent, &quot;    {\n&quot;);
</span><span class="cx">     if (IsDOMGlobalObject($interface)) {
</span><span class="cx">         push(@headerContent, &quot;        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::GlobalObjectType, StructureFlags), info());\n&quot;);
</span><del>-    } elsif ($codeGenerator-&gt;InheritsInterface($interface, &quot;Document&quot;)) {
-        push(@headerContent, &quot;        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSDocumentWrapperType), StructureFlags), info());\n&quot;);
-    } elsif ($codeGenerator-&gt;InheritsInterface($interface, &quot;Element&quot;)) {
-        push(@headerContent, &quot;        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSElementType), StructureFlags), info());\n&quot;);
</del><span class="cx">     } elsif ($codeGenerator-&gt;InheritsInterface($interface, &quot;Node&quot;)) {
</span><del>-        push(@headerContent, &quot;        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSNodeType), StructureFlags), info());\n&quot;);
</del><ins>+        my $type = GetJSTypeForNode($codeGenerator, $interface);
+        push(@headerContent, &quot;        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType($type), StructureFlags), info());\n&quot;);
</ins><span class="cx">     } else {
</span><span class="cx">         push(@headerContent, &quot;        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());\n&quot;);
</span><span class="cx">     }
</span><span class="lines">@@ -1669,7 +1700,7 @@
</span><span class="cx">             push(@headerContent, &quot;    $domJITClassName();\n&quot;);
</span><span class="cx">             push(@headerContent, &quot;#if ENABLE(JIT)\n&quot;);
</span><span class="cx">             push(@headerContent, &quot;    Ref&lt;JSC::DOMJIT::Patchpoint&gt; checkDOM() override;\n&quot;);
</span><del>-            push(@headerContent, &quot;    Ref&lt;JSC::DOMJIT::Patchpoint&gt; callDOM() override;\n&quot;);
</del><ins>+            push(@headerContent, &quot;    Ref&lt;JSC::DOMJIT::CallDOMPatchpoint&gt; callDOM() override;\n&quot;);
</ins><span class="cx">             push(@headerContent, &quot;#endif\n&quot;);
</span><span class="cx">             push(@headerContent, &quot;};\n\n&quot;);
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.idl (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.idl        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/WebCore/dom/Node.idl        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx">     // FIXME: the spec says this can also raise on retrieval.
</span><span class="cx">     [CEReactions, SetterMayThrowLegacyException] attribute DOMString? nodeValue;
</span><span class="cx"> 
</span><del>-    readonly attribute unsigned short nodeType;
</del><ins>+    [DOMJIT, CustomGetter] readonly attribute unsigned short nodeType;
</ins><span class="cx">     [DOMJIT] readonly attribute Node? parentNode;
</span><span class="cx">     readonly attribute NodeList childNodes;
</span><span class="cx">     [DOMJIT] readonly attribute Node? firstChild;
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeConstantshfromrev207238trunkSourceJavaScriptCoredomjitDOMJITGetterSetterh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/dom/NodeConstants.h (from rev 207238, trunk/Source/JavaScriptCore/domjit/DOMJITGetterSetter.h) (0 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/NodeConstants.h                                (rev 0)
+++ trunk/Source/WebCore/dom/NodeConstants.h        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace WebCore {
+
+struct NodeConstants {
+    enum NodeType {
+        ELEMENT_NODE = 1,
+        ATTRIBUTE_NODE = 2,
+        TEXT_NODE = 3,
+        CDATA_SECTION_NODE = 4,
+        PROCESSING_INSTRUCTION_NODE = 7,
+        COMMENT_NODE = 8,
+        DOCUMENT_NODE = 9,
+        DOCUMENT_TYPE_NODE = 10,
+        DOCUMENT_FRAGMENT_NODE = 11,
+    };
+
+    enum DeprecatedNodeType {
+        ENTITY_REFERENCE_NODE = 5,
+        ENTITY_NODE = 6,
+        NOTATION_NODE = 12,
+    };
+
+    static const uint8_t LastNodeType = NOTATION_NODE;
+};
+
+} // namespace WebCore::NodeType
</ins></span></pre></div>
<a id="trunkSourceWebCoredomjitJSNodeDOMJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/domjit/JSNodeDOMJIT.cpp (207238 => 207239)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/domjit/JSNodeDOMJIT.cpp        2016-10-12 20:41:49 UTC (rev 207238)
+++ trunk/Source/WebCore/domjit/JSNodeDOMJIT.cpp        2016-10-12 20:47:51 UTC (rev 207239)
</span><span class="lines">@@ -50,9 +50,9 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename WrappedNode&gt;
</span><del>-static Ref&lt;DOMJIT::Patchpoint&gt; createCallDOMForOffsetAccess(ptrdiff_t offset, IsContainerGuardRequirement isContainerGuardRequirement)
</del><ins>+static Ref&lt;DOMJIT::CallDOMPatchpoint&gt; createCallDOMForOffsetAccess(ptrdiff_t offset, IsContainerGuardRequirement isContainerGuardRequirement)
</ins><span class="cx"> {
</span><del>-    Ref&lt;DOMJIT::Patchpoint&gt; patchpoint = DOMJIT::Patchpoint::create();
</del><ins>+    Ref&lt;DOMJIT::CallDOMPatchpoint&gt; patchpoint = DOMJIT::CallDOMPatchpoint::create();
</ins><span class="cx">     patchpoint-&gt;numGPScratchRegisters = 1;
</span><span class="cx">     patchpoint-&gt;setGenerator([=](CCallHelpers&amp; jit, const DOMJIT::PatchpointParams&amp; params) {
</span><span class="cx">         JSValueRegs result = params[0].jsValueRegs();
</span><span class="lines">@@ -98,7 +98,7 @@
</span><span class="cx">     return checkNode();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;DOMJIT::Patchpoint&gt; NodeFirstChildDOMJIT::callDOM()
</del><ins>+Ref&lt;DOMJIT::CallDOMPatchpoint&gt; NodeFirstChildDOMJIT::callDOM()
</ins><span class="cx"> {
</span><span class="cx">     return createCallDOMForOffsetAccess&lt;Node&gt;(CAST_OFFSET(Node*, ContainerNode*) + ContainerNode::firstChildMemoryOffset(), IsContainerGuardRequirement::Required);
</span><span class="cx"> }
</span><span class="lines">@@ -109,7 +109,7 @@
</span><span class="cx">     return checkNode();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;DOMJIT::Patchpoint&gt; NodeLastChildDOMJIT::callDOM()
</del><ins>+Ref&lt;DOMJIT::CallDOMPatchpoint&gt; NodeLastChildDOMJIT::callDOM()
</ins><span class="cx"> {
</span><span class="cx">     return createCallDOMForOffsetAccess&lt;Node&gt;(CAST_OFFSET(Node*, ContainerNode*) + ContainerNode::lastChildMemoryOffset(), IsContainerGuardRequirement::Required);
</span><span class="cx"> }
</span><span class="lines">@@ -120,7 +120,7 @@
</span><span class="cx">     return checkNode();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;DOMJIT::Patchpoint&gt; NodeNextSiblingDOMJIT::callDOM()
</del><ins>+Ref&lt;DOMJIT::CallDOMPatchpoint&gt; NodeNextSiblingDOMJIT::callDOM()
</ins><span class="cx"> {
</span><span class="cx">     return createCallDOMForOffsetAccess&lt;Node&gt;(Node::nextSiblingMemoryOffset(), IsContainerGuardRequirement::NotRequired);
</span><span class="cx"> }
</span><span class="lines">@@ -131,7 +131,7 @@
</span><span class="cx">     return checkNode();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;DOMJIT::Patchpoint&gt; NodePreviousSiblingDOMJIT::callDOM()
</del><ins>+Ref&lt;DOMJIT::CallDOMPatchpoint&gt; NodePreviousSiblingDOMJIT::callDOM()
</ins><span class="cx"> {
</span><span class="cx">     return createCallDOMForOffsetAccess&lt;Node&gt;(Node::previousSiblingMemoryOffset(), IsContainerGuardRequirement::NotRequired);
</span><span class="cx"> }
</span><span class="lines">@@ -142,11 +142,32 @@
</span><span class="cx">     return checkNode();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;DOMJIT::Patchpoint&gt; NodeParentNodeDOMJIT::callDOM()
</del><ins>+Ref&lt;DOMJIT::CallDOMPatchpoint&gt; NodeParentNodeDOMJIT::callDOM()
</ins><span class="cx"> {
</span><span class="cx">     return createCallDOMForOffsetAccess&lt;ContainerNode&gt;(Node::parentNodeMemoryOffset(), IsContainerGuardRequirement::NotRequired);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// Node#nodeType.
+Ref&lt;DOMJIT::Patchpoint&gt; NodeNodeTypeDOMJIT::checkDOM()
+{
+    return checkNode();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Ref&lt;DOMJIT::CallDOMPatchpoint&gt; NodeNodeTypeDOMJIT::callDOM()
+{
+    Ref&lt;DOMJIT::CallDOMPatchpoint&gt; patchpoint = DOMJIT::CallDOMPatchpoint::create();
+    patchpoint-&gt;requireGlobalObject = false;
+    patchpoint-&gt;setGenerator([=](CCallHelpers&amp; jit, const DOMJIT::PatchpointParams&amp; params) {
+        JSValueRegs result = params[0].jsValueRegs();
+        GPRReg node = params[1].gpr();
+        jit.load8(CCallHelpers::Address(node, JSC::JSCell::typeInfoTypeOffset()), result.payloadGPR());
+        jit.and32(CCallHelpers::TrustedImm32(JSNodeTypeMask), result.payloadGPR());
+        jit.boxInt32(result.payloadGPR(), result);
+        return CCallHelpers::JumpList();
+    });
+    return patchpoint;
+}
+
+}
+
</ins><span class="cx"> #endif
</span></span></pre>
</div>
</div>

</body>
</html>