<!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>[212453] trunk/Source/JavaScriptCore</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/212453">212453</a></dd>
<dt>Author</dt> <dd>keith_miller@apple.com</dd>
<dt>Date</dt> <dd>2017-02-16 11:44:55 -0800 (Thu, 16 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Refactor AccessCase to be more like B3Value
https://bugs.webkit.org/show_bug.cgi?id=168408

Reviewed by Filip Pizlo.

This patch makes AccessCase (and new subclasses) more like B3Value. In the new system each
type has an associated AccessCase subclass. For instance any getter should use the
GetterSetterAccessCase subclass. The new system is easier to follow since you no longer need
to know exactly which members are used by which types. The subclass to AccessType mapping is:

GetterSetterAccessCase:
    Getter
    CustomAccessorGetter
    CustomValueGetter
    Setter

ProxyableAccessCase:
    Load
    Miss
    GetGetter

IntrinsicGetterAccessCase:
    IntrinsicGetter

AccessCase:
    Everything else

It also has the additional advantage that it uses less memory for the cases where we would have needed
rare data in the past but that case would only use a small bit of it.

This patch also removes megamorphic loads and renames some TryGetById related enum values from Pure to Try.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/AccessCase.cpp: Added.
(JSC::AccessCase::AccessCase):
(JSC::AccessCase::create):
(JSC::AccessCase::~AccessCase):
(JSC::AccessCase::fromStructureStubInfo):
(JSC::AccessCase::clone):
(JSC::AccessCase::commit):
(JSC::AccessCase::guardedByStructureCheck):
(JSC::AccessCase::doesCalls):
(JSC::AccessCase::couldStillSucceed):
(JSC::AccessCase::canReplace):
(JSC::AccessCase::dump):
(JSC::AccessCase::visitWeak):
(JSC::AccessCase::propagateTransitions):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generate):
(JSC::AccessCase::generateImpl):
* bytecode/AccessCase.h: Added.
(JSC::AccessCase::as):
(JSC::AccessCase::create):
(JSC::AccessCase::type):
(JSC::AccessCase::state):
(JSC::AccessCase::offset):
(JSC::AccessCase::structure):
(JSC::AccessCase::newStructure):
(JSC::AccessCase::conditionSet):
(JSC::AccessCase::alternateBase):
(JSC::AccessCase::additionalSet):
(JSC::AccessCase::viaProxy):
(JSC::AccessCase::isGetter):
(JSC::AccessCase::isAccessor):
(JSC::AccessCase::dumpImpl):
(JSC::AccessCase::resetState):
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
* bytecode/GetterSetterAccessCase.cpp: Added.
(JSC::GetterSetterAccessCase::GetterSetterAccessCase):
(JSC::GetterSetterAccessCase::create):
(JSC::GetterSetterAccessCase::~GetterSetterAccessCase):
(JSC::GetterSetterAccessCase::clone):
(JSC::GetterSetterAccessCase::alternateBase):
(JSC::GetterSetterAccessCase::dumpImpl):
(JSC::GetterSetterAccessCase::emitDOMJITGetter):
* bytecode/GetterSetterAccessCase.h: Added.
(JSC::GetterSetterAccessCase::callLinkInfo):
(JSC::GetterSetterAccessCase::customSlotBase):
(JSC::GetterSetterAccessCase::domJIT):
* bytecode/IntrinsicGetterAccessCase.cpp: Added.
(JSC::IntrinsicGetterAccessCase::IntrinsicGetterAccessCase):
(JSC::IntrinsicGetterAccessCase::create):
(JSC::IntrinsicGetterAccessCase::~IntrinsicGetterAccessCase):
(JSC::IntrinsicGetterAccessCase::clone):
* bytecode/IntrinsicGetterAccessCase.h: Added.
(JSC::IntrinsicGetterAccessCase::intrinsicFunction):
(JSC::IntrinsicGetterAccessCase::intrinsic):
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::regenerate):
(WTF::printInternal):
(JSC::AccessCase::AccessCase): Deleted.
(JSC::AccessCase::tryGet): Deleted.
(JSC::AccessCase::get): Deleted.
(JSC::AccessCase::megamorphicLoad): Deleted.
(JSC::AccessCase::replace): Deleted.
(JSC::AccessCase::transition): Deleted.
(JSC::AccessCase::setter): Deleted.
(JSC::AccessCase::in): Deleted.
(JSC::AccessCase::getLength): Deleted.
(JSC::AccessCase::getIntrinsic): Deleted.
(JSC::AccessCase::~AccessCase): Deleted.
(JSC::AccessCase::fromStructureStubInfo): Deleted.
(JSC::AccessCase::clone): Deleted.
(JSC::AccessCase::commit): Deleted.
(JSC::AccessCase::guardedByStructureCheck): Deleted.
(JSC::AccessCase::alternateBase): Deleted.
(JSC::AccessCase::doesCalls): Deleted.
(JSC::AccessCase::couldStillSucceed): Deleted.
(JSC::AccessCase::canBeReplacedByMegamorphicLoad): Deleted.
(JSC::AccessCase::canReplace): Deleted.
(JSC::AccessCase::dump): Deleted.
(JSC::AccessCase::visitWeak): Deleted.
(JSC::AccessCase::propagateTransitions): Deleted.
(JSC::AccessCase::generateWithGuard): Deleted.
(JSC::AccessCase::generate): Deleted.
(JSC::AccessCase::generateImpl): Deleted.
(JSC::AccessCase::emitDOMJITGetter): Deleted.
* bytecode/PolymorphicAccess.h:
(JSC::AccessCase::type): Deleted.
(JSC::AccessCase::state): Deleted.
(JSC::AccessCase::offset): Deleted.
(JSC::AccessCase::viaProxy): Deleted.
(JSC::AccessCase::structure): Deleted.
(JSC::AccessCase::newStructure): Deleted.
(JSC::AccessCase::conditionSet): Deleted.
(JSC::AccessCase::intrinsicFunction): Deleted.
(JSC::AccessCase::intrinsic): Deleted.
(JSC::AccessCase::domJIT): Deleted.
(JSC::AccessCase::additionalSet): Deleted.
(JSC::AccessCase::customSlotBase): Deleted.
(JSC::AccessCase::isGetter): Deleted.
(JSC::AccessCase::callLinkInfo): Deleted.
(JSC::AccessCase::RareData::RareData): Deleted.
* bytecode/ProxyableAccessCase.cpp: Added.
(JSC::ProxyableAccessCase::ProxyableAccessCase):
(JSC::ProxyableAccessCase::create):
(JSC::ProxyableAccessCase::~ProxyableAccessCase):
(JSC::ProxyableAccessCase::clone):
(JSC::ProxyableAccessCase::dumpImpl):
* bytecode/ProxyableAccessCase.h: Added.
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeForStubInfo):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::reset):
* bytecode/StructureStubInfo.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileTryGetById):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileGetById):
* jit/IntrinsicEmitter.cpp:
(JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
(JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
(JSC::AccessCase::canEmitIntrinsicGetter): Deleted.
(JSC::AccessCase::emitIntrinsicGetter): Deleted.
* jit/JITOperations.cpp:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_try_get_by_id):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_try_get_by_id):
* jit/Repatch.cpp:
(JSC::tryCacheGetByID):
(JSC::tryCachePutByID):
(JSC::tryRepatchIn):
* jit/Repatch.h:
* runtime/Options.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</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="#trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicAccesscpp">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicAccessh">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePutByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeStructureStubInfocpp">trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeStructureStubInfoh">trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitIntrinsicEmittercpp">trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccesscpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp">trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchcpp">trunk/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchh">trunk/Source/JavaScriptCore/jit/Repatch.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorebytecodeAccessCasecpp">trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeAccessCaseh">trunk/Source/JavaScriptCore/bytecode/AccessCase.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetterSetterAccessCasecpp">trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetterSetterAccessCaseh">trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeIntrinsicGetterAccessCasecpp">trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeIntrinsicGetterAccessCaseh">trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeProxyableAccessCasecpp">trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeProxyableAccessCaseh">trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -185,6 +185,7 @@
</span><span class="cx">     builtins/BuiltinExecutables.cpp
</span><span class="cx">     builtins/BuiltinExecutableCreator.cpp
</span><span class="cx"> 
</span><ins>+    bytecode/AccessCase.cpp
</ins><span class="cx">     bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp
</span><span class="cx">     bytecode/ArithProfile.cpp
</span><span class="cx">     bytecode/ArrayAllocationProfile.cpp
</span><span class="lines">@@ -218,9 +219,11 @@
</span><span class="cx">     bytecode/FunctionCodeBlock.cpp
</span><span class="cx">     bytecode/GetByIdStatus.cpp
</span><span class="cx">     bytecode/GetByIdVariant.cpp
</span><ins>+    bytecode/GetterSetterAccessCase.cpp
</ins><span class="cx">     bytecode/InlineAccess.cpp
</span><span class="cx">     bytecode/InlineCallFrame.cpp
</span><span class="cx">     bytecode/InlineCallFrameSet.cpp
</span><ins>+    bytecode/IntrinsicGetterAccessCase.cpp
</ins><span class="cx">     bytecode/JumpTable.cpp
</span><span class="cx">     bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp
</span><span class="cx">     bytecode/LazyOperandValueProfile.cpp
</span><span class="lines">@@ -233,6 +236,7 @@
</span><span class="cx">     bytecode/PreciseJumpTargets.cpp
</span><span class="cx">     bytecode/ProgramCodeBlock.cpp
</span><span class="cx">     bytecode/PropertyCondition.cpp
</span><ins>+    bytecode/ProxyableAccessCase.cpp
</ins><span class="cx">     bytecode/PutByIdFlags.cpp
</span><span class="cx">     bytecode/PutByIdStatus.cpp
</span><span class="cx">     bytecode/PutByIdVariant.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -1,3 +1,176 @@
</span><ins>+2017-02-16  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        Refactor AccessCase to be more like B3Value
+        https://bugs.webkit.org/show_bug.cgi?id=168408
+
+        Reviewed by Filip Pizlo.
+
+        This patch makes AccessCase (and new subclasses) more like B3Value. In the new system each
+        type has an associated AccessCase subclass. For instance any getter should use the
+        GetterSetterAccessCase subclass. The new system is easier to follow since you no longer need
+        to know exactly which members are used by which types. The subclass to AccessType mapping is:
+
+        GetterSetterAccessCase:
+            Getter
+            CustomAccessorGetter
+            CustomValueGetter
+            Setter
+
+        ProxyableAccessCase:
+            Load
+            Miss
+            GetGetter
+
+        IntrinsicGetterAccessCase:
+            IntrinsicGetter
+
+        AccessCase:
+            Everything else
+
+        It also has the additional advantage that it uses less memory for the cases where we would have needed
+        rare data in the past but that case would only use a small bit of it.
+
+        This patch also removes megamorphic loads and renames some TryGetById related enum values from Pure to Try.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/AccessCase.cpp: Added.
+        (JSC::AccessCase::AccessCase):
+        (JSC::AccessCase::create):
+        (JSC::AccessCase::~AccessCase):
+        (JSC::AccessCase::fromStructureStubInfo):
+        (JSC::AccessCase::clone):
+        (JSC::AccessCase::commit):
+        (JSC::AccessCase::guardedByStructureCheck):
+        (JSC::AccessCase::doesCalls):
+        (JSC::AccessCase::couldStillSucceed):
+        (JSC::AccessCase::canReplace):
+        (JSC::AccessCase::dump):
+        (JSC::AccessCase::visitWeak):
+        (JSC::AccessCase::propagateTransitions):
+        (JSC::AccessCase::generateWithGuard):
+        (JSC::AccessCase::generate):
+        (JSC::AccessCase::generateImpl):
+        * bytecode/AccessCase.h: Added.
+        (JSC::AccessCase::as):
+        (JSC::AccessCase::create):
+        (JSC::AccessCase::type):
+        (JSC::AccessCase::state):
+        (JSC::AccessCase::offset):
+        (JSC::AccessCase::structure):
+        (JSC::AccessCase::newStructure):
+        (JSC::AccessCase::conditionSet):
+        (JSC::AccessCase::alternateBase):
+        (JSC::AccessCase::additionalSet):
+        (JSC::AccessCase::viaProxy):
+        (JSC::AccessCase::isGetter):
+        (JSC::AccessCase::isAccessor):
+        (JSC::AccessCase::dumpImpl):
+        (JSC::AccessCase::resetState):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
+        * bytecode/GetterSetterAccessCase.cpp: Added.
+        (JSC::GetterSetterAccessCase::GetterSetterAccessCase):
+        (JSC::GetterSetterAccessCase::create):
+        (JSC::GetterSetterAccessCase::~GetterSetterAccessCase):
+        (JSC::GetterSetterAccessCase::clone):
+        (JSC::GetterSetterAccessCase::alternateBase):
+        (JSC::GetterSetterAccessCase::dumpImpl):
+        (JSC::GetterSetterAccessCase::emitDOMJITGetter):
+        * bytecode/GetterSetterAccessCase.h: Added.
+        (JSC::GetterSetterAccessCase::callLinkInfo):
+        (JSC::GetterSetterAccessCase::customSlotBase):
+        (JSC::GetterSetterAccessCase::domJIT):
+        * bytecode/IntrinsicGetterAccessCase.cpp: Added.
+        (JSC::IntrinsicGetterAccessCase::IntrinsicGetterAccessCase):
+        (JSC::IntrinsicGetterAccessCase::create):
+        (JSC::IntrinsicGetterAccessCase::~IntrinsicGetterAccessCase):
+        (JSC::IntrinsicGetterAccessCase::clone):
+        * bytecode/IntrinsicGetterAccessCase.h: Added.
+        (JSC::IntrinsicGetterAccessCase::intrinsicFunction):
+        (JSC::IntrinsicGetterAccessCase::intrinsic):
+        * bytecode/PolymorphicAccess.cpp:
+        (JSC::PolymorphicAccess::regenerate):
+        (WTF::printInternal):
+        (JSC::AccessCase::AccessCase): Deleted.
+        (JSC::AccessCase::tryGet): Deleted.
+        (JSC::AccessCase::get): Deleted.
+        (JSC::AccessCase::megamorphicLoad): Deleted.
+        (JSC::AccessCase::replace): Deleted.
+        (JSC::AccessCase::transition): Deleted.
+        (JSC::AccessCase::setter): Deleted.
+        (JSC::AccessCase::in): Deleted.
+        (JSC::AccessCase::getLength): Deleted.
+        (JSC::AccessCase::getIntrinsic): Deleted.
+        (JSC::AccessCase::~AccessCase): Deleted.
+        (JSC::AccessCase::fromStructureStubInfo): Deleted.
+        (JSC::AccessCase::clone): Deleted.
+        (JSC::AccessCase::commit): Deleted.
+        (JSC::AccessCase::guardedByStructureCheck): Deleted.
+        (JSC::AccessCase::alternateBase): Deleted.
+        (JSC::AccessCase::doesCalls): Deleted.
+        (JSC::AccessCase::couldStillSucceed): Deleted.
+        (JSC::AccessCase::canBeReplacedByMegamorphicLoad): Deleted.
+        (JSC::AccessCase::canReplace): Deleted.
+        (JSC::AccessCase::dump): Deleted.
+        (JSC::AccessCase::visitWeak): Deleted.
+        (JSC::AccessCase::propagateTransitions): Deleted.
+        (JSC::AccessCase::generateWithGuard): Deleted.
+        (JSC::AccessCase::generate): Deleted.
+        (JSC::AccessCase::generateImpl): Deleted.
+        (JSC::AccessCase::emitDOMJITGetter): Deleted.
+        * bytecode/PolymorphicAccess.h:
+        (JSC::AccessCase::type): Deleted.
+        (JSC::AccessCase::state): Deleted.
+        (JSC::AccessCase::offset): Deleted.
+        (JSC::AccessCase::viaProxy): Deleted.
+        (JSC::AccessCase::structure): Deleted.
+        (JSC::AccessCase::newStructure): Deleted.
+        (JSC::AccessCase::conditionSet): Deleted.
+        (JSC::AccessCase::intrinsicFunction): Deleted.
+        (JSC::AccessCase::intrinsic): Deleted.
+        (JSC::AccessCase::domJIT): Deleted.
+        (JSC::AccessCase::additionalSet): Deleted.
+        (JSC::AccessCase::customSlotBase): Deleted.
+        (JSC::AccessCase::isGetter): Deleted.
+        (JSC::AccessCase::callLinkInfo): Deleted.
+        (JSC::AccessCase::RareData::RareData): Deleted.
+        * bytecode/ProxyableAccessCase.cpp: Added.
+        (JSC::ProxyableAccessCase::ProxyableAccessCase):
+        (JSC::ProxyableAccessCase::create):
+        (JSC::ProxyableAccessCase::~ProxyableAccessCase):
+        (JSC::ProxyableAccessCase::clone):
+        (JSC::ProxyableAccessCase::dumpImpl):
+        * bytecode/ProxyableAccessCase.h: Added.
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeForStubInfo):
+        * bytecode/StructureStubInfo.cpp:
+        (JSC::StructureStubInfo::reset):
+        * bytecode/StructureStubInfo.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileTryGetById):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileGetById):
+        * jit/IntrinsicEmitter.cpp:
+        (JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
+        (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
+        (JSC::AccessCase::canEmitIntrinsicGetter): Deleted.
+        (JSC::AccessCase::emitIntrinsicGetter): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_try_get_by_id):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_try_get_by_id):
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+        (JSC::tryCachePutByID):
+        (JSC::tryRepatchIn):
+        * jit/Repatch.h:
+        * runtime/Options.h:
+
</ins><span class="cx"> 2017-02-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         JSONParseTest needs to hold the lock when the VM is destroyed
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -1304,6 +1304,11 @@
</span><span class="cx">                 534902851C7276B70012BCB8 /* TypedArrayCTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 534902821C7242C80012BCB8 /* TypedArrayCTest.cpp */; };
</span><span class="cx">                 534C457C1BC72411007476A7 /* JSTypedArrayViewConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 534C457B1BC72411007476A7 /* JSTypedArrayViewConstructor.h */; };
</span><span class="cx">                 534C457E1BC72549007476A7 /* JSTypedArrayViewConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 534C457D1BC72549007476A7 /* JSTypedArrayViewConstructor.cpp */; };
</span><ins>+                534E034E1E4D4B1600213F64 /* AccessCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 534E034D1E4D4B1600213F64 /* AccessCase.h */; };
+                534E03501E4D95ED00213F64 /* AccessCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 534E034F1E4D95ED00213F64 /* AccessCase.cpp */; };
+                534E03541E53BD2900213F64 /* IntrinsicGetterAccessCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 534E03531E53BD2900213F64 /* IntrinsicGetterAccessCase.h */; };
+                534E03561E53BEDE00213F64 /* ProxyableAccessCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 534E03551E53BEDE00213F64 /* ProxyableAccessCase.h */; };
+                534E03581E53BF2F00213F64 /* GetterSetterAccessCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 534E03571E53BF2F00213F64 /* GetterSetterAccessCase.h */; };
</ins><span class="cx">                 53529A4C1C457B75000B49C6 /* APIUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 53529A4B1C457B75000B49C6 /* APIUtils.h */; };
</span><span class="cx">                 535557141D9D9EA5006D583B /* WasmMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 535557131D9D9EA5006D583B /* WasmMemory.h */; };
</span><span class="cx">                 535557161D9DFA32006D583B /* WasmMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 535557151D9DFA32006D583B /* WasmMemory.cpp */; };
</span><span class="lines">@@ -1311,6 +1316,9 @@
</span><span class="cx">                 5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
</span><span class="cx">                 53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
</span><span class="cx">                 539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; };
</span><ins>+                53B0BE341E561AC900A8FC29 /* GetterSetterAccessCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53B0BE331E561AC900A8FC29 /* GetterSetterAccessCase.cpp */; };
+                53B0BE361E561B0900A8FC29 /* ProxyableAccessCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53B0BE351E561B0900A8FC29 /* ProxyableAccessCase.cpp */; };
+                53B0BE381E561B2400A8FC29 /* IntrinsicGetterAccessCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53B0BE371E561B2400A8FC29 /* IntrinsicGetterAccessCase.cpp */; };
</ins><span class="cx">                 53D444DC1DAF08AB00B92784 /* B3WasmAddressValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */; };
</span><span class="cx">                 53D444DE1DAF09A000B92784 /* B3WasmAddressValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53D444DD1DAF09A000B92784 /* B3WasmAddressValue.cpp */; };
</span><span class="cx">                 53F40E851D58F9770099A1B6 /* WasmSections.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E841D58F9770099A1B6 /* WasmSections.h */; };
</span><span class="lines">@@ -3741,6 +3749,11 @@
</span><span class="cx">                 534C457A1BC703DC007476A7 /* TypedArrayConstructor.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = TypedArrayConstructor.js; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 534C457B1BC72411007476A7 /* JSTypedArrayViewConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewConstructor.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 534C457D1BC72549007476A7 /* JSTypedArrayViewConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewConstructor.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                534E034D1E4D4B1600213F64 /* AccessCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessCase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                534E034F1E4D95ED00213F64 /* AccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessCase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                534E03531E53BD2900213F64 /* IntrinsicGetterAccessCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntrinsicGetterAccessCase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                534E03551E53BEDE00213F64 /* ProxyableAccessCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyableAccessCase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                534E03571E53BF2F00213F64 /* GetterSetterAccessCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetterSetterAccessCase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 53529A4B1C457B75000B49C6 /* APIUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIUtils.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 535557131D9D9EA5006D583B /* WasmMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmMemory.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 535557151D9DFA32006D583B /* WasmMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmMemory.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3751,6 +3764,9 @@
</span><span class="cx">                 53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
</span><span class="cx">                 539EB0711D553DF800C82EF7 /* testWasm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = testWasm.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                53B0BE331E561AC900A8FC29 /* GetterSetterAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetterSetterAccessCase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                53B0BE351E561B0900A8FC29 /* ProxyableAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyableAccessCase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                53B0BE371E561B2400A8FC29 /* IntrinsicGetterAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntrinsicGetterAccessCase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3WasmAddressValue.h; path = b3/B3WasmAddressValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53D444DD1DAF09A000B92784 /* B3WasmAddressValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3WasmAddressValue.cpp; path = b3/B3WasmAddressValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -6012,6 +6028,21 @@
</span><span class="cx">                         tabWidth = 4;
</span><span class="cx">                         usesTabs = 0;
</span><span class="cx">                 };
</span><ins>+                534E03521E53BBA900213F64 /* accessCase */ = {
+                        isa = PBXGroup;
+                        children = (
+                                534E034F1E4D95ED00213F64 /* AccessCase.cpp */,
+                                534E034D1E4D4B1600213F64 /* AccessCase.h */,
+                                53B0BE371E561B2400A8FC29 /* IntrinsicGetterAccessCase.cpp */,
+                                534E03531E53BD2900213F64 /* IntrinsicGetterAccessCase.h */,
+                                53B0BE351E561B0900A8FC29 /* ProxyableAccessCase.cpp */,
+                                534E03551E53BEDE00213F64 /* ProxyableAccessCase.h */,
+                                53B0BE331E561AC900A8FC29 /* GetterSetterAccessCase.cpp */,
+                                534E03571E53BF2F00213F64 /* GetterSetterAccessCase.h */,
+                        );
+                        name = accessCase;
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
</ins><span class="cx">                 650FDF8D09D0FCA700769E54 /* Derived Sources */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><span class="lines">@@ -7299,6 +7330,7 @@
</span><span class="cx">                 969A078F0ED1D3AE00F1F681 /* bytecode */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                534E03521E53BBA900213F64 /* accessCase */,
</ins><span class="cx">                                 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */,
</span><span class="cx">                                 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */,
</span><span class="cx">                                 79A228331D35D71E00D8E067 /* ArithProfile.cpp */,
</span><span class="lines">@@ -7980,6 +8012,7 @@
</span><span class="cx">                                 0F6B8AE51C4EFE1700969052 /* B3FixSSA.h in Headers */,
</span><span class="cx">                                 0F725CB01C506D3B00AD943A /* B3FoldPathConstants.h in Headers */,
</span><span class="cx">                                 0FEC85161BDACDAC0080FF74 /* B3FrequencyClass.h in Headers */,
</span><ins>+                                534E03561E53BEDE00213F64 /* ProxyableAccessCase.h in Headers */,
</ins><span class="cx">                                 0FEC85171BDACDAC0080FF74 /* B3FrequentedBlock.h in Headers */,
</span><span class="cx">                                 0FEC85191BDACDAC0080FF74 /* B3Generate.h in Headers */,
</span><span class="cx">                                 0FEC851A1BDACDAC0080FF74 /* B3GenericFrequentedBlock.h in Headers */,
</span><span class="lines">@@ -8435,6 +8468,7 @@
</span><span class="cx">                                 0FEA0A12170513DB00BB722C /* FTLState.h in Headers */,
</span><span class="cx">                                 A7FCC26D17A0B6AA00786D1A /* FTLSwitchCase.h in Headers */,
</span><span class="cx">                                 0F235BE217178E1C00690C7F /* FTLThunks.h in Headers */,
</span><ins>+                                534E03541E53BD2900213F64 /* IntrinsicGetterAccessCase.h in Headers */,
</ins><span class="cx">                                 0FEA0A201708B00700BB722C /* FTLTypedPointer.h in Headers */,
</span><span class="cx">                                 0FDB2CCA173DA523007B3C1B /* FTLValueFromBlock.h in Headers */,
</span><span class="cx">                                 0F5A6284188C98D40072C9DF /* FTLValueRange.h in Headers */,
</span><span class="lines">@@ -8449,6 +8483,7 @@
</span><span class="cx">                                 52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */,
</span><span class="cx">                                 FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */,
</span><span class="cx">                                 BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,
</span><ins>+                                534E03581E53BF2F00213F64 /* GetterSetterAccessCase.h in Headers */,
</ins><span class="cx">                                 62D2D3901ADF103F000206C1 /* FunctionRareData.h in Headers */,
</span><span class="cx">                                 FEA0C4031CDD7D1D00481991 /* FunctionWhitelist.h in Headers */,
</span><span class="cx">                                 2AACE63D18CA5A0300ED0191 /* GCActivityCallback.h in Headers */,
</span><span class="lines">@@ -8716,6 +8751,7 @@
</span><span class="cx">                                 A503FA1E188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h in Headers */,
</span><span class="cx">                                 7013CA8C1B491A9400CAE613 /* JSJob.h in Headers */,
</span><span class="cx">                                 BC18C4160E16F5CD00B34460 /* JSLexicalEnvironment.h in Headers */,
</span><ins>+                                534E034E1E4D4B1600213F64 /* AccessCase.h in Headers */,
</ins><span class="cx">                                 BC18C4230E16F5CD00B34460 /* JSLock.h in Headers */,
</span><span class="cx">                                 C25D709C16DE99F400FCA6BC /* JSManagedValue.h in Headers */,
</span><span class="cx">                                 2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */,
</span><span class="lines">@@ -10118,6 +10154,7 @@
</span><span class="cx">                                 0F235BE117178E1C00690C7F /* FTLThunks.cpp in Sources */,
</span><span class="cx">                                 0F5A6283188C98D40072C9DF /* FTLValueRange.cpp in Sources */,
</span><span class="cx">                                 2A83638918D7D0FE0000EBCC /* FullGCActivityCallback.cpp in Sources */,
</span><ins>+                                53B0BE381E561B2400A8FC29 /* IntrinsicGetterAccessCase.cpp in Sources */,
</ins><span class="cx">                                 14AD911B1DCA97FD0014F9FE /* FunctionCodeBlock.cpp in Sources */,
</span><span class="cx">                                 147F39CB107EC37600427A48 /* FunctionConstructor.cpp in Sources */,
</span><span class="cx">                                 147341E31DC2CE9600AA29BA /* FunctionExecutable.cpp in Sources */,
</span><span class="lines">@@ -10319,6 +10356,7 @@
</span><span class="cx">                                 53486BBB1C18E84500F6F3AF /* JSTypedArray.cpp in Sources */,
</span><span class="cx">                                 0F2B66FA17B6B5AB00A7AE3F /* JSTypedArrayConstructors.cpp in Sources */,
</span><span class="cx">                                 0F2B66FC17B6B5AB00A7AE3F /* JSTypedArrayPrototypes.cpp in Sources */,
</span><ins>+                                53B0BE361E561B0900A8FC29 /* ProxyableAccessCase.cpp in Sources */,
</ins><span class="cx">                                 0F2B66FE17B6B5AB00A7AE3F /* JSTypedArrays.cpp in Sources */,
</span><span class="cx">                                 534C457E1BC72549007476A7 /* JSTypedArrayViewConstructor.cpp in Sources */,
</span><span class="cx">                                 DEA7E2441BBC677200D78440 /* JSTypedArrayViewPrototype.cpp in Sources */,
</span><span class="lines">@@ -10338,6 +10376,7 @@
</span><span class="cx">                                 AD2FCBE81DB58DAD00B3E736 /* JSWebAssemblyRuntimeError.cpp in Sources */,
</span><span class="cx">                                 AD2FCBEA1DB58DAD00B3E736 /* JSWebAssemblyTable.cpp in Sources */,
</span><span class="cx">                                 1442566115EDE98D0066A49B /* JSWithScope.cpp in Sources */,
</span><ins>+                                534E03501E4D95ED00213F64 /* AccessCase.cpp in Sources */,
</ins><span class="cx">                                 86E3C618167BABEE006D760A /* JSWrapperMap.mm in Sources */,
</span><span class="cx">                                 14280870107EC1340013E7B2 /* JSWrapperObject.cpp in Sources */,
</span><span class="cx">                                 BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */,
</span><span class="lines">@@ -10578,6 +10617,7 @@
</span><span class="cx">                                 1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
</span><span class="cx">                                 14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
</span><span class="cx">                                 14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
</span><ins>+                                53B0BE341E561AC900A8FC29 /* GetterSetterAccessCase.cpp in Sources */,
</ins><span class="cx">                                 A7CA3AE317DA41AE006538AF /* WeakMapConstructor.cpp in Sources */,
</span><span class="cx">                                 A7CA3AEB17DA5168006538AF /* WeakMapData.cpp in Sources */,
</span><span class="cx">                                 A7CA3AE517DA41AE006538AF /* WeakMapPrototype.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeAccessCasecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp (0 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -0,0 +1,1005 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;AccessCase.h&quot;
+
+#if ENABLE(JIT)
+
+#include &quot;CCallHelpers.h&quot;
+#include &quot;CallLinkInfo.h&quot;
+#include &quot;DOMJITGetterSetter.h&quot;
+#include &quot;DirectArguments.h&quot;
+#include &quot;GetterSetter.h&quot;
+#include &quot;GetterSetterAccessCase.h&quot;
+#include &quot;HeapInlines.h&quot;
+#include &quot;IntrinsicGetterAccessCase.h&quot;
+#include &quot;JSCJSValueInlines.h&quot;
+#include &quot;LinkBuffer.h&quot;
+#include &quot;PolymorphicAccess.h&quot;
+#include &quot;ScopedArguments.h&quot;
+#include &quot;ScratchRegisterAllocator.h&quot;
+#include &quot;SlotVisitorInlines.h&quot;
+#include &quot;StructureStubInfo.h&quot;
+
+namespace JSC {
+
+static const bool verbose = false;
+
+AccessCase::AccessCase(VM&amp; vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet&amp; conditionSet)
+    : m_type(type)
+    , m_offset(offset)
+{
+    m_structure.setMayBeNull(vm, owner, structure);
+    m_conditionSet = conditionSet;
+}
+
+std::unique_ptr&lt;AccessCase&gt; AccessCase::create(VM&amp; vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet&amp; conditionSet)
+{
+    switch (type) {
+    case InHit:
+    case InMiss:
+    case ArrayLength:
+    case StringLength:
+    case DirectArgumentsLength:
+    case ScopedArgumentsLength:
+    case Replace:
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    };
+
+    return std::unique_ptr&lt;AccessCase&gt;(new AccessCase(vm, owner, type, offset, structure, conditionSet));
+}
+
+std::unique_ptr&lt;AccessCase&gt; AccessCase::create(
+    VM&amp; vm, JSCell* owner, PropertyOffset offset, Structure* oldStructure, Structure* newStructure,
+    const ObjectPropertyConditionSet&amp; conditionSet)
+{
+    RELEASE_ASSERT(oldStructure == newStructure-&gt;previousID());
+
+    // Skip optimizing the case where we need a realloc, if we don't have
+    // enough registers to make it happen.
+    if (GPRInfo::numberOfRegisters &lt; 6
+        &amp;&amp; oldStructure-&gt;outOfLineCapacity() != newStructure-&gt;outOfLineCapacity()
+        &amp;&amp; oldStructure-&gt;outOfLineCapacity()) {
+        return nullptr;
+    }
+
+    return std::unique_ptr&lt;AccessCase&gt;(new AccessCase(vm, owner, Transition, offset, newStructure, conditionSet));
+}
+
+AccessCase::~AccessCase()
+{
+}
+
+std::unique_ptr&lt;AccessCase&gt; AccessCase::fromStructureStubInfo(
+    VM&amp; vm, JSCell* owner, StructureStubInfo&amp; stubInfo)
+{
+    switch (stubInfo.cacheType) {
+    case CacheType::GetByIdSelf:
+        return ProxyableAccessCase::create(vm, owner, Load, stubInfo.u.byIdSelf.offset, stubInfo.u.byIdSelf.baseObjectStructure.get());
+
+    case CacheType::PutByIdReplace:
+        return AccessCase::create(vm, owner, Replace, stubInfo.u.byIdSelf.offset, stubInfo.u.byIdSelf.baseObjectStructure.get());
+
+    default:
+        return nullptr;
+    }
+}
+
+std::unique_ptr&lt;AccessCase&gt; AccessCase::clone() const
+{
+    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase(*this));
+    result-&gt;resetState();
+    return result;
+}
+
+Vector&lt;WatchpointSet*, 2&gt; AccessCase::commit(VM&amp; vm, const Identifier&amp; ident)
+{
+    // It's fine to commit something that is already committed. That arises when we switch to using
+    // newly allocated watchpoints. When it happens, it's not efficient - but we think that's OK
+    // because most AccessCases have no extra watchpoints anyway.
+    RELEASE_ASSERT(m_state == Primordial || m_state == Committed);
+
+    Vector&lt;WatchpointSet*, 2&gt; result;
+
+    if ((structure() &amp;&amp; structure()-&gt;needImpurePropertyWatchpoint())
+        || m_conditionSet.needImpurePropertyWatchpoint())
+        result.append(vm.ensureWatchpointSetForImpureProperty(ident));
+
+    if (additionalSet())
+        result.append(additionalSet());
+
+    m_state = Committed;
+
+    return result;
+}
+
+bool AccessCase::guardedByStructureCheck() const
+{
+    if (viaProxy())
+        return false;
+
+    switch (m_type) {
+    case ArrayLength:
+    case StringLength:
+    case DirectArgumentsLength:
+    case ScopedArgumentsLength:
+        return false;
+    default:
+        return true;
+    }
+}
+
+bool AccessCase::doesCalls(Vector&lt;JSCell*&gt;* cellsToMark) const
+{
+    switch (type()) {
+    case Getter:
+    case Setter:
+    case CustomValueGetter:
+    case CustomAccessorGetter:
+    case CustomValueSetter:
+    case CustomAccessorSetter:
+        return true;
+    case Transition:
+        if (newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity()
+            &amp;&amp; structure()-&gt;couldHaveIndexingHeader()) {
+            if (cellsToMark)
+                cellsToMark-&gt;append(newStructure());
+            return true;
+        }
+        return false;
+    default:
+        return false;
+    }
+}
+
+bool AccessCase::couldStillSucceed() const
+{
+    return m_conditionSet.structuresEnsureValidityAssumingImpurePropertyWatchpoint();
+}
+
+bool AccessCase::canReplace(const AccessCase&amp; other) const
+{
+    // This puts in a good effort to try to figure out if 'other' is made superfluous by '*this'.
+    // It's fine for this to return false if it's in doubt.
+
+    switch (type()) {
+    case ArrayLength:
+    case StringLength:
+    case DirectArgumentsLength:
+    case ScopedArgumentsLength:
+        return other.type() == type();
+    default:
+        if (!guardedByStructureCheck() || !other.guardedByStructureCheck())
+            return false;
+
+        return structure() == other.structure();
+    }
+}
+
+void AccessCase::dump(PrintStream&amp; out) const
+{
+    out.print(m_type, &quot;:(&quot;);
+
+    CommaPrinter comma;
+
+    out.print(comma, m_state);
+
+    if (m_type == Transition)
+        out.print(comma, &quot;structure = &quot;, pointerDump(structure()), &quot; -&gt; &quot;, pointerDump(newStructure()));
+    else if (m_structure)
+        out.print(comma, &quot;structure = &quot;, pointerDump(m_structure.get()));
+
+    if (isValidOffset(m_offset))
+        out.print(comma, &quot;offset = &quot;, m_offset);
+    if (!m_conditionSet.isEmpty())
+        out.print(comma, &quot;conditions = &quot;, m_conditionSet);
+
+    dumpImpl(out, comma);
+    out.print(&quot;)&quot;);
+}
+
+bool AccessCase::visitWeak(VM&amp; vm) const
+{
+    if (m_structure &amp;&amp; !Heap::isMarked(m_structure.get()))
+        return false;
+    if (!m_conditionSet.areStillLive())
+        return false;
+    if (isAccessor()) {
+        auto&amp; accessor = this-&gt;as&lt;GetterSetterAccessCase&gt;();
+        if (accessor.callLinkInfo())
+            accessor.callLinkInfo()-&gt;visitWeak(vm);
+        if (accessor.customSlotBase() &amp;&amp; !Heap::isMarked(accessor.customSlotBase()))
+            return false;
+    } else if (type() == IntrinsicGetter) {
+        auto&amp; intrinsic = this-&gt;as&lt;IntrinsicGetterAccessCase&gt;();
+        if (intrinsic.intrinsicFunction() &amp;&amp; !Heap::isMarked(intrinsic.intrinsicFunction()))
+            return false;
+    }
+
+    return true;
+}
+
+bool AccessCase::propagateTransitions(SlotVisitor&amp; visitor) const
+{
+    bool result = true;
+
+    if (m_structure)
+        result &amp;= m_structure-&gt;markIfCheap(visitor);
+
+    switch (m_type) {
+    case Transition:
+        if (Heap::isMarkedConcurrently(m_structure-&gt;previousID()))
+            visitor.appendUnbarriered(m_structure.get());
+        else
+            result = false;
+        break;
+    default:
+        break;
+    }
+
+    return result;
+}
+
+void AccessCase::generateWithGuard(
+    AccessGenerationState&amp; state, CCallHelpers::JumpList&amp; fallThrough)
+{
+    SuperSamplerScope superSamplerScope(false);
+
+    RELEASE_ASSERT(m_state == Committed);
+    m_state = Generated;
+
+    CCallHelpers&amp; jit = *state.jit;
+    VM&amp; vm = *jit.vm();
+    JSValueRegs valueRegs = state.valueRegs;
+    GPRReg baseGPR = state.baseGPR;
+    GPRReg scratchGPR = state.scratchGPR;
+
+    UNUSED_PARAM(vm);
+
+    switch (m_type) {
+    case ArrayLength: {
+        ASSERT(!viaProxy());
+        jit.load8(CCallHelpers::Address(baseGPR, JSCell::indexingTypeAndMiscOffset()), scratchGPR);
+        fallThrough.append(
+            jit.branchTest32(
+                CCallHelpers::Zero, scratchGPR, CCallHelpers::TrustedImm32(IsArray)));
+        fallThrough.append(
+            jit.branchTest32(
+                CCallHelpers::Zero, scratchGPR, CCallHelpers::TrustedImm32(IndexingShapeMask)));
+        break;
+    }
+
+    case StringLength: {
+        ASSERT(!viaProxy());
+        fallThrough.append(
+            jit.branch8(
+                CCallHelpers::NotEqual,
+                CCallHelpers::Address(baseGPR, JSCell::typeInfoTypeOffset()),
+                CCallHelpers::TrustedImm32(StringType)));
+        break;
+    }
+
+    case DirectArgumentsLength: {
+        ASSERT(!viaProxy());
+        fallThrough.append(
+            jit.branch8(
+                CCallHelpers::NotEqual,
+                CCallHelpers::Address(baseGPR, JSCell::typeInfoTypeOffset()),
+                CCallHelpers::TrustedImm32(DirectArgumentsType)));
+
+        fallThrough.append(
+            jit.branchTestPtr(
+                CCallHelpers::NonZero,
+                CCallHelpers::Address(baseGPR, DirectArguments::offsetOfMappedArguments())));
+        jit.load32(
+            CCallHelpers::Address(baseGPR, DirectArguments::offsetOfLength()),
+            valueRegs.payloadGPR());
+        jit.boxInt32(valueRegs.payloadGPR(), valueRegs);
+        state.succeed();
+        return;
+    }
+
+    case ScopedArgumentsLength: {
+        ASSERT(!viaProxy());
+        fallThrough.append(
+            jit.branch8(
+                CCallHelpers::NotEqual,
+                CCallHelpers::Address(baseGPR, JSCell::typeInfoTypeOffset()),
+                CCallHelpers::TrustedImm32(ScopedArgumentsType)));
+
+        fallThrough.append(
+            jit.branchTest8(
+                CCallHelpers::NonZero,
+                CCallHelpers::Address(baseGPR, ScopedArguments::offsetOfOverrodeThings())));
+        jit.load32(
+            CCallHelpers::Address(baseGPR, ScopedArguments::offsetOfTotalLength()),
+            valueRegs.payloadGPR());
+        jit.boxInt32(valueRegs.payloadGPR(), valueRegs);
+        state.succeed();
+        return;
+    }
+
+    default: {
+        if (viaProxy()) {
+            fallThrough.append(
+                jit.branch8(
+                    CCallHelpers::NotEqual,
+                    CCallHelpers::Address(baseGPR, JSCell::typeInfoTypeOffset()),
+                    CCallHelpers::TrustedImm32(PureForwardingProxyType)));
+
+            jit.loadPtr(CCallHelpers::Address(baseGPR, JSProxy::targetOffset()), scratchGPR);
+
+            fallThrough.append(
+                jit.branchStructure(
+                    CCallHelpers::NotEqual,
+                    CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()),
+                    structure()));
+        } else {
+            fallThrough.append(
+                jit.branchStructure(
+                    CCallHelpers::NotEqual,
+                    CCallHelpers::Address(baseGPR, JSCell::structureIDOffset()),
+                    structure()));
+        }
+        break;
+    } };
+
+    generateImpl(state);
+}
+
+void AccessCase::generate(AccessGenerationState&amp; state)
+{
+    RELEASE_ASSERT(m_state == Committed);
+    m_state = Generated;
+
+    generateImpl(state);
+}
+
+void AccessCase::generateImpl(AccessGenerationState&amp; state)
+{
+    SuperSamplerScope superSamplerScope(false);
+    if (verbose)
+        dataLog(&quot;\n\nGenerating code for: &quot;, *this, &quot;\n&quot;);
+
+    ASSERT(m_state == Generated); // We rely on the callers setting this for us.
+
+    CCallHelpers&amp; jit = *state.jit;
+    VM&amp; vm = *jit.vm();
+    CodeBlock* codeBlock = jit.codeBlock();
+    StructureStubInfo&amp; stubInfo = *state.stubInfo;
+    const Identifier&amp; ident = *state.ident;
+    JSValueRegs valueRegs = state.valueRegs;
+    GPRReg baseGPR = state.baseGPR;
+    GPRReg scratchGPR = state.scratchGPR;
+
+    ASSERT(m_conditionSet.structuresEnsureValidityAssumingImpurePropertyWatchpoint());
+
+    for (const ObjectPropertyCondition&amp; condition : m_conditionSet) {
+        Structure* structure = condition.object()-&gt;structure();
+
+        if (condition.isWatchableAssumingImpurePropertyWatchpoint()) {
+            structure-&gt;addTransitionWatchpoint(state.addWatchpoint(condition));
+            continue;
+        }
+
+        if (!condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint(structure)) {
+            // The reason why this cannot happen is that we require that PolymorphicAccess calls
+            // AccessCase::generate() only after it has verified that
+            // AccessCase::couldStillSucceed() returned true.
+
+            dataLog(&quot;This condition is no longer met: &quot;, condition, &quot;\n&quot;);
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+
+        // We will emit code that has a weak reference that isn't otherwise listed anywhere.
+        state.weakReferences.append(WriteBarrier&lt;JSCell&gt;(vm, codeBlock, structure));
+
+        jit.move(CCallHelpers::TrustedImmPtr(condition.object()), scratchGPR);
+        state.failAndRepatch.append(
+            jit.branchStructure(
+                CCallHelpers::NotEqual,
+                CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()),
+                structure));
+    }
+
+    switch (m_type) {
+    case InHit:
+    case InMiss:
+        jit.boxBooleanPayload(m_type == InHit, valueRegs.payloadGPR());
+        state.succeed();
+        return;
+
+    case Miss:
+        jit.moveTrustedValue(jsUndefined(), valueRegs);
+        state.succeed();
+        return;
+
+    case Load:
+    case GetGetter:
+    case Getter:
+    case Setter:
+    case CustomValueGetter:
+    case CustomAccessorGetter:
+    case CustomValueSetter:
+    case CustomAccessorSetter: {
+        GPRReg valueRegsPayloadGPR = valueRegs.payloadGPR();
+
+        if (isValidOffset(m_offset)) {
+            Structure* currStructure;
+            if (m_conditionSet.isEmpty())
+                currStructure = structure();
+            else
+                currStructure = m_conditionSet.slotBaseCondition().object()-&gt;structure();
+            currStructure-&gt;startWatchingPropertyForReplacements(vm, offset());
+        }
+
+        GPRReg baseForGetGPR;
+        if (viaProxy()) {
+            ASSERT(m_type != CustomValueSetter || m_type != CustomAccessorSetter); // Because setters need to not trash valueRegsPayloadGPR.
+            if (m_type == Getter || m_type == Setter)
+                baseForGetGPR = scratchGPR;
+            else
+                baseForGetGPR = valueRegsPayloadGPR;
+
+            ASSERT((m_type != Getter &amp;&amp; m_type != Setter) || baseForGetGPR != baseGPR);
+            ASSERT(m_type != Setter || baseForGetGPR != valueRegsPayloadGPR);
+
+            jit.loadPtr(
+                CCallHelpers::Address(baseGPR, JSProxy::targetOffset()),
+                baseForGetGPR);
+        } else
+            baseForGetGPR = baseGPR;
+
+        GPRReg baseForAccessGPR;
+        if (!m_conditionSet.isEmpty()) {
+            jit.move(
+                CCallHelpers::TrustedImmPtr(alternateBase()),
+                scratchGPR);
+            baseForAccessGPR = scratchGPR;
+        } else
+            baseForAccessGPR = baseForGetGPR;
+
+        GPRReg loadedValueGPR = InvalidGPRReg;
+        if (m_type != CustomValueGetter &amp;&amp; m_type != CustomAccessorGetter &amp;&amp; m_type != CustomValueSetter &amp;&amp; m_type != CustomAccessorSetter) {
+            if (m_type == Load || m_type == GetGetter)
+                loadedValueGPR = valueRegsPayloadGPR;
+            else
+                loadedValueGPR = scratchGPR;
+
+            ASSERT((m_type != Getter &amp;&amp; m_type != Setter) || loadedValueGPR != baseGPR);
+            ASSERT(m_type != Setter || loadedValueGPR != valueRegsPayloadGPR);
+
+            GPRReg storageGPR;
+            if (isInlineOffset(m_offset))
+                storageGPR = baseForAccessGPR;
+            else {
+                jit.loadPtr(
+                    CCallHelpers::Address(baseForAccessGPR, JSObject::butterflyOffset()),
+                    loadedValueGPR);
+                storageGPR = loadedValueGPR;
+            }
+
+#if USE(JSVALUE64)
+            jit.load64(
+                CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset)), loadedValueGPR);
+#else
+            if (m_type == Load || m_type == GetGetter) {
+                jit.load32(
+                    CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + TagOffset),
+                    valueRegs.tagGPR());
+            }
+            jit.load32(
+                CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + PayloadOffset),
+                loadedValueGPR);
+#endif
+        }
+
+        if (m_type == Load || m_type == GetGetter) {
+            state.succeed();
+            return;
+        }
+
+        if (Options::useDOMJIT() &amp;&amp; m_type == CustomAccessorGetter &amp;&amp; this-&gt;as&lt;GetterSetterAccessCase&gt;().domJIT()) {
+            auto&amp; access = this-&gt;as&lt;GetterSetterAccessCase&gt;();
+            // We do not need to emit CheckDOM operation since structure check ensures
+            // that the structure of the given base value is structure()! So all we should
+            // do is performing the CheckDOM thingy in IC compiling time here.
+            if (structure()-&gt;classInfo()-&gt;isSubClassOf(access.domJIT()-&gt;thisClassInfo())) {
+                access.emitDOMJITGetter(state, baseForGetGPR);
+                return;
+            }
+        }
+
+        // Stuff for custom getters/setters.
+        CCallHelpers::Call operationCall;
+
+        // Stuff for JS getters/setters.
+        CCallHelpers::DataLabelPtr addressOfLinkFunctionCheck;
+        CCallHelpers::Call fastPathCall;
+        CCallHelpers::Call slowPathCall;
+
+        // This also does the necessary calculations of whether or not we're an
+        // exception handling call site.
+        AccessGenerationState::SpillState spillState = state.preserveLiveRegistersToStackForCall();
+
+        auto restoreLiveRegistersFromStackForCall = [&amp;](AccessGenerationState::SpillState&amp; spillState, bool callHasReturnValue) {
+            RegisterSet dontRestore;
+            if (callHasReturnValue) {
+                // This is the result value. We don't want to overwrite the result with what we stored to the stack.
+                // We sometimes have to store it to the stack just in case we throw an exception and need the original value.
+                dontRestore.set(valueRegs);
+            }
+            state.restoreLiveRegistersFromStackForCall(spillState, dontRestore);
+        };
+
+        jit.store32(
+            CCallHelpers::TrustedImm32(state.callSiteIndexForExceptionHandlingOrOriginal().bits()),
+            CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(CallFrameSlot::argumentCount)));
+
+        if (m_type == Getter || m_type == Setter) {
+            auto&amp; access = this-&gt;as&lt;GetterSetterAccessCase&gt;();
+            ASSERT(baseGPR != loadedValueGPR);
+            ASSERT(m_type != Setter || (baseGPR != valueRegsPayloadGPR &amp;&amp; loadedValueGPR != valueRegsPayloadGPR));
+
+            // Create a JS call using a JS call inline cache. Assume that:
+            //
+            // - SP is aligned and represents the extent of the calling compiler's stack usage.
+            //
+            // - FP is set correctly (i.e. it points to the caller's call frame header).
+            //
+            // - SP - FP is an aligned difference.
+            //
+            // - Any byte between FP (exclusive) and SP (inclusive) could be live in the calling
+            //   code.
+            //
+            // Therefore, we temporarily grow the stack for the purpose of the call and then
+            // shrink it after.
+
+            state.setSpillStateForJSGetterSetter(spillState);
+
+            RELEASE_ASSERT(!access.callLinkInfo());
+            access.m_callLinkInfo = std::make_unique&lt;CallLinkInfo&gt;();
+
+            // FIXME: If we generated a polymorphic call stub that jumped back to the getter
+            // stub, which then jumped back to the main code, then we'd have a reachability
+            // situation that the GC doesn't know about. The GC would ensure that the polymorphic
+            // call stub stayed alive, and it would ensure that the main code stayed alive, but
+            // it wouldn't know that the getter stub was alive. Ideally JIT stub routines would
+            // be GC objects, and then we'd be able to say that the polymorphic call stub has a
+            // reference to the getter stub.
+            // https://bugs.webkit.org/show_bug.cgi?id=148914
+            access.callLinkInfo()-&gt;disallowStubs();
+
+            access.callLinkInfo()-&gt;setUpCall(
+                CallLinkInfo::Call, stubInfo.codeOrigin, loadedValueGPR);
+
+            CCallHelpers::JumpList done;
+
+            // There is a &quot;this&quot; argument.
+            unsigned numberOfParameters = 1;
+            // ... and a value argument if we're calling a setter.
+            if (m_type == Setter)
+                numberOfParameters++;
+
+            // Get the accessor; if there ain't one then the result is jsUndefined().
+            if (m_type == Setter) {
+                jit.loadPtr(
+                    CCallHelpers::Address(loadedValueGPR, GetterSetter::offsetOfSetter()),
+                    loadedValueGPR);
+            } else {
+                jit.loadPtr(
+                    CCallHelpers::Address(loadedValueGPR, GetterSetter::offsetOfGetter()),
+                    loadedValueGPR);
+            }
+
+            CCallHelpers::Jump returnUndefined = jit.branchTestPtr(
+                CCallHelpers::Zero, loadedValueGPR);
+
+            unsigned numberOfRegsForCall = CallFrame::headerSizeInRegisters + numberOfParameters;
+            unsigned numberOfBytesForCall = numberOfRegsForCall * sizeof(Register) - sizeof(CallerFrameAndPC);
+
+            unsigned alignedNumberOfBytesForCall =
+            WTF::roundUpToMultipleOf(stackAlignmentBytes(), numberOfBytesForCall);
+
+            jit.subPtr(
+                CCallHelpers::TrustedImm32(alignedNumberOfBytesForCall),
+                CCallHelpers::stackPointerRegister);
+
+            CCallHelpers::Address calleeFrame = CCallHelpers::Address(
+                CCallHelpers::stackPointerRegister,
+                -static_cast&lt;ptrdiff_t&gt;(sizeof(CallerFrameAndPC)));
+
+            jit.store32(
+                CCallHelpers::TrustedImm32(numberOfParameters),
+                calleeFrame.withOffset(CallFrameSlot::argumentCount * sizeof(Register) + PayloadOffset));
+
+            jit.storeCell(
+                loadedValueGPR, calleeFrame.withOffset(CallFrameSlot::callee * sizeof(Register)));
+
+            jit.storeCell(
+                baseGPR,
+                calleeFrame.withOffset(virtualRegisterForArgument(0).offset() * sizeof(Register)));
+
+            if (m_type == Setter) {
+                jit.storeValue(
+                    valueRegs,
+                    calleeFrame.withOffset(
+                        virtualRegisterForArgument(1).offset() * sizeof(Register)));
+            }
+
+            CCallHelpers::Jump slowCase = jit.branchPtrWithPatch(
+                CCallHelpers::NotEqual, loadedValueGPR, addressOfLinkFunctionCheck,
+                CCallHelpers::TrustedImmPtr(0));
+
+            fastPathCall = jit.nearCall();
+            if (m_type == Getter)
+                jit.setupResults(valueRegs);
+            done.append(jit.jump());
+
+            slowCase.link(&amp;jit);
+            jit.move(loadedValueGPR, GPRInfo::regT0);
+#if USE(JSVALUE32_64)
+            // We *always* know that the getter/setter, if non-null, is a cell.
+            jit.move(CCallHelpers::TrustedImm32(JSValue::CellTag), GPRInfo::regT1);
+#endif
+            jit.move(CCallHelpers::TrustedImmPtr(access.callLinkInfo()), GPRInfo::regT2);
+            slowPathCall = jit.nearCall();
+            if (m_type == Getter)
+                jit.setupResults(valueRegs);
+            done.append(jit.jump());
+
+            returnUndefined.link(&amp;jit);
+            if (m_type == Getter)
+                jit.moveTrustedValue(jsUndefined(), valueRegs);
+
+            done.link(&amp;jit);
+
+            jit.addPtr(CCallHelpers::TrustedImm32((codeBlock-&gt;stackPointerOffset() * sizeof(Register)) - state.preservedReusedRegisterState.numberOfBytesPreserved - spillState.numberOfStackBytesUsedForRegisterPreservation),
+                GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);
+            bool callHasReturnValue = isGetter();
+            restoreLiveRegistersFromStackForCall(spillState, callHasReturnValue);
+
+            jit.addLinkTask([=, &amp;vm] (LinkBuffer&amp; linkBuffer) {
+                this-&gt;as&lt;GetterSetterAccessCase&gt;().callLinkInfo()-&gt;setCallLocations(
+                    CodeLocationLabel(linkBuffer.locationOfNearCall(slowPathCall)),
+                    CodeLocationLabel(linkBuffer.locationOf(addressOfLinkFunctionCheck)),
+                    linkBuffer.locationOfNearCall(fastPathCall));
+
+                linkBuffer.link(
+                    slowPathCall,
+                    CodeLocationLabel(vm.getCTIStub(linkCallThunkGenerator).code()));
+            });
+        } else {
+            ASSERT(m_type == CustomValueGetter || m_type == CustomAccessorGetter || m_type == CustomValueSetter || m_type == CustomAccessorSetter);
+
+            // Need to make room for the C call so any of our stack spillage isn't overwritten. It's
+            // hard to track if someone did spillage or not, so we just assume that we always need
+            // to make some space here.
+            jit.makeSpaceOnStackForCCall();
+
+            // getter: EncodedJSValue (*GetValueFunc)(ExecState*, EncodedJSValue thisValue, PropertyName);
+            // setter: void (*PutValueFunc)(ExecState*, EncodedJSValue thisObject, EncodedJSValue value);
+            // Custom values are passed the slotBase (the property holder), custom accessors are passed the thisVaule (reciever).
+            // FIXME: Remove this differences in custom values and custom accessors.
+            // https://bugs.webkit.org/show_bug.cgi?id=158014
+            GPRReg baseForCustomValue = m_type == CustomValueGetter || m_type == CustomValueSetter ? baseForAccessGPR : baseForGetGPR;
+#if USE(JSVALUE64)
+            if (m_type == CustomValueGetter || m_type == CustomAccessorGetter) {
+                jit.setupArgumentsWithExecState(
+                    baseForCustomValue,
+                    CCallHelpers::TrustedImmPtr(ident.impl()));
+            } else
+                jit.setupArgumentsWithExecState(baseForCustomValue, valueRegs.gpr());
+#else
+            if (m_type == CustomValueGetter || m_type == CustomAccessorGetter) {
+                jit.setupArgumentsWithExecState(
+                    EABI_32BIT_DUMMY_ARG baseForCustomValue,
+                    CCallHelpers::TrustedImm32(JSValue::CellTag),
+                    CCallHelpers::TrustedImmPtr(ident.impl()));
+            } else {
+                jit.setupArgumentsWithExecState(
+                    EABI_32BIT_DUMMY_ARG baseForCustomValue,
+                    CCallHelpers::TrustedImm32(JSValue::CellTag),
+                    valueRegs.payloadGPR(), valueRegs.tagGPR());
+            }
+#endif
+            jit.storePtr(GPRInfo::callFrameRegister, &amp;vm.topCallFrame);
+
+            operationCall = jit.call();
+            jit.addLinkTask([=] (LinkBuffer&amp; linkBuffer) {
+                linkBuffer.link(operationCall, FunctionPtr(this-&gt;as&lt;GetterSetterAccessCase&gt;().m_customAccessor.opaque));
+            });
+
+            if (m_type == CustomValueGetter || m_type == CustomAccessorGetter)
+                jit.setupResults(valueRegs);
+            jit.reclaimSpaceOnStackForCCall();
+
+            CCallHelpers::Jump noException =
+            jit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck);
+
+            state.restoreLiveRegistersFromStackForCallWithThrownException(spillState);
+            state.emitExplicitExceptionHandler();
+
+            noException.link(&amp;jit);
+            bool callHasReturnValue = isGetter();
+            restoreLiveRegistersFromStackForCall(spillState, callHasReturnValue);
+        }
+        state.succeed();
+        return;
+    }
+
+    case Replace: {
+        if (InferredType* type = structure()-&gt;inferredTypeFor(ident.impl())) {
+            if (verbose)
+                dataLog(&quot;Have type: &quot;, type-&gt;descriptor(), &quot;\n&quot;);
+            state.failAndRepatch.append(
+                jit.branchIfNotType(valueRegs, scratchGPR, type-&gt;descriptor()));
+        } else if (verbose)
+            dataLog(&quot;Don't have type.\n&quot;);
+
+        if (isInlineOffset(m_offset)) {
+            jit.storeValue(
+                valueRegs,
+                CCallHelpers::Address(
+                    baseGPR,
+                    JSObject::offsetOfInlineStorage() +
+                    offsetInInlineStorage(m_offset) * sizeof(JSValue)));
+        } else {
+            jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR);
+            jit.storeValue(
+                valueRegs,
+                CCallHelpers::Address(
+                    scratchGPR, offsetInButterfly(m_offset) * sizeof(JSValue)));
+        }
+        state.succeed();
+        return;
+    }
+
+    case Transition: {
+        // AccessCase::transition() should have returned null if this wasn't true.
+        RELEASE_ASSERT(GPRInfo::numberOfRegisters &gt;= 6 || !structure()-&gt;outOfLineCapacity() || structure()-&gt;outOfLineCapacity() == newStructure()-&gt;outOfLineCapacity());
+
+        if (InferredType* type = newStructure()-&gt;inferredTypeFor(ident.impl())) {
+            if (verbose)
+                dataLog(&quot;Have type: &quot;, type-&gt;descriptor(), &quot;\n&quot;);
+            state.failAndRepatch.append(
+                jit.branchIfNotType(valueRegs, scratchGPR, type-&gt;descriptor()));
+        } else if (verbose)
+            dataLog(&quot;Don't have type.\n&quot;);
+
+        // NOTE: This logic is duplicated in AccessCase::doesCalls(). It's important that doesCalls() knows
+        // exactly when this would make calls.
+        bool allocating = newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity();
+        bool reallocating = allocating &amp;&amp; structure()-&gt;outOfLineCapacity();
+        bool allocatingInline = allocating &amp;&amp; !structure()-&gt;couldHaveIndexingHeader();
+
+        ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
+        allocator.lock(baseGPR);
+#if USE(JSVALUE32_64)
+        allocator.lock(static_cast&lt;GPRReg&gt;(stubInfo.patch.baseTagGPR));
+#endif
+        allocator.lock(valueRegs);
+        allocator.lock(scratchGPR);
+
+        GPRReg scratchGPR2 = InvalidGPRReg;
+        GPRReg scratchGPR3 = InvalidGPRReg;
+        if (allocatingInline) {
+            scratchGPR2 = allocator.allocateScratchGPR();
+            scratchGPR3 = allocator.allocateScratchGPR();
+        }
+
+        ScratchRegisterAllocator::PreservedState preservedState =
+        allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+
+        CCallHelpers::JumpList slowPath;
+
+        ASSERT(structure()-&gt;transitionWatchpointSetHasBeenInvalidated());
+
+        if (allocating) {
+            size_t newSize = newStructure()-&gt;outOfLineCapacity() * sizeof(JSValue);
+
+            if (allocatingInline) {
+                MarkedAllocator* allocator = vm.auxiliarySpace.allocatorFor(newSize);
+
+                if (!allocator) {
+                    // Yuck, this case would suck!
+                    slowPath.append(jit.jump());
+                }
+
+                jit.move(CCallHelpers::TrustedImmPtr(allocator), scratchGPR2);
+                jit.emitAllocate(scratchGPR, allocator, scratchGPR2, scratchGPR3, slowPath);
+                jit.addPtr(CCallHelpers::TrustedImm32(newSize + sizeof(IndexingHeader)), scratchGPR);
+
+                size_t oldSize = structure()-&gt;outOfLineCapacity() * sizeof(JSValue);
+                ASSERT(newSize &gt; oldSize);
+
+                if (reallocating) {
+                    // Handle the case where we are reallocating (i.e. the old structure/butterfly
+                    // already had out-of-line property storage).
+
+                    jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR3);
+
+                    // We have scratchGPR = new storage, scratchGPR3 = old storage,
+                    // scratchGPR2 = available
+                    for (size_t offset = 0; offset &lt; oldSize; offset += sizeof(void*)) {
+                        jit.loadPtr(
+                            CCallHelpers::Address(
+                                scratchGPR3,
+                                -static_cast&lt;ptrdiff_t&gt;(
+                                    offset + sizeof(JSValue) + sizeof(void*))),
+                            scratchGPR2);
+                        jit.storePtr(
+                            scratchGPR2,
+                            CCallHelpers::Address(
+                                scratchGPR,
+                                -static_cast&lt;ptrdiff_t&gt;(offset + sizeof(JSValue) + sizeof(void*))));
+                    }
+                }
+
+                for (size_t offset = oldSize; offset &lt; newSize; offset += sizeof(void*))
+                    jit.storePtr(CCallHelpers::TrustedImmPtr(0), CCallHelpers::Address(scratchGPR, -static_cast&lt;ptrdiff_t&gt;(offset + sizeof(JSValue) + sizeof(void*))));
+            } else {
+                // Handle the case where we are allocating out-of-line using an operation.
+                RegisterSet extraRegistersToPreserve;
+                extraRegistersToPreserve.set(baseGPR);
+                extraRegistersToPreserve.set(valueRegs);
+                AccessGenerationState::SpillState spillState = state.preserveLiveRegistersToStackForCall(extraRegistersToPreserve);
+                
+                jit.store32(
+                    CCallHelpers::TrustedImm32(
+                        state.callSiteIndexForExceptionHandlingOrOriginal().bits()),
+                    CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(CallFrameSlot::argumentCount)));
+                
+                jit.makeSpaceOnStackForCCall();
+                
+                if (!reallocating) {
+                    jit.setupArgumentsWithExecState(baseGPR);
+                    
+                    CCallHelpers::Call operationCall = jit.call();
+                    jit.addLinkTask([=] (LinkBuffer&amp; linkBuffer) {
+                        linkBuffer.link(
+                            operationCall,
+                            FunctionPtr(operationReallocateButterflyToHavePropertyStorageWithInitialCapacity));
+                    });
+                } else {
+                    // Handle the case where we are reallocating (i.e. the old structure/butterfly
+                    // already had out-of-line property storage).
+                    jit.setupArgumentsWithExecState(
+                        baseGPR, CCallHelpers::TrustedImm32(newSize / sizeof(JSValue)));
+                    
+                    CCallHelpers::Call operationCall = jit.call();
+                    jit.addLinkTask([=] (LinkBuffer&amp; linkBuffer) {
+                        linkBuffer.link(
+                            operationCall,
+                            FunctionPtr(operationReallocateButterflyToGrowPropertyStorage));
+                    });
+                }
+                
+                jit.reclaimSpaceOnStackForCCall();
+                jit.move(GPRInfo::returnValueGPR, scratchGPR);
+                
+                CCallHelpers::Jump noException = jit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck);
+                
+                state.restoreLiveRegistersFromStackForCallWithThrownException(spillState);
+                state.emitExplicitExceptionHandler();
+                
+                noException.link(&amp;jit);
+                state.restoreLiveRegistersFromStackForCall(spillState);
+            }
+        }
+        
+        if (isInlineOffset(m_offset)) {
+            jit.storeValue(
+                valueRegs,
+                CCallHelpers::Address(
+                    baseGPR,
+                    JSObject::offsetOfInlineStorage() +
+                    offsetInInlineStorage(m_offset) * sizeof(JSValue)));
+        } else {
+            if (!allocating)
+                jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR);
+            jit.storeValue(
+                valueRegs,
+                CCallHelpers::Address(scratchGPR, offsetInButterfly(m_offset) * sizeof(JSValue)));
+        }
+        
+        if (allocatingInline) {
+            // We set the new butterfly and the structure last. Doing it this way ensures that
+            // whatever we had done up to this point is forgotten if we choose to branch to slow
+            // path.
+            jit.nukeStructureAndStoreButterfly(scratchGPR, baseGPR);
+        }
+        
+        uint32_t structureBits = bitwise_cast&lt;uint32_t&gt;(newStructure()-&gt;id());
+        jit.store32(
+            CCallHelpers::TrustedImm32(structureBits),
+            CCallHelpers::Address(baseGPR, JSCell::structureIDOffset()));
+        
+        allocator.restoreReusedRegistersByPopping(jit, preservedState);
+        state.succeed();
+        
+        // We will have a slow path if we were allocating without the help of an operation.
+        if (allocatingInline) {
+            if (allocator.didReuseRegisters()) {
+                slowPath.link(&amp;jit);
+                allocator.restoreReusedRegistersByPopping(jit, preservedState);
+                state.failAndIgnore.append(jit.jump());
+            } else
+                state.failAndIgnore.append(slowPath);
+        } else
+            RELEASE_ASSERT(slowPath.empty());
+        return;
+    }
+        
+    case ArrayLength: {
+        jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR);
+        jit.load32(CCallHelpers::Address(scratchGPR, ArrayStorage::lengthOffset()), scratchGPR);
+        state.failAndIgnore.append(
+            jit.branch32(CCallHelpers::LessThan, scratchGPR, CCallHelpers::TrustedImm32(0)));
+        jit.boxInt32(scratchGPR, valueRegs);
+        state.succeed();
+        return;
+    }
+        
+    case StringLength: {
+        jit.load32(CCallHelpers::Address(baseGPR, JSString::offsetOfLength()), valueRegs.payloadGPR());
+        jit.boxInt32(valueRegs.payloadGPR(), valueRegs);
+        state.succeed();
+        return;
+    }
+        
+    case IntrinsicGetter: {
+        RELEASE_ASSERT(isValidOffset(offset()));
+        
+        // We need to ensure the getter value does not move from under us. Note that GetterSetters
+        // are immutable so we just need to watch the property not any value inside it.
+        Structure* currStructure;
+        if (m_conditionSet.isEmpty())
+            currStructure = structure();
+        else
+            currStructure = m_conditionSet.slotBaseCondition().object()-&gt;structure();
+        currStructure-&gt;startWatchingPropertyForReplacements(vm, offset());
+        
+        this-&gt;as&lt;IntrinsicGetterAccessCase&gt;().emitIntrinsicGetter(state);
+        return;
+    }
+        
+    case DirectArgumentsLength:
+    case ScopedArgumentsLength:
+        // These need to be handled by generateWithGuard(), since the guard is part of the
+        // algorithm. We can be sure that nobody will call generate() directly for these since they
+        // are not guarded by structure checks.
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace JSC
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeAccessCaseh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/AccessCase.h (0 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/AccessCase.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/AccessCase.h        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -0,0 +1,232 @@
</span><ins>+/*
+ * Copyright (C) 2017 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;JSFunctionInlines.h&quot;
+#include &quot;ObjectPropertyConditionSet.h&quot;
+
+namespace JSC {
+
+struct AccessGenerationState;
+
+// An AccessCase describes one of the cases of a PolymorphicAccess. A PolymorphicAccess represents a
+// planned (to generate in future) or generated stub for some inline cache. That stub contains fast
+// path code for some finite number of fast cases, each described by an AccessCase object.
+//
+// An AccessCase object has a lifecycle that proceeds through several states. Note that the states
+// of AccessCase have a lot to do with the global effect epoch (we'll say epoch for short). This is
+// a simple way of reasoning about the state of the system outside this AccessCase. Any observable
+// effect - like storing to a property, changing an object's structure, etc. - increments the epoch.
+// The states are:
+//
+// Primordial:   This is an AccessCase that was just allocated. It does not correspond to any actual
+//               code and it is not owned by any PolymorphicAccess. In this state, the AccessCase
+//               assumes that it is in the same epoch as when it was created. This is important
+//               because it may make claims about itself (&quot;I represent a valid case so long as you
+//               register a watchpoint on this set&quot;) that could be contradicted by some outside
+//               effects (like firing and deleting the watchpoint set in question). This is also the
+//               state that an AccessCase is in when it is cloned (AccessCase::clone()).
+//
+// Committed:    This happens as soon as some PolymorphicAccess takes ownership of this AccessCase.
+//               In this state, the AccessCase no longer assumes anything about the epoch. To
+//               accomplish this, PolymorphicAccess calls AccessCase::commit(). This must be done
+//               during the same epoch when the AccessCase was created, either by the client or by
+//               clone(). When created by the client, committing during the same epoch works because
+//               we can be sure that whatever watchpoint sets they spoke of are still valid. When
+//               created by clone(), we can be sure that the set is still valid because the original
+//               of the clone still has watchpoints on it.
+//
+// Generated:    This is the state when the PolymorphicAccess generates code for this case by
+//               calling AccessCase::generate() or AccessCase::generateWithGuard(). At this point
+//               the case object will have some extra stuff in it, like possibly the CallLinkInfo
+//               object associated with the inline cache.
+//               FIXME: Moving into the Generated state should not mutate the AccessCase object or
+//               put more stuff into it. If we fix this, then we can get rid of AccessCase::clone().
+//               https://bugs.webkit.org/show_bug.cgi?id=156456
+//
+// An AccessCase may be destroyed while in any of these states.
+//
+// We will sometimes buffer committed AccessCases in the PolymorphicAccess object before generating
+// code. This allows us to only regenerate once we've accumulated (hopefully) more than one new
+// AccessCase.
+class AccessCase {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    enum AccessType : uint8_t {
+        Load,
+        Transition,
+        Replace,
+        Miss,
+        GetGetter,
+        Getter,
+        Setter,
+        CustomValueGetter,
+        CustomAccessorGetter,
+        CustomValueSetter,
+        CustomAccessorSetter,
+        IntrinsicGetter,
+        InHit,
+        InMiss,
+        ArrayLength,
+        StringLength,
+        DirectArgumentsLength,
+        ScopedArgumentsLength
+    };
+
+    enum State : uint8_t {
+        Primordial,
+        Committed,
+        Generated
+    };
+
+    template&lt;typename T&gt;
+    T&amp; as() { return *static_cast&lt;T*&gt;(this); }
+
+    template&lt;typename T&gt;
+    const T&amp; as() const { return *static_cast&lt;const T*&gt;(this); }
+
+
+    template&lt;typename AccessCaseType, typename... Arguments&gt;
+    static std::unique_ptr&lt;AccessCaseType&gt; create(Arguments... arguments)
+    {
+        return std::unique_ptr&lt;AccessCaseType&gt;(new AccessCaseType(arguments...));
+    }
+
+    static std::unique_ptr&lt;AccessCase&gt; create(VM&amp;, JSCell* owner, AccessType, PropertyOffset = invalidOffset,
+        Structure* = nullptr, const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet());
+
+    // This create method should be used for transitions.
+    static std::unique_ptr&lt;AccessCase&gt; create(VM&amp;, JSCell* owner, PropertyOffset, Structure* oldStructure,
+        Structure* newStructure, const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet());
+
+    static std::unique_ptr&lt;AccessCase&gt; fromStructureStubInfo(VM&amp;, JSCell* owner, StructureStubInfo&amp;);
+
+    AccessType type() const { return m_type; }
+    State state() const { return m_state; }
+    PropertyOffset offset() const { return m_offset; }
+
+    Structure* structure() const
+    {
+        if (m_type == Transition)
+            return m_structure-&gt;previousID();
+        return m_structure.get();
+    }
+    bool guardedByStructureCheck() const;
+
+    Structure* newStructure() const
+    {
+        ASSERT(m_type == Transition);
+        return m_structure.get();
+    }
+
+    ObjectPropertyConditionSet conditionSet() const { return m_conditionSet; }
+
+    virtual JSObject* alternateBase() const { return conditionSet().slotBaseCondition().object(); }
+    virtual WatchpointSet* additionalSet() const { return nullptr; }
+    virtual bool viaProxy() const { return false; }
+
+    // If you supply the optional vector, this will append the set of cells that this will need to keep alive
+    // past the call.
+    bool doesCalls(Vector&lt;JSCell*&gt;* cellsToMark = nullptr) const;
+
+    bool isGetter() const
+    {
+        switch (type()) {
+        case Getter:
+        case CustomValueGetter:
+        case CustomAccessorGetter:
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    bool isAccessor() const { return isGetter() || type() == Setter; }
+
+    // Is it still possible for this case to ever be taken? Must call this as a prerequisite for
+    // calling generate() and friends. If this returns true, then you can call generate(). If
+    // this returns false, then generate() will crash. You must call generate() in the same epoch
+    // as when you called couldStillSucceed().
+    bool couldStillSucceed() const;
+
+    // If this method returns true, then it's a good idea to remove 'other' from the access once 'this'
+    // is added. This method assumes that in case of contradictions, 'this' represents a newer, and so
+    // more useful, truth. This method can be conservative; it will return false when it doubt.
+    bool canReplace(const AccessCase&amp; other) const;
+
+    void dump(PrintStream&amp; out) const;
+    virtual void dumpImpl(PrintStream&amp;, CommaPrinter&amp;) const { }
+
+    virtual ~AccessCase();
+
+protected:
+    AccessCase(VM&amp;, JSCell* owner, AccessType, PropertyOffset, Structure*, const ObjectPropertyConditionSet&amp;);
+    AccessCase(const AccessCase&amp;) = default;
+    AccessCase&amp; operator=(const AccessCase&amp;) = delete;
+    void resetState() { m_state = Primordial; }
+
+private:
+    friend class CodeBlock;
+    friend class PolymorphicAccess;
+
+    bool visitWeak(VM&amp;) const;
+    bool propagateTransitions(SlotVisitor&amp;) const;
+
+    // FIXME: This only exists because of how AccessCase puts post-generation things into itself.
+    // https://bugs.webkit.org/show_bug.cgi?id=156456
+    virtual std::unique_ptr&lt;AccessCase&gt; clone() const;
+
+    // Perform any action that must be performed before the end of the epoch in which the case
+    // was created. Returns a set of watchpoint sets that will need to be watched.
+    Vector&lt;WatchpointSet*, 2&gt; commit(VM&amp;, const Identifier&amp;);
+
+    // Fall through on success. Two kinds of failures are supported: fall-through, which means that we
+    // should try a different case; and failure, which means that this was the right case but it needs
+    // help from the slow path.
+    void generateWithGuard(AccessGenerationState&amp;, MacroAssembler::JumpList&amp; fallThrough);
+
+    // Fall through on success, add a jump to the failure list on failure.
+    void generate(AccessGenerationState&amp;);
+
+    void generateImpl(AccessGenerationState&amp;);
+
+    AccessType m_type;
+    State m_state { Primordial };
+    PropertyOffset m_offset;
+
+    // Usually this is the structure that we expect the base object to have. But, this is the *new*
+    // structure for a transition and we rely on the fact that it has a strong reference to the old
+    // structure. For proxies, this is the structure of the object behind the proxy.
+    WriteBarrier&lt;Structure&gt; m_structure;
+
+    ObjectPropertyConditionSet m_conditionSet;
+};
+
+} // namespace JSC
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -28,6 +28,8 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;ComplexGetStatus.h&quot;
</span><ins>+#include &quot;GetterSetterAccessCase.h&quot;
+#include &quot;IntrinsicGetterAccessCase.h&quot;
</ins><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSScope.h&quot;
</span><span class="cx"> #include &quot;LLIntData.h&quot;
</span><span class="lines">@@ -231,12 +233,12 @@
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                 case AccessCase::IntrinsicGetter: {
</span><del>-                    intrinsicFunction = access.intrinsicFunction();
</del><ins>+                    intrinsicFunction = access.as&lt;IntrinsicGetterAccessCase&gt;().intrinsicFunction();
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                 case AccessCase::Getter: {
</span><span class="cx">                     callLinkStatus = std::make_unique&lt;CallLinkStatus&gt;();
</span><del>-                    if (CallLinkInfo* callLinkInfo = access.callLinkInfo()) {
</del><ins>+                    if (CallLinkInfo* callLinkInfo = access.as&lt;GetterSetterAccessCase&gt;().callLinkInfo()) {
</ins><span class="cx">                         *callLinkStatus = CallLinkStatus::computeFor(
</span><span class="cx">                             locker, profiledBlock, *callLinkInfo, callExitSiteData);
</span><span class="cx">                     }
</span><span class="lines">@@ -243,7 +245,7 @@
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                 case AccessCase::CustomAccessorGetter: {
</span><del>-                    domJIT = access.domJIT();
</del><ins>+                    domJIT = access.as&lt;GetterSetterAccessCase&gt;().domJIT();
</ins><span class="cx">                     if (!domJIT)
</span><span class="cx">                         return GetByIdStatus(slowPathState, true);
</span><span class="cx">                     result.m_state = Custom;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetterSetterAccessCasecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.cpp (0 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -0,0 +1,238 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;GetterSetterAccessCase.h&quot;
+
+#if ENABLE(JIT)
+
+#include &quot;DOMJITAccessCasePatchpointParams.h&quot;
+#include &quot;DOMJITCallDOMGetterPatchpoint.h&quot;
+#include &quot;DOMJITGetterSetter.h&quot;
+#include &quot;HeapInlines.h&quot;
+#include &quot;JSCJSValueInlines.h&quot;
+#include &quot;PolymorphicAccess.h&quot;
+#include &quot;StructureStubInfo.h&quot;
+
+namespace JSC {
+
+static const bool verbose = false;
+
+GetterSetterAccessCase::GetterSetterAccessCase(VM&amp; vm, JSCell* owner, AccessType accessType, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet&amp; conditionSet, bool viaProxy, WatchpointSet* additionalSet, JSObject* customSlotBase)
+    : Base(vm, owner, accessType, offset, structure, conditionSet, viaProxy, additionalSet)
+{
+    m_customSlotBase.setMayBeNull(vm, owner, customSlotBase);
+}
+
+
+std::unique_ptr&lt;AccessCase&gt; GetterSetterAccessCase::create(
+    VM&amp; vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure,
+    const ObjectPropertyConditionSet&amp; conditionSet, bool viaProxy, WatchpointSet* additionalSet,
+    PropertySlot::GetValueFunc customGetter, JSObject* customSlotBase, DOMJIT::GetterSetter* domJIT)
+{
+    switch (type) {
+    case Getter:
+    case CustomAccessorGetter:
+    case CustomValueGetter:
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    };
+
+    std::unique_ptr&lt;GetterSetterAccessCase&gt; result(new GetterSetterAccessCase(vm, owner, type, offset, structure, conditionSet, viaProxy, additionalSet, customSlotBase));
+    result-&gt;m_domJIT = domJIT;
+    result-&gt;m_customAccessor.getter = customGetter;
+    return WTFMove(result);
+}
+
+std::unique_ptr&lt;AccessCase&gt; GetterSetterAccessCase::create(VM&amp; vm, JSCell* owner, AccessType type, Structure* structure, PropertyOffset offset,
+    const ObjectPropertyConditionSet&amp; conditionSet, PutPropertySlot::PutValueFunc customSetter,
+    JSObject* customSlotBase)
+{
+    ASSERT(type == Setter || type == CustomValueSetter || type == CustomAccessorSetter);
+    std::unique_ptr&lt;GetterSetterAccessCase&gt; result(new GetterSetterAccessCase(vm, owner, type, offset, structure, conditionSet, false, nullptr, customSlotBase));
+    result-&gt;m_customAccessor.setter = customSetter;
+    return WTFMove(result);
+}
+
+
+GetterSetterAccessCase::~GetterSetterAccessCase()
+{
+}
+
+
+GetterSetterAccessCase::GetterSetterAccessCase(const GetterSetterAccessCase&amp; other)
+    : Base(other)
+    , m_customSlotBase(other.m_customSlotBase)
+{
+    m_customAccessor.opaque = other.m_customAccessor.opaque;
+    m_domJIT = other.m_domJIT;
+}
+
+std::unique_ptr&lt;AccessCase&gt; GetterSetterAccessCase::clone() const
+{
+    std::unique_ptr&lt;GetterSetterAccessCase&gt; result(new GetterSetterAccessCase(*this));
+    result-&gt;resetState();
+    return WTFMove(result);
+}
+
+JSObject* GetterSetterAccessCase::alternateBase() const
+{
+    if (customSlotBase())
+        return customSlotBase();
+    return conditionSet().slotBaseCondition().object();
+}
+
+void GetterSetterAccessCase::dumpImpl(PrintStream&amp; out, CommaPrinter&amp; comma) const
+{
+    Base::dumpImpl(out, comma);
+    out.print(comma, &quot;customSlotBase = &quot;, RawPointer(customSlotBase()));
+    if (callLinkInfo())
+        out.print(comma, &quot;callLinkInfo = &quot;, RawPointer(callLinkInfo()));
+    out.print(comma, &quot;customAccessor = &quot;, RawPointer(m_customAccessor.opaque));
+}
+
+void GetterSetterAccessCase::emitDOMJITGetter(AccessGenerationState&amp; state, GPRReg baseForGetGPR)
+{
+    CCallHelpers&amp; jit = *state.jit;
+    StructureStubInfo&amp; stubInfo = *state.stubInfo;
+    JSValueRegs valueRegs = state.valueRegs;
+    GPRReg baseGPR = state.baseGPR;
+    GPRReg scratchGPR = state.scratchGPR;
+
+    // We construct the environment that can execute the DOMJIT::Patchpoint here.
+    Ref&lt;DOMJIT::CallDOMGetterPatchpoint&gt; patchpoint = domJIT()-&gt;callDOMGetter();
+
+    Vector&lt;GPRReg&gt; gpScratch;
+    Vector&lt;FPRReg&gt; fpScratch;
+    Vector&lt;DOMJIT::Value&gt; regs;
+
+    ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
+    allocator.lock(baseGPR);
+#if USE(JSVALUE32_64)
+    allocator.lock(static_cast&lt;GPRReg&gt;(stubInfo.patch.baseTagGPR));
+#endif
+    allocator.lock(valueRegs);
+    allocator.lock(scratchGPR);
+
+    GPRReg paramBaseGPR = InvalidGPRReg;
+    GPRReg paramGlobalObjectGPR = InvalidGPRReg;
+    JSValueRegs paramValueRegs = valueRegs;
+    GPRReg remainingScratchGPR = InvalidGPRReg;
+
+    // valueRegs and baseForGetGPR may be the same. For example, in Baseline JIT, we pass the same regT0 for baseGPR and valueRegs.
+    // In FTL, there is no constraint that the baseForGetGPR interferes with the result. To make implementation simple in
+    // DOMJIT::Patchpoint, DOMJIT::Patchpoint assumes that result registers always early interfere with input registers, in this case,
+    // baseForGetGPR. So we move baseForGetGPR to the other register if baseForGetGPR == valueRegs.
+    if (baseForGetGPR != valueRegs.payloadGPR()) {
+        paramBaseGPR = baseForGetGPR;
+        if (!patchpoint-&gt;requireGlobalObject)
+            remainingScratchGPR = scratchGPR;
+        else
+            paramGlobalObjectGPR = scratchGPR;
+    } else {
+        jit.move(valueRegs.payloadGPR(), scratchGPR);
+        paramBaseGPR = scratchGPR;
+        if (patchpoint-&gt;requireGlobalObject)
+            paramGlobalObjectGPR = allocator.allocateScratchGPR();
+    }
+
+    JSGlobalObject* globalObjectForDOMJIT = structure()-&gt;globalObject();
+
+    regs.append(paramValueRegs);
+    regs.append(paramBaseGPR);
+    if (patchpoint-&gt;requireGlobalObject) {
+        ASSERT(paramGlobalObjectGPR != InvalidGPRReg);
+        regs.append(DOMJIT::Value(paramGlobalObjectGPR, globalObjectForDOMJIT));
+    }
+
+    if (patchpoint-&gt;numGPScratchRegisters) {
+        unsigned i = 0;
+        if (remainingScratchGPR != InvalidGPRReg) {
+            gpScratch.append(remainingScratchGPR);
+            ++i;
+        }
+        for (; i &lt; patchpoint-&gt;numGPScratchRegisters; ++i)
+            gpScratch.append(allocator.allocateScratchGPR());
+    }
+
+    for (unsigned i = 0; i &lt; patchpoint-&gt;numFPScratchRegisters; ++i)
+        fpScratch.append(allocator.allocateScratchFPR());
+
+    // Let's store the reused registers to the stack. After that, we can use allocated scratch registers.
+    ScratchRegisterAllocator::PreservedState preservedState =
+    allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+
+    if (verbose) {
+        dataLog(&quot;baseGPR = &quot;, baseGPR, &quot;\n&quot;);
+        dataLog(&quot;valueRegs = &quot;, valueRegs, &quot;\n&quot;);
+        dataLog(&quot;scratchGPR = &quot;, scratchGPR, &quot;\n&quot;);
+        dataLog(&quot;paramBaseGPR = &quot;, paramBaseGPR, &quot;\n&quot;);
+        if (paramGlobalObjectGPR != InvalidGPRReg)
+            dataLog(&quot;paramGlobalObjectGPR = &quot;, paramGlobalObjectGPR, &quot;\n&quot;);
+        dataLog(&quot;paramValueRegs = &quot;, paramValueRegs, &quot;\n&quot;);
+        for (unsigned i = 0; i &lt; patchpoint-&gt;numGPScratchRegisters; ++i)
+            dataLog(&quot;gpScratch[&quot;, i, &quot;] = &quot;, gpScratch[i], &quot;\n&quot;);
+    }
+
+    if (patchpoint-&gt;requireGlobalObject)
+        jit.move(CCallHelpers::TrustedImmPtr(globalObjectForDOMJIT), paramGlobalObjectGPR);
+
+    // We just spill the registers used in DOMJIT::Patchpoint here. For not spilled registers here explicitly,
+    // they must be in the used register set passed by the callers (Baseline, DFG, and FTL) if they need to be kept.
+    // Some registers can be locked, but not in the used register set. For example, the caller could make baseGPR
+    // same to valueRegs, and not include it in the used registers since it will be changed.
+    RegisterSet registersToSpillForCCall;
+    for (auto&amp; value : regs) {
+        DOMJIT::Reg reg = value.reg();
+        if (reg.isJSValueRegs())
+            registersToSpillForCCall.set(reg.jsValueRegs());
+        else if (reg.isGPR())
+            registersToSpillForCCall.set(reg.gpr());
+        else
+            registersToSpillForCCall.set(reg.fpr());
+    }
+    for (GPRReg reg : gpScratch)
+        registersToSpillForCCall.set(reg);
+    for (FPRReg reg : fpScratch)
+        registersToSpillForCCall.set(reg);
+    registersToSpillForCCall.exclude(RegisterSet::registersToNotSaveForCCall());
+
+    DOMJITAccessCasePatchpointParams params(WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch));
+    patchpoint-&gt;generator()-&gt;run(jit, params);
+    allocator.restoreReusedRegistersByPopping(jit, preservedState);
+    state.succeed();
+    
+    CCallHelpers::JumpList exceptions = params.emitSlowPathCalls(state, registersToSpillForCCall, jit);
+    if (!exceptions.empty()) {
+        exceptions.link(&amp;jit);
+        allocator.restoreReusedRegistersByPopping(jit, preservedState);
+        state.emitExplicitExceptionHandler();
+    }
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetterSetterAccessCaseh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.h (0 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.h        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -0,0 +1,84 @@
</span><ins>+/*
+ * Copyright (C) 2017 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;ProxyableAccessCase.h&quot;
+
+namespace JSC {
+
+class GetterSetterAccessCase : public ProxyableAccessCase {
+public:
+    typedef ProxyableAccessCase Base;
+    friend class AccessCase;
+
+    // This can return null if it hasn't been generated yet. That's
+    // actually somewhat likely because of how we do buffering of new cases.
+    CallLinkInfo* callLinkInfo() const { return m_callLinkInfo.get(); }
+    JSObject* customSlotBase() const { return m_customSlotBase.get(); }
+    DOMJIT::GetterSetter* domJIT() const { return m_domJIT; }
+
+    JSObject* alternateBase() const override;
+
+    void emitDOMJITGetter(AccessGenerationState&amp;, GPRReg baseForGetGPR);
+
+    static std::unique_ptr&lt;AccessCase&gt; create(
+        VM&amp;, JSCell* owner, AccessType, PropertyOffset, Structure*,
+        const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet(),
+        bool viaProxy = false,
+        WatchpointSet* additionalSet = nullptr,
+        PropertySlot::GetValueFunc = nullptr,
+        JSObject* customSlotBase = nullptr,
+        DOMJIT::GetterSetter* = nullptr);
+
+    static std::unique_ptr&lt;AccessCase&gt; create(VM&amp;, JSCell* owner, AccessType, Structure*, PropertyOffset,
+        const ObjectPropertyConditionSet&amp;, PutPropertySlot::PutValueFunc = nullptr,
+        JSObject* customSlotBase = nullptr);
+
+    void dumpImpl(PrintStream&amp;, CommaPrinter&amp;) const override;
+    std::unique_ptr&lt;AccessCase&gt; clone() const override;
+
+    ~GetterSetterAccessCase();
+
+private:
+    GetterSetterAccessCase(VM&amp;, JSCell*, AccessType, PropertyOffset, Structure*, const ObjectPropertyConditionSet&amp;, bool viaProxy, WatchpointSet* additionalSet, JSObject* customSlotBase);
+
+    GetterSetterAccessCase(const GetterSetterAccessCase&amp;);
+
+    WriteBarrier&lt;JSObject&gt; m_customSlotBase;
+    std::unique_ptr&lt;CallLinkInfo&gt; m_callLinkInfo;
+    union {
+        PutPropertySlot::PutValueFunc setter;
+        PropertySlot::GetValueFunc getter;
+        void* opaque;
+    } m_customAccessor;
+    DOMJIT::GetterSetter* m_domJIT;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeIntrinsicGetterAccessCasecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.cpp (0 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;IntrinsicGetterAccessCase.h&quot;
+
+#if ENABLE(JIT)
+
+#include &quot;HeapInlines.h&quot;
+
+namespace JSC {
+
+IntrinsicGetterAccessCase::IntrinsicGetterAccessCase(VM&amp; vm, JSCell* owner, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet&amp; conditionSet, JSFunction* intrinsicFunction)
+    : Base(vm, owner, IntrinsicGetter, offset, structure, conditionSet)
+{
+    m_intrinsicFunction.set(vm, owner, intrinsicFunction);
+}
+
+std::unique_ptr&lt;AccessCase&gt; IntrinsicGetterAccessCase::create(VM&amp; vm, JSCell* owner, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet&amp; conditionSet, JSFunction* intrinsicFunction)
+{
+    return std::unique_ptr&lt;AccessCase&gt;(new IntrinsicGetterAccessCase(vm, owner, offset, structure, conditionSet, intrinsicFunction));
+}
+
+IntrinsicGetterAccessCase::~IntrinsicGetterAccessCase()
+{
+}
+
+std::unique_ptr&lt;AccessCase&gt; IntrinsicGetterAccessCase::clone() const
+{
+    std::unique_ptr&lt;IntrinsicGetterAccessCase&gt; result(new IntrinsicGetterAccessCase(*this));
+    result-&gt;resetState();
+    return WTFMove(result);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeIntrinsicGetterAccessCaseh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.h (0 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.h        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+/*
+ * Copyright (C) 2017 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;AccessCase.h&quot;
+
+namespace JSC {
+
+class IntrinsicGetterAccessCase : public AccessCase {
+public:
+    typedef AccessCase Base;
+    friend class AccessCase;
+
+    JSFunction* intrinsicFunction() const { return m_intrinsicFunction.get(); }
+    Intrinsic intrinsic() const { return m_intrinsicFunction-&gt;intrinsic(); }
+
+    static bool canEmitIntrinsicGetter(JSFunction*, Structure*);
+    void emitIntrinsicGetter(AccessGenerationState&amp;);
+
+    static std::unique_ptr&lt;AccessCase&gt; create(VM&amp;, JSCell*, PropertyOffset, Structure*, const ObjectPropertyConditionSet&amp;, JSFunction* intrinsicFunction);
+
+    std::unique_ptr&lt;AccessCase&gt; clone() const override;
+
+    ~IntrinsicGetterAccessCase();
+
+private:
+    IntrinsicGetterAccessCase(VM&amp;, JSCell*, PropertyOffset, Structure*, const ObjectPropertyConditionSet&amp;, JSFunction* intrinsicFunction);
+
+    WriteBarrier&lt;JSFunction&gt; m_intrinsicFunction;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -31,16 +31,10 @@
</span><span class="cx"> #include &quot;BinarySwitch.h&quot;
</span><span class="cx"> #include &quot;CCallHelpers.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><del>-#include &quot;DOMJITAccessCasePatchpointParams.h&quot;
-#include &quot;DOMJITCallDOMGetterPatchpoint.h&quot;
-#include &quot;DirectArguments.h&quot;
-#include &quot;GetterSetter.h&quot;
</del><span class="cx"> #include &quot;Heap.h&quot;
</span><span class="cx"> #include &quot;JITOperations.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;LinkBuffer.h&quot;
</span><del>-#include &quot;ScopedArguments.h&quot;
-#include &quot;ScratchRegisterAllocator.h&quot;
</del><span class="cx"> #include &quot;StructureStubClearingWatchpoint.h&quot;
</span><span class="cx"> #include &quot;StructureStubInfo.h&quot;
</span><span class="cx"> #include &lt;wtf/CommaPrinter.h&gt;
</span><span class="lines">@@ -210,1359 +204,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-AccessCase::AccessCase()
-{
-}
</del><span class="cx"> 
</span><del>-std::unique_ptr&lt;AccessCase&gt; AccessCase::tryGet(
-    VM&amp; vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure,
-    const ObjectPropertyConditionSet&amp; conditionSet, bool viaProxy, WatchpointSet* additionalSet)
-{
-    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
-
-    result-&gt;m_type = type;
-    result-&gt;m_offset = offset;
-    result-&gt;m_structure.set(vm, owner, structure);
-    result-&gt;m_conditionSet = conditionSet;
-
-    if (viaProxy || additionalSet) {
-        result-&gt;m_rareData = std::make_unique&lt;RareData&gt;();
-        result-&gt;m_rareData-&gt;viaProxy = viaProxy;
-        result-&gt;m_rareData-&gt;additionalSet = additionalSet;
-    }
-
-    return result;
-}
-
-std::unique_ptr&lt;AccessCase&gt; AccessCase::get(
-    VM&amp; vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure,
-    const ObjectPropertyConditionSet&amp; conditionSet, bool viaProxy, WatchpointSet* additionalSet,
-    PropertySlot::GetValueFunc customGetter, JSObject* customSlotBase, DOMJIT::GetterSetter* domJIT)
-{
-    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
-
-    result-&gt;m_type = type;
-    result-&gt;m_offset = offset;
-    result-&gt;m_structure.set(vm, owner, structure);
-    result-&gt;m_conditionSet = conditionSet;
-
-    if (viaProxy || additionalSet || result-&gt;doesCalls() || customGetter || customSlotBase || domJIT) {
-        result-&gt;m_rareData = std::make_unique&lt;RareData&gt;();
-        result-&gt;m_rareData-&gt;viaProxy = viaProxy;
-        result-&gt;m_rareData-&gt;additionalSet = additionalSet;
-        result-&gt;m_rareData-&gt;customAccessor.getter = customGetter;
-        result-&gt;m_rareData-&gt;customSlotBase.setMayBeNull(vm, owner, customSlotBase);
-        result-&gt;m_rareData-&gt;domJIT = domJIT;
-    }
-
-    return result;
-}
-
-std::unique_ptr&lt;AccessCase&gt; AccessCase::megamorphicLoad(VM&amp; vm, JSCell* owner)
-{
-    UNUSED_PARAM(vm);
-    UNUSED_PARAM(owner);
-    
-    if (GPRInfo::numberOfRegisters &lt; 9)
-        return nullptr;
-    
-    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
-    
-    result-&gt;m_type = MegamorphicLoad;
-    
-    return result;
-}
-
-std::unique_ptr&lt;AccessCase&gt; AccessCase::replace(
-    VM&amp; vm, JSCell* owner, Structure* structure, PropertyOffset offset)
-{
-    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
-
-    result-&gt;m_type = Replace;
-    result-&gt;m_offset = offset;
-    result-&gt;m_structure.set(vm, owner, structure);
-
-    return result;
-}
-
-std::unique_ptr&lt;AccessCase&gt; AccessCase::transition(
-    VM&amp; vm, JSCell* owner, Structure* oldStructure, Structure* newStructure, PropertyOffset offset,
-    const ObjectPropertyConditionSet&amp; conditionSet)
-{
-    RELEASE_ASSERT(oldStructure == newStructure-&gt;previousID());
-
-    // Skip optimizing the case where we need a realloc, if we don't have
-    // enough registers to make it happen.
-    if (GPRInfo::numberOfRegisters &lt; 6
-        &amp;&amp; oldStructure-&gt;outOfLineCapacity() != newStructure-&gt;outOfLineCapacity()
-        &amp;&amp; oldStructure-&gt;outOfLineCapacity()) {
-        return nullptr;
-    }
-
-    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
-
-    result-&gt;m_type = Transition;
-    result-&gt;m_offset = offset;
-    result-&gt;m_structure.set(vm, owner, newStructure);
-    result-&gt;m_conditionSet = conditionSet;
-
-    return result;
-}
-
-std::unique_ptr&lt;AccessCase&gt; AccessCase::setter(
-    VM&amp; vm, JSCell* owner, AccessType type, Structure* structure, PropertyOffset offset,
-    const ObjectPropertyConditionSet&amp; conditionSet, PutPropertySlot::PutValueFunc customSetter,
-    JSObject* customSlotBase)
-{
-    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
-
-    result-&gt;m_type = type;
-    result-&gt;m_offset = offset;
-    result-&gt;m_structure.set(vm, owner, structure);
-    result-&gt;m_conditionSet = conditionSet;
-    result-&gt;m_rareData = std::make_unique&lt;RareData&gt;();
-    result-&gt;m_rareData-&gt;customAccessor.setter = customSetter;
-    result-&gt;m_rareData-&gt;customSlotBase.setMayBeNull(vm, owner, customSlotBase);
-
-    return result;
-}
-
-std::unique_ptr&lt;AccessCase&gt; AccessCase::in(
-    VM&amp; vm, JSCell* owner, AccessType type, Structure* structure,
-    const ObjectPropertyConditionSet&amp; conditionSet)
-{
-    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
-
-    result-&gt;m_type = type;
-    result-&gt;m_structure.set(vm, owner, structure);
-    result-&gt;m_conditionSet = conditionSet;
-
-    return result;
-}
-
-std::unique_ptr&lt;AccessCase&gt; AccessCase::getLength(VM&amp;, JSCell*, AccessType type)
-{
-    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
-
-    result-&gt;m_type = type;
-
-    return result;
-}
-
-std::unique_ptr&lt;AccessCase&gt; AccessCase::getIntrinsic(
-    VM&amp; vm, JSCell* owner, JSFunction* getter, PropertyOffset offset,
-    Structure* structure, const ObjectPropertyConditionSet&amp; conditionSet)
-{
-    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
-
-    result-&gt;m_type = IntrinsicGetter;
-    result-&gt;m_structure.set(vm, owner, structure);
-    result-&gt;m_conditionSet = conditionSet;
-    result-&gt;m_offset = offset;
-
-    result-&gt;m_rareData = std::make_unique&lt;RareData&gt;();
-    result-&gt;m_rareData-&gt;intrinsicFunction.set(vm, owner, getter);
-
-    return result;
-}
-
-AccessCase::~AccessCase()
-{
-}
-
-std::unique_ptr&lt;AccessCase&gt; AccessCase::fromStructureStubInfo(
-    VM&amp; vm, JSCell* owner, StructureStubInfo&amp; stubInfo)
-{
-    switch (stubInfo.cacheType) {
-    case CacheType::GetByIdSelf:
-        return get(
-            vm, owner, Load, stubInfo.u.byIdSelf.offset,
-            stubInfo.u.byIdSelf.baseObjectStructure.get());
-
-    case CacheType::PutByIdReplace:
-        return replace(
-            vm, owner, stubInfo.u.byIdSelf.baseObjectStructure.get(), stubInfo.u.byIdSelf.offset);
-
-    default:
-        return nullptr;
-    }
-}
-
-std::unique_ptr&lt;AccessCase&gt; AccessCase::clone() const
-{
-    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
-    result-&gt;m_type = m_type;
-    result-&gt;m_offset = m_offset;
-    result-&gt;m_structure = m_structure;
-    result-&gt;m_conditionSet = m_conditionSet;
-    if (RareData* rareData = m_rareData.get()) {
-        result-&gt;m_rareData = std::make_unique&lt;RareData&gt;();
-        result-&gt;m_rareData-&gt;viaProxy = rareData-&gt;viaProxy;
-        result-&gt;m_rareData-&gt;additionalSet = rareData-&gt;additionalSet;
-        // NOTE: We don't copy the callLinkInfo, since that's created during code generation.
-        result-&gt;m_rareData-&gt;customAccessor.opaque = rareData-&gt;customAccessor.opaque;
-        result-&gt;m_rareData-&gt;customSlotBase = rareData-&gt;customSlotBase;
-        result-&gt;m_rareData-&gt;intrinsicFunction = rareData-&gt;intrinsicFunction;
-        result-&gt;m_rareData-&gt;domJIT = rareData-&gt;domJIT;
-    }
-    return result;
-}
-
-Vector&lt;WatchpointSet*, 2&gt; AccessCase::commit(VM&amp; vm, const Identifier&amp; ident)
-{
-    // It's fine to commit something that is already committed. That arises when we switch to using
-    // newly allocated watchpoints. When it happens, it's not efficient - but we think that's OK
-    // because most AccessCases have no extra watchpoints anyway.
-    RELEASE_ASSERT(m_state == Primordial || m_state == Committed);
-    
-    Vector&lt;WatchpointSet*, 2&gt; result;
-    
-    if ((structure() &amp;&amp; structure()-&gt;needImpurePropertyWatchpoint())
-        || m_conditionSet.needImpurePropertyWatchpoint())
-        result.append(vm.ensureWatchpointSetForImpureProperty(ident));
-
-    if (additionalSet())
-        result.append(additionalSet());
-    
-    m_state = Committed;
-    
-    return result;
-}
-
-bool AccessCase::guardedByStructureCheck() const
-{
-    if (viaProxy())
-        return false;
-
-    switch (m_type) {
-    case MegamorphicLoad:
-    case ArrayLength:
-    case StringLength:
-    case DirectArgumentsLength:
-    case ScopedArgumentsLength:
-        return false;
-    default:
-        return true;
-    }
-}
-
-JSObject* AccessCase::alternateBase() const
-{
-    if (customSlotBase())
-        return customSlotBase();
-    return conditionSet().slotBaseCondition().object();
-}
-
-bool AccessCase::doesCalls(Vector&lt;JSCell*&gt;* cellsToMark) const
-{
-    switch (type()) {
-    case Getter:
-    case Setter:
-    case CustomValueGetter:
-    case CustomAccessorGetter:
-    case CustomValueSetter:
-    case CustomAccessorSetter:
-        return true;
-    case Transition:
-        if (newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity()
-            &amp;&amp; structure()-&gt;couldHaveIndexingHeader()) {
-            if (cellsToMark)
-                cellsToMark-&gt;append(newStructure());
-            return true;
-        }
-        return false;
-    default:
-        return false;
-    }
-}
-
-bool AccessCase::couldStillSucceed() const
-{
-    return m_conditionSet.structuresEnsureValidityAssumingImpurePropertyWatchpoint();
-}
-
-bool AccessCase::canBeReplacedByMegamorphicLoad() const
-{
-    if (type() == MegamorphicLoad)
-        return true;
-    
-    return type() == Load
-        &amp;&amp; !viaProxy()
-        &amp;&amp; conditionSet().isEmpty()
-        &amp;&amp; !additionalSet()
-        &amp;&amp; !customSlotBase();
-}
-
-bool AccessCase::canReplace(const AccessCase&amp; other) const
-{
-    // This puts in a good effort to try to figure out if 'other' is made superfluous by '*this'.
-    // It's fine for this to return false if it's in doubt.
-
-    switch (type()) {
-    case MegamorphicLoad:
-        return other.canBeReplacedByMegamorphicLoad();
-    case ArrayLength:
-    case StringLength:
-    case DirectArgumentsLength:
-    case ScopedArgumentsLength:
-        return other.type() == type();
-    default:
-        if (!guardedByStructureCheck() || !other.guardedByStructureCheck())
-            return false;
-        
-        return structure() == other.structure();
-    }
-}
-
-void AccessCase::dump(PrintStream&amp; out) const
-{
-    out.print(m_type, &quot;:(&quot;);
-
-    CommaPrinter comma;
-    
-    out.print(comma, m_state);
-
-    if (m_type == Transition)
-        out.print(comma, &quot;structure = &quot;, pointerDump(structure()), &quot; -&gt; &quot;, pointerDump(newStructure()));
-    else if (m_structure)
-        out.print(comma, &quot;structure = &quot;, pointerDump(m_structure.get()));
-
-    if (isValidOffset(m_offset))
-        out.print(comma, &quot;offset = &quot;, m_offset);
-    if (!m_conditionSet.isEmpty())
-        out.print(comma, &quot;conditions = &quot;, m_conditionSet);
-
-    if (RareData* rareData = m_rareData.get()) {
-        if (rareData-&gt;viaProxy)
-            out.print(comma, &quot;viaProxy = &quot;, rareData-&gt;viaProxy);
-        if (rareData-&gt;additionalSet)
-            out.print(comma, &quot;additionalSet = &quot;, RawPointer(rareData-&gt;additionalSet.get()));
-        if (rareData-&gt;callLinkInfo)
-            out.print(comma, &quot;callLinkInfo = &quot;, RawPointer(rareData-&gt;callLinkInfo.get()));
-        if (rareData-&gt;customAccessor.opaque)
-            out.print(comma, &quot;customAccessor = &quot;, RawPointer(rareData-&gt;customAccessor.opaque));
-        if (rareData-&gt;customSlotBase)
-            out.print(comma, &quot;customSlotBase = &quot;, RawPointer(rareData-&gt;customSlotBase.get()));
-    }
-
-    out.print(&quot;)&quot;);
-}
-
-bool AccessCase::visitWeak(VM&amp; vm) const
-{
-    if (m_structure &amp;&amp; !Heap::isMarked(m_structure.get()))
-        return false;
-    if (!m_conditionSet.areStillLive())
-        return false;
-    if (m_rareData) {
-        if (m_rareData-&gt;callLinkInfo)
-            m_rareData-&gt;callLinkInfo-&gt;visitWeak(vm);
-        if (m_rareData-&gt;customSlotBase &amp;&amp; !Heap::isMarked(m_rareData-&gt;customSlotBase.get()))
-            return false;
-        if (m_rareData-&gt;intrinsicFunction &amp;&amp; !Heap::isMarked(m_rareData-&gt;intrinsicFunction.get()))
-            return false;
-    }
-    return true;
-}
-
-bool AccessCase::propagateTransitions(SlotVisitor&amp; visitor) const
-{
-    bool result = true;
-    
-    if (m_structure)
-        result &amp;= m_structure-&gt;markIfCheap(visitor);
-    
-    switch (m_type) {
-    case Transition:
-        if (Heap::isMarkedConcurrently(m_structure-&gt;previousID()))
-            visitor.appendUnbarriered(m_structure.get());
-        else
-            result = false;
-        break;
-    default:
-        break;
-    }
-    
-    return result;
-}
-
-void AccessCase::generateWithGuard(
-    AccessGenerationState&amp; state, CCallHelpers::JumpList&amp; fallThrough)
-{
-    SuperSamplerScope superSamplerScope(false);
-
-    RELEASE_ASSERT(m_state == Committed);
-    m_state = Generated;
-    
-    CCallHelpers&amp; jit = *state.jit;
-    VM&amp; vm = *jit.vm();
-    const Identifier&amp; ident = *state.ident;
-    StructureStubInfo&amp; stubInfo = *state.stubInfo;
-    JSValueRegs valueRegs = state.valueRegs;
-    GPRReg baseGPR = state.baseGPR;
-    GPRReg scratchGPR = state.scratchGPR;
-    
-    UNUSED_PARAM(vm);
-
-    switch (m_type) {
-    case ArrayLength: {
-        ASSERT(!viaProxy());
-        jit.load8(CCallHelpers::Address(baseGPR, JSCell::indexingTypeAndMiscOffset()), scratchGPR);
-        fallThrough.append(
-            jit.branchTest32(
-                CCallHelpers::Zero, scratchGPR, CCallHelpers::TrustedImm32(IsArray)));
-        fallThrough.append(
-            jit.branchTest32(
-                CCallHelpers::Zero, scratchGPR, CCallHelpers::TrustedImm32(IndexingShapeMask)));
-        break;
-    }
-
-    case StringLength: {
-        ASSERT(!viaProxy());
-        fallThrough.append(
-            jit.branch8(
-                CCallHelpers::NotEqual,
-                CCallHelpers::Address(baseGPR, JSCell::typeInfoTypeOffset()),
-                CCallHelpers::TrustedImm32(StringType)));
-        break;
-    }
-        
-    case DirectArgumentsLength: {
-        ASSERT(!viaProxy());
-        fallThrough.append(
-            jit.branch8(
-                CCallHelpers::NotEqual,
-                CCallHelpers::Address(baseGPR, JSCell::typeInfoTypeOffset()),
-                CCallHelpers::TrustedImm32(DirectArgumentsType)));
-
-        fallThrough.append(
-            jit.branchTestPtr(
-                CCallHelpers::NonZero,
-                CCallHelpers::Address(baseGPR, DirectArguments::offsetOfMappedArguments())));
-        jit.load32(
-            CCallHelpers::Address(baseGPR, DirectArguments::offsetOfLength()),
-            valueRegs.payloadGPR());
-        jit.boxInt32(valueRegs.payloadGPR(), valueRegs);
-        state.succeed();
-        return;
-    }
-        
-    case ScopedArgumentsLength: {
-        ASSERT(!viaProxy());
-        fallThrough.append(
-            jit.branch8(
-                CCallHelpers::NotEqual,
-                CCallHelpers::Address(baseGPR, JSCell::typeInfoTypeOffset()),
-                CCallHelpers::TrustedImm32(ScopedArgumentsType)));
-
-        fallThrough.append(
-            jit.branchTest8(
-                CCallHelpers::NonZero,
-                CCallHelpers::Address(baseGPR, ScopedArguments::offsetOfOverrodeThings())));
-        jit.load32(
-            CCallHelpers::Address(baseGPR, ScopedArguments::offsetOfTotalLength()),
-            valueRegs.payloadGPR());
-        jit.boxInt32(valueRegs.payloadGPR(), valueRegs);
-        state.succeed();
-        return;
-    }
-        
-    case MegamorphicLoad: {
-        UniquedStringImpl* key = ident.impl();
-        unsigned hash = IdentifierRepHash::hash(key);
-        
-        ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
-        allocator.lock(baseGPR);
-#if USE(JSVALUE32_64)
-        allocator.lock(static_cast&lt;GPRReg&gt;(stubInfo.patch.baseTagGPR));
-#endif
-        allocator.lock(valueRegs);
-        allocator.lock(scratchGPR);
-        
-        GPRReg intermediateGPR = scratchGPR;
-        GPRReg maskGPR = allocator.allocateScratchGPR();
-        GPRReg maskedHashGPR = allocator.allocateScratchGPR();
-        GPRReg indexGPR = allocator.allocateScratchGPR();
-        GPRReg offsetGPR = allocator.allocateScratchGPR();
-        
-        if (verbose) {
-            dataLog(&quot;baseGPR = &quot;, baseGPR, &quot;\n&quot;);
-            dataLog(&quot;valueRegs = &quot;, valueRegs, &quot;\n&quot;);
-            dataLog(&quot;scratchGPR = &quot;, scratchGPR, &quot;\n&quot;);
-            dataLog(&quot;intermediateGPR = &quot;, intermediateGPR, &quot;\n&quot;);
-            dataLog(&quot;maskGPR = &quot;, maskGPR, &quot;\n&quot;);
-            dataLog(&quot;maskedHashGPR = &quot;, maskedHashGPR, &quot;\n&quot;);
-            dataLog(&quot;indexGPR = &quot;, indexGPR, &quot;\n&quot;);
-            dataLog(&quot;offsetGPR = &quot;, offsetGPR, &quot;\n&quot;);
-        }
-
-        ScratchRegisterAllocator::PreservedState preservedState =
-            allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
-
-        CCallHelpers::JumpList myFailAndIgnore;
-        CCallHelpers::JumpList myFallThrough;
-        
-        jit.emitLoadStructure(baseGPR, intermediateGPR, maskGPR);
-        jit.loadPtr(
-            CCallHelpers::Address(intermediateGPR, Structure::propertyTableUnsafeOffset()),
-            intermediateGPR);
-        
-        myFailAndIgnore.append(jit.branchTestPtr(CCallHelpers::Zero, intermediateGPR));
-        
-        jit.load32(CCallHelpers::Address(intermediateGPR, PropertyTable::offsetOfIndexMask()), maskGPR);
-        jit.loadPtr(CCallHelpers::Address(intermediateGPR, PropertyTable::offsetOfIndex()), indexGPR);
-        jit.load32(
-            CCallHelpers::Address(intermediateGPR, PropertyTable::offsetOfIndexSize()),
-            intermediateGPR);
-
-        jit.move(maskGPR, maskedHashGPR);
-        jit.and32(CCallHelpers::TrustedImm32(hash), maskedHashGPR);
-        jit.lshift32(CCallHelpers::TrustedImm32(2), intermediateGPR);
-        jit.addPtr(indexGPR, intermediateGPR);
-        
-        CCallHelpers::Label loop = jit.label();
-        
-        jit.load32(CCallHelpers::BaseIndex(indexGPR, maskedHashGPR, CCallHelpers::TimesFour), offsetGPR);
-        
-        myFallThrough.append(
-            jit.branch32(
-                CCallHelpers::Equal,
-                offsetGPR,
-                CCallHelpers::TrustedImm32(PropertyTable::EmptyEntryIndex)));
-        
-        jit.sub32(CCallHelpers::TrustedImm32(1), offsetGPR);
-        jit.mul32(CCallHelpers::TrustedImm32(sizeof(PropertyMapEntry)), offsetGPR, offsetGPR);
-        jit.addPtr(intermediateGPR, offsetGPR);
-        
-        CCallHelpers::Jump collision =  jit.branchPtr(
-            CCallHelpers::NotEqual,
-            CCallHelpers::Address(offsetGPR, OBJECT_OFFSETOF(PropertyMapEntry, key)),
-            CCallHelpers::TrustedImmPtr(key));
-        
-        // offsetGPR currently holds a pointer to the PropertyMapEntry, which has the offset and attributes.
-        // Check them and then attempt the load.
-        
-        myFallThrough.append(
-            jit.branchTest32(
-                CCallHelpers::NonZero,
-                CCallHelpers::Address(offsetGPR, OBJECT_OFFSETOF(PropertyMapEntry, attributes)),
-                CCallHelpers::TrustedImm32(Accessor | CustomAccessor)));
-        
-        jit.load32(CCallHelpers::Address(offsetGPR, OBJECT_OFFSETOF(PropertyMapEntry, offset)), offsetGPR);
-        
-        jit.loadProperty(baseGPR, offsetGPR, valueRegs);
-        
-        allocator.restoreReusedRegistersByPopping(jit, preservedState);
-        state.succeed();
-        
-        collision.link(&amp;jit);
-
-        jit.add32(CCallHelpers::TrustedImm32(1), maskedHashGPR);
-        
-        // FIXME: We could be smarter about this. Currently we're burning a GPR for the mask. But looping
-        // around isn't super common so we could, for example, recompute the mask from the difference between
-        // the table and index. But before we do that we should probably make it easier to multiply and
-        // divide by the size of PropertyMapEntry. That probably involves making PropertyMapEntry be arranged
-        // to have a power-of-2 size.
-        jit.and32(maskGPR, maskedHashGPR);
-        jit.jump().linkTo(loop, &amp;jit);
-        
-        if (allocator.didReuseRegisters()) {
-            myFailAndIgnore.link(&amp;jit);
-            allocator.restoreReusedRegistersByPopping(jit, preservedState);
-            state.failAndIgnore.append(jit.jump());
-            
-            myFallThrough.link(&amp;jit);
-            allocator.restoreReusedRegistersByPopping(jit, preservedState);
-            fallThrough.append(jit.jump());
-        } else {
-            state.failAndIgnore.append(myFailAndIgnore);
-            fallThrough.append(myFallThrough);
-        }
-        return;
-    }
-
-    default: {
-        if (viaProxy()) {
-            fallThrough.append(
-                jit.branch8(
-                    CCallHelpers::NotEqual,
-                    CCallHelpers::Address(baseGPR, JSCell::typeInfoTypeOffset()),
-                    CCallHelpers::TrustedImm32(PureForwardingProxyType)));
-
-            jit.loadPtr(CCallHelpers::Address(baseGPR, JSProxy::targetOffset()), scratchGPR);
-
-            fallThrough.append(
-                jit.branchStructure(
-                    CCallHelpers::NotEqual,
-                    CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()),
-                    structure()));
-        } else {
-            fallThrough.append(
-                jit.branchStructure(
-                    CCallHelpers::NotEqual,
-                    CCallHelpers::Address(baseGPR, JSCell::structureIDOffset()),
-                    structure()));
-        }
-        break;
-    } };
-
-    generateImpl(state);
-}
-
-void AccessCase::generate(AccessGenerationState&amp; state)
-{
-    RELEASE_ASSERT(m_state == Committed);
-    m_state = Generated;
-    
-    generateImpl(state);
-}
-
-void AccessCase::generateImpl(AccessGenerationState&amp; state)
-{
-    SuperSamplerScope superSamplerScope(false);
-    if (verbose)
-        dataLog(&quot;Generating code for: &quot;, *this, &quot;\n&quot;);
-    
-    ASSERT(m_state == Generated); // We rely on the callers setting this for us.
-    
-    CCallHelpers&amp; jit = *state.jit;
-    VM&amp; vm = *jit.vm();
-    CodeBlock* codeBlock = jit.codeBlock();
-    StructureStubInfo&amp; stubInfo = *state.stubInfo;
-    const Identifier&amp; ident = *state.ident;
-    JSValueRegs valueRegs = state.valueRegs;
-    GPRReg baseGPR = state.baseGPR;
-    GPRReg scratchGPR = state.scratchGPR;
-
-    ASSERT(m_conditionSet.structuresEnsureValidityAssumingImpurePropertyWatchpoint());
-
-    for (const ObjectPropertyCondition&amp; condition : m_conditionSet) {
-        Structure* structure = condition.object()-&gt;structure();
-
-        if (condition.isWatchableAssumingImpurePropertyWatchpoint()) {
-            structure-&gt;addTransitionWatchpoint(state.addWatchpoint(condition));
-            continue;
-        }
-
-        if (!condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint(structure)) {
-            // The reason why this cannot happen is that we require that PolymorphicAccess calls
-            // AccessCase::generate() only after it has verified that
-            // AccessCase::couldStillSucceed() returned true.
-            
-            dataLog(&quot;This condition is no longer met: &quot;, condition, &quot;\n&quot;);
-            RELEASE_ASSERT_NOT_REACHED();
-        }
-
-        // We will emit code that has a weak reference that isn't otherwise listed anywhere.
-        state.weakReferences.append(WriteBarrier&lt;JSCell&gt;(vm, codeBlock, structure));
-        
-        jit.move(CCallHelpers::TrustedImmPtr(condition.object()), scratchGPR);
-        state.failAndRepatch.append(
-            jit.branchStructure(
-                CCallHelpers::NotEqual,
-                CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()),
-                structure));
-    }
-
-    switch (m_type) {
-    case InHit:
-    case InMiss:
-        jit.boxBooleanPayload(m_type == InHit, valueRegs.payloadGPR());
-        state.succeed();
-        return;
-
-    case Miss:
-        jit.moveTrustedValue(jsUndefined(), valueRegs);
-        state.succeed();
-        return;
-
-    case Load:
-    case GetGetter:
-    case Getter:
-    case Setter:
-    case CustomValueGetter:
-    case CustomAccessorGetter:
-    case CustomValueSetter:
-    case CustomAccessorSetter: {
-        GPRReg valueRegsPayloadGPR = valueRegs.payloadGPR();
-        
-        if (isValidOffset(m_offset)) {
-            Structure* currStructure;
-            if (m_conditionSet.isEmpty())
-                currStructure = structure();
-            else
-                currStructure = m_conditionSet.slotBaseCondition().object()-&gt;structure();
-            currStructure-&gt;startWatchingPropertyForReplacements(vm, offset());
-        }
-
-        GPRReg baseForGetGPR;
-        if (viaProxy()) {
-            ASSERT(m_type != CustomValueSetter || m_type != CustomAccessorSetter); // Because setters need to not trash valueRegsPayloadGPR.
-            if (m_type == Getter || m_type == Setter)
-                baseForGetGPR = scratchGPR;
-            else
-                baseForGetGPR = valueRegsPayloadGPR;
-
-            ASSERT((m_type != Getter &amp;&amp; m_type != Setter) || baseForGetGPR != baseGPR);
-            ASSERT(m_type != Setter || baseForGetGPR != valueRegsPayloadGPR);
-
-            jit.loadPtr(
-                CCallHelpers::Address(baseGPR, JSProxy::targetOffset()),
-                baseForGetGPR);
-        } else
-            baseForGetGPR = baseGPR;
-
-        GPRReg baseForAccessGPR;
-        if (!m_conditionSet.isEmpty()) {
-            jit.move(
-                CCallHelpers::TrustedImmPtr(alternateBase()),
-                scratchGPR);
-            baseForAccessGPR = scratchGPR;
-        } else
-            baseForAccessGPR = baseForGetGPR;
-
-        GPRReg loadedValueGPR = InvalidGPRReg;
-        if (m_type != CustomValueGetter &amp;&amp; m_type != CustomAccessorGetter &amp;&amp; m_type != CustomValueSetter &amp;&amp; m_type != CustomAccessorSetter) {
-            if (m_type == Load || m_type == GetGetter)
-                loadedValueGPR = valueRegsPayloadGPR;
-            else
-                loadedValueGPR = scratchGPR;
-
-            ASSERT((m_type != Getter &amp;&amp; m_type != Setter) || loadedValueGPR != baseGPR);
-            ASSERT(m_type != Setter || loadedValueGPR != valueRegsPayloadGPR);
-
-            GPRReg storageGPR;
-            if (isInlineOffset(m_offset))
-                storageGPR = baseForAccessGPR;
-            else {
-                jit.loadPtr(
-                    CCallHelpers::Address(baseForAccessGPR, JSObject::butterflyOffset()),
-                    loadedValueGPR);
-                storageGPR = loadedValueGPR;
-            }
-
-#if USE(JSVALUE64)
-            jit.load64(
-                CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset)), loadedValueGPR);
-#else
-            if (m_type == Load || m_type == GetGetter) {
-                jit.load32(
-                    CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + TagOffset),
-                    valueRegs.tagGPR());
-            }
-            jit.load32(
-                CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + PayloadOffset),
-                loadedValueGPR);
-#endif
-        }
-
-        if (m_type == Load || m_type == GetGetter) {
-            state.succeed();
-            return;
-        }
-
-        if (Options::useDOMJIT() &amp;&amp; m_type == CustomAccessorGetter &amp;&amp; m_rareData-&gt;domJIT) {
-            // We do not need to emit CheckDOM operation since structure check ensures
-            // that the structure of the given base value is structure()! So all we should
-            // do is performing the CheckDOM thingy in IC compiling time here.
-            if (structure()-&gt;classInfo()-&gt;isSubClassOf(m_rareData-&gt;domJIT-&gt;thisClassInfo())) {
-                emitDOMJITGetter(state, baseForGetGPR);
-                return;
-            }
-        }
-
-        // Stuff for custom getters/setters.
-        CCallHelpers::Call operationCall;
-
-        // Stuff for JS getters/setters.
-        CCallHelpers::DataLabelPtr addressOfLinkFunctionCheck;
-        CCallHelpers::Call fastPathCall;
-        CCallHelpers::Call slowPathCall;
-
-        // This also does the necessary calculations of whether or not we're an
-        // exception handling call site.
-        AccessGenerationState::SpillState spillState = state.preserveLiveRegistersToStackForCall();
-
-        auto restoreLiveRegistersFromStackForCall = [&amp;](AccessGenerationState::SpillState&amp; spillState, bool callHasReturnValue) {
-            RegisterSet dontRestore;
-            if (callHasReturnValue) {
-                // This is the result value. We don't want to overwrite the result with what we stored to the stack.
-                // We sometimes have to store it to the stack just in case we throw an exception and need the original value.
-                dontRestore.set(valueRegs);
-            }
-            state.restoreLiveRegistersFromStackForCall(spillState, dontRestore);
-        };
-
-        jit.store32(
-            CCallHelpers::TrustedImm32(state.callSiteIndexForExceptionHandlingOrOriginal().bits()),
-            CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(CallFrameSlot::argumentCount)));
-
-        if (m_type == Getter || m_type == Setter) {
-            ASSERT(baseGPR != loadedValueGPR);
-            ASSERT(m_type != Setter || (baseGPR != valueRegsPayloadGPR &amp;&amp; loadedValueGPR != valueRegsPayloadGPR));
-
-            // Create a JS call using a JS call inline cache. Assume that:
-            //
-            // - SP is aligned and represents the extent of the calling compiler's stack usage.
-            //
-            // - FP is set correctly (i.e. it points to the caller's call frame header).
-            //
-            // - SP - FP is an aligned difference.
-            //
-            // - Any byte between FP (exclusive) and SP (inclusive) could be live in the calling
-            //   code.
-            //
-            // Therefore, we temporarily grow the stack for the purpose of the call and then
-            // shrink it after.
-
-            state.setSpillStateForJSGetterSetter(spillState);
-
-            RELEASE_ASSERT(!m_rareData-&gt;callLinkInfo);
-            m_rareData-&gt;callLinkInfo = std::make_unique&lt;CallLinkInfo&gt;();
-            
-            // FIXME: If we generated a polymorphic call stub that jumped back to the getter
-            // stub, which then jumped back to the main code, then we'd have a reachability
-            // situation that the GC doesn't know about. The GC would ensure that the polymorphic
-            // call stub stayed alive, and it would ensure that the main code stayed alive, but
-            // it wouldn't know that the getter stub was alive. Ideally JIT stub routines would
-            // be GC objects, and then we'd be able to say that the polymorphic call stub has a
-            // reference to the getter stub.
-            // https://bugs.webkit.org/show_bug.cgi?id=148914
-            m_rareData-&gt;callLinkInfo-&gt;disallowStubs();
-            
-            m_rareData-&gt;callLinkInfo-&gt;setUpCall(
-                CallLinkInfo::Call, stubInfo.codeOrigin, loadedValueGPR);
-
-            CCallHelpers::JumpList done;
-
-            // There is a &quot;this&quot; argument.
-            unsigned numberOfParameters = 1;
-            // ... and a value argument if we're calling a setter.
-            if (m_type == Setter)
-                numberOfParameters++;
-
-            // Get the accessor; if there ain't one then the result is jsUndefined().
-            if (m_type == Setter) {
-                jit.loadPtr(
-                    CCallHelpers::Address(loadedValueGPR, GetterSetter::offsetOfSetter()),
-                    loadedValueGPR);
-            } else {
-                jit.loadPtr(
-                    CCallHelpers::Address(loadedValueGPR, GetterSetter::offsetOfGetter()),
-                    loadedValueGPR);
-            }
-
-            CCallHelpers::Jump returnUndefined = jit.branchTestPtr(
-                CCallHelpers::Zero, loadedValueGPR);
-
-            unsigned numberOfRegsForCall = CallFrame::headerSizeInRegisters + numberOfParameters;
-
-            unsigned numberOfBytesForCall =
-                numberOfRegsForCall * sizeof(Register) - sizeof(CallerFrameAndPC);
-
-            unsigned alignedNumberOfBytesForCall =
-                WTF::roundUpToMultipleOf(stackAlignmentBytes(), numberOfBytesForCall);
-
-            jit.subPtr(
-                CCallHelpers::TrustedImm32(alignedNumberOfBytesForCall),
-                CCallHelpers::stackPointerRegister);
-
-            CCallHelpers::Address calleeFrame = CCallHelpers::Address(
-                CCallHelpers::stackPointerRegister,
-                -static_cast&lt;ptrdiff_t&gt;(sizeof(CallerFrameAndPC)));
-
-            jit.store32(
-                CCallHelpers::TrustedImm32(numberOfParameters),
-                calleeFrame.withOffset(CallFrameSlot::argumentCount * sizeof(Register) + PayloadOffset));
-
-            jit.storeCell(
-                loadedValueGPR, calleeFrame.withOffset(CallFrameSlot::callee * sizeof(Register)));
-
-            jit.storeCell(
-                baseGPR,
-                calleeFrame.withOffset(virtualRegisterForArgument(0).offset() * sizeof(Register)));
-
-            if (m_type == Setter) {
-                jit.storeValue(
-                    valueRegs,
-                    calleeFrame.withOffset(
-                        virtualRegisterForArgument(1).offset() * sizeof(Register)));
-            }
-
-            CCallHelpers::Jump slowCase = jit.branchPtrWithPatch(
-                CCallHelpers::NotEqual, loadedValueGPR, addressOfLinkFunctionCheck,
-                CCallHelpers::TrustedImmPtr(0));
-
-            fastPathCall = jit.nearCall();
-            if (m_type == Getter)
-                jit.setupResults(valueRegs);
-            done.append(jit.jump());
-
-            slowCase.link(&amp;jit);
-            jit.move(loadedValueGPR, GPRInfo::regT0);
-#if USE(JSVALUE32_64)
-            // We *always* know that the getter/setter, if non-null, is a cell.
-            jit.move(CCallHelpers::TrustedImm32(JSValue::CellTag), GPRInfo::regT1);
-#endif
-            jit.move(CCallHelpers::TrustedImmPtr(m_rareData-&gt;callLinkInfo.get()), GPRInfo::regT2);
-            slowPathCall = jit.nearCall();
-            if (m_type == Getter)
-                jit.setupResults(valueRegs);
-            done.append(jit.jump());
-
-            returnUndefined.link(&amp;jit);
-            if (m_type == Getter)
-                jit.moveTrustedValue(jsUndefined(), valueRegs);
-
-            done.link(&amp;jit);
-
-            jit.addPtr(CCallHelpers::TrustedImm32((codeBlock-&gt;stackPointerOffset() * sizeof(Register)) - state.preservedReusedRegisterState.numberOfBytesPreserved - spillState.numberOfStackBytesUsedForRegisterPreservation),
-                GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);
-            bool callHasReturnValue = isGetter();
-            restoreLiveRegistersFromStackForCall(spillState, callHasReturnValue);
-
-            jit.addLinkTask(
-                [=, &amp;vm] (LinkBuffer&amp; linkBuffer) {
-                    m_rareData-&gt;callLinkInfo-&gt;setCallLocations(
-                        CodeLocationLabel(linkBuffer.locationOfNearCall(slowPathCall)),
-                        CodeLocationLabel(linkBuffer.locationOf(addressOfLinkFunctionCheck)),
-                        linkBuffer.locationOfNearCall(fastPathCall));
-
-                    linkBuffer.link(
-                        slowPathCall,
-                        CodeLocationLabel(vm.getCTIStub(linkCallThunkGenerator).code()));
-                });
-        } else {
-            ASSERT(m_type == CustomValueGetter || m_type == CustomAccessorGetter || m_type == CustomValueSetter || m_type == CustomAccessorSetter);
-
-            // Need to make room for the C call so any of our stack spillage isn't overwritten. It's
-            // hard to track if someone did spillage or not, so we just assume that we always need
-            // to make some space here.
-            jit.makeSpaceOnStackForCCall();
-
-            // getter: EncodedJSValue (*GetValueFunc)(ExecState*, EncodedJSValue thisValue, PropertyName);
-            // setter: void (*PutValueFunc)(ExecState*, EncodedJSValue thisObject, EncodedJSValue value);
-            // Custom values are passed the slotBase (the property holder), custom accessors are passed the thisVaule (reciever).
-            // FIXME: Remove this differences in custom values and custom accessors.
-            // https://bugs.webkit.org/show_bug.cgi?id=158014
-            GPRReg baseForCustomValue = m_type == CustomValueGetter || m_type == CustomValueSetter ? baseForAccessGPR : baseForGetGPR;
-#if USE(JSVALUE64)
-            if (m_type == CustomValueGetter || m_type == CustomAccessorGetter) {
-                jit.setupArgumentsWithExecState(
-                    baseForCustomValue,
-                    CCallHelpers::TrustedImmPtr(ident.impl()));
-            } else
-                jit.setupArgumentsWithExecState(baseForCustomValue, valueRegs.gpr());
-#else
-            if (m_type == CustomValueGetter || m_type == CustomAccessorGetter) {
-                jit.setupArgumentsWithExecState(
-                    EABI_32BIT_DUMMY_ARG baseForCustomValue,
-                    CCallHelpers::TrustedImm32(JSValue::CellTag),
-                    CCallHelpers::TrustedImmPtr(ident.impl()));
-            } else {
-                jit.setupArgumentsWithExecState(
-                    EABI_32BIT_DUMMY_ARG baseForCustomValue,
-                    CCallHelpers::TrustedImm32(JSValue::CellTag),
-                    valueRegs.payloadGPR(), valueRegs.tagGPR());
-            }
-#endif
-            jit.storePtr(GPRInfo::callFrameRegister, &amp;vm.topCallFrame);
-
-            operationCall = jit.call();
-            jit.addLinkTask(
-                [=] (LinkBuffer&amp; linkBuffer) {
-                    linkBuffer.link(operationCall, FunctionPtr(m_rareData-&gt;customAccessor.opaque));
-                });
-
-            if (m_type == CustomValueGetter || m_type == CustomAccessorGetter)
-                jit.setupResults(valueRegs);
-            jit.reclaimSpaceOnStackForCCall();
-
-            CCallHelpers::Jump noException =
-                jit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck);
-
-            state.restoreLiveRegistersFromStackForCallWithThrownException(spillState);
-            state.emitExplicitExceptionHandler();
-        
-            noException.link(&amp;jit);
-            bool callHasReturnValue = isGetter();
-            restoreLiveRegistersFromStackForCall(spillState, callHasReturnValue);
-        }
-        state.succeed();
-        return;
-    }
-
-    case Replace: {
-        if (InferredType* type = structure()-&gt;inferredTypeFor(ident.impl())) {
-            if (verbose)
-                dataLog(&quot;Have type: &quot;, type-&gt;descriptor(), &quot;\n&quot;);
-            state.failAndRepatch.append(
-                jit.branchIfNotType(valueRegs, scratchGPR, type-&gt;descriptor()));
-        } else if (verbose)
-            dataLog(&quot;Don't have type.\n&quot;);
-        
-        if (isInlineOffset(m_offset)) {
-            jit.storeValue(
-                valueRegs,
-                CCallHelpers::Address(
-                    baseGPR,
-                    JSObject::offsetOfInlineStorage() +
-                    offsetInInlineStorage(m_offset) * sizeof(JSValue)));
-        } else {
-            jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR);
-            jit.storeValue(
-                valueRegs,
-                CCallHelpers::Address(
-                    scratchGPR, offsetInButterfly(m_offset) * sizeof(JSValue)));
-        }
-        state.succeed();
-        return;
-    }
-
-    case Transition: {
-        // AccessCase::transition() should have returned null if this wasn't true.
-        RELEASE_ASSERT(GPRInfo::numberOfRegisters &gt;= 6 || !structure()-&gt;outOfLineCapacity() || structure()-&gt;outOfLineCapacity() == newStructure()-&gt;outOfLineCapacity());
-
-        if (InferredType* type = newStructure()-&gt;inferredTypeFor(ident.impl())) {
-            if (verbose)
-                dataLog(&quot;Have type: &quot;, type-&gt;descriptor(), &quot;\n&quot;);
-            state.failAndRepatch.append(
-                jit.branchIfNotType(valueRegs, scratchGPR, type-&gt;descriptor()));
-        } else if (verbose)
-            dataLog(&quot;Don't have type.\n&quot;);
-        
-        // NOTE: This logic is duplicated in AccessCase::doesCalls(). It's important that doesCalls() knows
-        // exactly when this would make calls.
-        bool allocating = newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity();
-        bool reallocating = allocating &amp;&amp; structure()-&gt;outOfLineCapacity();
-        bool allocatingInline = allocating &amp;&amp; !structure()-&gt;couldHaveIndexingHeader();
-
-        ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
-        allocator.lock(baseGPR);
-#if USE(JSVALUE32_64)
-        allocator.lock(static_cast&lt;GPRReg&gt;(stubInfo.patch.baseTagGPR));
-#endif
-        allocator.lock(valueRegs);
-        allocator.lock(scratchGPR);
-
-        GPRReg scratchGPR2 = InvalidGPRReg;
-        GPRReg scratchGPR3 = InvalidGPRReg;
-        if (allocatingInline) {
-            scratchGPR2 = allocator.allocateScratchGPR();
-            scratchGPR3 = allocator.allocateScratchGPR();
-        }
-
-        ScratchRegisterAllocator::PreservedState preservedState =
-            allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
-        
-        CCallHelpers::JumpList slowPath;
-
-        ASSERT(structure()-&gt;transitionWatchpointSetHasBeenInvalidated());
-
-        if (allocating) {
-            size_t newSize = newStructure()-&gt;outOfLineCapacity() * sizeof(JSValue);
-            
-            if (allocatingInline) {
-                MarkedAllocator* allocator = vm.auxiliarySpace.allocatorFor(newSize);
-                
-                if (!allocator) {
-                    // Yuck, this case would suck!
-                    slowPath.append(jit.jump());
-                }
-                
-                jit.move(CCallHelpers::TrustedImmPtr(allocator), scratchGPR2);
-                jit.emitAllocate(scratchGPR, allocator, scratchGPR2, scratchGPR3, slowPath);
-                jit.addPtr(CCallHelpers::TrustedImm32(newSize + sizeof(IndexingHeader)), scratchGPR);
-                
-                size_t oldSize = structure()-&gt;outOfLineCapacity() * sizeof(JSValue);
-                ASSERT(newSize &gt; oldSize);
-                
-                if (reallocating) {
-                    // Handle the case where we are reallocating (i.e. the old structure/butterfly
-                    // already had out-of-line property storage).
-                    
-                    jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR3);
-                    
-                    // We have scratchGPR = new storage, scratchGPR3 = old storage,
-                    // scratchGPR2 = available
-                    for (size_t offset = 0; offset &lt; oldSize; offset += sizeof(void*)) {
-                        jit.loadPtr(
-                            CCallHelpers::Address(
-                                scratchGPR3,
-                                -static_cast&lt;ptrdiff_t&gt;(
-                                    offset + sizeof(JSValue) + sizeof(void*))),
-                            scratchGPR2);
-                        jit.storePtr(
-                            scratchGPR2,
-                            CCallHelpers::Address(
-                                scratchGPR,
-                                -static_cast&lt;ptrdiff_t&gt;(offset + sizeof(JSValue) + sizeof(void*))));
-                    }
-                }
-                
-                for (size_t offset = oldSize; offset &lt; newSize; offset += sizeof(void*))
-                    jit.storePtr(CCallHelpers::TrustedImmPtr(0), CCallHelpers::Address(scratchGPR, -static_cast&lt;ptrdiff_t&gt;(offset + sizeof(JSValue) + sizeof(void*))));
-            } else {
-                // Handle the case where we are allocating out-of-line using an operation.
-                RegisterSet extraRegistersToPreserve;
-                extraRegistersToPreserve.set(baseGPR);
-                extraRegistersToPreserve.set(valueRegs);
-                AccessGenerationState::SpillState spillState = state.preserveLiveRegistersToStackForCall(extraRegistersToPreserve);
-                
-                jit.store32(
-                    CCallHelpers::TrustedImm32(
-                        state.callSiteIndexForExceptionHandlingOrOriginal().bits()),
-                    CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(CallFrameSlot::argumentCount)));
-                
-                jit.makeSpaceOnStackForCCall();
-                
-                if (!reallocating) {
-                    jit.setupArgumentsWithExecState(baseGPR);
-                    
-                    CCallHelpers::Call operationCall = jit.call();
-                    jit.addLinkTask(
-                        [=] (LinkBuffer&amp; linkBuffer) {
-                            linkBuffer.link(
-                                operationCall,
-                                FunctionPtr(operationReallocateButterflyToHavePropertyStorageWithInitialCapacity));
-                        });
-                } else {
-                    // Handle the case where we are reallocating (i.e. the old structure/butterfly
-                    // already had out-of-line property storage).
-                    jit.setupArgumentsWithExecState(
-                        baseGPR, CCallHelpers::TrustedImm32(newSize / sizeof(JSValue)));
-                    
-                    CCallHelpers::Call operationCall = jit.call();
-                    jit.addLinkTask(
-                        [=] (LinkBuffer&amp; linkBuffer) {
-                            linkBuffer.link(
-                                operationCall,
-                                FunctionPtr(operationReallocateButterflyToGrowPropertyStorage));
-                        });
-                }
-                
-                jit.reclaimSpaceOnStackForCCall();
-                jit.move(GPRInfo::returnValueGPR, scratchGPR);
-                
-                CCallHelpers::Jump noException =
-                    jit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck);
-                
-                state.restoreLiveRegistersFromStackForCallWithThrownException(spillState);
-                state.emitExplicitExceptionHandler();
-                
-                noException.link(&amp;jit);
-                state.restoreLiveRegistersFromStackForCall(spillState);
-            }
-        }
-
-        if (isInlineOffset(m_offset)) {
-            jit.storeValue(
-                valueRegs,
-                CCallHelpers::Address(
-                    baseGPR,
-                    JSObject::offsetOfInlineStorage() +
-                    offsetInInlineStorage(m_offset) * sizeof(JSValue)));
-        } else {
-            if (!allocating)
-                jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR);
-            jit.storeValue(
-                valueRegs,
-                CCallHelpers::Address(scratchGPR, offsetInButterfly(m_offset) * sizeof(JSValue)));
-        }
-        
-        if (allocatingInline) {
-            // We set the new butterfly and the structure last. Doing it this way ensures that
-            // whatever we had done up to this point is forgotten if we choose to branch to slow
-            // path.
-            jit.nukeStructureAndStoreButterfly(scratchGPR, baseGPR);
-        }
-        
-        uint32_t structureBits = bitwise_cast&lt;uint32_t&gt;(newStructure()-&gt;id());
-        jit.store32(
-            CCallHelpers::TrustedImm32(structureBits),
-            CCallHelpers::Address(baseGPR, JSCell::structureIDOffset()));
-
-        allocator.restoreReusedRegistersByPopping(jit, preservedState);
-        state.succeed();
-        
-        // We will have a slow path if we were allocating without the help of an operation.
-        if (allocatingInline) {
-            if (allocator.didReuseRegisters()) {
-                slowPath.link(&amp;jit);
-                allocator.restoreReusedRegistersByPopping(jit, preservedState);
-                state.failAndIgnore.append(jit.jump());
-            } else
-                state.failAndIgnore.append(slowPath);
-        } else
-            RELEASE_ASSERT(slowPath.empty());
-        return;
-    }
-
-    case ArrayLength: {
-        jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR);
-        jit.load32(CCallHelpers::Address(scratchGPR, ArrayStorage::lengthOffset()), scratchGPR);
-        state.failAndIgnore.append(
-            jit.branch32(CCallHelpers::LessThan, scratchGPR, CCallHelpers::TrustedImm32(0)));
-        jit.boxInt32(scratchGPR, valueRegs);
-        state.succeed();
-        return;
-    }
-
-    case StringLength: {
-        jit.load32(CCallHelpers::Address(baseGPR, JSString::offsetOfLength()), valueRegs.payloadGPR());
-        jit.boxInt32(valueRegs.payloadGPR(), valueRegs);
-        state.succeed();
-        return;
-    }
-        
-    case IntrinsicGetter: {
-        RELEASE_ASSERT(isValidOffset(offset()));
-
-        // We need to ensure the getter value does not move from under us. Note that GetterSetters
-        // are immutable so we just need to watch the property not any value inside it.
-        Structure* currStructure;
-        if (m_conditionSet.isEmpty())
-            currStructure = structure();
-        else
-            currStructure = m_conditionSet.slotBaseCondition().object()-&gt;structure();
-        currStructure-&gt;startWatchingPropertyForReplacements(vm, offset());
-
-        emitIntrinsicGetter(state);
-        return;
-    }
-
-    case DirectArgumentsLength:
-    case ScopedArgumentsLength:
-    case MegamorphicLoad:
-        // These need to be handled by generateWithGuard(), since the guard is part of the
-        // algorithm. We can be sure that nobody will call generate() directly for these since they
-        // are not guarded by structure checks.
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-    
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-void AccessCase::emitDOMJITGetter(AccessGenerationState&amp; state, GPRReg baseForGetGPR)
-{
-    CCallHelpers&amp; jit = *state.jit;
-    StructureStubInfo&amp; stubInfo = *state.stubInfo;
-    JSValueRegs valueRegs = state.valueRegs;
-    GPRReg baseGPR = state.baseGPR;
-    GPRReg scratchGPR = state.scratchGPR;
-
-    // We construct the environment that can execute the DOMJIT::Patchpoint here.
-    Ref&lt;DOMJIT::CallDOMGetterPatchpoint&gt; patchpoint = m_rareData-&gt;domJIT-&gt;callDOMGetter();
-
-    Vector&lt;GPRReg&gt; gpScratch;
-    Vector&lt;FPRReg&gt; fpScratch;
-    Vector&lt;DOMJIT::Value&gt; regs;
-
-    ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
-    allocator.lock(baseGPR);
-#if USE(JSVALUE32_64)
-    allocator.lock(static_cast&lt;GPRReg&gt;(stubInfo.patch.baseTagGPR));
-#endif
-    allocator.lock(valueRegs);
-    allocator.lock(scratchGPR);
-
-    GPRReg paramBaseGPR = InvalidGPRReg;
-    GPRReg paramGlobalObjectGPR = InvalidGPRReg;
-    JSValueRegs paramValueRegs = valueRegs;
-    GPRReg remainingScratchGPR = InvalidGPRReg;
-
-    // valueRegs and baseForGetGPR may be the same. For example, in Baseline JIT, we pass the same regT0 for baseGPR and valueRegs.
-    // In FTL, there is no constraint that the baseForGetGPR interferes with the result. To make implementation simple in
-    // DOMJIT::Patchpoint, DOMJIT::Patchpoint assumes that result registers always early interfere with input registers, in this case,
-    // baseForGetGPR. So we move baseForGetGPR to the other register if baseForGetGPR == valueRegs.
-    if (baseForGetGPR != valueRegs.payloadGPR()) {
-        paramBaseGPR = baseForGetGPR;
-        if (!patchpoint-&gt;requireGlobalObject)
-            remainingScratchGPR = scratchGPR;
-        else
-            paramGlobalObjectGPR = scratchGPR;
-    } else {
-        jit.move(valueRegs.payloadGPR(), scratchGPR);
-        paramBaseGPR = scratchGPR;
-        if (patchpoint-&gt;requireGlobalObject)
-            paramGlobalObjectGPR = allocator.allocateScratchGPR();
-    }
-
-    JSGlobalObject* globalObjectForDOMJIT = structure()-&gt;globalObject();
-
-    regs.append(paramValueRegs);
-    regs.append(paramBaseGPR);
-    if (patchpoint-&gt;requireGlobalObject) {
-        ASSERT(paramGlobalObjectGPR != InvalidGPRReg);
-        regs.append(DOMJIT::Value(paramGlobalObjectGPR, globalObjectForDOMJIT));
-    }
-
-    if (patchpoint-&gt;numGPScratchRegisters) {
-        unsigned i = 0;
-        if (remainingScratchGPR != InvalidGPRReg) {
-            gpScratch.append(remainingScratchGPR);
-            ++i;
-        }
-        for (; i &lt; patchpoint-&gt;numGPScratchRegisters; ++i)
-            gpScratch.append(allocator.allocateScratchGPR());
-    }
-
-    for (unsigned i = 0; i &lt; patchpoint-&gt;numFPScratchRegisters; ++i)
-        fpScratch.append(allocator.allocateScratchFPR());
-
-    // Let's store the reused registers to the stack. After that, we can use allocated scratch registers.
-    ScratchRegisterAllocator::PreservedState preservedState =
-        allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
-
-    if (verbose) {
-        dataLog(&quot;baseGPR = &quot;, baseGPR, &quot;\n&quot;);
-        dataLog(&quot;valueRegs = &quot;, valueRegs, &quot;\n&quot;);
-        dataLog(&quot;scratchGPR = &quot;, scratchGPR, &quot;\n&quot;);
-        dataLog(&quot;paramBaseGPR = &quot;, paramBaseGPR, &quot;\n&quot;);
-        if (paramGlobalObjectGPR != InvalidGPRReg)
-            dataLog(&quot;paramGlobalObjectGPR = &quot;, paramGlobalObjectGPR, &quot;\n&quot;);
-        dataLog(&quot;paramValueRegs = &quot;, paramValueRegs, &quot;\n&quot;);
-        for (unsigned i = 0; i &lt; patchpoint-&gt;numGPScratchRegisters; ++i)
-            dataLog(&quot;gpScratch[&quot;, i, &quot;] = &quot;, gpScratch[i], &quot;\n&quot;);
-    }
-
-    if (patchpoint-&gt;requireGlobalObject)
-        jit.move(CCallHelpers::TrustedImmPtr(globalObjectForDOMJIT), paramGlobalObjectGPR);
-
-    // We just spill the registers used in DOMJIT::Patchpoint here. For not spilled registers here explicitly,
-    // they must be in the used register set passed by the callers (Baseline, DFG, and FTL) if they need to be kept.
-    // Some registers can be locked, but not in the used register set. For example, the caller could make baseGPR
-    // same to valueRegs, and not include it in the used registers since it will be changed.
-    RegisterSet registersToSpillForCCall;
-    for (auto&amp; value : regs) {
-        DOMJIT::Reg reg = value.reg();
-        if (reg.isJSValueRegs())
-            registersToSpillForCCall.set(reg.jsValueRegs());
-        else if (reg.isGPR())
-            registersToSpillForCCall.set(reg.gpr());
-        else
-            registersToSpillForCCall.set(reg.fpr());
-    }
-    for (GPRReg reg : gpScratch)
-        registersToSpillForCCall.set(reg);
-    for (FPRReg reg : fpScratch)
-        registersToSpillForCCall.set(reg);
-    registersToSpillForCCall.exclude(RegisterSet::registersToNotSaveForCCall());
-
-    DOMJITAccessCasePatchpointParams params(WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch));
-    patchpoint-&gt;generator()-&gt;run(jit, params);
-    allocator.restoreReusedRegistersByPopping(jit, preservedState);
-    state.succeed();
-
-    CCallHelpers::JumpList exceptions = params.emitSlowPathCalls(state, registersToSpillForCCall, jit);
-    if (!exceptions.empty()) {
-        exceptions.link(&amp;jit);
-        allocator.restoreReusedRegistersByPopping(jit, preservedState);
-        state.emitExplicitExceptionHandler();
-    }
-}
-
</del><span class="cx"> PolymorphicAccess::PolymorphicAccess() { }
</span><span class="cx"> PolymorphicAccess::~PolymorphicAccess() { }
</span><span class="cx"> 
</span><span class="lines">@@ -1756,32 +398,6 @@
</span><span class="cx">     m_list.resize(dstIndex);
</span><span class="cx">     
</span><span class="cx">     if (verbose)
</span><del>-        dataLog(&quot;In regenerate: cases: &quot;, listDump(cases), &quot;\n&quot;);
-    
-    // Now that we've removed obviously unnecessary cases, we can check if the megamorphic load
-    // optimization is applicable. Note that we basically tune megamorphicLoadCost according to code
-    // size. It would be faster to just allow more repatching with many load cases, and avoid the
-    // megamorphicLoad optimization, if we had infinite executable memory.
-    if (cases.size() &gt;= Options::maxAccessVariantListSize()) {
-        unsigned numSelfLoads = 0;
-        for (auto&amp; newCase : cases) {
-            if (newCase-&gt;canBeReplacedByMegamorphicLoad())
-                numSelfLoads++;
-        }
-        
-        if (numSelfLoads &gt;= Options::megamorphicLoadCost()) {
-            if (auto mega = AccessCase::megamorphicLoad(vm, codeBlock)) {
-                cases.removeAllMatching(
-                    [&amp;] (std::unique_ptr&lt;AccessCase&gt;&amp; newCase) -&gt; bool {
-                        return newCase-&gt;canBeReplacedByMegamorphicLoad();
-                    });
-                
-                cases.append(WTFMove(mega));
-            }
-        }
-    }
-    
-    if (verbose)
</del><span class="cx">         dataLog(&quot;Optimized cases: &quot;, listDump(cases), &quot;\n&quot;);
</span><span class="cx">     
</span><span class="cx">     // At this point we're convinced that 'cases' contains the cases that we want to JIT now and we
</span><span class="lines">@@ -1978,9 +594,6 @@
</span><span class="cx">     case AccessCase::Load:
</span><span class="cx">         out.print(&quot;Load&quot;);
</span><span class="cx">         return;
</span><del>-    case AccessCase::MegamorphicLoad:
-        out.print(&quot;MegamorphicLoad&quot;);
-        return;
</del><span class="cx">     case AccessCase::Transition:
</span><span class="cx">         out.print(&quot;Transition&quot;);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;AccessCase.h&quot;
</ins><span class="cx"> #include &quot;CodeOrigin.h&quot;
</span><span class="cx"> #include &quot;JITStubRoutine.h&quot;
</span><span class="cx"> #include &quot;JSFunctionInlines.h&quot;
</span><span class="lines">@@ -47,277 +48,6 @@
</span><span class="cx"> class WatchpointsOnStructureStubInfo;
</span><span class="cx"> class ScratchRegisterAllocator;
</span><span class="cx"> 
</span><del>-struct AccessGenerationState;
-
-// An AccessCase describes one of the cases of a PolymorphicAccess. A PolymorphicAccess represents a
-// planned (to generate in future) or generated stub for some inline cache. That stub contains fast
-// path code for some finite number of fast cases, each described by an AccessCase object.
-//
-// An AccessCase object has a lifecycle that proceeds through several states. Note that the states
-// of AccessCase have a lot to do with the global effect epoch (we'll say epoch for short). This is
-// a simple way of reasoning about the state of the system outside this AccessCase. Any observable
-// effect - like storing to a property, changing an object's structure, etc. - increments the epoch.
-// The states are:
-//
-// Primordial:   This is an AccessCase that was just allocated. It does not correspond to any actual
-//               code and it is not owned by any PolymorphicAccess. In this state, the AccessCase
-//               assumes that it is in the same epoch as when it was created. This is important
-//               because it may make claims about itself (&quot;I represent a valid case so long as you
-//               register a watchpoint on this set&quot;) that could be contradicted by some outside
-//               effects (like firing and deleting the watchpoint set in question). This is also the
-//               state that an AccessCase is in when it is cloned (AccessCase::clone()).
-//
-// Committed:    This happens as soon as some PolymorphicAccess takes ownership of this AccessCase.
-//               In this state, the AccessCase no longer assumes anything about the epoch. To
-//               accomplish this, PolymorphicAccess calls AccessCase::commit(). This must be done
-//               during the same epoch when the AccessCase was created, either by the client or by
-//               clone(). When created by the client, committing during the same epoch works because
-//               we can be sure that whatever watchpoint sets they spoke of are still valid. When
-//               created by clone(), we can be sure that the set is still valid because the original
-//               of the clone still has watchpoints on it.
-//
-// Generated:    This is the state when the PolymorphicAccess generates code for this case by
-//               calling AccessCase::generate() or AccessCase::generateWithGuard(). At this point
-//               the case object will have some extra stuff in it, like possibly the CallLinkInfo
-//               object associated with the inline cache.
-//               FIXME: Moving into the Generated state should not mutate the AccessCase object or
-//               put more stuff into it. If we fix this, then we can get rid of AccessCase::clone().
-//               https://bugs.webkit.org/show_bug.cgi?id=156456
-//
-// An AccessCase may be destroyed while in any of these states.
-//
-// We will sometimes buffer committed AccessCases in the PolymorphicAccess object before generating
-// code. This allows us to only regenerate once we've accumulated (hopefully) more than one new
-// AccessCase.
-class AccessCase {
-    WTF_MAKE_NONCOPYABLE(AccessCase);
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    enum AccessType : uint8_t {
-        Load,
-        MegamorphicLoad,
-        Transition,
-        Replace,
-        Miss,
-        GetGetter,
-        Getter,
-        Setter,
-        CustomValueGetter,
-        CustomAccessorGetter,
-        CustomValueSetter,
-        CustomAccessorSetter,
-        IntrinsicGetter,
-        InHit,
-        InMiss,
-        ArrayLength,
-        StringLength,
-        DirectArgumentsLength,
-        ScopedArgumentsLength
-    };
-    
-    enum State : uint8_t {
-        Primordial,
-        Committed,
-        Generated
-    };
-
-    static std::unique_ptr&lt;AccessCase&gt; tryGet(
-        VM&amp;, JSCell* owner, AccessType, PropertyOffset, Structure*,
-        const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet(),
-        bool viaProxy = false,
-        WatchpointSet* additionalSet = nullptr);
-
-    static std::unique_ptr&lt;AccessCase&gt; get(
-        VM&amp;, JSCell* owner, AccessType, PropertyOffset, Structure*,
-        const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet(),
-        bool viaProxy = false,
-        WatchpointSet* additionalSet = nullptr,
-        PropertySlot::GetValueFunc = nullptr,
-        JSObject* customSlotBase = nullptr,
-        DOMJIT::GetterSetter* = nullptr);
-    
-    static std::unique_ptr&lt;AccessCase&gt; megamorphicLoad(VM&amp;, JSCell* owner);
-    
-    static std::unique_ptr&lt;AccessCase&gt; replace(VM&amp;, JSCell* owner, Structure*, PropertyOffset);
-
-    static std::unique_ptr&lt;AccessCase&gt; transition(
-        VM&amp;, JSCell* owner, Structure* oldStructure, Structure* newStructure, PropertyOffset,
-        const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet());
-
-    static std::unique_ptr&lt;AccessCase&gt; setter(
-        VM&amp;, JSCell* owner, AccessType, Structure*, PropertyOffset,
-        const ObjectPropertyConditionSet&amp;, PutPropertySlot::PutValueFunc = nullptr,
-        JSObject* customSlotBase = nullptr);
-
-    static std::unique_ptr&lt;AccessCase&gt; in(
-        VM&amp;, JSCell* owner, AccessType, Structure*,
-        const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet());
-
-    static std::unique_ptr&lt;AccessCase&gt; getLength(VM&amp;, JSCell* owner, AccessType);
-    static std::unique_ptr&lt;AccessCase&gt; getIntrinsic(VM&amp;, JSCell* owner, JSFunction* intrinsic, PropertyOffset, Structure*, const ObjectPropertyConditionSet&amp;);
-    
-    static std::unique_ptr&lt;AccessCase&gt; fromStructureStubInfo(VM&amp;, JSCell* owner, StructureStubInfo&amp;);
-
-    ~AccessCase();
-    
-    AccessType type() const { return m_type; }
-    State state() const { return m_state; }
-    PropertyOffset offset() const { return m_offset; }
-    bool viaProxy() const { return m_rareData ? m_rareData-&gt;viaProxy : false; }
-    
-    Structure* structure() const
-    {
-        if (m_type == Transition)
-            return m_structure-&gt;previousID();
-        return m_structure.get();
-    }
-    bool guardedByStructureCheck() const;
-
-    Structure* newStructure() const
-    {
-        ASSERT(m_type == Transition);
-        return m_structure.get();
-    }
-    
-    ObjectPropertyConditionSet conditionSet() const { return m_conditionSet; }
-    JSFunction* intrinsicFunction() const
-    {
-        ASSERT(type() == IntrinsicGetter &amp;&amp; m_rareData);
-        return m_rareData-&gt;intrinsicFunction.get();
-    }
-    Intrinsic intrinsic() const
-    {
-        return intrinsicFunction()-&gt;intrinsic();
-    }
-
-    DOMJIT::GetterSetter* domJIT() const
-    {
-        ASSERT(m_rareData);
-        return m_rareData-&gt;domJIT;
-    }
-
-    WatchpointSet* additionalSet() const
-    {
-        return m_rareData ? m_rareData-&gt;additionalSet.get() : nullptr;
-    }
-
-    JSObject* customSlotBase() const
-    {
-        return m_rareData ? m_rareData-&gt;customSlotBase.get() : nullptr;
-    }
-
-    JSObject* alternateBase() const;
-
-    // If you supply the optional vector, this will append the set of cells that this will need to keep alive
-    // past the call.
-    bool doesCalls(Vector&lt;JSCell*&gt;* cellsToMark = nullptr) const;
-
-    bool isGetter() const
-    {
-        switch (type()) {
-        case Getter:
-        case CustomValueGetter:
-        case CustomAccessorGetter:
-            return true;
-        default:
-            return false;
-        }
-    }
-
-    // This can return null even for a getter/setter, if it hasn't been generated yet. That's
-    // actually somewhat likely because of how we do buffering of new cases.
-    CallLinkInfo* callLinkInfo() const
-    {
-        if (!m_rareData)
-            return nullptr;
-        return m_rareData-&gt;callLinkInfo.get();
-    }
-    
-    // Is it still possible for this case to ever be taken?  Must call this as a prerequisite for
-    // calling generate() and friends.  If this returns true, then you can call generate().  If
-    // this returns false, then generate() will crash.  You must call generate() in the same epoch
-    // as when you called couldStillSucceed().
-    bool couldStillSucceed() const;
-    
-    static bool canEmitIntrinsicGetter(JSFunction*, Structure*);
-
-    bool canBeReplacedByMegamorphicLoad() const;
-
-    // If this method returns true, then it's a good idea to remove 'other' from the access once 'this'
-    // is added. This method assumes that in case of contradictions, 'this' represents a newer, and so
-    // more useful, truth. This method can be conservative; it will return false when it doubt.
-    bool canReplace(const AccessCase&amp; other) const;
-
-    void dump(PrintStream&amp; out) const;
-    
-private:
-    friend class CodeBlock;
-    friend class PolymorphicAccess;
-
-    AccessCase();
-
-    bool visitWeak(VM&amp;) const;
-    bool propagateTransitions(SlotVisitor&amp;) const;
-    
-    // FIXME: This only exists because of how AccessCase puts post-generation things into itself.
-    // https://bugs.webkit.org/show_bug.cgi?id=156456
-    std::unique_ptr&lt;AccessCase&gt; clone() const;
-    
-    // Perform any action that must be performed before the end of the epoch in which the case
-    // was created. Returns a set of watchpoint sets that will need to be watched.
-    Vector&lt;WatchpointSet*, 2&gt; commit(VM&amp;, const Identifier&amp;);
-
-    // Fall through on success. Two kinds of failures are supported: fall-through, which means that we
-    // should try a different case; and failure, which means that this was the right case but it needs
-    // help from the slow path.
-    void generateWithGuard(AccessGenerationState&amp;, MacroAssembler::JumpList&amp; fallThrough);
-
-    // Fall through on success, add a jump to the failure list on failure.
-    void generate(AccessGenerationState&amp;);
-    
-    void generateImpl(AccessGenerationState&amp;);
-    void emitIntrinsicGetter(AccessGenerationState&amp;);
-    void emitDOMJITGetter(AccessGenerationState&amp;, GPRReg baseForGetGPR);
-    
-    AccessType m_type { Load };
-    State m_state { Primordial };
-    PropertyOffset m_offset { invalidOffset };
-
-    // Usually this is the structure that we expect the base object to have. But, this is the *new*
-    // structure for a transition and we rely on the fact that it has a strong reference to the old
-    // structure. For proxies, this is the structure of the object behind the proxy.
-    WriteBarrier&lt;Structure&gt; m_structure;
-
-    ObjectPropertyConditionSet m_conditionSet;
-
-    class RareData {
-        WTF_MAKE_FAST_ALLOCATED;
-    public:
-        RareData()
-            : viaProxy(false)
-            , domJIT(nullptr)
-        {
-            customAccessor.opaque = nullptr;
-        }
-        
-        bool viaProxy;
-        RefPtr&lt;WatchpointSet&gt; additionalSet;
-        // FIXME: This should probably live in the stub routine object.
-        // https://bugs.webkit.org/show_bug.cgi?id=156456
-        std::unique_ptr&lt;CallLinkInfo&gt; callLinkInfo;
-        union {
-            PropertySlot::GetValueFunc getter;
-            PutPropertySlot::PutValueFunc setter;
-            void* opaque;
-        } customAccessor;
-        WriteBarrier&lt;JSObject&gt; customSlotBase;
-        WriteBarrier&lt;JSFunction&gt; intrinsicFunction;
-        DOMJIT::GetterSetter* domJIT;
-    };
-
-    std::unique_ptr&lt;RareData&gt; m_rareData;
-};
-
</del><span class="cx"> class AccessGenerationResult {
</span><span class="cx"> public:
</span><span class="cx">     enum Kind {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeProxyableAccessCasecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.cpp (0 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;ProxyableAccessCase.h&quot;
+
+#if ENABLE(JIT)
+
+namespace JSC {
+
+ProxyableAccessCase::ProxyableAccessCase(VM&amp; vm, JSCell* owner, AccessType accessType, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet&amp; conditionSet, bool viaProxy, WatchpointSet* additionalSet)
+    : Base(vm, owner, accessType, offset, structure, conditionSet)
+    , m_viaProxy(viaProxy)
+    , m_additionalSet(additionalSet)
+{
+}
+
+std::unique_ptr&lt;AccessCase&gt; ProxyableAccessCase::create(VM&amp; vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet&amp; conditionSet, bool viaProxy, WatchpointSet* additionalSet)
+{
+    ASSERT(type == Load || type == Miss || type == GetGetter);
+    return std::unique_ptr&lt;AccessCase&gt;(new ProxyableAccessCase(vm, owner, type, offset, structure, conditionSet, viaProxy, additionalSet));
+}
+
+ProxyableAccessCase::~ProxyableAccessCase()
+{
+}
+
+std::unique_ptr&lt;AccessCase&gt; ProxyableAccessCase::clone() const
+{
+    std::unique_ptr&lt;ProxyableAccessCase&gt; result(new ProxyableAccessCase(*this));
+    result-&gt;resetState();
+    return WTFMove(result);
+}
+
+void ProxyableAccessCase::dumpImpl(PrintStream&amp; out, CommaPrinter&amp; comma) const
+{
+    Base::dumpImpl(out, comma);
+    out.print(comma, &quot;viaProxy = &quot;, viaProxy());
+    out.print(comma, &quot;additionalSet = &quot;, RawPointer(additionalSet()));
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeProxyableAccessCaseh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.h (0 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.h        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+/*
+ * Copyright (C) 2017 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;AccessCase.h&quot;
+
+namespace JSC {
+
+class ProxyableAccessCase : public AccessCase {
+public:
+    typedef AccessCase Base;
+
+    bool viaProxy() const override { return m_viaProxy; }
+    WatchpointSet* additionalSet() const override { return m_additionalSet.get(); }
+
+    static std::unique_ptr&lt;AccessCase&gt; create(VM&amp;, JSCell*, AccessType, PropertyOffset, Structure*, const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet(),
+        bool viaProxy = false, WatchpointSet* additionalSet = nullptr);
+
+    void dumpImpl(PrintStream&amp;, CommaPrinter&amp;) const override;
+    std::unique_ptr&lt;AccessCase&gt; clone() const override;
+
+    ~ProxyableAccessCase();
+
+protected:
+    ProxyableAccessCase(VM&amp;, JSCell*, AccessType, PropertyOffset, Structure*, const ObjectPropertyConditionSet&amp;, bool viaProxy, WatchpointSet* additionalSet);
+
+private:
+    bool m_viaProxy;
+    RefPtr&lt;WatchpointSet&gt; m_additionalSet;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePutByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;ComplexGetStatus.h&quot;
</span><ins>+#include &quot;GetterSetterAccessCase.h&quot;
</ins><span class="cx"> #include &quot;LLIntData.h&quot;
</span><span class="cx"> #include &quot;LowLevelInterpreter.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="lines">@@ -227,7 +228,7 @@
</span><span class="cx">                 case ComplexGetStatus::Inlineable: {
</span><span class="cx">                     std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus =
</span><span class="cx">                         std::make_unique&lt;CallLinkStatus&gt;();
</span><del>-                    if (CallLinkInfo* callLinkInfo = access.callLinkInfo()) {
</del><ins>+                    if (CallLinkInfo* callLinkInfo = access.as&lt;GetterSetterAccessCase&gt;().callLinkInfo()) {
</ins><span class="cx">                         *callLinkStatus = CallLinkStatus::computeFor(
</span><span class="cx">                             locker, profiledBlock, *callLinkInfo, callExitSiteData);
</span><span class="cx">                     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureStubInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -216,8 +216,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     switch (accessType) {
</span><del>-    case AccessType::GetPure:
-        resetGetByID(codeBlock, *this, GetByIDKind::Pure);
</del><ins>+    case AccessType::TryGet:
+        resetGetByID(codeBlock, *this, GetByIDKind::Try);
</ins><span class="cx">         break;
</span><span class="cx">     case AccessType::Get:
</span><span class="cx">         resetGetByID(codeBlock, *this, GetByIDKind::Normal);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureStubInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx"> 
</span><span class="cx"> enum class AccessType : int8_t {
</span><span class="cx">     Get,
</span><del>-    GetPure,
</del><ins>+    TryGet,
</ins><span class="cx">     Put,
</span><span class="cx">     In
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -4531,7 +4531,7 @@
</span><span class="cx">                 m_inlineStackTop-&gt;m_profiledBlock, m_dfgCodeBlock,
</span><span class="cx">                 m_inlineStackTop-&gt;m_stubInfos, m_dfgStubInfos,
</span><span class="cx">                 currentCodeOrigin(), uid);
</span><del>-            AccessType type = op_try_get_by_id == opcodeID ? AccessType::GetPure : AccessType::Get;
</del><ins>+            AccessType type = op_try_get_by_id == opcodeID ? AccessType::TryGet : AccessType::Get;
</ins><span class="cx"> 
</span><span class="cx">             unsigned opcodeLength = opcodeID == op_try_get_by_id ? OPCODE_LENGTH(op_try_get_by_id) : OPCODE_LENGTH(op_get_by_id);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -1006,7 +1006,7 @@
</span><span class="cx"> 
</span><span class="cx">         base.use();
</span><span class="cx"> 
</span><del>-        cachedGetById(node-&gt;origin.semantic, baseRegs, resultRegs, node-&gt;identifierNumber(), JITCompiler::Jump(), NeedToSpill, AccessType::GetPure);
</del><ins>+        cachedGetById(node-&gt;origin.semantic, baseRegs, resultRegs, node-&gt;identifierNumber(), JITCompiler::Jump(), NeedToSpill, AccessType::TryGet);
</ins><span class="cx"> 
</span><span class="cx">         jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);
</span><span class="cx">         break;
</span><span class="lines">@@ -1023,7 +1023,7 @@
</span><span class="cx"> 
</span><span class="cx">         JITCompiler::Jump notCell = m_jit.branchIfNotCell(baseRegs);
</span><span class="cx"> 
</span><del>-        cachedGetById(node-&gt;origin.semantic, baseRegs, resultRegs, node-&gt;identifierNumber(), notCell, NeedToSpill, AccessType::GetPure);
</del><ins>+        cachedGetById(node-&gt;origin.semantic, baseRegs, resultRegs, node-&gt;identifierNumber(), notCell, NeedToSpill, AccessType::TryGet);
</ins><span class="cx"> 
</span><span class="cx">         jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -626,7 +626,7 @@
</span><span class="cx">             compilePutStructure();
</span><span class="cx">             break;
</span><span class="cx">         case TryGetById:
</span><del>-            compileGetById(AccessType::GetPure);
</del><ins>+            compileGetById(AccessType::TryGet);
</ins><span class="cx">             break;
</span><span class="cx">         case GetById:
</span><span class="cx">         case GetByIdFlush:
</span><span class="lines">@@ -2814,7 +2814,7 @@
</span><span class="cx">     
</span><span class="cx">     void compileGetById(AccessType type)
</span><span class="cx">     {
</span><del>-        ASSERT(type == AccessType::Get || type == AccessType::GetPure);
</del><ins>+        ASSERT(type == AccessType::Get || type == AccessType::TryGet);
</ins><span class="cx">         switch (m_node-&gt;child1().useKind()) {
</span><span class="cx">         case CellUse: {
</span><span class="cx">             setJSValue(getById(lowCell(m_node-&gt;child1()), type));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitIntrinsicEmittercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;CCallHelpers.h&quot;
</span><span class="cx"> #include &quot;CallFrame.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><ins>+#include &quot;IntrinsicGetterAccessCase.h&quot;
</ins><span class="cx"> #include &quot;JSArrayBufferView.h&quot;
</span><span class="cx"> #include &quot;JSCJSValueInlines.h&quot;
</span><span class="cx"> #include &quot;JSCellInlines.h&quot;
</span><span class="lines">@@ -48,7 +49,7 @@
</span><span class="cx"> typedef CCallHelpers::TrustedImm64 TrustedImm64;
</span><span class="cx"> typedef CCallHelpers::Imm64 Imm64;
</span><span class="cx"> 
</span><del>-bool AccessCase::canEmitIntrinsicGetter(JSFunction* getter, Structure* structure)
</del><ins>+bool IntrinsicGetterAccessCase::canEmitIntrinsicGetter(JSFunction* getter, Structure* structure)
</ins><span class="cx"> {
</span><span class="cx"> 
</span><span class="cx">     switch (getter-&gt;intrinsic()) {
</span><span class="lines">@@ -68,7 +69,7 @@
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AccessCase::emitIntrinsicGetter(AccessGenerationState&amp; state)
</del><ins>+void IntrinsicGetterAccessCase::emitIntrinsicGetter(AccessGenerationState&amp; state)
</ins><span class="cx"> {
</span><span class="cx">     CCallHelpers&amp; jit = *state.jit;
</span><span class="cx">     JSValueRegs valueRegs = state.valueRegs;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -211,7 +211,7 @@
</span><span class="cx">     RETURN_IF_EXCEPTION(scope, encodedJSValue());
</span><span class="cx"> 
</span><span class="cx">     if (stubInfo-&gt;considerCaching(exec-&gt;codeBlock(), baseValue.structureOrNull()) &amp;&amp; !slot.isTaintedByOpaqueObject() &amp;&amp; (slot.isCacheableValue() || slot.isCacheableGetter() || slot.isUnset()))
</span><del>-        repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Pure);
</del><ins>+        repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Try);
</ins><span class="cx"> 
</span><span class="cx">     return JSValue::encode(slot.getPureResult());
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -579,7 +579,7 @@
</span><span class="cx"> 
</span><span class="cx">     JITGetByIdGenerator gen(
</span><span class="cx">         m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(),
</span><del>-        ident-&gt;impl(), JSValueRegs(regT0), JSValueRegs(regT0), AccessType::GetPure);
</del><ins>+        ident-&gt;impl(), JSValueRegs(regT0), JSValueRegs(regT0), AccessType::TryGet);
</ins><span class="cx">     gen.generateFastPath(*this);
</span><span class="cx">     addSlowCase(gen.slowPathJump());
</span><span class="cx">     m_getByIds.append(gen);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITPropertyAccess32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -594,7 +594,7 @@
</span><span class="cx"> 
</span><span class="cx">     JITGetByIdGenerator gen(
</span><span class="cx">         m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(),
</span><del>-        ident-&gt;impl(), JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), AccessType::GetPure);
</del><ins>+        ident-&gt;impl(), JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), AccessType::TryGet);
</ins><span class="cx">     gen.generateFastPath(*this);
</span><span class="cx">     addSlowCase(gen.slowPathJump());
</span><span class="cx">     m_getByIds.append(gen);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.cpp (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.cpp        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/jit/Repatch.cpp        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -39,8 +39,10 @@
</span><span class="cx"> #include &quot;FunctionCodeBlock.h&quot;
</span><span class="cx"> #include &quot;GCAwareJITStubRoutine.h&quot;
</span><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><ins>+#include &quot;GetterSetterAccessCase.h&quot;
</ins><span class="cx"> #include &quot;ICStats.h&quot;
</span><span class="cx"> #include &quot;InlineAccess.h&quot;
</span><ins>+#include &quot;IntrinsicGetterAccessCase.h&quot;
</ins><span class="cx"> #include &quot;JIT.h&quot;
</span><span class="cx"> #include &quot;JITInlines.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="lines">@@ -176,18 +178,18 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            newCase = AccessCase::getLength(vm, codeBlock, AccessCase::ArrayLength);
</del><ins>+            newCase = AccessCase::create(vm, codeBlock, AccessCase::ArrayLength);
</ins><span class="cx">         } else if (isJSString(baseValue))
</span><del>-            newCase = AccessCase::getLength(vm, codeBlock, AccessCase::StringLength);
</del><ins>+            newCase = AccessCase::create(vm, codeBlock, AccessCase::StringLength);
</ins><span class="cx">         else if (DirectArguments* arguments = jsDynamicCast&lt;DirectArguments*&gt;(vm, baseValue)) {
</span><span class="cx">             // If there were overrides, then we can handle this as a normal property load! Guarding
</span><span class="cx">             // this with such a check enables us to add an IC case for that load if needed.
</span><span class="cx">             if (!arguments-&gt;overrodeThings())
</span><del>-                newCase = AccessCase::getLength(vm, codeBlock, AccessCase::DirectArgumentsLength);
</del><ins>+                newCase = AccessCase::create(vm, codeBlock, AccessCase::DirectArgumentsLength);
</ins><span class="cx">         } else if (ScopedArguments* arguments = jsDynamicCast&lt;ScopedArguments*&gt;(vm, baseValue)) {
</span><span class="cx">             // Ditto.
</span><span class="cx">             if (!arguments-&gt;overrodeThings())
</span><del>-                newCase = AccessCase::getLength(vm, codeBlock, AccessCase::ScopedArgumentsLength);
</del><ins>+                newCase = AccessCase::create(vm, codeBlock, AccessCase::ScopedArgumentsLength);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -267,7 +269,7 @@
</span><span class="cx">         if (slot.isCacheableCustom() &amp;&amp; slot.domJIT())
</span><span class="cx">             domJIT = slot.domJIT();
</span><span class="cx"> 
</span><del>-        if (kind == GetByIDKind::Pure) {
</del><ins>+        if (kind == GetByIDKind::Try) {
</ins><span class="cx">             AccessCase::AccessType type;
</span><span class="cx">             if (slot.isCacheableValue())
</span><span class="cx">                 type = AccessCase::Load;
</span><span class="lines">@@ -278,27 +280,28 @@
</span><span class="cx">             else
</span><span class="cx">                 RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> 
</span><del>-            newCase = AccessCase::tryGet(vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy, slot.watchpointSet());
-        } else if (!loadTargetFromProxy &amp;&amp; getter &amp;&amp; AccessCase::canEmitIntrinsicGetter(getter, structure))
-            newCase = AccessCase::getIntrinsic(vm, codeBlock, getter, slot.cachedOffset(), structure, conditionSet);
</del><ins>+            newCase = ProxyableAccessCase::create(vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy, slot.watchpointSet());
+        } else if (!loadTargetFromProxy &amp;&amp; getter &amp;&amp; IntrinsicGetterAccessCase::canEmitIntrinsicGetter(getter, structure))
+            newCase = IntrinsicGetterAccessCase::create(vm, codeBlock, slot.cachedOffset(), structure, conditionSet, getter);
</ins><span class="cx">         else {
</span><del>-            AccessCase::AccessType type;
-            if (slot.isCacheableValue())
-                type = AccessCase::Load;
-            else if (slot.isUnset())
-                type = AccessCase::Miss;
-            else if (slot.isCacheableGetter())
-                type = AccessCase::Getter;
-            else if (slot.attributes() &amp; CustomAccessor)
-                type = AccessCase::CustomAccessorGetter;
-            else
-                type = AccessCase::CustomValueGetter;
</del><ins>+            if (slot.isCacheableValue() || slot.isUnset()) {
+                newCase = ProxyableAccessCase::create(vm, codeBlock, slot.isUnset() ? AccessCase::Miss : AccessCase::Load,
+                    offset, structure, conditionSet, loadTargetFromProxy, slot.watchpointSet());
+            } else {
+                AccessCase::AccessType type;
+                if (slot.isCacheableGetter())
+                    type = AccessCase::Getter;
+                else if (slot.attributes() &amp; CustomAccessor)
+                    type = AccessCase::CustomAccessorGetter;
+                else
+                    type = AccessCase::CustomValueGetter;
</ins><span class="cx"> 
</span><del>-            newCase = AccessCase::get(
-                vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy,
-                slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr,
-                slot.isCacheableCustom() ? slot.slotBase() : nullptr,
-                domJIT);
</del><ins>+                newCase = GetterSetterAccessCase::create(
+                    vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy,
+                    slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr,
+                    slot.isCacheableCustom() ? slot.slotBase() : nullptr,
+                    domJIT);
+            }
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -386,7 +389,7 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            newCase = AccessCase::replace(vm, codeBlock, structure, slot.cachedOffset());
</del><ins>+            newCase = AccessCase::create(vm, codeBlock, AccessCase::Replace, slot.cachedOffset(), structure);
</ins><span class="cx">         } else {
</span><span class="cx">             ASSERT(slot.type() == PutPropertySlot::NewProperty);
</span><span class="cx"> 
</span><span class="lines">@@ -419,7 +422,7 @@
</span><span class="cx">                     return GiveUpOnCache;
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            newCase = AccessCase::transition(vm, codeBlock, structure, newStructure, offset, conditionSet);
</del><ins>+            newCase = AccessCase::create(vm, codeBlock, offset, structure, newStructure, conditionSet);
</ins><span class="cx">         }
</span><span class="cx">     } else if (slot.isCacheableCustom() || slot.isCacheableSetter()) {
</span><span class="cx">         if (slot.isCacheableCustom()) {
</span><span class="lines">@@ -433,7 +436,7 @@
</span><span class="cx">                     return GiveUpOnCache;
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            newCase = AccessCase::setter(
</del><ins>+            newCase = GetterSetterAccessCase::create(
</ins><span class="cx">                 vm, codeBlock, slot.isCustomAccessor() ? AccessCase::CustomAccessorSetter : AccessCase::CustomValueSetter, structure, invalidOffset, conditionSet,
</span><span class="cx">                 slot.customSetter(), slot.base());
</span><span class="cx">         } else {
</span><span class="lines">@@ -450,7 +453,7 @@
</span><span class="cx">             } else
</span><span class="cx">                 offset = slot.cachedOffset();
</span><span class="cx"> 
</span><del>-            newCase = AccessCase::setter(
</del><ins>+            newCase = GetterSetterAccessCase::create(
</ins><span class="cx">                 vm, codeBlock, AccessCase::Setter, structure, offset, conditionSet);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -513,8 +516,8 @@
</span><span class="cx"> 
</span><span class="cx">     LOG_IC((ICEvent::InAddAccessCase, structure-&gt;classInfo(), ident));
</span><span class="cx"> 
</span><del>-    std::unique_ptr&lt;AccessCase&gt; newCase = AccessCase::in(
-        vm, codeBlock, wasFound ? AccessCase::InHit : AccessCase::InMiss, structure, conditionSet);
</del><ins>+    std::unique_ptr&lt;AccessCase&gt; newCase = AccessCase::create(
+        vm, codeBlock, wasFound ? AccessCase::InHit : AccessCase::InMiss, invalidOffset, structure, conditionSet);
</ins><span class="cx"> 
</span><span class="cx">     AccessGenerationResult result = stubInfo.addAccessCase(codeBlock, ident, WTFMove(newCase));
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.h (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.h        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/jit/Repatch.h        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -36,7 +36,7 @@
</span><span class="cx"> 
</span><span class="cx"> enum class GetByIDKind {
</span><span class="cx">     Normal,
</span><del>-    Pure
</del><ins>+    Try
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> void repatchGetByID(ExecState*, JSValue, const Identifier&amp;, const PropertySlot&amp;, StructureStubInfo&amp;, GetByIDKind);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (212452 => 212453)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2017-02-16 19:43:42 UTC (rev 212452)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2017-02-16 19:44:55 UTC (rev 212453)
</span><span class="lines">@@ -228,7 +228,6 @@
</span><span class="cx">     v(bool, clobberAllRegsInFTLICSlowPath, !ASSERT_DISABLED, Normal, nullptr) \
</span><span class="cx">     v(bool, useAccessInlining, true, Normal, nullptr) \
</span><span class="cx">     v(unsigned, maxAccessVariantListSize, 8, Normal, nullptr) \
</span><del>-    v(unsigned, megamorphicLoadCost, 999, Normal, nullptr) /* This used to be 10, but we're temporarily testing what happens when the feature is disabled. */\
</del><span class="cx">     v(bool, usePolyvariantDevirtualization, true, Normal, nullptr) \
</span><span class="cx">     v(bool, usePolymorphicAccessInlining, true, Normal, nullptr) \
</span><span class="cx">     v(bool, usePolymorphicCallInlining, true, Normal, nullptr) \
</span></span></pre>
</div>
</div>

</body>
</html>