<!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>[206846] 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/206846">206846</a></dd>
<dt>Author</dt> <dd>utatane.tea@gmail.com</dd>
<dt>Date</dt> <dd>2016-10-05 22:20:10 -0700 (Wed, 05 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[DOMJIT] Add initial CheckDOM and CallDOM implementations
https://bugs.webkit.org/show_bug.cgi?id=162941

Reviewed by Filip Pizlo.

JSTests:

* stress/domjit-getter-poly.js: Added.
(shouldBe):
(access):
* stress/domjit-getter-proto.js: Added.
(shouldBe):
(access):
* stress/domjit-getter-super-poly.js: Added.
(shouldBe):
(access):
* stress/domjit-getter.js: Added.
(shouldBe):
(access):

Source/JavaScriptCore:

This patch implements a prototype of DOMJIT accelerated getter.
We add two new DFG nodes, CheckDOM and CallDOM.

CheckDOM is used to filter inappropriate |this| object for DOM getter. Its functionality
is equivalent to jsDynamicCast's Check. You can use like &quot;CheckDOM, @1, JSNode::info()&quot;,
and this CheckDOM incurs a BadType exit if the class of the given @1 is not a subclass of
JSNode::info().

CallDOM is used to emit actual DOM operations. It takes GlobalObject and checked DOM
object. And it returns JSValue as its result.

Both CheckDOM and CallDOM can take a DOMJIT::Patchpoint. This is somewhat code snippet
generator, and is injectable to DFG and FTL. DFG and FTL set up registers correctly
according to DOMJIT::Patchpoint's requirement and invoke this patchpoint generator to emit code.
While CallDOM always requires a patchpoint, ideally CheckDOM does not require it since
isSubclassOf check can be implemented in DFG / FTL side. However, some classes have a
faster way to query isSubclassOf. For example, JSNode in WebCore introduces a special
JSType to optimize this query. CheckDOM's patchpoint gives us a chance to emit special
faster code for such a case.

By leveraging above nodes, we can construct DOMJIT accelerated getter. When DFG recognizes the
given getter call is CustomGetter and it has DOMJIT::GetterSetter information, DFG emits the above nodes.
We implemented a prototype in jsc.cpp shell as DOMJITGetter to test the functionality.

Notes about the future extensions.

1. Currently, we do not allow CallDOM to emit any function calls. This will be extended by
   adding `addSlowPathCall` functionality to DOMJIT::Patchpoint later. Interesting thing is that
   we need to create an abstraction over DFG slow path call and FTL slow path call!

2. CheckDOM is not handled in DFGTypeCheckHoistingPhase yet. And we have a chance to merge several CheckDOM into one.
   For example, given CheckDOM A and CheckDOM B to the same target. If A is subclass of B, we can merge them to CheckDOM A.

* JavaScriptCore.xcodeproj/project.pbxproj:
* b3/B3Effects.h:
(JSC::B3::Effects::forCheck):
* b3/B3Value.cpp:
(JSC::B3::Value::effects):
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::GetByIdStatus::makesCalls):
(JSC::GetByIdStatus::dump):
* bytecode/GetByIdStatus.h:
(JSC::GetByIdStatus::GetByIdStatus):
(JSC::GetByIdStatus::isCustom):
(JSC::GetByIdStatus::takesSlowPath):
(JSC::GetByIdStatus::isSimple): Deleted.
* bytecode/SpeculatedType.cpp:
(JSC::speculationFromClassInfo):
* dfg/DFGAbstractInterpreter.h:
(JSC::DFG::AbstractInterpreter::filterClassInfo):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::filterClassInfo):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::filterClassInfo):
* dfg/DFGAbstractValue.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleDOMJITGetter):
(JSC::DFG::ByteCodeParser::handleGetById):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasDOMJIT):
(JSC::DFG::Node::domJIT):
(JSC::DFG::Node::hasClassInfo):
(JSC::DFG::Node::classInfo):
(JSC::DFG::Node::OpInfoWrapper::OpInfoWrapper):
(JSC::DFG::Node::OpInfoWrapper::operator=):
* dfg/DFGNodeType.h:
* dfg/DFGOpInfo.h:
(JSC::DFG::OpInfo::OpInfo):
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::allocateTemporaryRegistersForPatchpoint):
(JSC::DFG::SpeculativeJIT::compileCallDOM):
(JSC::DFG::SpeculativeJIT::compileCheckDOM):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStructureAbstractValue.cpp:
(JSC::DFG::StructureAbstractValue::filterClassInfoSlow):
(JSC::DFG::StructureAbstractValue::isSubClassOf):
* dfg/DFGStructureAbstractValue.h:
(JSC::DFG::StructureAbstractValue::filterClassInfo):
(JSC::DFG::StructureAbstractValue::filter): Deleted.
* domjit/DOMJITPatchpointParams.h: Copied from Source/JavaScriptCore/dfg/DFGOpInfo.h.
(JSC::DOMJIT::PatchpointParams::~PatchpointParams):
(JSC::DOMJIT::PatchpointParams::size):
(JSC::DOMJIT::PatchpointParams::at):
(JSC::DOMJIT::PatchpointParams::operator[]):
(JSC::DOMJIT::PatchpointParams::gpScratch):
(JSC::DOMJIT::PatchpointParams::fpScratch):
(JSC::DOMJIT::PatchpointParams::PatchpointParams):
* domjit/DOMJITReg.h: Added.
(JSC::DOMJIT::Reg::Reg):
(JSC::DOMJIT::Reg::isGPR):
(JSC::DOMJIT::Reg::isFPR):
(JSC::DOMJIT::Reg::isJSValueRegs):
(JSC::DOMJIT::Reg::gpr):
(JSC::DOMJIT::Reg::fpr):
(JSC::DOMJIT::Reg::jsValueRegs):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckDOM):
(JSC::FTL::DFG::LowerDFGToB3::compileCallDOM):
(JSC::FTL::DFG::LowerDFGToB3::compileUnreachable): Deleted.
* jit/AssemblyHelpers.h:
* jsc.cpp:
(WTF::DOMJITNode::DOMJITNode):
(WTF::DOMJITNode::createStructure):
(WTF::DOMJITNode::create):
(WTF::DOMJITNode::value):
(WTF::DOMJITNode::offsetOfValue):
(WTF::DOMJITGetter::DOMJITGetter):
(WTF::DOMJITGetter::createStructure):
(WTF::DOMJITGetter::create):
(WTF::DOMJITGetter::DOMJITNodeDOMJIT::DOMJITNodeDOMJIT):
(WTF::DOMJITGetter::domJITNodeGetterSetter):
(WTF::DOMJITGetter::finishCreation):
(WTF::DOMJITGetter::customGetter):
(GlobalObject::finishCreation):
(functionCreateDOMJITNodeObject):
(functionCreateDOMJITGetterObject):

Source/WTF:

* wtf/Box.h:
(WTF::Box::Box):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/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="#trunkSourceJavaScriptCoreb3B3Effectsh">trunk/Source/JavaScriptCore/b3/B3Effects.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Valuecpp">trunk/Source/JavaScriptCore/b3/B3Value.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetByIdStatush">trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeSpeculatedTypecpp">trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractValuecpp">trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractValueh">trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOpInfoh">trunk/Source/JavaScriptCore/dfg/DFGOpInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureAbstractValuecpp">trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureAbstractValueh">trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelpersh">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfBoxh">trunk/Source/WTF/wtf/Box.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsstressdomjitgetterpolyjs">trunk/JSTests/stress/domjit-getter-poly.js</a></li>
<li><a href="#trunkJSTestsstressdomjitgetterprotojs">trunk/JSTests/stress/domjit-getter-proto.js</a></li>
<li><a href="#trunkJSTestsstressdomjitgettersuperpolyjs">trunk/JSTests/stress/domjit-getter-super-poly.js</a></li>
<li><a href="#trunkJSTestsstressdomjitgetterjs">trunk/JSTests/stress/domjit-getter.js</a></li>
<li><a href="#trunkSourceJavaScriptCoredomjitDOMJITPatchpointParamsh">trunk/Source/JavaScriptCore/domjit/DOMJITPatchpointParams.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredomjitDOMJITRegh">trunk/Source/JavaScriptCore/domjit/DOMJITReg.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/JSTests/ChangeLog        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-10-05  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [DOMJIT] Add initial CheckDOM and CallDOM implementations
+        https://bugs.webkit.org/show_bug.cgi?id=162941
+
+        Reviewed by Filip Pizlo.
+
+        * stress/domjit-getter-poly.js: Added.
+        (shouldBe):
+        (access):
+        * stress/domjit-getter-proto.js: Added.
+        (shouldBe):
+        (access):
+        * stress/domjit-getter-super-poly.js: Added.
+        (shouldBe):
+        (access):
+        * stress/domjit-getter.js: Added.
+        (shouldBe):
+        (access):
+
</ins><span class="cx"> 2016-10-04  Saam Barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         String.prototype.toLowerCase should be a DFG/FTL intrinsic
</span></span></pre></div>
<a id="trunkJSTestsstressdomjitgetterpolyjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/domjit-getter-poly.js (0 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/domjit-getter-poly.js                                (rev 0)
+++ trunk/JSTests/stress/domjit-getter-poly.js        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error(`bad value: ${String(actual)}`);
+}
+
+var domjit1 = createDOMJITGetterObject();
+var domjit2 = createDOMJITGetterObject();
+
+function access(domjit)
+{
+    return domjit.customGetter + domjit.customGetter;
+}
+
+for (var i = 0; i &lt; 1e4; ++i)
+    shouldBe(access((i &amp; 0x1) ? domjit1 : domjit2), 84);
+
+shouldBe(access({ customGetter: 42 }), 84);
+domjit1.test = 44;
+shouldBe(access(domjit1), 84);
</ins></span></pre></div>
<a id="trunkJSTestsstressdomjitgetterprotojs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/domjit-getter-proto.js (0 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/domjit-getter-proto.js                                (rev 0)
+++ trunk/JSTests/stress/domjit-getter-proto.js        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error(`bad value: ${String(actual)}`);
+}
+
+var domjit = createDOMJITNodeObject();
+function access(domjit)
+{
+    return domjit.customGetter + domjit.customGetter;
+}
+
+for (var i = 0; i &lt; 1e4; ++i)
+    shouldBe(access(domjit), 84);
+
+shouldBe(access({ customGetter: 42 }), 84);
+domjit.test = 44;
+shouldBe(access(domjit), 84);
</ins></span></pre></div>
<a id="trunkJSTestsstressdomjitgettersuperpolyjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/domjit-getter-super-poly.js (0 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/domjit-getter-super-poly.js                                (rev 0)
+++ trunk/JSTests/stress/domjit-getter-super-poly.js        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error(`bad value: ${String(actual)}`);
+}
+
+var domjits = [];
+for (var i = 0; i &lt; 100; ++i)
+    domjits.push(createDOMJITGetterObject());
+
+function access(domjit)
+{
+    return domjit.customGetter + domjit.customGetter;
+}
+
+for (var i = 0; i &lt; 1e2; ++i) {
+    for (var j = 0; j &lt; domjits.length; ++j)
+        shouldBe(access(domjits[j]), 84);
+}
</ins></span></pre></div>
<a id="trunkJSTestsstressdomjitgetterjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/domjit-getter.js (0 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/domjit-getter.js                                (rev 0)
+++ trunk/JSTests/stress/domjit-getter.js        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error(`bad value: ${String(actual)}`);
+}
+
+var domjit = createDOMJITGetterObject();
+
+function access(domjit)
+{
+    return domjit.customGetter + domjit.customGetter;
+}
+
+for (var i = 0; i &lt; 1e4; ++i)
+    shouldBe(access(domjit), 84);
+
+shouldBe(access({ customGetter: 42 }), 84);
+domjit.test = 44;
+shouldBe(access(domjit), 84);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -1,5 +1,150 @@
</span><span class="cx"> 2016-10-05  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><ins>+        [DOMJIT] Add initial CheckDOM and CallDOM implementations
+        https://bugs.webkit.org/show_bug.cgi?id=162941
+
+        Reviewed by Filip Pizlo.
+
+        This patch implements a prototype of DOMJIT accelerated getter.
+        We add two new DFG nodes, CheckDOM and CallDOM.
+
+        CheckDOM is used to filter inappropriate |this| object for DOM getter. Its functionality
+        is equivalent to jsDynamicCast's Check. You can use like &quot;CheckDOM, @1, JSNode::info()&quot;,
+        and this CheckDOM incurs a BadType exit if the class of the given @1 is not a subclass of
+        JSNode::info().
+
+        CallDOM is used to emit actual DOM operations. It takes GlobalObject and checked DOM
+        object. And it returns JSValue as its result.
+
+        Both CheckDOM and CallDOM can take a DOMJIT::Patchpoint. This is somewhat code snippet
+        generator, and is injectable to DFG and FTL. DFG and FTL set up registers correctly
+        according to DOMJIT::Patchpoint's requirement and invoke this patchpoint generator to emit code.
+        While CallDOM always requires a patchpoint, ideally CheckDOM does not require it since
+        isSubclassOf check can be implemented in DFG / FTL side. However, some classes have a
+        faster way to query isSubclassOf. For example, JSNode in WebCore introduces a special
+        JSType to optimize this query. CheckDOM's patchpoint gives us a chance to emit special
+        faster code for such a case.
+
+        By leveraging above nodes, we can construct DOMJIT accelerated getter. When DFG recognizes the
+        given getter call is CustomGetter and it has DOMJIT::GetterSetter information, DFG emits the above nodes.
+        We implemented a prototype in jsc.cpp shell as DOMJITGetter to test the functionality.
+
+        Notes about the future extensions.
+
+        1. Currently, we do not allow CallDOM to emit any function calls. This will be extended by
+           adding `addSlowPathCall` functionality to DOMJIT::Patchpoint later. Interesting thing is that
+           we need to create an abstraction over DFG slow path call and FTL slow path call!
+
+        2. CheckDOM is not handled in DFGTypeCheckHoistingPhase yet. And we have a chance to merge several CheckDOM into one.
+           For example, given CheckDOM A and CheckDOM B to the same target. If A is subclass of B, we can merge them to CheckDOM A.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * b3/B3Effects.h:
+        (JSC::B3::Effects::forCheck):
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::effects):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
+        (JSC::GetByIdStatus::makesCalls):
+        (JSC::GetByIdStatus::dump):
+        * bytecode/GetByIdStatus.h:
+        (JSC::GetByIdStatus::GetByIdStatus):
+        (JSC::GetByIdStatus::isCustom):
+        (JSC::GetByIdStatus::takesSlowPath):
+        (JSC::GetByIdStatus::isSimple): Deleted.
+        * bytecode/SpeculatedType.cpp:
+        (JSC::speculationFromClassInfo):
+        * dfg/DFGAbstractInterpreter.h:
+        (JSC::DFG::AbstractInterpreter::filterClassInfo):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::filterClassInfo):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::filterClassInfo):
+        * dfg/DFGAbstractValue.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleDOMJITGetter):
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasHeapPrediction):
+        (JSC::DFG::Node::hasDOMJIT):
+        (JSC::DFG::Node::domJIT):
+        (JSC::DFG::Node::hasClassInfo):
+        (JSC::DFG::Node::classInfo):
+        (JSC::DFG::Node::OpInfoWrapper::OpInfoWrapper):
+        (JSC::DFG::Node::OpInfoWrapper::operator=):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOpInfo.h:
+        (JSC::DFG::OpInfo::OpInfo):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::allocateTemporaryRegistersForPatchpoint):
+        (JSC::DFG::SpeculativeJIT::compileCallDOM):
+        (JSC::DFG::SpeculativeJIT::compileCheckDOM):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStructureAbstractValue.cpp:
+        (JSC::DFG::StructureAbstractValue::filterClassInfoSlow):
+        (JSC::DFG::StructureAbstractValue::isSubClassOf):
+        * dfg/DFGStructureAbstractValue.h:
+        (JSC::DFG::StructureAbstractValue::filterClassInfo):
+        (JSC::DFG::StructureAbstractValue::filter): Deleted.
+        * domjit/DOMJITPatchpointParams.h: Copied from Source/JavaScriptCore/dfg/DFGOpInfo.h.
+        (JSC::DOMJIT::PatchpointParams::~PatchpointParams):
+        (JSC::DOMJIT::PatchpointParams::size):
+        (JSC::DOMJIT::PatchpointParams::at):
+        (JSC::DOMJIT::PatchpointParams::operator[]):
+        (JSC::DOMJIT::PatchpointParams::gpScratch):
+        (JSC::DOMJIT::PatchpointParams::fpScratch):
+        (JSC::DOMJIT::PatchpointParams::PatchpointParams):
+        * domjit/DOMJITReg.h: Added.
+        (JSC::DOMJIT::Reg::Reg):
+        (JSC::DOMJIT::Reg::isGPR):
+        (JSC::DOMJIT::Reg::isFPR):
+        (JSC::DOMJIT::Reg::isJSValueRegs):
+        (JSC::DOMJIT::Reg::gpr):
+        (JSC::DOMJIT::Reg::fpr):
+        (JSC::DOMJIT::Reg::jsValueRegs):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCheckDOM):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCallDOM):
+        (JSC::FTL::DFG::LowerDFGToB3::compileUnreachable): Deleted.
+        * jit/AssemblyHelpers.h:
+        * jsc.cpp:
+        (WTF::DOMJITNode::DOMJITNode):
+        (WTF::DOMJITNode::createStructure):
+        (WTF::DOMJITNode::create):
+        (WTF::DOMJITNode::value):
+        (WTF::DOMJITNode::offsetOfValue):
+        (WTF::DOMJITGetter::DOMJITGetter):
+        (WTF::DOMJITGetter::createStructure):
+        (WTF::DOMJITGetter::create):
+        (WTF::DOMJITGetter::DOMJITNodeDOMJIT::DOMJITNodeDOMJIT):
+        (WTF::DOMJITGetter::domJITNodeGetterSetter):
+        (WTF::DOMJITGetter::finishCreation):
+        (WTF::DOMJITGetter::customGetter):
+        (GlobalObject::finishCreation):
+        (functionCreateDOMJITNodeObject):
+        (functionCreateDOMJITGetterObject):
+
+2016-10-05  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
</ins><span class="cx">         [JSC] Do not construct Simple GetByIdStatus against self-custom-accessor case
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=162993
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -2098,6 +2098,8 @@
</span><span class="cx">                 E35E03601B7AB43E0073AD2A /* InspectorInstrumentationObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E35E035E1B7AB43E0073AD2A /* InspectorInstrumentationObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 E3794E751B77EB97005543AE /* ModuleAnalyzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3794E731B77EB97005543AE /* ModuleAnalyzer.cpp */; };
</span><span class="cx">                 E3794E761B77EB97005543AE /* ModuleAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = E3794E741B77EB97005543AE /* ModuleAnalyzer.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                E37AD83C1DA4928600F3D412 /* DOMJITPatchpointParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E37AD83A1DA4928000F3D412 /* DOMJITPatchpointParams.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                E37AD83D1DA4928600F3D412 /* DOMJITReg.h in Headers */ = {isa = PBXBuildFile; fileRef = E37AD83B1DA4928000F3D412 /* DOMJITReg.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 E3963CEE1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3963CEC1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp */; };
</span><span class="cx">                 E39D45F51D39005600B3B377 /* InterpreterInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E39D9D841D39000600667282 /* InterpreterInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 E39DA4A61B7E8B7C0084F33A /* JSModuleRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */; };
</span><span class="lines">@@ -4397,6 +4399,8 @@
</span><span class="cx">                 E35E03611B7AB4850073AD2A /* InspectorInstrumentationObject.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = InspectorInstrumentationObject.js; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E3794E731B77EB97005543AE /* ModuleAnalyzer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModuleAnalyzer.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E3794E741B77EB97005543AE /* ModuleAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleAnalyzer.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                E37AD83A1DA4928000F3D412 /* DOMJITPatchpointParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITPatchpointParams.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                E37AD83B1DA4928000F3D412 /* DOMJITReg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITReg.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 E3963CEC1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NodesAnalyzeModule.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E39D9D841D39000600667282 /* InterpreterInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterpreterInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleRecord.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -7183,6 +7187,8 @@
</span><span class="cx">                         children = (
</span><span class="cx">                                 E3FF752F1D9CEA1200C7E16D /* DOMJITGetterSetter.h */,
</span><span class="cx">                                 E3C08E3B1DA41B7B0039478F /* DOMJITPatchpoint.h */,
</span><ins>+                                E37AD83A1DA4928000F3D412 /* DOMJITPatchpointParams.h */,
+                                E37AD83B1DA4928000F3D412 /* DOMJITReg.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = domjit;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -7600,6 +7606,7 @@
</span><span class="cx">                                 E39D45F51D39005600B3B377 /* InterpreterInlines.h in Headers */,
</span><span class="cx">                                 0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */,
</span><span class="cx">                                 0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */,
</span><ins>+                                E37AD83D1DA4928600F3D412 /* DOMJITReg.h in Headers */,
</ins><span class="cx">                                 0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */,
</span><span class="cx">                                 0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */,
</span><span class="cx">                                 0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */,
</span><span class="lines">@@ -8428,6 +8435,7 @@
</span><span class="cx">                                 9959E92E1BD17FA4001AA413 /* xxd.pl in Headers */,
</span><span class="cx">                                 79B1788E1D399B8000B1A567 /* JITMathICForwards.h in Headers */,
</span><span class="cx">                                 451539B912DC994500EF7AC4 /* Yarr.h in Headers */,
</span><ins>+                                E37AD83C1DA4928600F3D412 /* DOMJITPatchpointParams.h in Headers */,
</ins><span class="cx">                                 86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */,
</span><span class="cx">                                 86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */,
</span><span class="cx">                                 0FB4767F1D99AEAD008EA6CB /* GCDeferralContextInlines.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Effectsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Effects.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Effects.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/b3/B3Effects.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -78,6 +78,15 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    static Effects forCheck()
+    {
+        Effects result;
+        result.exitsSideways = true;
+        // The program could read anything after exiting, and it's on us to declare this.
+        result.reads = HeapRange::top();
+        return result;
+    }
+
</ins><span class="cx">     bool mustExecute() const
</span><span class="cx">     {
</span><span class="cx">         return terminal || exitsSideways || writesLocalState || writes;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/b3/B3Value.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -614,9 +614,7 @@
</span><span class="cx">     case CheckSub:
</span><span class="cx">     case CheckMul:
</span><span class="cx">     case Check:
</span><del>-        result.exitsSideways = true;
-        // The program could read anything after exiting, and it's on us to declare this.
-        result.reads = HeapRange::top();
</del><ins>+        result = Effects::forCheck();
</ins><span class="cx">         break;
</span><span class="cx">     case Upsilon:
</span><span class="cx">     case Set:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -246,6 +246,7 @@
</span><span class="cx">                     domJIT = access.domJIT();
</span><span class="cx">                     if (!domJIT)
</span><span class="cx">                         return GetByIdStatus(slowPathState, true);
</span><ins>+                    result.m_state = Custom;
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                 default: {
</span><span class="lines">@@ -263,6 +264,16 @@
</span><span class="cx"> 
</span><span class="cx">                 if (!result.appendVariant(variant))
</span><span class="cx">                     return GetByIdStatus(slowPathState, true);
</span><ins>+
+                if (domJIT) {
+                    // Give up when cutom accesses are not merged into one.
+                    if (result.numVariants() != 1)
+                        return GetByIdStatus(slowPathState, true);
+                } else {
+                    // Give up when custom access and simple access are mixed.
+                    if (result.m_state == Custom)
+                        return GetByIdStatus(slowPathState, true);
+                }
</ins><span class="cx">                 break;
</span><span class="cx">             } }
</span><span class="cx">         }
</span><span class="lines">@@ -362,6 +373,7 @@
</span><span class="cx">     switch (m_state) {
</span><span class="cx">     case NoInformation:
</span><span class="cx">     case TakesSlowPath:
</span><ins>+    case Custom:
</ins><span class="cx">         return false;
</span><span class="cx">     case Simple:
</span><span class="cx">         for (unsigned i = m_variants.size(); i--;) {
</span><span class="lines">@@ -403,6 +415,9 @@
</span><span class="cx">     case Simple:
</span><span class="cx">         out.print(&quot;Simple&quot;);
</span><span class="cx">         break;
</span><ins>+    case Custom:
+        out.print(&quot;Custom&quot;);
+        break;
</ins><span class="cx">     case TakesSlowPath:
</span><span class="cx">         out.print(&quot;TakesSlowPath&quot;);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdStatush"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx">         NoInformation,  // It's uncached so we have no information.
</span><span class="cx">         Simple,         // It's cached for a simple access to a known object property with
</span><span class="cx">                         // a possible structure chain and a possible specific value.
</span><ins>+        Custom,         // It's cached for a custom accessor with a possible structure chain.
</ins><span class="cx">         TakesSlowPath,  // It's known to often take slow path.
</span><span class="cx">         MakesCalls      // It's known to take paths that make calls.
</span><span class="cx">     };
</span><span class="lines">@@ -64,7 +65,7 @@
</span><span class="cx">         : m_state(state)
</span><span class="cx">         , m_wasSeenInJIT(wasSeenInJIT)
</span><span class="cx">     {
</span><del>-        ASSERT((state == Simple) == variant.isSet());
</del><ins>+        ASSERT((state == Simple || state == Custom) == variant.isSet());
</ins><span class="cx">         m_variants.append(variant);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -82,6 +83,7 @@
</span><span class="cx">     bool isSet() const { return m_state != NoInformation; }
</span><span class="cx">     bool operator!() const { return !isSet(); }
</span><span class="cx">     bool isSimple() const { return m_state == Simple; }
</span><ins>+    bool isCustom() const { return m_state == Custom; }
</ins><span class="cx"> 
</span><span class="cx">     size_t numVariants() const { return m_variants.size(); }
</span><span class="cx">     const Vector&lt;GetByIdVariant, 1&gt;&amp; variants() const { return m_variants; }
</span><span class="lines">@@ -88,7 +90,7 @@
</span><span class="cx">     const GetByIdVariant&amp; at(size_t index) const { return m_variants[index]; }
</span><span class="cx">     const GetByIdVariant&amp; operator[](size_t index) const { return at(index); }
</span><span class="cx"> 
</span><del>-    bool takesSlowPath() const { return m_state == TakesSlowPath || m_state == MakesCalls; }
</del><ins>+    bool takesSlowPath() const { return m_state == TakesSlowPath || m_state == MakesCalls || m_state == Custom; }
</ins><span class="cx">     bool makesCalls() const;
</span><span class="cx">     
</span><span class="cx">     bool wasSeenInJIT() const { return m_wasSeenInJIT; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeSpeculatedTypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -353,6 +353,12 @@
</span><span class="cx"> 
</span><span class="cx"> SpeculatedType speculationFromClassInfo(const ClassInfo* classInfo)
</span><span class="cx"> {
</span><ins>+    if (classInfo == JSString::info())
+        return SpecString;
+
+    if (classInfo == Symbol::info())
+        return SpecSymbol;
+
</ins><span class="cx">     if (classInfo == JSFinalObject::info())
</span><span class="cx">         return SpecFinalObject;
</span><span class="cx">     
</span><span class="lines">@@ -385,6 +391,9 @@
</span><span class="cx">     
</span><span class="cx">     if (isTypedView(classInfo-&gt;typedArrayStorageType))
</span><span class="cx">         return speculationFromTypedArrayType(classInfo-&gt;typedArrayStorageType);
</span><ins>+
+    if (classInfo-&gt;isSubClassOf(JSArray::info()))
+        return SpecDerivedArray;
</ins><span class="cx">     
</span><span class="cx">     if (classInfo-&gt;isSubClassOf(JSObject::info()))
</span><span class="cx">         return SpecObjectOther;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -134,10 +134,17 @@
</span><span class="cx">         return filterByValue(forNode(node), value);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    template&lt;typename T&gt;
+    FiltrationResult filterClassInfo(T node, const ClassInfo* classInfo)
+    {
+        return filterClassInfo(forNode(node), classInfo);
+    }
+
</ins><span class="cx">     FiltrationResult filter(AbstractValue&amp;, const StructureSet&amp;, SpeculatedType admittedTypes = SpecNone);
</span><span class="cx">     FiltrationResult filterArrayModes(AbstractValue&amp;, ArrayModes);
</span><span class="cx">     FiltrationResult filter(AbstractValue&amp;, SpeculatedType);
</span><span class="cx">     FiltrationResult filterByValue(AbstractValue&amp;, FrozenValue);
</span><ins>+    FiltrationResult filterClassInfo(AbstractValue&amp;, const ClassInfo*);
</ins><span class="cx">     
</span><span class="cx">     PhiChildren* phiChildren() { return m_phiChildren.get(); }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ArrayConstructor.h&quot;
</span><span class="cx"> #include &quot;DFGAbstractInterpreter.h&quot;
</span><ins>+#include &quot;DOMJITGetterSetter.h&quot;
</ins><span class="cx"> #include &quot;GetByIdStatus.h&quot;
</span><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><span class="cx"> #include &quot;HashMapImpl.h&quot;
</span><span class="lines">@@ -2268,6 +2269,28 @@
</span><span class="cx">     case ReallocatePropertyStorage:
</span><span class="cx">         forNode(node).clear(); // The result is not a JS value.
</span><span class="cx">         break;
</span><ins>+    case CheckDOM: {
+        JSValue constant = forNode(node-&gt;child1()).value();
+        if (constant) {
+            if (constant.isCell() &amp;&amp; constant.asCell()-&gt;inherits(node-&gt;classInfo())) {
+                m_state.setFoundConstants(true);
+                ASSERT(constant);
+                break;
+            }
+        }
+
+        AbstractValue&amp; value = forNode(node-&gt;child1());
+
+        if (value.m_structure.isSubClassOf(node-&gt;classInfo()))
+            m_state.setFoundConstants(true);
+
+        filterClassInfo(value, node-&gt;classInfo());
+        break;
+    }
+    case CallDOM:
+        clobberWorld(node-&gt;origin.semantic, clobberLimit);
+        forNode(node).makeBytecodeTop();
+        break;
</ins><span class="cx">     case CheckArray: {
</span><span class="cx">         if (node-&gt;arrayMode().alreadyChecked(m_graph, node, forNode(node-&gt;child1()))) {
</span><span class="cx">             m_state.setFoundConstants(true);
</span><span class="lines">@@ -3056,6 +3079,16 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename AbstractStateType&gt;
</span><ins>+FiltrationResult AbstractInterpreter&lt;AbstractStateType&gt;::filterClassInfo(
+    AbstractValue&amp; value, const ClassInfo* classInfo)
+{
+    if (value.filterClassInfo(m_graph, classInfo) == FiltrationOK)
+        return FiltrationOK;
+    m_state.setIsValid(false);
+    return Contradiction;
+}
+
+template&lt;typename AbstractStateType&gt;
</ins><span class="cx"> void AbstractInterpreter&lt;AbstractStateType&gt;::executeDoubleUnaryOpEffects(Node* node, double(*equivalentFunction)(double))
</span><span class="cx"> {
</span><span class="cx">     JSValue child = forNode(node-&gt;child1()).value();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -306,6 +306,23 @@
</span><span class="cx">     return normalizeClarity();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+FiltrationResult AbstractValue::filterClassInfo(Graph&amp; graph, const ClassInfo* classInfo)
+{
+    // FIXME: AI should track ClassInfo to leverage hierarchical class information.
+    // https://bugs.webkit.org/show_bug.cgi?id=162989
+    if (isClear())
+        return FiltrationOK;
+
+    m_type &amp;= speculationFromClassInfo(classInfo);
+    m_structure.filterClassInfo(classInfo);
+
+    m_structure.filter(m_type);
+
+    filterArrayModesByType();
+    filterValueByType();
+    return normalizeClarity(graph);
+}
+
</ins><span class="cx"> FiltrationResult AbstractValue::filter(SpeculatedType type)
</span><span class="cx"> {
</span><span class="cx">     if ((m_type &amp; type) == m_type)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -307,6 +307,7 @@
</span><span class="cx">     FiltrationResult filter(SpeculatedType);
</span><span class="cx">     FiltrationResult filterByValue(const FrozenValue&amp; value);
</span><span class="cx">     FiltrationResult filter(const AbstractValue&amp;);
</span><ins>+    FiltrationResult filterClassInfo(Graph&amp;, const ClassInfo*);
</ins><span class="cx"> 
</span><span class="cx">     FiltrationResult filter(Graph&amp;, const InferredType::Descriptor&amp;);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -219,6 +219,7 @@
</span><span class="cx">     bool handleConstantInternalFunction(Node* callTargetNode, int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind, SpeculatedType, const ChecksFunctor&amp; insertChecks);
</span><span class="cx">     Node* handlePutByOffset(Node* base, unsigned identifier, PropertyOffset, const InferredType::Descriptor&amp;, Node* value);
</span><span class="cx">     Node* handleGetByOffset(SpeculatedType, Node* base, unsigned identifierNumber, PropertyOffset, const InferredType::Descriptor&amp;, NodeType = GetByOffset);
</span><ins>+    bool handleDOMJITGetter(int resultOperand, const GetByIdVariant&amp;, Node* thisNode, SpeculatedType prediction);
</ins><span class="cx"> 
</span><span class="cx">     // Create a presence ObjectPropertyCondition based on some known offset and structure set. Does not
</span><span class="cx">     // check the validity of the condition, but it may return a null one if it encounters a contradiction.
</span><span class="lines">@@ -2673,6 +2674,28 @@
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool ByteCodeParser::handleDOMJITGetter(int resultOperand, const GetByIdVariant&amp; variant, Node* thisNode, SpeculatedType prediction)
+{
+    if (!variant.domJIT())
+        return false;
+
+    DOMJIT::GetterSetter* domJIT = variant.domJIT();
+
+    // We do not need to actually look up CustomGetterSetter here. Checking Structures or registering watchpoints are enough,
+    // since replacement of CustomGetterSetter always incurs Structure transition.
+    if (!check(variant.conditionSet()))
+        return false;
+    addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(variant.structureSet())), thisNode);
+
+    // We do not need to emit CheckCell thingy here. When the custom accessor is replaced to different one, Structure transition occurs.
+    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.
+    addVarArgChild(thisNode);
+    set(VirtualRegister(resultOperand), addToGraph(Node::VarArg, CallDOM, OpInfo(domJIT), OpInfo(prediction)));
+    return true;
+}
+
</ins><span class="cx"> template&lt;typename ChecksFunctor&gt;
</span><span class="cx"> bool ByteCodeParser::handleTypedArrayConstructor(
</span><span class="cx">     int resultOperand, InternalFunction* function, int registerOffset,
</span><span class="lines">@@ -3267,6 +3290,20 @@
</span><span class="cx">     else
</span><span class="cx">         getById = TryGetById;
</span><span class="cx"> 
</span><ins>+    // Special path for custom accessors since custom's offset does not have any meanings.
+    // So, this is completely different from Simple one. But we have a chance to optimize it when we use DOMJIT.
+    if (getByIdStatus.isCustom()) {
+        ASSERT(getByIdStatus.numVariants() == 1);
+        ASSERT(!getByIdStatus.makesCalls());
+        GetByIdVariant variant = getByIdStatus[0];
+        ASSERT(variant.domJIT());
+        if (handleDOMJITGetter(destinationOperand, variant, base, prediction)) {
+            if (m_graph.compilation())
+                m_graph.compilation()-&gt;noticeInlinedGetById();
+            return;
+        }
+    }
+
</ins><span class="cx">     ASSERT(type == AccessType::Get || !getByIdStatus.makesCalls());
</span><span class="cx">     if (!getByIdStatus.isSimple() || !getByIdStatus.numVariants() || !Options::useAccessInlining()) {
</span><span class="cx">         set(VirtualRegister(destinationOperand),
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -885,6 +885,15 @@
</span><span class="cx">         def(HeapLocation(ButterflyLoc, JSObject_butterfly, node-&gt;child1()), LazyNode(node));
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    case CheckDOM:
+        def(PureValue(node, node-&gt;classInfo()));
+        return;
+
+    case CallDOM:
+        read(World);
+        write(Heap);
+        return;
+
</ins><span class="cx">     case Arrayify:
</span><span class="cx">     case ArrayifyToStructure:
</span><span class="cx">         read(JSCell_structureID);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -158,6 +158,28 @@
</span><span class="cx">                 }
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><ins>+
+            case CheckDOM: {
+                JSValue constant = m_state.forNode(node-&gt;child1()).value();
+                if (constant) {
+                    if (constant.isCell() &amp;&amp; constant.asCell()-&gt;inherits(node-&gt;classInfo())) {
+                        m_interpreter.execute(indexInBlock);
+                        node-&gt;remove();
+                        eliminated = true;
+                        break;
+                    }
+                }
+
+                AbstractValue&amp; value = m_state.forNode(node-&gt;child1());
+
+                if (value.m_structure.isSubClassOf(node-&gt;classInfo())) {
+                    m_interpreter.execute(indexInBlock);
+                    node-&gt;remove();
+                    eliminated = true;
+                    break;
+                }
+                break;
+            }
</ins><span class="cx">                 
</span><span class="cx">             case GetIndexedPropertyStorage: {
</span><span class="cx">                 JSArrayBufferView* view = m_graph.tryGetFoldableView(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -118,6 +118,8 @@
</span><span class="cx">     case CheckStructure:
</span><span class="cx">     case GetExecutable:
</span><span class="cx">     case GetButterfly:
</span><ins>+    case CallDOM:
+    case CheckDOM:
</ins><span class="cx">     case CheckArray:
</span><span class="cx">     case GetScope:
</span><span class="cx">     case SkipScope:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -1699,6 +1699,15 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case CheckDOM:
+            fixEdge&lt;CellUse&gt;(node-&gt;child1());
+            break;
+
+        case CallDOM:
+            fixEdge&lt;KnownCellUse&gt;(m_graph.varArgChild(node, 0)); // GlobalObject.
+            fixEdge&lt;CellUse&gt;(m_graph.varArgChild(node, 1)); // DOM.
+            break;
+
</ins><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 class="cx">         case SetArgument:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -1446,6 +1446,7 @@
</span><span class="cx">         case StringReplaceRegExp:
</span><span class="cx">         case ToNumber:
</span><span class="cx">         case LoadFromJSMapBucket:
</span><ins>+        case CallDOM:
</ins><span class="cx">             return true;
</span><span class="cx">         default:
</span><span class="cx">             return false;
</span><span class="lines">@@ -2312,7 +2313,28 @@
</span><span class="cx">         ASSERT(hasBasicBlockLocation());
</span><span class="cx">         return m_opInfo.as&lt;BasicBlockLocation*&gt;();
</span><span class="cx">     }
</span><del>-    
</del><ins>+
+    bool hasDOMJIT() const
+    {
+        return op() == CheckDOM || op() == CallDOM;
+    }
+
+    DOMJIT::GetterSetter* domJIT()
+    {
+        ASSERT(hasDOMJIT());
+        return m_opInfo.as&lt;DOMJIT::GetterSetter*&gt;();
+    }
+
+    bool hasClassInfo() const
+    {
+        return op() == CheckDOM;
+    }
+
+    const ClassInfo* classInfo()
+    {
+        return m_opInfo2.as&lt;const ClassInfo*&gt;();
+    }
+
</ins><span class="cx">     Node* replacement() const
</span><span class="cx">     {
</span><span class="cx">         return m_misc.replacement;
</span><span class="lines">@@ -2392,6 +2414,11 @@
</span><span class="cx">             u.int64 = 0;
</span><span class="cx">             u.pointer = pointer;
</span><span class="cx">         }
</span><ins>+        OpInfoWrapper(const void* constPointer)
+        {
+            u.int64 = 0;
+            u.constPointer = constPointer;
+        }
</ins><span class="cx">         OpInfoWrapper&amp; operator=(uint32_t int32)
</span><span class="cx">         {
</span><span class="cx">             u.int64 = 0;
</span><span class="lines">@@ -2415,12 +2442,23 @@
</span><span class="cx">             u.pointer = pointer;
</span><span class="cx">             return *this;
</span><span class="cx">         }
</span><ins>+        OpInfoWrapper&amp; operator=(const void* constPointer)
+        {
+            u.int64 = 0;
+            u.constPointer = constPointer;
+            return *this;
+        }
</ins><span class="cx">         template &lt;typename T&gt;
</span><del>-        ALWAYS_INLINE auto as() const -&gt; typename std::enable_if&lt;std::is_pointer&lt;T&gt;::value, T&gt;::type
</del><ins>+        ALWAYS_INLINE auto as() const -&gt; typename std::enable_if&lt;std::is_pointer&lt;T&gt;::value &amp;&amp; !std::is_const&lt;typename std::remove_pointer&lt;T&gt;::type&gt;::value, T&gt;::type
</ins><span class="cx">         {
</span><span class="cx">             return static_cast&lt;T&gt;(u.pointer);
</span><span class="cx">         }
</span><span class="cx">         template &lt;typename T&gt;
</span><ins>+        ALWAYS_INLINE auto as() const -&gt; typename std::enable_if&lt;std::is_pointer&lt;T&gt;::value &amp;&amp; std::is_const&lt;typename std::remove_pointer&lt;T&gt;::type&gt;::value, T&gt;::type
+        {
+            return static_cast&lt;T&gt;(u.constPointer);
+        }
+        template &lt;typename T&gt;
</ins><span class="cx">         ALWAYS_INLINE auto as() const -&gt; typename std::enable_if&lt;std::is_integral&lt;T&gt;::value &amp;&amp; sizeof(T) == 4, T&gt;::type
</span><span class="cx">         {
</span><span class="cx">             return u.int32;
</span><span class="lines">@@ -2434,6 +2472,7 @@
</span><span class="cx">             uint32_t int32;
</span><span class="cx">             uint64_t int64;
</span><span class="cx">             void* pointer;
</span><ins>+            const void* constPointer;
</ins><span class="cx">         } u;
</span><span class="cx">     };
</span><span class="cx">     OpInfoWrapper m_opInfo;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -398,6 +398,9 @@
</span><span class="cx">     macro(IsNonEmptyMapBucket, NodeResultBoolean) \
</span><span class="cx">     \
</span><span class="cx">     macro(ToLowerCase, NodeResultJS) \
</span><ins>+    /* Nodes for DOM JIT */\
+    macro(CheckDOM, NodeMustGenerate) \
+    macro(CallDOM, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
</ins><span class="cx"> 
</span><span class="cx"> // This enum generates a monotonically increasing id for all Node types,
</span><span class="cx"> // and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOpInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOpInfo.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOpInfo.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGOpInfo.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx">     explicit OpInfo(uintptr_t value) : m_value(static_cast&lt;uint64_t&gt;(value)) { }
</span><span class="cx"> #endif
</span><span class="cx">     explicit OpInfo(void* value) : m_value(static_cast&lt;uint64_t&gt;(reinterpret_cast&lt;uintptr_t&gt;(value))) { }
</span><ins>+    explicit OpInfo(const void* value) : m_value(static_cast&lt;uint64_t&gt;(reinterpret_cast&lt;uintptr_t&gt;(value))) { }
</ins><span class="cx">     uint64_t m_value;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -699,7 +699,8 @@
</span><span class="cx">         case GetClosureVar:
</span><span class="cx">         case GetFromArguments:
</span><span class="cx">         case LoadFromJSMapBucket:
</span><del>-        case ToNumber: {
</del><ins>+        case ToNumber:
+        case CallDOM: {
</ins><span class="cx">             setPrediction(m_currentNode-&gt;getHeapPrediction());
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -824,6 +825,9 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case CheckDOM:
+            break;
+
</ins><span class="cx">         case CallObjectConstructor: {
</span><span class="cx">             setPrediction(SpecObject);
</span><span class="cx">             break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -218,6 +218,8 @@
</span><span class="cx">     case CheckStructure:
</span><span class="cx">     case GetExecutable:
</span><span class="cx">     case GetButterfly:
</span><ins>+    case CallDOM:
+    case CheckDOM:
</ins><span class="cx">     case CheckArray:
</span><span class="cx">     case Arrayify:
</span><span class="cx">     case ArrayifyToStructure:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -38,6 +38,8 @@
</span><span class="cx"> #include &quot;DFGOSRExitFuzz.h&quot;
</span><span class="cx"> #include &quot;DFGSaneStringGetByValSlowPathGenerator.h&quot;
</span><span class="cx"> #include &quot;DFGSlowPathGenerator.h&quot;
</span><ins>+#include &quot;DOMJITPatchpoint.h&quot;
+#include &quot;DOMJITPatchpointParams.h&quot;
</ins><span class="cx"> #include &quot;DirectArguments.h&quot;
</span><span class="cx"> #include &quot;JITAddGenerator.h&quot;
</span><span class="cx"> #include &quot;JITBitAndGenerator.h&quot;
</span><span class="lines">@@ -7111,6 +7113,74 @@
</span><span class="cx">     storageResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void allocateTemporaryRegistersForPatchpoint(SpeculativeJIT* jit, Vector&lt;GPRTemporary&gt;&amp; gpHolders, Vector&lt;FPRTemporary&gt;&amp; fpHolders, Vector&lt;GPRReg&gt;&amp; gpScratch, Vector&lt;FPRReg&gt;&amp; fpScratch, DOMJIT::Patchpoint&amp; patchpoint)
+{
+    for (unsigned i = 0; i &lt; patchpoint.numGPScratchRegisters; ++i) {
+        GPRTemporary temporary(jit);
+        gpScratch.append(temporary.gpr());
+        gpHolders.append(WTFMove(temporary));
+    }
+
+    for (unsigned i = 0; i &lt; patchpoint.numFPScratchRegisters; ++i) {
+        FPRTemporary temporary(jit);
+        fpScratch.append(temporary.fpr());
+        fpHolders.append(WTFMove(temporary));
+    }
+}
+
+void SpeculativeJIT::compileCallDOM(Node* node)
+{
+    Ref&lt;DOMJIT::Patchpoint&gt; patchpoint = node-&gt;domJIT()-&gt;callDOM();
+
+    Vector&lt;GPRReg&gt; gpScratch;
+    Vector&lt;FPRReg&gt; fpScratch;
+    Vector&lt;DOMJIT::Reg&gt; regs;
+
+    // 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));
+    JSValueRegsTemporary result(this);
+
+    regs.append(result.regs());
+    regs.append(globalObject.gpr());
+    regs.append(base.gpr());
+#if USE(JSVALUE64)
+    regs.append(static_cast&lt;GPRReg&gt;(GPRInfo::tagMaskRegister));
+    regs.append(static_cast&lt;GPRReg&gt;(GPRInfo::tagTypeNumberRegister));
+#endif
+
+    Vector&lt;GPRTemporary&gt; gpTempraries;
+    Vector&lt;FPRTemporary&gt; fpTempraries;
+    allocateTemporaryRegistersForPatchpoint(this, gpTempraries, fpTempraries, gpScratch, fpScratch, patchpoint.get());
+    DOMJIT::PatchpointParams params(WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch));
+    patchpoint-&gt;generator()-&gt;run(m_jit, params);
+    jsValueResult(result.regs(), node);
+}
+
+void SpeculativeJIT::compileCheckDOM(Node* node)
+{
+    // FIXME: We can add the fallback implementation that inlines jsDynamicCast things here.
+    Ref&lt;DOMJIT::Patchpoint&gt; patchpoint = node-&gt;domJIT()-&gt;checkDOM();
+
+    Vector&lt;GPRReg&gt; gpScratch;
+    Vector&lt;FPRReg&gt; fpScratch;
+    Vector&lt;DOMJIT::Reg&gt; regs;
+
+    SpeculateCellOperand base(this, node-&gt;child1());
+    GPRReg baseGPR = base.gpr();
+    regs.append(baseGPR);
+
+    Vector&lt;GPRTemporary&gt; gpTempraries;
+    Vector&lt;FPRTemporary&gt; fpTempraries;
+    allocateTemporaryRegistersForPatchpoint(this, gpTempraries, fpTempraries, gpScratch, fpScratch, patchpoint.get());
+
+    DOMJIT::PatchpointParams params(WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch));
+    CCallHelpers::JumpList failureCases = patchpoint-&gt;generator()-&gt;run(m_jit, params);
+    speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node-&gt;child1(), failureCases);
+    noResult(node);
+}
+
</ins><span class="cx"> GPRReg SpeculativeJIT::temporaryRegisterForPutByVal(GPRTemporary&amp; temporary, ArrayMode arrayMode)
</span><span class="cx"> {
</span><span class="cx">     if (!putByValWillNeedExtraRegister(arrayMode))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -2543,6 +2543,8 @@
</span><span class="cx">     void compileAllocatePropertyStorage(Node*);
</span><span class="cx">     void compileReallocatePropertyStorage(Node*);
</span><span class="cx">     void compileGetButterfly(Node*);
</span><ins>+    void compileCallDOM(Node*);
+    void compileCheckDOM(Node*);
</ins><span class="cx">     
</span><span class="cx"> #if USE(JSVALUE32_64)
</span><span class="cx">     template&lt;typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -5435,6 +5435,14 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case CallDOM:
+        compileCallDOM(node);
+        break;
+
+    case CheckDOM:
+        compileCheckDOM(node);
+        break;
+
</ins><span class="cx">     case Unreachable:
</span><span class="cx">         unreachable(node);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -5566,6 +5566,14 @@
</span><span class="cx">         compileMaterializeNewObject(node);
</span><span class="cx">         break;
</span><span class="cx"> 
</span><ins>+    case CallDOM:
+        compileCallDOM(node);
+        break;
+
+    case CheckDOM:
+        compileCheckDOM(node);
+        break;
+
</ins><span class="cx"> #if ENABLE(FTL_JIT)        
</span><span class="cx">     case CheckTierUpInLoop: {
</span><span class="cx">         MacroAssembler::Jump callTierUp = m_jit.branchAdd32(
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStructureAbstractValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -258,6 +258,15 @@
</span><span class="cx">         });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void StructureAbstractValue::filterClassInfoSlow(const ClassInfo* classInfo)
+{
+    ASSERT(!isTop());
+    m_set.genericFilter(
+        [&amp;] (Structure* structure) {
+            return structure-&gt;classInfo()-&gt;isSubClassOf(classInfo);
+        });
+}
+
</ins><span class="cx"> bool StructureAbstractValue::contains(Structure* structure) const
</span><span class="cx"> {
</span><span class="cx">     if (isInfinite())
</span><span class="lines">@@ -319,6 +328,19 @@
</span><span class="cx">     return overlaps(other.m_set);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool StructureAbstractValue::isSubClassOf(const ClassInfo* classInfo) const
+{
+    if (isInfinite())
+        return false;
+
+    // Note taht this function returns true if the structure set is empty.
+    for (const Structure* structure : m_set) {
+        if (!structure-&gt;classInfo()-&gt;isSubClassOf(classInfo))
+            return false;
+    }
+    return true;
+}
+
</ins><span class="cx"> bool StructureAbstractValue::equalsSlow(const StructureAbstractValue&amp; other) const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_set.m_pointer != other.m_set.m_pointer);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStructureAbstractValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -163,6 +163,12 @@
</span><span class="cx">         if (isNeitherClearNorTop())
</span><span class="cx">             filterSlow(type);
</span><span class="cx">     }
</span><ins>+
+    ALWAYS_INLINE void filterClassInfo(const ClassInfo* classInfo)
+    {
+        if (isNeitherClearNorTop())
+            filterClassInfoSlow(classInfo);
+    }
</ins><span class="cx">     
</span><span class="cx">     ALWAYS_INLINE bool operator==(const StructureAbstractValue&amp; other) const
</span><span class="cx">     {
</span><span class="lines">@@ -231,6 +237,8 @@
</span><span class="cx">     
</span><span class="cx">     bool overlaps(const StructureSet&amp; other) const;
</span><span class="cx">     bool overlaps(const StructureAbstractValue&amp; other) const;
</span><ins>+
+    bool isSubClassOf(const ClassInfo*) const;
</ins><span class="cx">     
</span><span class="cx">     void validateReferences(const TrackedReferences&amp;) const;
</span><span class="cx">     
</span><span class="lines">@@ -241,6 +249,7 @@
</span><span class="cx">     static const unsigned clobberedSupremacyThreshold = 2;
</span><span class="cx">     
</span><span class="cx">     void filterSlow(SpeculatedType type);
</span><ins>+    void filterClassInfoSlow(const ClassInfo*);
</ins><span class="cx">     bool mergeSlow(const StructureAbstractValue&amp; other);
</span><span class="cx">     
</span><span class="cx">     bool equalsSlow(const StructureAbstractValue&amp; other) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredomjitDOMJITPatchpointParamshfromrev206844trunkSourceJavaScriptCoredfgDFGOpInfoh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/domjit/DOMJITPatchpointParams.h (from rev 206844, trunk/Source/JavaScriptCore/dfg/DFGOpInfo.h) (0 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/domjit/DOMJITPatchpointParams.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/domjit/DOMJITPatchpointParams.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -0,0 +1,64 @@
</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;CCallHelpers.h&quot;
+#include &quot;DOMJITReg.h&quot;
+#include &quot;RegisterSet.h&quot;
+
+namespace JSC { namespace DOMJIT {
+
+class PatchpointParams {
+WTF_MAKE_NONCOPYABLE(PatchpointParams);
+public:
+    virtual ~PatchpointParams() { }
+
+    unsigned size() const { return m_regs.size(); }
+    const Reg&amp; at(unsigned index) const { return m_regs[index]; }
+    const Reg&amp; operator[](unsigned index) const { return at(index); }
+
+    GPRReg gpScratch(unsigned index) const { return m_gpScratch[index]; }
+    FPRReg fpScratch(unsigned index) const { return m_fpScratch[index]; }
+
+    PatchpointParams(Vector&lt;Reg&gt;&amp;&amp; regs, Vector&lt;GPRReg&gt;&amp;&amp; gpScratch, Vector&lt;FPRReg&gt;&amp;&amp; fpScratch)
+        : m_regs(WTFMove(regs))
+        , m_gpScratch(WTFMove(gpScratch))
+        , m_fpScratch(WTFMove(fpScratch))
+    {
+    }
+
+private:
+
+    Vector&lt;Reg&gt; m_regs;
+    Vector&lt;GPRReg&gt; m_gpScratch;
+    Vector&lt;FPRReg&gt; m_fpScratch;
+};
+
+} }
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoredomjitDOMJITRegh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/domjit/DOMJITReg.h (0 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/domjit/DOMJITReg.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/domjit/DOMJITReg.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -0,0 +1,93 @@
</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
+
+#include &quot;Reg.h&quot;
+#include &lt;wtf/Variant.h&gt;
+
+#if ENABLE(JIT)
+
+namespace JSC { namespace DOMJIT {
+
+// It is quite unfortunate that 32 bit environment exists on DFG! This means that JSValueRegs contains 2 registers
+// in such an environment. If we use GPRReg and FPRReg in DOMJITPatchpointParams, DOMJITPatchpointParams may contain
+// different number of registers in 32bit and 64bit environments when we pass JSValueRegs, it is confusing.
+// Therefore, we introduce an abstraction that DOMJIT::Reg, which is a polymorphic register class. It can refer FPRReg,
+// GPRReg, and &quot;JSValueRegs&quot;. Note that isGPR() will return false if the target Reg is &quot;JSValueRegs&quot; even if the
+// environment is 64bit.
+//
+// FIXME: Eventually we should move this class into JSC and make is available for other JIT code.
+// https://bugs.webkit.org/show_bug.cgi?id=162990
+class Reg {
+public:
+    enum class Type : uint8_t {
+        GPR = 0,
+        FPR = 1,
+        JSValue = 2,
+    };
+
+    Reg(GPRReg reg)
+        : m_variant(reg)
+    {
+    }
+
+    Reg(FPRReg reg)
+        : m_variant(reg)
+    {
+    }
+
+    Reg(JSValueRegs regs)
+        : m_variant(regs)
+    {
+    }
+
+    bool isGPR() const { return m_variant.index() == static_cast&lt;unsigned&gt;(Type::GPR); }
+    bool isFPR() const { return m_variant.index() == static_cast&lt;unsigned&gt;(Type::FPR); }
+    bool isJSValueRegs() const { return m_variant.index() == static_cast&lt;unsigned&gt;(Type::JSValue); }
+
+    GPRReg gpr() const
+    {
+        ASSERT(isGPR());
+        return std::experimental::get&lt;GPRReg&gt;(m_variant);
+    }
+    FPRReg fpr() const
+    {
+        ASSERT(isFPR());
+        return std::experimental::get&lt;FPRReg&gt;(m_variant);
+    }
+    JSValueRegs jsValueRegs() const
+    {
+        ASSERT(isJSValueRegs());
+        return std::experimental::get&lt;JSValueRegs&gt;(m_variant);
+    }
+
+private:
+    std::experimental::variant&lt;GPRReg, FPRReg, JSValueRegs&gt; m_variant;
+};
+
+} }
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -266,6 +266,8 @@
</span><span class="cx">     case DefineDataProperty:
</span><span class="cx">     case DefineAccessorProperty:
</span><span class="cx">     case ToLowerCase:
</span><ins>+    case CheckDOM:
+    case CallDOM:
</ins><span class="cx">         // These are OK.
</span><span class="cx">         break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -44,6 +44,8 @@
</span><span class="cx"> #include &quot;DFGInPlaceAbstractState.h&quot;
</span><span class="cx"> #include &quot;DFGOSRAvailabilityAnalysisPhase.h&quot;
</span><span class="cx"> #include &quot;DFGOSRExitFuzz.h&quot;
</span><ins>+#include &quot;DOMJITPatchpoint.h&quot;
+#include &quot;DOMJITPatchpointParams.h&quot;
</ins><span class="cx"> #include &quot;DirectArguments.h&quot;
</span><span class="cx"> #include &quot;FTLAbstractHeapRepository.h&quot;
</span><span class="cx"> #include &quot;FTLAvailableRecovery.h&quot;
</span><span class="lines">@@ -1046,6 +1048,12 @@
</span><span class="cx">         case ToLowerCase:
</span><span class="cx">             compileToLowerCase();
</span><span class="cx">             break;
</span><ins>+        case CheckDOM:
+            compileCheckDOM();
+            break;
+        case CallDOM:
+            compileCallDOM();
+            break;
</ins><span class="cx"> 
</span><span class="cx">         case PhantomLocal:
</span><span class="cx">         case LoopHint:
</span><span class="lines">@@ -8712,6 +8720,94 @@
</span><span class="cx">         
</span><span class="cx">         crash();
</span><span class="cx">     }
</span><ins>+
+    void compileCheckDOM()
+    {
+        LValue cell = lowCell(m_node-&gt;child1());
+
+        RefPtr&lt;DOMJIT::Patchpoint&gt; domJIT = m_node-&gt;domJIT()-&gt;checkDOM();
+
+        PatchpointValue* patchpoint = m_out.patchpoint(Void);
+        patchpoint-&gt;appendSomeRegister(cell);
+        patchpoint-&gt;numGPScratchRegisters = domJIT-&gt;numGPScratchRegisters;
+        patchpoint-&gt;numFPScratchRegisters = domJIT-&gt;numFPScratchRegisters;
+
+        State* state = &amp;m_ftlState;
+        NodeOrigin origin = m_origin;
+        unsigned osrExitArgumentOffset = patchpoint-&gt;numChildren();
+        OSRExitDescriptor* exitDescriptor = appendOSRExitDescriptor(jsValueValue(cell), m_node-&gt;child1().node());
+        patchpoint-&gt;appendColdAnys(buildExitArguments(exitDescriptor, origin.forExit, jsValueValue(cell)));
+
+        patchpoint-&gt;setGenerator(
+            [=] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
+                Vector&lt;GPRReg&gt; gpScratch;
+                Vector&lt;FPRReg&gt; fpScratch;
+                Vector&lt;DOMJIT::Reg&gt; regs;
+
+                regs.append(params[0].gpr());
+
+                for (unsigned i = 0; i &lt; domJIT-&gt;numGPScratchRegisters; ++i)
+                    gpScratch.append(params.gpScratch(i));
+
+                for (unsigned i = 0; i &lt; domJIT-&gt;numFPScratchRegisters; ++i)
+                    fpScratch.append(params.fpScratch(i));
+
+                RefPtr&lt;OSRExitHandle&gt; handle = exitDescriptor-&gt;emitOSRExitLater(*state, BadType, origin, params, osrExitArgumentOffset);
+
+                DOMJIT::PatchpointParams domJITParams(WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch));
+                CCallHelpers::JumpList failureCases = domJIT-&gt;generator()-&gt;run(jit, domJITParams);
+
+                jit.addLinkTask([=] (LinkBuffer&amp; linkBuffer) {
+                    linkBuffer.link(failureCases, linkBuffer.locationOf(handle-&gt;label));
+                });
+            });
+        patchpoint-&gt;effects = Effects::forCheck();
+    }
+
+    void compileCallDOM()
+    {
+        LValue globalObject = lowCell(m_graph.varArgChild(m_node, 0));
+        LValue cell = lowCell(m_graph.varArgChild(m_node, 1));
+
+        RefPtr&lt;DOMJIT::Patchpoint&gt; domJIT = m_node-&gt;domJIT()-&gt;callDOM();
+        PatchpointValue* patchpoint = m_out.patchpoint(Int64);
+        patchpoint-&gt;appendSomeRegister(globalObject);
+        patchpoint-&gt;appendSomeRegister(cell);
+        patchpoint-&gt;append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
+        patchpoint-&gt;append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
+        RefPtr&lt;PatchpointExceptionHandle&gt; exceptionHandle = preparePatchpointForExceptions(patchpoint);
+        patchpoint-&gt;clobber(RegisterSet::macroScratchRegisters());
+        patchpoint-&gt;numGPScratchRegisters = domJIT-&gt;numGPScratchRegisters;
+        patchpoint-&gt;numFPScratchRegisters = domJIT-&gt;numFPScratchRegisters;
+
+        patchpoint-&gt;setGenerator(
+            [=] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params) {
+                Vector&lt;GPRReg&gt; gpScratch;
+                Vector&lt;FPRReg&gt; fpScratch;
+                Vector&lt;DOMJIT::Reg&gt; regs;
+
+                // FIXME: patchpoint should have a way to tell this can reuse &quot;base&quot; register.
+                // Teaching DFG about DOMJIT::Patchpoint clobber information is nice.
+                regs.append(JSValueRegs(params[0].gpr()));
+                regs.append(params[1].gpr());
+                regs.append(params[2].gpr());
+                regs.append(params[3].gpr());
+                regs.append(params[4].gpr());
+
+                for (unsigned i = 0; i &lt; domJIT-&gt;numGPScratchRegisters; ++i)
+                    gpScratch.append(params.gpScratch(i));
+
+                for (unsigned i = 0; i &lt; domJIT-&gt;numFPScratchRegisters; ++i)
+                    fpScratch.append(params.fpScratch(i));
+
+                Box&lt;CCallHelpers::JumpList&gt; exceptions = exceptionHandle-&gt;scheduleExitCreation(params)-&gt;jumps(jit);
+
+                DOMJIT::PatchpointParams domJITParams(WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch));
+                domJIT-&gt;generator()-&gt;run(jit, domJITParams);
+            });
+        patchpoint-&gt;effects = Effects::forCall();
+        setJSValue(patchpoint);
+    }
</ins><span class="cx">     
</span><span class="cx">     void compareEqObjectOrOtherToObject(Edge leftChild, Edge rightChild)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -1209,9 +1209,9 @@
</span><span class="cx">     
</span><span class="cx">     enum ExceptionCheckKind { NormalExceptionCheck, InvertedExceptionCheck };
</span><span class="cx">     enum ExceptionJumpWidth { NormalJumpWidth, FarJumpWidth };
</span><del>-    Jump emitExceptionCheck(
</del><ins>+    JS_EXPORT_PRIVATE Jump emitExceptionCheck(
</ins><span class="cx">         ExceptionCheckKind = NormalExceptionCheck, ExceptionJumpWidth = NormalJumpWidth);
</span><del>-    Jump emitNonPatchableExceptionCheck();
</del><ins>+    JS_EXPORT_PRIVATE Jump emitNonPatchableExceptionCheck();
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(SAMPLING_COUNTERS)
</span><span class="cx">     static void emitCount(MacroAssembler&amp; jit, AbstractSamplingCounter&amp; counter, int32_t increment = 1)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -28,6 +28,9 @@
</span><span class="cx"> #include &quot;ButterflyInlines.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;Completion.h&quot;
</span><ins>+#include &quot;DOMJITGetterSetter.h&quot;
+#include &quot;DOMJITPatchpoint.h&quot;
+#include &quot;DOMJITPatchpointParams.h&quot;
</ins><span class="cx"> #include &quot;Disassembler.h&quot;
</span><span class="cx"> #include &quot;Exception.h&quot;
</span><span class="cx"> #include &quot;ExceptionHelpers.h&quot;
</span><span class="lines">@@ -72,6 +75,7 @@
</span><span class="cx"> #include &lt;type_traits&gt;
</span><span class="cx"> #include &lt;wtf/CurrentTime.h&gt;
</span><span class="cx"> #include &lt;wtf/MainThread.h&gt;
</span><ins>+#include &lt;wtf/NeverDestroyed.h&gt;
</ins><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringBuilder.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -537,12 +541,133 @@
</span><span class="cx">     WriteBarrier&lt;JSC::Unknown&gt; m_hiddenValue;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+class DOMJITNode : public JSNonFinalObject {
+public:
+    DOMJITNode(VM&amp; vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
</ins><span class="cx"> 
</span><ins>+    DECLARE_INFO;
+    typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
+
+    static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
+    }
+
+    static DOMJITNode* create(VM&amp; vm, Structure* structure)
+    {
+        DOMJITNode* getter = new (NotNull, allocateCell&lt;DOMJITNode&gt;(vm.heap, sizeof(DOMJITNode))) DOMJITNode(vm, structure);
+        getter-&gt;finishCreation(vm);
+        return getter;
+    }
+
+    int32_t value() const
+    {
+        return m_value;
+    }
+
+    static ptrdiff_t offsetOfValue() { return OBJECT_OFFSETOF(DOMJITNode, m_value); }
+
+private:
+    int32_t m_value { 42 };
+};
+
+class DOMJITGetter : public DOMJITNode {
+public:
+    DOMJITGetter(VM&amp; vm, Structure* structure)
+        : Base(vm, structure)
+    {
+    }
+
+    DECLARE_INFO;
+    typedef DOMJITNode Base;
+    static const unsigned StructureFlags = Base::StructureFlags;
+
+    static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
+    }
+
+    static DOMJITGetter* create(VM&amp; vm, Structure* structure)
+    {
+        DOMJITGetter* getter = new (NotNull, allocateCell&lt;DOMJITGetter&gt;(vm.heap, sizeof(DOMJITGetter))) DOMJITGetter(vm, structure);
+        getter-&gt;finishCreation(vm);
+        return getter;
+    }
+
+    class DOMJITNodeDOMJIT : public DOMJIT::GetterSetter {
+    public:
+        DOMJITNodeDOMJIT()
+            : DOMJIT::GetterSetter(DOMJITGetter::customGetter, nullptr, DOMJITNode::info())
+        {
+        }
+
+        Ref&lt;DOMJIT::Patchpoint&gt; checkDOM() override
+        {
+            Ref&lt;DOMJIT::Patchpoint&gt; patchpoint = DOMJIT::Patchpoint::create();
+            patchpoint-&gt;setGenerator([=](CCallHelpers&amp; jit, const DOMJIT::PatchpointParams&amp; params) {
+                CCallHelpers::JumpList failureCases;
+                failureCases.append(jit.branch8(
+                    CCallHelpers::NotEqual,
+                    CCallHelpers::Address(params[0].gpr(), JSCell::typeInfoTypeOffset()),
+                    CCallHelpers::TrustedImm32(JSC::JSType(LastJSCObjectType + 1))));
+                return failureCases;
+            });
+            return patchpoint;
+        }
+
+        Ref&lt;DOMJIT::Patchpoint&gt; callDOM() override
+        {
+            Ref&lt;DOMJIT::Patchpoint&gt; patchpoint = DOMJIT::Patchpoint::create();
+            patchpoint-&gt;setGenerator([=](CCallHelpers&amp; jit, const DOMJIT::PatchpointParams&amp; params) {
+                JSValueRegs results = params[0].jsValueRegs();
+                GPRReg dom = params[2].gpr();
+
+                jit.load32(CCallHelpers::Address(dom, DOMJITNode::offsetOfValue()), results.payloadGPR());
+                jit.boxInt32(results.payloadGPR(), results);
+                return CCallHelpers::JumpList();
+            });
+            return patchpoint;
+        }
+    };
+
+    static DOMJIT::GetterSetter* domJITNodeGetterSetter()
+    {
+        static NeverDestroyed&lt;DOMJITNodeDOMJIT&gt; graph;
+        return &amp;graph.get();
+    }
+
+private:
+    void finishCreation(VM&amp; vm)
+    {
+        Base::finishCreation(vm);
+        DOMJIT::GetterSetter* domJIT = domJITNodeGetterSetter();
+        CustomGetterSetter* customGetterSetter = CustomGetterSetter::create(vm, domJIT-&gt;getter(), domJIT-&gt;setter(), domJIT);
+        putDirectCustomAccessor(vm, Identifier::fromString(&amp;vm, &quot;customGetter&quot;), customGetterSetter, ReadOnly | CustomAccessor);
+    }
+
+    static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
+    {
+        VM&amp; vm = exec-&gt;vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        DOMJITNode* thisObject = jsDynamicCast&lt;DOMJITNode*&gt;(JSValue::decode(thisValue));
+        if (!thisObject)
+            return throwVMTypeError(exec, scope);
+        return JSValue::encode(jsNumber(thisObject-&gt;value()));
+    }
+};
+
</ins><span class="cx"> const ClassInfo Element::s_info = { &quot;Element&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(Element) };
</span><span class="cx"> const ClassInfo Masquerader::s_info = { &quot;Masquerader&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(Masquerader) };
</span><span class="cx"> const ClassInfo Root::s_info = { &quot;Root&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(Root) };
</span><span class="cx"> const ClassInfo ImpureGetter::s_info = { &quot;ImpureGetter&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(ImpureGetter) };
</span><span class="cx"> const ClassInfo CustomGetter::s_info = { &quot;CustomGetter&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(CustomGetter) };
</span><ins>+const ClassInfo DOMJITNode::s_info = { &quot;DOMJITNode&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(DOMJITNode) };
+const ClassInfo DOMJITGetter::s_info = { &quot;DOMJITGetter&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(DOMJITGetter) };
</ins><span class="cx"> const ClassInfo RuntimeArray::s_info = { &quot;RuntimeArray&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(RuntimeArray) };
</span><span class="cx"> const ClassInfo SimpleObject::s_info = { &quot;SimpleObject&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(SimpleObject) };
</span><span class="cx"> static bool test262AsyncPassed { false };
</span><span class="lines">@@ -571,6 +696,8 @@
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState*);
</span><ins>+static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(ExecState*);
</ins><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState*);
</span><span class="lines">@@ -855,6 +982,8 @@
</span><span class="cx"> 
</span><span class="cx">         addFunction(vm, &quot;createImpureGetter&quot;, functionCreateImpureGetter, 1);
</span><span class="cx">         addFunction(vm, &quot;createCustomGetterObject&quot;, functionCreateCustomGetterObject, 0);
</span><ins>+        addFunction(vm, &quot;createDOMJITNodeObject&quot;, functionCreateDOMJITNodeObject, 0);
+        addFunction(vm, &quot;createDOMJITGetterObject&quot;, functionCreateDOMJITGetterObject, 0);
</ins><span class="cx">         addFunction(vm, &quot;createBuiltin&quot;, functionCreateBuiltin, 2);
</span><span class="cx">         addFunction(vm, &quot;createGlobalObject&quot;, functionCreateGlobalObject, 0);
</span><span class="cx">         addFunction(vm, &quot;setImpureGetterDelegate&quot;, functionSetImpureGetterDelegate, 2);
</span><span class="lines">@@ -1359,6 +1488,22 @@
</span><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(ExecState* exec)
+{
+    JSLockHolder lock(exec);
+    Structure* structure = DOMJITNode::createStructure(exec-&gt;vm(), exec-&gt;lexicalGlobalObject(), DOMJITGetter::create(exec-&gt;vm(), DOMJITGetter::createStructure(exec-&gt;vm(), exec-&gt;lexicalGlobalObject(), jsNull())));
+    DOMJITNode* result = DOMJITNode::create(exec-&gt;vm(), structure);
+    return JSValue::encode(result);
+}
+
+EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(ExecState* exec)
+{
+    JSLockHolder lock(exec);
+    Structure* structure = DOMJITGetter::createStructure(exec-&gt;vm(), exec-&gt;lexicalGlobalObject(), jsNull());
+    DOMJITGetter* result = DOMJITGetter::create(exec-&gt;vm(), structure);
+    return JSValue::encode(result);
+}
+
</ins><span class="cx"> EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     JSLockHolder lock(exec);
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/WTF/ChangeLog        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-10-05  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [DOMJIT] Add initial CheckDOM and CallDOM implementations
+        https://bugs.webkit.org/show_bug.cgi?id=162941
+
+        Reviewed by Filip Pizlo.
+
+        * wtf/Box.h:
+        (WTF::Box::Box):
+
</ins><span class="cx"> 2016-10-05  Zan Dobersek  &lt;zdobersek@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rename ENABLE_ENCRYPTED_MEDIA_V2 to ENABLE_LEGACY_ENCRYPTED_MEDIA
</span></span></pre></div>
<a id="trunkSourceWTFwtfBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Box.h (206845 => 206846)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Box.h        2016-10-06 05:15:32 UTC (rev 206845)
+++ trunk/Source/WTF/wtf/Box.h        2016-10-06 05:20:10 UTC (rev 206846)
</span><span class="lines">@@ -40,6 +40,10 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    Box(std::nullptr_t)
+    {
+    }
+
</ins><span class="cx">     template&lt;typename... Arguments&gt;
</span><span class="cx">     static Box create(Arguments&amp;&amp;... arguments)
</span><span class="cx">     {
</span></span></pre>
</div>
</div>

</body>
</html>