<!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>[189586] trunk</title>
</head>
<body>

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

<h3>Log Message</h3>
<pre>There should be one stub hanging off an inline cache that contains code for all of the cases, rather than forming a linked list consisting of one stub per case
https://bugs.webkit.org/show_bug.cgi?id=148717

Reviewed by Michael Saboff.

Source/JavaScriptCore:

This is a major rewrite of the JSC get/put/in inline caches (ICs), motivated by the need to add
fancy new kinds of inline caches for property type inference (https://webkit.org/b/148610).

Previously, our inline caches had some problems that made them difficult to work with. It was
impossible to change any code that was previously generated by the IC except by blowing the
whole IC away, the ICs scaled poorly if there were many cases, and there was a lot of duplicate
and ad hoc code.

Impossible to regenerate a previously generated stub: Say that some access (o.f = v) causes our
IC code to emit some stub; let's call it stub1. Then later we find that we need to emit a
different stub, stub2, where we think that stub2 might subsume stub1. We say that stub2
subsumes stub1 if failing to execute stub2 to completion means that we are guaranteed to fail
to execute stub1 to completion. This could happen in trunk if stub2 has the same base structure
as stub1 but different prototype conditions. It could happen with property type inference if
stub2 has a looser type check on v than stub1 did. Currently, if this happened, we would emit
stub2 and have its slow path jump to stub1. Hence, we would still end up executing the checks
of stub1 before falling through to the slow path. This gets bad when there are many stubs.
Stub1 might be in front of a bunch of other stubs, so when we add stub2, we will end up
executing both stub2's and stub1's checks before falling through to the other stubs. It would
be better if we could remove stub1 from the list at this point. But since stub1 could be linked
to from a different stub that we had already generated, we'd have to have a way of patching
stubs or regenerating them from scratch. This is currenty impossible because we just don't keep
around enough meta-data to mess with a stub after it's generated. After this change, we never
link new stubs onto a linked list of pre-existing stubs; instead each IC will have one stub
hanging off of it and we always regenerate that one stub from scratch. That one stub contains
either a BinarySwitch or a branch cascade to select one of the AccessCases. Each AccessCase is
an object that describes everything we need to regenerate it in the future. This means that
when we add a new case to an IC stub, we can figure out which previous cases this one subsumes.

Poor scalability when there are many cases: Previously, the cases of a polymorphic inline cache
formed a linked list of branches. This meant that the complexity of an inline cache grew
linearly with the number of cases. This change turns this into a BinarySwitch in most cases,
leading to logarithmic scaling.

Duplicate code between get, put, and in: The code for op_get_by_id, op_put_by_id, and op_in
inline caches grew independently and ended up having a lot of duplicate code. We had the worst
kinds of duplicate code. In some cases, the code was copy-pasted. In other cases, we wrote code
that felt like it was new despite the fact that it was logically identical to code that was
already written elsewhere. The main sources of duplication were in selecting a scratch
register, checking all of the ObjectPropertyConditions and the base structure, the pro forma
involved in generating a stub, and the data structures needed to describe all of the access
cases. This change deduplicates all of that code. Now, all of those ICs use the same classes:
the PolymorphicAccess and AccessCase. There is code in those classes that handles all of the
common things, and for the most part the only code that actually specializes for the kind of
access is in some switch statement in AccessCase::generate().

Special-casing of array length and string length: Previously, array.length and string.length
were handled in an ad hoc manner in the get_by_id repatching code. The handling was separate
from the polymorphic get_by_id handling, which meant that we could not handle polymorphic
length accesses if one of the length cases was either array or string length. For example, if
you had &quot;o.length&quot; where the length was either array length or a vanilla length property, then
the get_by_id inline cache would either emit a monomorphic stub for array length, or a
monomorphic stub for the vanilla length property, but never a polymorphic stub (or list) that
could do both. This change addresses this problem by folding array length and string length
into the polymorphic get_by_id code.

This was meant to be a perf-neutral change to enable property type inference, but it ended up
being a 1% Octane speed-up, mainly because of a 14% speed-up in raytrace. This isn't too
surprising, since that test does use inline caches a lot and this change makes inline caches
more scalable.

This also fixes and adds a test for a BinarySwitch bug. BinarySwitch had an optimization for
consecutive integer cases. Using it on typed array structures triggers this bug. It's a hard
bug to trigger any other way because our other switch optimizations will usually use a jump
table in case of consecutive integers.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/MacroAssemblerCodeRef.h:
(JSC::MacroAssemblerCodePtr::dumpWithName):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::printGetByIdCacheStatus):
(JSC::CodeBlock::printPutByIdCacheStatus):
(JSC::CodeBlock::propagateTransitions):
(JSC::CodeBlock::getByValInfoMap):
(JSC::CodeBlock::addStubInfo):
(JSC::CodeBlock::findStubInfo):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::stubInfoBegin):
(JSC::CodeBlock::stubInfoEnd):
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
* bytecode/PolymorphicAccess.cpp: Copied from Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp.
(JSC::AccessGenerationState::addWatchpoint):
(JSC::AccessGenerationState::restoreScratch):
(JSC::AccessGenerationState::succeed):
(JSC::AccessCase::AccessCase):
(JSC::AccessCase::get):
(JSC::AccessCase::replace):
(JSC::AccessCase::transition):
(JSC::AccessCase::setter):
(JSC::AccessCase::in):
(JSC::AccessCase::getLength):
(JSC::AccessCase::~AccessCase):
(JSC::AccessCase::fromStructureStubInfo):
(JSC::AccessCase::clone):
(JSC::AccessCase::guardedByStructureCheck):
(JSC::AccessCase::alternateBase):
(JSC::AccessCase::canReplace):
(JSC::AccessCase::dump):
(JSC::AccessCase::visitWeak):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generate):
(JSC::PolymorphicAccess::PolymorphicAccess):
(JSC::PolymorphicAccess::~PolymorphicAccess):
(JSC::PolymorphicAccess::regenerateWithCases):
(JSC::PolymorphicAccess::regenerateWithCase):
(JSC::PolymorphicAccess::visitWeak):
(JSC::PolymorphicAccess::dump):
(JSC::PolymorphicAccess::regenerate):
(WTF::printInternal):
(JSC::GetByIdAccess::GetByIdAccess): Deleted.
(JSC::GetByIdAccess::~GetByIdAccess): Deleted.
(JSC::GetByIdAccess::fromStructureStubInfo): Deleted.
(JSC::GetByIdAccess::visitWeak): Deleted.
(JSC::PolymorphicGetByIdList::PolymorphicGetByIdList): Deleted.
(JSC::PolymorphicGetByIdList::from): Deleted.
(JSC::PolymorphicGetByIdList::~PolymorphicGetByIdList): Deleted.
(JSC::PolymorphicGetByIdList::currentSlowPathTarget): Deleted.
(JSC::PolymorphicGetByIdList::addAccess): Deleted.
(JSC::PolymorphicGetByIdList::isFull): Deleted.
(JSC::PolymorphicGetByIdList::isAlmostFull): Deleted.
(JSC::PolymorphicGetByIdList::didSelfPatching): Deleted.
(JSC::PolymorphicGetByIdList::visitWeak): Deleted.
* bytecode/PolymorphicAccess.h: Copied from Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h.
(JSC::AccessCase::isGet):
(JSC::AccessCase::isPut):
(JSC::AccessCase::isIn):
(JSC::AccessCase::type):
(JSC::AccessCase::offset):
(JSC::AccessCase::viaProxy):
(JSC::AccessCase::structure):
(JSC::AccessCase::newStructure):
(JSC::AccessCase::conditionSet):
(JSC::AccessCase::additionalSet):
(JSC::AccessCase::customSlotBase):
(JSC::AccessCase::doesCalls):
(JSC::AccessCase::callLinkInfo):
(JSC::AccessCase::RareData::RareData):
(JSC::PolymorphicAccess::isEmpty):
(JSC::PolymorphicAccess::size):
(JSC::PolymorphicAccess::at):
(JSC::PolymorphicAccess::operator[]):
(JSC::GetByIdAccess::GetByIdAccess): Deleted.
(JSC::GetByIdAccess::isSet): Deleted.
(JSC::GetByIdAccess::operator!): Deleted.
(JSC::GetByIdAccess::type): Deleted.
(JSC::GetByIdAccess::structure): Deleted.
(JSC::GetByIdAccess::conditionSet): Deleted.
(JSC::GetByIdAccess::stubRoutine): Deleted.
(JSC::GetByIdAccess::doesCalls): Deleted.
(JSC::PolymorphicGetByIdList::isEmpty): Deleted.
(JSC::PolymorphicGetByIdList::size): Deleted.
(JSC::PolymorphicGetByIdList::at): Deleted.
(JSC::PolymorphicGetByIdList::operator[]): Deleted.
* bytecode/PolymorphicAccessStructureList.h: Removed.
* bytecode/PolymorphicGetByIdList.cpp: Removed.
* bytecode/PolymorphicGetByIdList.h: Removed.
* bytecode/PolymorphicPutByIdList.cpp: Removed.
* bytecode/PolymorphicPutByIdList.h: Removed.
* bytecode/PutByIdStatus.cpp:
(JSC::PutByIdStatus::computeForStubInfo):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::deref):
(JSC::StructureStubInfo::addAccessCase):
(JSC::StructureStubInfo::reset):
(JSC::StructureStubInfo::visitWeakReferences):
* bytecode/StructureStubInfo.h:
(JSC::StructureStubInfo::StructureStubInfo):
(JSC::StructureStubInfo::initGetByIdSelf):
(JSC::StructureStubInfo::initPutByIdReplace):
(JSC::StructureStubInfo::initStub):
(JSC::StructureStubInfo::setSeen):
(JSC::getStructureStubInfoCodeOrigin):
(JSC::isGetByIdAccess): Deleted.
(JSC::isPutByIdAccess): Deleted.
(JSC::isInAccess): Deleted.
(JSC::StructureStubInfo::initGetByIdList): Deleted.
(JSC::StructureStubInfo::initPutByIdTransition): Deleted.
(JSC::StructureStubInfo::initPutByIdList): Deleted.
(JSC::StructureStubInfo::initInList): Deleted.
(JSC::StructureStubInfo::addWatchpoint): Deleted.
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileIn):
* ftl/FTLCompile.cpp:
(JSC::FTL::mmAllocateDataSection):
* jit/AccessorCallJITStubRoutine.cpp: Removed.
* jit/AccessorCallJITStubRoutine.h: Removed.
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::branchIfEmpty):
(JSC::AssemblyHelpers::branchStructure):
(JSC::AssemblyHelpers::boxBooleanPayload):
(JSC::AssemblyHelpers::boxBoolean):
(JSC::AssemblyHelpers::boxInt32):
* jit/BinarySwitch.cpp:
(JSC::BinarySwitch::BinarySwitch):
(JSC::BinarySwitch::build):
(JSC::BinarySwitch::Case::dump):
(JSC::BinarySwitch::BranchCode::dump):
* jit/BinarySwitch.h:
(JSC::BinarySwitch::Case::operator&lt;):
(JSC::BinarySwitch::BranchCode::BranchCode):
* jit/JIT.h:
* jit/JITInlineCacheGenerator.cpp:
(JSC::garbageStubInfo):
(JSC::JITInlineCacheGenerator::JITInlineCacheGenerator):
(JSC::JITByIdGenerator::JITByIdGenerator):
(JSC::JITGetByIdGenerator::JITGetByIdGenerator):
(JSC::JITPutByIdGenerator::JITPutByIdGenerator):
* jit/JITInlineCacheGenerator.h:
(JSC::JITInlineCacheGenerator::JITInlineCacheGenerator):
(JSC::JITInlineCacheGenerator::stubInfo):
(JSC::JITByIdGenerator::JITByIdGenerator):
(JSC::JITByIdGenerator::reportSlowPathCall):
* jit/JITOperations.cpp:
* jit/Repatch.cpp:
(JSC::repatchCall):
(JSC::repatchByIdSelfAccess):
(JSC::resetGetByIDCheckAndLoad):
(JSC::resetPutByIDCheckAndLoad):
(JSC::replaceWithJump):
(JSC::tryCacheGetByID):
(JSC::repatchGetByID):
(JSC::appropriateGenericPutByIdFunction):
(JSC::appropriateOptimizingPutByIdFunction):
(JSC::tryCachePutByID):
(JSC::repatchPutByID):
(JSC::tryRepatchIn):
(JSC::repatchIn):
(JSC::resetGetByID):
(JSC::resetPutByID):
(JSC::checkObjectPropertyCondition): Deleted.
(JSC::checkObjectPropertyConditions): Deleted.
(JSC::emitRestoreScratch): Deleted.
(JSC::linkRestoreScratch): Deleted.
(JSC::toString): Deleted.
(JSC::kindFor): Deleted.
(JSC::customFor): Deleted.
(JSC::generateByIdStub): Deleted.
(JSC::patchJumpToGetByIdStub): Deleted.
(JSC::tryBuildGetByIDList): Deleted.
(JSC::buildGetByIDList): Deleted.
(JSC::appropriateListBuildingPutByIdFunction): Deleted.
(JSC::emitPutReplaceStub): Deleted.
(JSC::emitPutTransitionStub): Deleted.
(JSC::tryBuildPutByIdList): Deleted.
(JSC::buildPutByIdList): Deleted.
* jit/ScratchRegisterAllocator.cpp:
(JSC::ScratchRegisterAllocator::lock):
(JSC::ScratchRegisterAllocator::allocateScratch):
* jit/ScratchRegisterAllocator.h:
(JSC::ScratchRegisterAllocator::ScratchRegisterAllocator):
* jsc.cpp:
(GlobalObject::finishCreation):
(functionQuit):
(functionAbort):
(functionFalse1):
(functionFalse2):
* runtime/Options.h:
* tests/stress/array-message-passing.js: Added.
(window.addEventListener):
(window.postMessage):
(window._handleEvents):
(testPassed):
(testFailed):
(classCompare):
(bufferCompare):
(viewCompare):
(typedArrayCompare):
(dataViewCompare):
(dataViewCompare2):
(dataViewCompare3):
(createBuffer):
(createTypedArray):
(createTypedArrayOverBuffer):
(new.DataView):
(testList.testList.concat.basicBufferTypes.map):
(doneTest):

Source/WTF:

Beef up dumping a bit.

* wtf/PrintStream.h:
(WTF::pointerDump):
(WTF::printInternal):</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="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerCodeRefh">trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockh">trunk/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp</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="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelpersh">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitBinarySwitchcpp">trunk/Source/JavaScriptCore/jit/BinarySwitch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitBinarySwitchh">trunk/Source/JavaScriptCore/jit/BinarySwitch.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITInlineCacheGeneratorcpp">trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITInlineCacheGeneratorh">trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchcpp">trunk/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitScratchRegisterAllocatorcpp">trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitScratchRegisterAllocatorh">trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfPrintStreamh">trunk/Source/WTF/wtf/PrintStream.h</a></li>
<li><a href="#trunkToolsScriptsrunjscstresstests">trunk/Tools/Scripts/run-jsc-stress-tests</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<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="#trunkSourceJavaScriptCoretestsstressarraymessagepassingjs">trunk/Source/JavaScriptCore/tests/stress/array-message-passing.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicAccessStructureListh">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccessStructureList.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicGetByIdListcpp">trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicGetByIdListh">trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicPutByIdListcpp">trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicPutByIdListh">trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAccessorCallJITStubRoutinecpp">trunk/Source/JavaScriptCore/jit/AccessorCallJITStubRoutine.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAccessorCallJITStubRoutineh">trunk/Source/JavaScriptCore/jit/AccessorCallJITStubRoutine.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 (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -104,8 +104,7 @@
</span><span class="cx">     bytecode/ObjectPropertyCondition.cpp
</span><span class="cx">     bytecode/ObjectPropertyConditionSet.cpp
</span><span class="cx">     bytecode/Opcode.cpp
</span><del>-    bytecode/PolymorphicGetByIdList.cpp
-    bytecode/PolymorphicPutByIdList.cpp
</del><ins>+    bytecode/PolymorphicAccess.cpp
</ins><span class="cx">     bytecode/PreciseJumpTargets.cpp
</span><span class="cx">     bytecode/PropertyCondition.cpp
</span><span class="cx">     bytecode/PutByIdStatus.cpp
</span><span class="lines">@@ -357,7 +356,6 @@
</span><span class="cx">     interpreter/ProtoCallFrame.cpp
</span><span class="cx">     interpreter/StackVisitor.cpp
</span><span class="cx"> 
</span><del>-    jit/AccessorCallJITStubRoutine.cpp
</del><span class="cx">     jit/AssemblyHelpers.cpp
</span><span class="cx">     jit/BinarySwitch.cpp
</span><span class="cx">     jit/ExecutableAllocationFuzz.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,3 +1,291 @@
</span><ins>+2015-09-09  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        There should be one stub hanging off an inline cache that contains code for all of the cases, rather than forming a linked list consisting of one stub per case
+        https://bugs.webkit.org/show_bug.cgi?id=148717
+
+        Reviewed by Michael Saboff.
+
+        This is a major rewrite of the JSC get/put/in inline caches (ICs), motivated by the need to add
+        fancy new kinds of inline caches for property type inference (https://webkit.org/b/148610).
+
+        Previously, our inline caches had some problems that made them difficult to work with. It was
+        impossible to change any code that was previously generated by the IC except by blowing the
+        whole IC away, the ICs scaled poorly if there were many cases, and there was a lot of duplicate
+        and ad hoc code.
+
+        Impossible to regenerate a previously generated stub: Say that some access (o.f = v) causes our
+        IC code to emit some stub; let's call it stub1. Then later we find that we need to emit a
+        different stub, stub2, where we think that stub2 might subsume stub1. We say that stub2
+        subsumes stub1 if failing to execute stub2 to completion means that we are guaranteed to fail
+        to execute stub1 to completion. This could happen in trunk if stub2 has the same base structure
+        as stub1 but different prototype conditions. It could happen with property type inference if
+        stub2 has a looser type check on v than stub1 did. Currently, if this happened, we would emit
+        stub2 and have its slow path jump to stub1. Hence, we would still end up executing the checks
+        of stub1 before falling through to the slow path. This gets bad when there are many stubs.
+        Stub1 might be in front of a bunch of other stubs, so when we add stub2, we will end up
+        executing both stub2's and stub1's checks before falling through to the other stubs. It would
+        be better if we could remove stub1 from the list at this point. But since stub1 could be linked
+        to from a different stub that we had already generated, we'd have to have a way of patching
+        stubs or regenerating them from scratch. This is currenty impossible because we just don't keep
+        around enough meta-data to mess with a stub after it's generated. After this change, we never
+        link new stubs onto a linked list of pre-existing stubs; instead each IC will have one stub
+        hanging off of it and we always regenerate that one stub from scratch. That one stub contains
+        either a BinarySwitch or a branch cascade to select one of the AccessCases. Each AccessCase is
+        an object that describes everything we need to regenerate it in the future. This means that
+        when we add a new case to an IC stub, we can figure out which previous cases this one subsumes.
+
+        Poor scalability when there are many cases: Previously, the cases of a polymorphic inline cache
+        formed a linked list of branches. This meant that the complexity of an inline cache grew
+        linearly with the number of cases. This change turns this into a BinarySwitch in most cases,
+        leading to logarithmic scaling.
+
+        Duplicate code between get, put, and in: The code for op_get_by_id, op_put_by_id, and op_in
+        inline caches grew independently and ended up having a lot of duplicate code. We had the worst
+        kinds of duplicate code. In some cases, the code was copy-pasted. In other cases, we wrote code
+        that felt like it was new despite the fact that it was logically identical to code that was
+        already written elsewhere. The main sources of duplication were in selecting a scratch
+        register, checking all of the ObjectPropertyConditions and the base structure, the pro forma
+        involved in generating a stub, and the data structures needed to describe all of the access
+        cases. This change deduplicates all of that code. Now, all of those ICs use the same classes:
+        the PolymorphicAccess and AccessCase. There is code in those classes that handles all of the
+        common things, and for the most part the only code that actually specializes for the kind of
+        access is in some switch statement in AccessCase::generate().
+
+        Special-casing of array length and string length: Previously, array.length and string.length
+        were handled in an ad hoc manner in the get_by_id repatching code. The handling was separate
+        from the polymorphic get_by_id handling, which meant that we could not handle polymorphic
+        length accesses if one of the length cases was either array or string length. For example, if
+        you had &quot;o.length&quot; where the length was either array length or a vanilla length property, then
+        the get_by_id inline cache would either emit a monomorphic stub for array length, or a
+        monomorphic stub for the vanilla length property, but never a polymorphic stub (or list) that
+        could do both. This change addresses this problem by folding array length and string length
+        into the polymorphic get_by_id code.
+
+        This was meant to be a perf-neutral change to enable property type inference, but it ended up
+        being a 1% Octane speed-up, mainly because of a 14% speed-up in raytrace. This isn't too
+        surprising, since that test does use inline caches a lot and this change makes inline caches
+        more scalable.
+
+        This also fixes and adds a test for a BinarySwitch bug. BinarySwitch had an optimization for
+        consecutive integer cases. Using it on typed array structures triggers this bug. It's a hard
+        bug to trigger any other way because our other switch optimizations will usually use a jump
+        table in case of consecutive integers.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/MacroAssemblerCodeRef.h:
+        (JSC::MacroAssemblerCodePtr::dumpWithName):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printGetByIdCacheStatus):
+        (JSC::CodeBlock::printPutByIdCacheStatus):
+        (JSC::CodeBlock::propagateTransitions):
+        (JSC::CodeBlock::getByValInfoMap):
+        (JSC::CodeBlock::addStubInfo):
+        (JSC::CodeBlock::findStubInfo):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::stubInfoBegin):
+        (JSC::CodeBlock::stubInfoEnd):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
+        * bytecode/PolymorphicAccess.cpp: Copied from Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp.
+        (JSC::AccessGenerationState::addWatchpoint):
+        (JSC::AccessGenerationState::restoreScratch):
+        (JSC::AccessGenerationState::succeed):
+        (JSC::AccessCase::AccessCase):
+        (JSC::AccessCase::get):
+        (JSC::AccessCase::replace):
+        (JSC::AccessCase::transition):
+        (JSC::AccessCase::setter):
+        (JSC::AccessCase::in):
+        (JSC::AccessCase::getLength):
+        (JSC::AccessCase::~AccessCase):
+        (JSC::AccessCase::fromStructureStubInfo):
+        (JSC::AccessCase::clone):
+        (JSC::AccessCase::guardedByStructureCheck):
+        (JSC::AccessCase::alternateBase):
+        (JSC::AccessCase::canReplace):
+        (JSC::AccessCase::dump):
+        (JSC::AccessCase::visitWeak):
+        (JSC::AccessCase::generateWithGuard):
+        (JSC::AccessCase::generate):
+        (JSC::PolymorphicAccess::PolymorphicAccess):
+        (JSC::PolymorphicAccess::~PolymorphicAccess):
+        (JSC::PolymorphicAccess::regenerateWithCases):
+        (JSC::PolymorphicAccess::regenerateWithCase):
+        (JSC::PolymorphicAccess::visitWeak):
+        (JSC::PolymorphicAccess::dump):
+        (JSC::PolymorphicAccess::regenerate):
+        (WTF::printInternal):
+        (JSC::GetByIdAccess::GetByIdAccess): Deleted.
+        (JSC::GetByIdAccess::~GetByIdAccess): Deleted.
+        (JSC::GetByIdAccess::fromStructureStubInfo): Deleted.
+        (JSC::GetByIdAccess::visitWeak): Deleted.
+        (JSC::PolymorphicGetByIdList::PolymorphicGetByIdList): Deleted.
+        (JSC::PolymorphicGetByIdList::from): Deleted.
+        (JSC::PolymorphicGetByIdList::~PolymorphicGetByIdList): Deleted.
+        (JSC::PolymorphicGetByIdList::currentSlowPathTarget): Deleted.
+        (JSC::PolymorphicGetByIdList::addAccess): Deleted.
+        (JSC::PolymorphicGetByIdList::isFull): Deleted.
+        (JSC::PolymorphicGetByIdList::isAlmostFull): Deleted.
+        (JSC::PolymorphicGetByIdList::didSelfPatching): Deleted.
+        (JSC::PolymorphicGetByIdList::visitWeak): Deleted.
+        * bytecode/PolymorphicAccess.h: Copied from Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h.
+        (JSC::AccessCase::isGet):
+        (JSC::AccessCase::isPut):
+        (JSC::AccessCase::isIn):
+        (JSC::AccessCase::type):
+        (JSC::AccessCase::offset):
+        (JSC::AccessCase::viaProxy):
+        (JSC::AccessCase::structure):
+        (JSC::AccessCase::newStructure):
+        (JSC::AccessCase::conditionSet):
+        (JSC::AccessCase::additionalSet):
+        (JSC::AccessCase::customSlotBase):
+        (JSC::AccessCase::doesCalls):
+        (JSC::AccessCase::callLinkInfo):
+        (JSC::AccessCase::RareData::RareData):
+        (JSC::PolymorphicAccess::isEmpty):
+        (JSC::PolymorphicAccess::size):
+        (JSC::PolymorphicAccess::at):
+        (JSC::PolymorphicAccess::operator[]):
+        (JSC::GetByIdAccess::GetByIdAccess): Deleted.
+        (JSC::GetByIdAccess::isSet): Deleted.
+        (JSC::GetByIdAccess::operator!): Deleted.
+        (JSC::GetByIdAccess::type): Deleted.
+        (JSC::GetByIdAccess::structure): Deleted.
+        (JSC::GetByIdAccess::conditionSet): Deleted.
+        (JSC::GetByIdAccess::stubRoutine): Deleted.
+        (JSC::GetByIdAccess::doesCalls): Deleted.
+        (JSC::PolymorphicGetByIdList::isEmpty): Deleted.
+        (JSC::PolymorphicGetByIdList::size): Deleted.
+        (JSC::PolymorphicGetByIdList::at): Deleted.
+        (JSC::PolymorphicGetByIdList::operator[]): Deleted.
+        * bytecode/PolymorphicAccessStructureList.h: Removed.
+        * bytecode/PolymorphicGetByIdList.cpp: Removed.
+        * bytecode/PolymorphicGetByIdList.h: Removed.
+        * bytecode/PolymorphicPutByIdList.cpp: Removed.
+        * bytecode/PolymorphicPutByIdList.h: Removed.
+        * bytecode/PutByIdStatus.cpp:
+        (JSC::PutByIdStatus::computeForStubInfo):
+        * bytecode/StructureStubInfo.cpp:
+        (JSC::StructureStubInfo::deref):
+        (JSC::StructureStubInfo::addAccessCase):
+        (JSC::StructureStubInfo::reset):
+        (JSC::StructureStubInfo::visitWeakReferences):
+        * bytecode/StructureStubInfo.h:
+        (JSC::StructureStubInfo::StructureStubInfo):
+        (JSC::StructureStubInfo::initGetByIdSelf):
+        (JSC::StructureStubInfo::initPutByIdReplace):
+        (JSC::StructureStubInfo::initStub):
+        (JSC::StructureStubInfo::setSeen):
+        (JSC::getStructureStubInfoCodeOrigin):
+        (JSC::isGetByIdAccess): Deleted.
+        (JSC::isPutByIdAccess): Deleted.
+        (JSC::isInAccess): Deleted.
+        (JSC::StructureStubInfo::initGetByIdList): Deleted.
+        (JSC::StructureStubInfo::initPutByIdTransition): Deleted.
+        (JSC::StructureStubInfo::initPutByIdList): Deleted.
+        (JSC::StructureStubInfo::initInList): Deleted.
+        (JSC::StructureStubInfo::addWatchpoint): Deleted.
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileIn):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * jit/AccessorCallJITStubRoutine.cpp: Removed.
+        * jit/AccessorCallJITStubRoutine.h: Removed.
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::branchIfEmpty):
+        (JSC::AssemblyHelpers::branchStructure):
+        (JSC::AssemblyHelpers::boxBooleanPayload):
+        (JSC::AssemblyHelpers::boxBoolean):
+        (JSC::AssemblyHelpers::boxInt32):
+        * jit/BinarySwitch.cpp:
+        (JSC::BinarySwitch::BinarySwitch):
+        (JSC::BinarySwitch::build):
+        (JSC::BinarySwitch::Case::dump):
+        (JSC::BinarySwitch::BranchCode::dump):
+        * jit/BinarySwitch.h:
+        (JSC::BinarySwitch::Case::operator&lt;):
+        (JSC::BinarySwitch::BranchCode::BranchCode):
+        * jit/JIT.h:
+        * jit/JITInlineCacheGenerator.cpp:
+        (JSC::garbageStubInfo):
+        (JSC::JITInlineCacheGenerator::JITInlineCacheGenerator):
+        (JSC::JITByIdGenerator::JITByIdGenerator):
+        (JSC::JITGetByIdGenerator::JITGetByIdGenerator):
+        (JSC::JITPutByIdGenerator::JITPutByIdGenerator):
+        * jit/JITInlineCacheGenerator.h:
+        (JSC::JITInlineCacheGenerator::JITInlineCacheGenerator):
+        (JSC::JITInlineCacheGenerator::stubInfo):
+        (JSC::JITByIdGenerator::JITByIdGenerator):
+        (JSC::JITByIdGenerator::reportSlowPathCall):
+        * jit/JITOperations.cpp:
+        * jit/Repatch.cpp:
+        (JSC::repatchCall):
+        (JSC::repatchByIdSelfAccess):
+        (JSC::resetGetByIDCheckAndLoad):
+        (JSC::resetPutByIDCheckAndLoad):
+        (JSC::replaceWithJump):
+        (JSC::tryCacheGetByID):
+        (JSC::repatchGetByID):
+        (JSC::appropriateGenericPutByIdFunction):
+        (JSC::appropriateOptimizingPutByIdFunction):
+        (JSC::tryCachePutByID):
+        (JSC::repatchPutByID):
+        (JSC::tryRepatchIn):
+        (JSC::repatchIn):
+        (JSC::resetGetByID):
+        (JSC::resetPutByID):
+        (JSC::checkObjectPropertyCondition): Deleted.
+        (JSC::checkObjectPropertyConditions): Deleted.
+        (JSC::emitRestoreScratch): Deleted.
+        (JSC::linkRestoreScratch): Deleted.
+        (JSC::toString): Deleted.
+        (JSC::kindFor): Deleted.
+        (JSC::customFor): Deleted.
+        (JSC::generateByIdStub): Deleted.
+        (JSC::patchJumpToGetByIdStub): Deleted.
+        (JSC::tryBuildGetByIDList): Deleted.
+        (JSC::buildGetByIDList): Deleted.
+        (JSC::appropriateListBuildingPutByIdFunction): Deleted.
+        (JSC::emitPutReplaceStub): Deleted.
+        (JSC::emitPutTransitionStub): Deleted.
+        (JSC::tryBuildPutByIdList): Deleted.
+        (JSC::buildPutByIdList): Deleted.
+        * jit/ScratchRegisterAllocator.cpp:
+        (JSC::ScratchRegisterAllocator::lock):
+        (JSC::ScratchRegisterAllocator::allocateScratch):
+        * jit/ScratchRegisterAllocator.h:
+        (JSC::ScratchRegisterAllocator::ScratchRegisterAllocator):
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionQuit):
+        (functionAbort):
+        (functionFalse1):
+        (functionFalse2):
+        * runtime/Options.h:
+        * tests/stress/array-message-passing.js: Added.
+        (window.addEventListener):
+        (window.postMessage):
+        (window._handleEvents):
+        (testPassed):
+        (testFailed):
+        (classCompare):
+        (bufferCompare):
+        (viewCompare):
+        (typedArrayCompare):
+        (dataViewCompare):
+        (dataViewCompare2):
+        (dataViewCompare3):
+        (createBuffer):
+        (createTypedArray):
+        (createTypedArrayOverBuffer):
+        (new.DataView):
+        (testList.testList.concat.basicBufferTypes.map):
+        (doneTest):
+
</ins><span class="cx"> 2015-09-10  Geoffrey Garen  &lt;ggaren@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         CodeBlock::codeType() doesn't need to compute anything
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -343,8 +343,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\ObjectPropertyCondition.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\ObjectPropertyConditionSet.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\Opcode.cpp&quot; /&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\bytecode\PolymorphicGetByIdList.cpp&quot; /&gt;
-    &lt;ClCompile Include=&quot;..\bytecode\PolymorphicPutByIdList.cpp&quot; /&gt;
</del><ins>+    &lt;ClCompile Include=&quot;..\bytecode\PolymorphicAccess.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\PreciseJumpTargets.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\PropertyCondition.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\PutByIdStatus.cpp&quot; /&gt;
</span><span class="lines">@@ -617,7 +616,6 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\interpreter\JSStack.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\interpreter\ProtoCallFrame.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\interpreter\StackVisitor.cpp&quot; /&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\jit\AccessorCallJITStubRoutine.cpp&quot; /&gt;
</del><span class="cx">     &lt;ClCompile Include=&quot;..\jit\AssemblyHelpers.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\BinarySwitch.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\jit\ExecutableAllocationFuzz.cpp&quot; /&gt;
</span><span class="lines">@@ -1045,8 +1043,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\ObjectPropertyConditionSet.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\Opcode.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\Operands.h&quot; /&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\bytecode\PolymorphicGetByIdList.h&quot; /&gt;
-    &lt;ClInclude Include=&quot;..\bytecode\PolymorphicPutByIdList.h&quot; /&gt;
</del><ins>+    &lt;ClInclude Include=&quot;..\bytecode\PolymorphicAccess.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\PreciseJumpTargets.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\PropertyCondition.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\PutByIdStatus.h&quot; /&gt;
</span><span class="lines">@@ -1417,7 +1414,6 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\interpreter\ProtoCallFrame.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\interpreter\Register.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\interpreter\StackVisitor.h&quot; /&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\jit\AccessorCallJITStubRoutine.h&quot; /&gt;
</del><span class="cx">     &lt;ClInclude Include=&quot;..\jit\AssemblyHelpers.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\BinarySwitch.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\jit\CCallHelpers.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -198,7 +198,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\Opcode.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;bytecode&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\bytecode\PolymorphicPutByIdList.cpp&quot;&gt;
</del><ins>+    &lt;ClCompile Include=&quot;..\bytecode\PolymorphicAccess.cpp&quot;&gt;
</ins><span class="cx">       &lt;Filter&gt;bytecode&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\PutByIdStatus.cpp&quot;&gt;
</span><span class="lines">@@ -1623,9 +1623,6 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\llvm\LLVMAPI.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;llvm&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\jit\AccessorCallJITStubRoutine.cpp&quot;&gt;
-      &lt;Filter&gt;jit&lt;/Filter&gt;
-    &lt;/ClCompile&gt;
</del><span class="cx">     &lt;ClCompile Include=&quot;..\inspector\ConsoleMessage.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;inspector&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -1692,9 +1689,6 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\inspector\JSJavaScriptCallFramePrototype.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;inspector&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><del>-    &lt;ClCompile Include=&quot;..\bytecode\PolymorphicGetByIdList.cpp&quot;&gt;
-      &lt;Filter&gt;bytecode&lt;/Filter&gt;
-    &lt;/ClCompile&gt;
</del><span class="cx">     &lt;ClCompile Include=&quot;..\profiler\ProfilerJettisonReason.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;profiler&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -2097,7 +2091,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\Operands.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;bytecode&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\bytecode\PolymorphicPutByIdList.h&quot;&gt;
</del><ins>+    &lt;ClInclude Include=&quot;..\bytecode\PolymorphicAccess.h&quot;&gt;
</ins><span class="cx">       &lt;Filter&gt;bytecode&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\PutByIdStatus.h&quot;&gt;
</span><span class="lines">@@ -4202,9 +4196,6 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\llvm\LLVMHeaders.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;llvm&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\jit\AccessorCallJITStubRoutine.h&quot;&gt;
-      &lt;Filter&gt;jit&lt;/Filter&gt;
-    &lt;/ClInclude&gt;
</del><span class="cx">     &lt;ClInclude Include=&quot;..\assembler\AbortReason.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;assembler&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><span class="lines">@@ -4283,9 +4274,6 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\JSCInlines.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;runtime&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\bytecode\PolymorphicGetByIdList.h&quot;&gt;
-      &lt;Filter&gt;bytecode&lt;/Filter&gt;
-    &lt;/ClInclude&gt;
</del><span class="cx">     &lt;ClInclude Include=&quot;..\profiler\ProfilerJettisonReason.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;profiler&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -272,7 +272,6 @@
</span><span class="cx">                 0F300B7C18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F300B7A18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; };
</span><span class="cx">                 0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0F34B14C16D43E0D001CDA5A /* PolymorphicAccessStructureList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */; };
</span><span class="cx">                 0F38B01217CF078300B144D3 /* LLIntEntrypoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38B01017CF077F00B144D3 /* LLIntEntrypoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F38B01717CFE75500B144D3 /* DFGCompilationKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B01317CFE75500B144D3 /* DFGCompilationKey.cpp */; };
</span><span class="lines">@@ -324,8 +323,6 @@
</span><span class="cx">                 0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F493AF816D0CAD10084508B /* SourceProvider.cpp */; };
</span><span class="cx">                 0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0F4CED5E18CEA7AB00802FE0 /* PolymorphicGetByIdList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4CED5C18CEA7AB00802FE0 /* PolymorphicGetByIdList.cpp */; };
-                0F4CED5F18CEA7AB00802FE0 /* PolymorphicGetByIdList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4CED5D18CEA7AB00802FE0 /* PolymorphicGetByIdList.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
</span><span class="cx">                 0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -394,8 +391,6 @@
</span><span class="cx">                 0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */; };
</span><span class="cx">                 0F714CA516EA92F200F3EBEB /* DFGBackwardsPropagationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 652A3A201651C66100A80AFE /* ARM64Disassembler.cpp */; };
</span><del>-                0F7576D218E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7576D018E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp */; };
-                0F7576D318E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7576D118E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */; };
</span><span class="cx">                 0F766D2B15A8CC38008F363E /* JITStubRoutineSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */; };
</span><span class="cx">                 0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D2A15A8CC34008F363E /* JITStubRoutineSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -469,8 +464,6 @@
</span><span class="cx">                 0F9E32641B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9E32621B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F9FB4F417FCB91700CB67F8 /* DFGStackLayoutPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9FB4F217FCB91700CB67F8 /* DFGStackLayoutPhase.cpp */; };
</span><span class="cx">                 0F9FB4F517FCB91700CB67F8 /* DFGStackLayoutPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9FB4F317FCB91700CB67F8 /* DFGStackLayoutPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */; };
-                0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 0F9FC8C514E1B60400D52AE0 /* PutKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9FC8C114E1B5FB00D52AE0 /* PutKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FA2C17B17D7CF84009D015F /* TestRunnerUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA2C17917D7CF84009D015F /* TestRunnerUtils.cpp */; };
</span><span class="cx">                 0FA2C17C17D7CF84009D015F /* TestRunnerUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA2C17A17D7CF84009D015F /* TestRunnerUtils.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -738,6 +731,8 @@
</span><span class="cx">                 0FF8BDEA1AD4CF7100DFE884 /* InferredValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF8BDE81AD4CF7100DFE884 /* InferredValue.cpp */; };
</span><span class="cx">                 0FF8BDEB1AD4CF7100DFE884 /* InferredValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF8BDE91AD4CF7100DFE884 /* InferredValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FF922D414F46B410041A24E /* LLIntOffsetsExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */; };
</span><ins>+                0FF9CE731B9CD6D0004EDCA6 /* PolymorphicAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF9CE711B9CD6D0004EDCA6 /* PolymorphicAccess.cpp */; };
+                0FF9CE741B9CD6D0004EDCA6 /* PolymorphicAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF9CE721B9CD6D0004EDCA6 /* PolymorphicAccess.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0FFA549716B8835000B3A982 /* A64DOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 652A3A221651C69700A80AFE /* A64DOpcode.cpp */; };
</span><span class="cx">                 0FFA549816B8835300B3A982 /* A64DOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 652A3A231651C69700A80AFE /* A64DOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FFB6C381AF48DDC00DB1BF7 /* TypeofType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFB6C361AF48DDC00DB1BF7 /* TypeofType.cpp */; };
</span><span class="lines">@@ -2103,7 +2098,6 @@
</span><span class="cx">                 0F300B7A18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGIntegerCheckCombiningPhase.h; path = dfg/DFGIntegerCheckCombiningPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicAccessStructureList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoint.cpp; path = llint/LLIntEntrypoint.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F38B01017CF077F00B144D3 /* LLIntEntrypoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoint.h; path = llint/LLIntEntrypoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F38B01317CFE75500B144D3 /* DFGCompilationKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCompilationKey.cpp; path = dfg/DFGCompilationKey.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2156,8 +2150,6 @@
</span><span class="cx">                 0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLRecoveryOpcode.h; path = ftl/FTLRecoveryOpcode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F493AF816D0CAD10084508B /* SourceProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProvider.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F4CED5C18CEA7AB00802FE0 /* PolymorphicGetByIdList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicGetByIdList.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F4CED5D18CEA7AB00802FE0 /* PolymorphicGetByIdList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicGetByIdList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureClobberState.h; path = dfg/DFGStructureClobberState.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2225,8 +2217,6 @@
</span><span class="cx">                 0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilerCommon.h; path = dfg/DFGOSRExitCompilerCommon.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBackwardsPropagationPhase.cpp; path = dfg/DFGBackwardsPropagationPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBackwardsPropagationPhase.h; path = dfg/DFGBackwardsPropagationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F7576D018E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessorCallJITStubRoutine.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F7576D118E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessorCallJITStubRoutine.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F766D1C15A5028D008F363E /* JITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutine.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITStubRoutine.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITStubRoutineSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2299,8 +2289,6 @@
</span><span class="cx">                 0F9E32621B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStoreBarrierInsertionPhase.h; path = dfg/DFGStoreBarrierInsertionPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F9FB4F217FCB91700CB67F8 /* DFGStackLayoutPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStackLayoutPhase.cpp; path = dfg/DFGStackLayoutPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F9FB4F317FCB91700CB67F8 /* DFGStackLayoutPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStackLayoutPhase.h; path = dfg/DFGStackLayoutPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicPutByIdList.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicPutByIdList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F9FC8C114E1B5FB00D52AE0 /* PutKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutKind.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA2C17917D7CF84009D015F /* TestRunnerUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestRunnerUtils.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA2C17A17D7CF84009D015F /* TestRunnerUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestRunnerUtils.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2575,6 +2563,8 @@
</span><span class="cx">                 0FF8BDE81AD4CF7100DFE884 /* InferredValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InferredValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FF8BDE91AD4CF7100DFE884 /* InferredValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InferredValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = &quot;compiled.mach-o.executable&quot;; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
</span><ins>+                0FF9CE711B9CD6D0004EDCA6 /* PolymorphicAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicAccess.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FF9CE721B9CD6D0004EDCA6 /* PolymorphicAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicAccess.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FFB6C361AF48DDC00DB1BF7 /* TypeofType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeofType.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FFB6C371AF48DDC00DB1BF7 /* TypeofType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeofType.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FFC99D0184EC8AD009C10AB /* ConstantMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4096,16 +4086,14 @@
</span><span class="cx">                 1429D92C0ED22D7000B89619 /* jit */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><del>-                                0FF054F71AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp */,
-                                0FF054F81AC35B4400E5BE57 /* ExecutableAllocationFuzz.h */,
-                                0F7576D018E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp */,
-                                0F7576D118E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h */,
</del><span class="cx">                                 0F24E53B17EA9F5900ABB217 /* AssemblyHelpers.cpp */,
</span><span class="cx">                                 0F24E53C17EA9F5900ABB217 /* AssemblyHelpers.h */,
</span><span class="cx">                                 0F64B26F1A784BAF006E4E66 /* BinarySwitch.cpp */,
</span><span class="cx">                                 0F64B2701A784BAF006E4E66 /* BinarySwitch.h */,
</span><span class="cx">                                 0F24E53D17EA9F5900ABB217 /* CCallHelpers.h */,
</span><span class="cx">                                 0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,
</span><ins>+                                0FF054F71AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp */,
+                                0FF054F81AC35B4400E5BE57 /* ExecutableAllocationFuzz.h */,
</ins><span class="cx">                                 A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */,
</span><span class="cx">                                 A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */,
</span><span class="cx">                                 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */,
</span><span class="lines">@@ -5606,11 +5594,8 @@
</span><span class="cx">                                 969A07950ED1D3AE00F1F681 /* Opcode.h */,
</span><span class="cx">                                 0F2BDC2B151FDE8B00CD8910 /* Operands.h */,
</span><span class="cx">                                 A70447E917A0BD4600F5898E /* OperandsInlines.h */,
</span><del>-                                0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */,
-                                0F4CED5C18CEA7AB00802FE0 /* PolymorphicGetByIdList.cpp */,
-                                0F4CED5D18CEA7AB00802FE0 /* PolymorphicGetByIdList.h */,
-                                0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */,
-                                0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */,
</del><ins>+                                0FF9CE711B9CD6D0004EDCA6 /* PolymorphicAccess.cpp */,
+                                0FF9CE721B9CD6D0004EDCA6 /* PolymorphicAccess.h */,
</ins><span class="cx">                                 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */,
</span><span class="cx">                                 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */,
</span><span class="cx">                                 0FD3E4071B618B6600C80E1E /* PropertyCondition.cpp */,
</span><span class="lines">@@ -5641,8 +5626,8 @@
</span><span class="cx">                                 0F2D4DE719832DAC007D4B19 /* TypeLocation.h */,
</span><span class="cx">                                 A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */,
</span><span class="cx">                                 A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */,
</span><del>-                                14142E501B796ECE00F4BF4B /* UnlinkedFunctionExecutable.h */,
</del><span class="cx">                                 14142E541B7973C000F4BF4B /* UnlinkedFunctionExecutable.cpp */,
</span><ins>+                                14142E501B796ECE00F4BF4B /* UnlinkedFunctionExecutable.h */,
</ins><span class="cx">                                 B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */,
</span><span class="cx">                                 B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */,
</span><span class="cx">                                 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */,
</span><span class="lines">@@ -6207,7 +6192,6 @@
</span><span class="cx">                                 0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */,
</span><span class="cx">                                 0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */,
</span><span class="cx">                                 0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */,
</span><del>-                                0F4CED5F18CEA7AB00802FE0 /* PolymorphicGetByIdList.h in Headers */,
</del><span class="cx">                                 0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */,
</span><span class="cx">                                 0FFFC95C14EF90AF00C72532 /* DFGPhase.h in Headers */,
</span><span class="cx">                                 A5EA70EE19F5B5C40098F5EC /* JSContextRefInspectorSupport.h in Headers */,
</span><span class="lines">@@ -6256,6 +6240,7 @@
</span><span class="cx">                                 99E45A2418A1B2590026D88F /* EmptyInputCursor.h in Headers */,
</span><span class="cx">                                 14142E531B796EDD00F4BF4B /* ExecutableInfo.h in Headers */,
</span><span class="cx">                                 99E45A2618A1B2590026D88F /* EncodedValue.h in Headers */,
</span><ins>+                                0FF9CE741B9CD6D0004EDCA6 /* PolymorphicAccess.h in Headers */,
</ins><span class="cx">                                 0F5874EE194FEB1200AAB2C1 /* DFGMayExit.h in Headers */,
</span><span class="cx">                                 BC3046070E1F497F003232CF /* Error.h in Headers */,
</span><span class="cx">                                 BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */,
</span><span class="lines">@@ -6488,7 +6473,6 @@
</span><span class="cx">                                 BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */,
</span><span class="cx">                                 148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
</span><span class="cx">                                 A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */,
</span><del>-                                0F7576D318E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h in Headers */,
</del><span class="cx">                                 0F2B66EC17B6B5AB00A7AE3F /* JSDataView.h in Headers */,
</span><span class="cx">                                 0F2B66EE17B6B5AB00A7AE3F /* JSDataViewPrototype.h in Headers */,
</span><span class="cx">                                 978801411471AD920041B016 /* JSDateMath.h in Headers */,
</span><span class="lines">@@ -6688,8 +6672,6 @@
</span><span class="cx">                                 0FCCAE4516D0CF7400D0C65B /* ParserError.h in Headers */,
</span><span class="cx">                                 A77F1825164192C700640A47 /* ParserModes.h in Headers */,
</span><span class="cx">                                 65303D641447B9E100D3F904 /* ParserTokens.h in Headers */,
</span><del>-                                0F34B14C16D43E0D001CDA5A /* PolymorphicAccessStructureList.h in Headers */,
-                                0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */,
</del><span class="cx">                                 0F8F14341ADF090100ED792C /* DFGEpoch.h in Headers */,
</span><span class="cx">                                 0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */,
</span><span class="cx">                                 0F2DD8151AB3D8BE00BBB8E8 /* DFGForAllKills.h in Headers */,
</span><span class="lines">@@ -7848,7 +7830,6 @@
</span><span class="cx">                                 0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
</span><span class="cx">                                 0FCEFACD1805E75500472CE4 /* LLVMAPI.cpp in Sources */,
</span><span class="cx">                                 A7E5AB371799E4B200D2833D /* LLVMDisassembler.cpp in Sources */,
</span><del>-                                0F4CED5E18CEA7AB00802FE0 /* PolymorphicGetByIdList.cpp in Sources */,
</del><span class="cx">                                 14469DDE107EC7E700650446 /* Lookup.cpp in Sources */,
</span><span class="cx">                                 0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
</span><span class="cx">                                 14B723B212D7DA46003BD5ED /* MachineStackMarker.cpp in Sources */,
</span><span class="lines">@@ -7890,7 +7871,6 @@
</span><span class="cx">                                 0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */,
</span><span class="cx">                                 148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */,
</span><span class="cx">                                 93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */,
</span><del>-                                0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
</del><span class="cx">                                 0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
</span><span class="cx">                                 95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
</span><span class="cx">                                 0F2B9CF819D0BAC100B1D1B5 /* FTLOperations.cpp in Sources */,
</span><span class="lines">@@ -7907,6 +7887,7 @@
</span><span class="cx">                                 0F190CAC189D82F6000AE5F0 /* ProfilerJettisonReason.cpp in Sources */,
</span><span class="cx">                                 0FF729B3166AD35C000F5BA3 /* ProfilerOrigin.cpp in Sources */,
</span><span class="cx">                                 0FF729B4166AD35C000F5BA3 /* ProfilerOriginStack.cpp in Sources */,
</span><ins>+                                0FF9CE731B9CD6D0004EDCA6 /* PolymorphicAccess.cpp in Sources */,
</ins><span class="cx">                                 0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
</span><span class="cx">                                 0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */,
</span><span class="cx">                                 0F13912B16771C3A009CCB07 /* ProfilerProfiledBytecodes.cpp in Sources */,
</span><span class="lines">@@ -8015,7 +7996,6 @@
</span><span class="cx">                                 A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */,
</span><span class="cx">                                 B59F89391891F29F00D5CCDC /* UnlinkedInstructionStream.cpp in Sources */,
</span><span class="cx">                                 E39DA4A61B7E8B7C0084F33A /* JSModuleRecord.cpp in Sources */,
</span><del>-                                0F7576D218E1FEE9002EF4CD /* AccessorCallJITStubRoutine.cpp in Sources */,
</del><span class="cx">                                 0F24E55817F74EDB00ABB217 /* ValueRecovery.cpp in Sources */,
</span><span class="cx">                                 E18E3A590DF9278C00D90B34 /* VM.cpp in Sources */,
</span><span class="cx">                                 FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerCodeRefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -327,6 +327,10 @@
</span><span class="cx"> 
</span><span class="cx">     void dumpWithName(const char* name, PrintStream&amp; out) const
</span><span class="cx">     {
</span><ins>+        if (!m_value) {
+            out.print(name, &quot;(null)&quot;);
+            return;
+        }
</ins><span class="cx">         if (executableAddress() == dataLocation()) {
</span><span class="cx">             out.print(name, &quot;(&quot;, RawPointer(executableAddress()), &quot;)&quot;);
</span><span class="cx">             return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -53,8 +53,7 @@
</span><span class="cx"> #include &quot;LLIntEntrypoint.h&quot;
</span><span class="cx"> #include &quot;LowLevelInterpreter.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><del>-#include &quot;PolymorphicGetByIdList.h&quot;
-#include &quot;PolymorphicPutByIdList.h&quot;
</del><ins>+#include &quot;PolymorphicAccess.h&quot;
</ins><span class="cx"> #include &quot;ProfilerDatabase.h&quot;
</span><span class="cx"> #include &quot;ReduceWhitespace.h&quot;
</span><span class="cx"> #include &quot;Repatch.h&quot;
</span><span class="lines">@@ -347,20 +346,19 @@
</span><span class="cx">         if (stubInfo.seen) {
</span><span class="cx">             out.printf(&quot; jit(&quot;);
</span><span class="cx">             
</span><del>-            Structure* baseStructure = 0;
-            Structure* prototypeStructure = 0;
-            PolymorphicGetByIdList* list = 0;
</del><ins>+            Structure* baseStructure = nullptr;
+            PolymorphicAccess* stub = nullptr;
</ins><span class="cx">             
</span><del>-            switch (stubInfo.accessType) {
-            case access_get_by_id_self:
</del><ins>+            switch (stubInfo.cacheType) {
+            case CacheType::GetByIdSelf:
</ins><span class="cx">                 out.printf(&quot;self&quot;);
</span><del>-                baseStructure = stubInfo.u.getByIdSelf.baseObjectStructure.get();
</del><ins>+                baseStructure = stubInfo.u.byIdSelf.baseObjectStructure.get();
</ins><span class="cx">                 break;
</span><del>-            case access_get_by_id_list:
-                out.printf(&quot;list&quot;);
-                list = stubInfo.u.getByIdList.list;
</del><ins>+            case CacheType::Stub:
+                out.printf(&quot;stub&quot;);
+                stub = stubInfo.u.stub;
</ins><span class="cx">                 break;
</span><del>-            case access_unset:
</del><ins>+            case CacheType::Unset:
</ins><span class="cx">                 out.printf(&quot;unset&quot;);
</span><span class="cx">                 break;
</span><span class="cx">             default:
</span><span class="lines">@@ -372,27 +370,10 @@
</span><span class="cx">                 out.printf(&quot;, &quot;);
</span><span class="cx">                 dumpStructure(out, &quot;struct&quot;, baseStructure, ident);
</span><span class="cx">             }
</span><del>-            
-            if (prototypeStructure) {
-                out.printf(&quot;, &quot;);
-                dumpStructure(out, &quot;prototypeStruct&quot;, baseStructure, ident);
-            }
-            
-            if (list) {
-                out.printf(&quot;, list = %p: [&quot;, list);
-                for (unsigned i = 0; i &lt; list-&gt;size(); ++i) {
-                    if (i)
-                        out.printf(&quot;, &quot;);
-                    out.printf(&quot;(&quot;);
-                    dumpStructure(out, &quot;base&quot;, list-&gt;at(i).structure(), ident);
-                    if (!list-&gt;at(i).conditionSet().isEmpty()) {
-                        out.printf(&quot;, &quot;);
-                        out.print(list-&gt;at(i).conditionSet());
-                    }
-                    out.printf(&quot;)&quot;);
-                }
-                out.printf(&quot;]&quot;);
-            }
</del><ins>+
+            if (stub)
+                out.print(&quot;, &quot;, *stub);
+
</ins><span class="cx">             out.printf(&quot;)&quot;);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -448,53 +429,16 @@
</span><span class="cx">         if (stubInfo.seen) {
</span><span class="cx">             out.printf(&quot; jit(&quot;);
</span><span class="cx">             
</span><del>-            switch (stubInfo.accessType) {
-            case access_put_by_id_replace:
</del><ins>+            switch (stubInfo.cacheType) {
+            case CacheType::PutByIdReplace:
</ins><span class="cx">                 out.print(&quot;replace, &quot;);
</span><del>-                dumpStructure(out, &quot;struct&quot;, stubInfo.u.putByIdReplace.baseObjectStructure.get(), ident);
</del><ins>+                dumpStructure(out, &quot;struct&quot;, stubInfo.u.byIdSelf.baseObjectStructure.get(), ident);
</ins><span class="cx">                 break;
</span><del>-            case access_put_by_id_transition_normal:
-            case access_put_by_id_transition_direct:
-                out.print(&quot;transition, &quot;);
-                dumpStructure(out, &quot;prev&quot;, stubInfo.u.putByIdTransition.previousStructure.get(), ident);
-                out.print(&quot;, &quot;);
-                dumpStructure(out, &quot;next&quot;, stubInfo.u.putByIdTransition.structure.get(), ident);
-                if (stubInfo.u.putByIdTransition.rawConditionSet)
-                    out.print(&quot;, &quot;, ObjectPropertyConditionSet::fromRawPointer(stubInfo.u.putByIdTransition.rawConditionSet));
</del><ins>+            case CacheType::Stub: {
+                out.print(&quot;stub, &quot;, *stubInfo.u.stub);
</ins><span class="cx">                 break;
</span><del>-            case access_put_by_id_list: {
-                out.printf(&quot;list = [&quot;);
-                PolymorphicPutByIdList* list = stubInfo.u.putByIdList.list;
-                CommaPrinter comma;
-                for (unsigned i = 0; i &lt; list-&gt;size(); ++i) {
-                    out.print(comma, &quot;(&quot;);
-                    const PutByIdAccess&amp; access = list-&gt;at(i);
-                    
-                    if (access.isReplace()) {
-                        out.print(&quot;replace, &quot;);
-                        dumpStructure(out, &quot;struct&quot;, access.oldStructure(), ident);
-                    } else if (access.isSetter()) {
-                        out.print(&quot;setter, &quot;);
-                        dumpStructure(out, &quot;struct&quot;, access.oldStructure(), ident);
-                    } else if (access.isCustom()) {
-                        out.print(&quot;custom, &quot;);
-                        dumpStructure(out, &quot;struct&quot;, access.oldStructure(), ident);
-                    } else if (access.isTransition()) {
-                        out.print(&quot;transition, &quot;);
-                        dumpStructure(out, &quot;prev&quot;, access.oldStructure(), ident);
-                        out.print(&quot;, &quot;);
-                        dumpStructure(out, &quot;next&quot;, access.newStructure(), ident);
-                        if (!access.conditionSet().isEmpty())
-                            out.print(&quot;, &quot;, access.conditionSet());
-                    } else
-                        out.print(&quot;unknown&quot;);
-                    
-                    out.print(&quot;)&quot;);
-                }
-                out.print(&quot;]&quot;);
-                break;
</del><span class="cx">             }
</span><del>-            case access_unset:
</del><ins>+            case CacheType::Unset:
</ins><span class="cx">                 out.printf(&quot;unset&quot;);
</span><span class="cx">                 break;
</span><span class="cx">             default:
</span><span class="lines">@@ -2469,40 +2413,23 @@
</span><span class="cx">     if (JITCode::isJIT(jitType())) {
</span><span class="cx">         for (Bag&lt;StructureStubInfo&gt;::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
</span><span class="cx">             StructureStubInfo&amp; stubInfo = **iter;
</span><del>-            switch (stubInfo.accessType) {
-            case access_put_by_id_transition_normal:
-            case access_put_by_id_transition_direct: {
-                JSCell* origin = stubInfo.codeOrigin.codeOriginOwner();
-                if ((!origin || Heap::isMarked(origin))
-                    &amp;&amp; Heap::isMarked(stubInfo.u.putByIdTransition.previousStructure.get()))
-                    visitor.append(&amp;stubInfo.u.putByIdTransition.structure);
</del><ins>+            if (stubInfo.cacheType != CacheType::Stub)
+                continue;
+            PolymorphicAccess* list = stubInfo.u.stub;
+            JSCell* origin = stubInfo.codeOrigin.codeOriginOwner();
+            if (origin &amp;&amp; !Heap::isMarked(origin)) {
+                allAreMarkedSoFar = false;
+                continue;
+            }
+            for (unsigned j = list-&gt;size(); j--;) {
+                const AccessCase&amp; access = list-&gt;at(j);
+                if (access.type() != AccessCase::Transition)
+                    continue;
+                if (Heap::isMarked(access.structure()))
+                    visitor.appendUnbarrieredReadOnlyPointer(access.newStructure());
</ins><span class="cx">                 else
</span><span class="cx">                     allAreMarkedSoFar = false;
</span><del>-                break;
</del><span class="cx">             }
</span><del>-
-            case access_put_by_id_list: {
-                PolymorphicPutByIdList* list = stubInfo.u.putByIdList.list;
-                JSCell* origin = stubInfo.codeOrigin.codeOriginOwner();
-                if (origin &amp;&amp; !Heap::isMarked(origin)) {
-                    allAreMarkedSoFar = false;
-                    break;
-                }
-                for (unsigned j = list-&gt;size(); j--;) {
-                    PutByIdAccess&amp; access = list-&gt;m_list[j];
-                    if (!access.isTransition())
-                        continue;
-                    if (Heap::isMarked(access.oldStructure()))
-                        visitor.append(&amp;access.m_newStructure);
-                    else
-                        allAreMarkedSoFar = false;
-                }
-                break;
-            }
-            
-            default:
-                break;
-            }
</del><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> #endif // ENABLE(JIT)
</span><span class="lines">@@ -2793,10 +2720,10 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-StructureStubInfo* CodeBlock::addStubInfo()
</del><ins>+StructureStubInfo* CodeBlock::addStubInfo(AccessType accessType)
</ins><span class="cx"> {
</span><span class="cx">     ConcurrentJITLocker locker(m_lock);
</span><del>-    return m_stubInfos.add();
</del><ins>+    return m_stubInfos.add(accessType);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> StructureStubInfo* CodeBlock::findStubInfo(CodeOrigin codeOrigin)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -211,7 +211,7 @@
</span><span class="cx">     void getByValInfoMap(ByValInfoMap&amp; result);
</span><span class="cx">     
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-    StructureStubInfo* addStubInfo();
</del><ins>+    StructureStubInfo* addStubInfo(AccessType);
</ins><span class="cx">     Bag&lt;StructureStubInfo&gt;::iterator stubInfoBegin() { return m_stubInfos.begin(); }
</span><span class="cx">     Bag&lt;StructureStubInfo&gt;::iterator stubInfoEnd() { return m_stubInfos.end(); }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -26,14 +26,13 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;GetByIdStatus.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;AccessorCallJITStubRoutine.h&quot;
</del><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;ComplexGetStatus.h&quot;
</span><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="cx"> #include &quot;LowLevelInterpreter.h&quot;
</span><del>-#include &quot;PolymorphicGetByIdList.h&quot;
</del><ins>+#include &quot;PolymorphicAccess.h&quot;
</ins><span class="cx"> #include &lt;wtf/ListDump.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -139,12 +138,12 @@
</span><span class="cx">     if (!stubInfo-&gt;seen)
</span><span class="cx">         return GetByIdStatus(NoInformation);
</span><span class="cx">     
</span><del>-    PolymorphicGetByIdList* list = 0;
</del><ins>+    PolymorphicAccess* list = 0;
</ins><span class="cx">     State slowPathState = TakesSlowPath;
</span><del>-    if (stubInfo-&gt;accessType == access_get_by_id_list) {
-        list = stubInfo-&gt;u.getByIdList.list;
</del><ins>+    if (stubInfo-&gt;cacheType == CacheType::Stub) {
+        list = stubInfo-&gt;u.stub;
</ins><span class="cx">         for (unsigned i = 0; i &lt; list-&gt;size(); ++i) {
</span><del>-            const GetByIdAccess&amp; access = list-&gt;at(i);
</del><ins>+            const AccessCase&amp; access = list-&gt;at(i);
</ins><span class="cx">             if (access.doesCalls())
</span><span class="cx">                 slowPathState = MakesCalls;
</span><span class="cx">         }
</span><span class="lines">@@ -157,12 +156,12 @@
</span><span class="cx">     GetByIdStatus result;
</span><span class="cx">     result.m_state = Simple;
</span><span class="cx">     result.m_wasSeenInJIT = true; // This is interesting for bytecode dumping only.
</span><del>-    switch (stubInfo-&gt;accessType) {
-    case access_unset:
</del><ins>+    switch (stubInfo-&gt;cacheType) {
+    case CacheType::Unset:
</ins><span class="cx">         return GetByIdStatus(NoInformation);
</span><span class="cx">         
</span><del>-    case access_get_by_id_self: {
-        Structure* structure = stubInfo-&gt;u.getByIdSelf.baseObjectStructure.get();
</del><ins>+    case CacheType::GetByIdSelf: {
+        Structure* structure = stubInfo-&gt;u.byIdSelf.baseObjectStructure.get();
</ins><span class="cx">         if (structure-&gt;takesSlowPathInDFGForImpureProperty())
</span><span class="cx">             return GetByIdStatus(slowPathState, true);
</span><span class="cx">         unsigned attributesIgnored;
</span><span class="lines">@@ -177,12 +176,25 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    case access_get_by_id_list: {
</del><ins>+    case CacheType::Stub: {
</ins><span class="cx">         for (unsigned listIndex = 0; listIndex &lt; list-&gt;size(); ++listIndex) {
</span><del>-            Structure* structure = list-&gt;at(listIndex).structure();
</del><ins>+            const AccessCase&amp; access = list-&gt;at(listIndex);
+            if (access.viaProxy())
+                return GetByIdStatus(slowPathState, true);
</ins><span class="cx">             
</span><ins>+            Structure* structure = access.structure();
+            if (!structure) {
+                // The null structure cases arise due to array.length and string.length. We have no way
+                // of creating a GetByIdVariant for those, and we don't really have to since the DFG
+                // handles those cases in FixupPhase using value profiling. That's a bit awkward - we
+                // shouldn't have to use value profiling to discover something that the AccessCase
+                // could have told us. But, it works well enough. So, our only concern here is to not
+                // crash on null structure.
+                return GetByIdStatus(slowPathState, true);
+            }
+            
</ins><span class="cx">             ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(
</span><del>-                structure, list-&gt;at(listIndex).conditionSet(), uid);
</del><ins>+                structure, access.conditionSet(), uid);
</ins><span class="cx">              
</span><span class="cx">             switch (complexGetStatus.kind()) {
</span><span class="cx">             case ComplexGetStatus::ShouldSkip:
</span><span class="lines">@@ -193,29 +205,23 @@
</span><span class="cx">                  
</span><span class="cx">             case ComplexGetStatus::Inlineable: {
</span><span class="cx">                 std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus;
</span><del>-                switch (list-&gt;at(listIndex).type()) {
-                case GetByIdAccess::SimpleInline:
-                case GetByIdAccess::SimpleStub: {
</del><ins>+                switch (access.type()) {
+                case AccessCase::Load: {
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                case GetByIdAccess::Getter: {
-                    AccessorCallJITStubRoutine* stub = static_cast&lt;AccessorCallJITStubRoutine*&gt;(
-                        list-&gt;at(listIndex).stubRoutine());
</del><ins>+                case AccessCase::Getter: {
+                    CallLinkInfo* callLinkInfo = access.callLinkInfo();
+                    ASSERT(callLinkInfo);
</ins><span class="cx">                     callLinkStatus = std::make_unique&lt;CallLinkStatus&gt;(
</span><span class="cx">                         CallLinkStatus::computeFor(
</span><del>-                            locker, profiledBlock, *stub-&gt;m_callLinkInfo, callExitSiteData));
</del><ins>+                            locker, profiledBlock, *callLinkInfo, callExitSiteData));
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                case GetByIdAccess::SimpleMiss:
-                case GetByIdAccess::CustomGetter:
-                case GetByIdAccess::WatchedStub:{
-                    // FIXME: It would be totally sweet to support this at some point in the future.
-                    // https://bugs.webkit.org/show_bug.cgi?id=133052
</del><ins>+                default: {
+                    // FIXME: It would be totally sweet to support more of these at some point in the
+                    // future. https://bugs.webkit.org/show_bug.cgi?id=133052
</ins><span class="cx">                     return GetByIdStatus(slowPathState, true);
</span><del>-                }
-                default:
-                    RELEASE_ASSERT_NOT_REACHED();
-                }
</del><ins>+                } }
</ins><span class="cx">                  
</span><span class="cx">                 GetByIdVariant variant(
</span><span class="cx">                     StructureSet(structure), complexGetStatus.offset(),
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccesscppfromrev189324trunkSourceJavaScriptCorebytecodePolymorphicGetByIdListcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (from rev 189324, trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp) (0 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -0,0 +1,1186 @@
</span><ins>+/*
+ * Copyright (C) 2014, 2015 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;PolymorphicAccess.h&quot;
+
+#if ENABLE(JIT)
+
+#include &quot;BinarySwitch.h&quot;
+#include &quot;CCallHelpers.h&quot;
+#include &quot;CodeBlock.h&quot;
+#include &quot;GetterSetter.h&quot;
+#include &quot;Heap.h&quot;
+#include &quot;JITOperations.h&quot;
+#include &quot;JSCInlines.h&quot;
+#include &quot;LinkBuffer.h&quot;
+#include &quot;ScratchRegisterAllocator.h&quot;
+#include &quot;StructureStubClearingWatchpoint.h&quot;
+#include &quot;StructureStubInfo.h&quot;
+#include &lt;wtf/CommaPrinter.h&gt;
+#include &lt;wtf/ListDump.h&gt;
+
+namespace JSC {
+
+static const bool verbose = false;
+
+struct AccessGenerationState {
+    CCallHelpers* jit { nullptr };
+    ScratchRegisterAllocator* allocator;
+    size_t numberOfPaddingBytes { 0 };
+    PolymorphicAccess* access { nullptr };
+    StructureStubInfo* stubInfo { nullptr };
+    CCallHelpers::JumpList success;
+    CCallHelpers::JumpList failAndRepatch;
+    CCallHelpers::JumpList failAndIgnore;
+    GPRReg baseGPR { InvalidGPRReg };
+    JSValueRegs valueRegs;
+    GPRReg scratchGPR { InvalidGPRReg };
+    Vector&lt;std::function&lt;void(LinkBuffer&amp;)&gt;&gt; callbacks;
+    const Identifier* ident;
+    std::unique_ptr&lt;WatchpointsOnStructureStubInfo&gt; watchpoints;
+
+    Watchpoint* addWatchpoint(const ObjectPropertyCondition&amp; condition = ObjectPropertyCondition())
+    {
+        return WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint(
+            watchpoints, jit-&gt;codeBlock(), stubInfo, condition);
+    }
+
+    void restoreScratch()
+    {
+        allocator-&gt;restoreReusedRegistersByPopping(*jit, numberOfPaddingBytes);
+    }
+
+    void succeed()
+    {
+        restoreScratch();
+        success.append(jit-&gt;jump());
+    }
+};
+
+AccessCase::AccessCase()
+{
+}
+
+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)
+{
+    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) {
+        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);
+    }
+
+    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;
+    }
+
+    // Skip optimizing the case where we need realloc, and the structure has
+    // indexing storage.
+    // FIXME: We shouldn't skip this! Implement it!
+    // https://bugs.webkit.org/show_bug.cgi?id=130914
+    if (oldStructure-&gt;couldHaveIndexingHeader())
+        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;
+}
+
+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;
+    }
+    return result;
+}
+
+bool AccessCase::guardedByStructureCheck() const
+{
+    if (viaProxy())
+        return false;
+
+    switch (m_type) {
+    case ArrayLength:
+    case StringLength:
+        return false;
+    default:
+        return true;
+    }
+}
+
+JSObject* AccessCase::alternateBase() const
+{
+    if (customSlotBase())
+        return customSlotBase();
+    return conditionSet().slotBaseCondition().object();
+}
+
+bool AccessCase::canReplace(const AccessCase&amp; other)
+{
+    // We could do a lot better here, but for now we just do something obvious.
+
+    if (!guardedByStructureCheck() || !other.guardedByStructureCheck()) {
+        // FIXME: Implement this!
+        return false;
+    }
+
+    return structure() == other.structure();
+}
+
+void AccessCase::dump(PrintStream&amp; out) const
+{
+    out.print(m_type, &quot;:(&quot;);
+
+    CommaPrinter comma;
+
+    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;
+    }
+    return true;
+}
+
+void AccessCase::generateWithGuard(
+    AccessGenerationState&amp; state, CCallHelpers::JumpList&amp; fallThrough)
+{
+    CCallHelpers&amp; jit = *state.jit;
+
+    switch (m_type) {
+    case ArrayLength: {
+        ASSERT(!viaProxy());
+        jit.load8(CCallHelpers::Address(state.baseGPR, JSCell::indexingTypeOffset()), state.scratchGPR);
+        fallThrough.append(
+            jit.branchTest32(
+                CCallHelpers::Zero, state.scratchGPR, CCallHelpers::TrustedImm32(IsArray)));
+        fallThrough.append(
+            jit.branchTest32(
+                CCallHelpers::Zero, state.scratchGPR, CCallHelpers::TrustedImm32(IndexingShapeMask)));
+        break;
+    }
+
+    case StringLength: {
+        ASSERT(!viaProxy());
+        fallThrough.append(
+            jit.branch8(
+                CCallHelpers::NotEqual,
+                CCallHelpers::Address(state.baseGPR, JSCell::typeInfoTypeOffset()),
+                CCallHelpers::TrustedImm32(StringType)));
+        break;
+    }
+
+    default: {
+        if (viaProxy()) {
+            fallThrough.append(
+                jit.branch8(
+                    CCallHelpers::NotEqual,
+                    CCallHelpers::Address(state.baseGPR, JSCell::typeInfoTypeOffset()),
+                    CCallHelpers::TrustedImm32(PureForwardingProxyType)));
+
+            jit.loadPtr(
+                CCallHelpers::Address(state.baseGPR, JSProxy::targetOffset()),
+                state.scratchGPR);
+
+            fallThrough.append(
+                jit.branchStructure(
+                    CCallHelpers::NotEqual,
+                    CCallHelpers::Address(state.scratchGPR, JSCell::structureIDOffset()),
+                    structure()));
+        } else {
+            fallThrough.append(
+                jit.branchStructure(
+                    CCallHelpers::NotEqual,
+                    CCallHelpers::Address(state.baseGPR, JSCell::structureIDOffset()),
+                    structure()));
+        }
+        break;
+    } };
+
+    generate(state);
+}
+
+void AccessCase::generate(AccessGenerationState&amp; state)
+{
+    if (verbose)
+        dataLog(&quot;Generating code for: &quot;, *this, &quot;\n&quot;);
+    
+    CCallHelpers&amp; jit = *state.jit;
+    VM&amp; vm = *jit.vm();
+    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());
+
+    if ((structure() &amp;&amp; structure()-&gt;needImpurePropertyWatchpoint())
+        || m_conditionSet.needImpurePropertyWatchpoint())
+        vm.registerWatchpointForImpureProperty(ident, state.addWatchpoint());
+
+    if (additionalSet())
+        additionalSet()-&gt;add(state.addWatchpoint());
+
+    for (const ObjectPropertyCondition&amp; condition : m_conditionSet) {
+        Structure* structure = condition.object()-&gt;structure();
+
+        if (condition.isWatchableAssumingImpurePropertyWatchpoint()) {
+            structure-&gt;addTransitionWatchpoint(state.addWatchpoint(condition));
+            continue;
+        }
+
+        RELEASE_ASSERT(condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint(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 Getter:
+    case Setter:
+    case CustomGetter:
+    case CustomSetter: {
+        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()) {
+            baseForGetGPR = valueRegs.payloadGPR();
+            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 != CustomGetter &amp;&amp; m_type != CustomSetter) {
+            if (m_type == Load)
+                loadedValueGPR = valueRegs.payloadGPR();
+            else
+                loadedValueGPR = scratchGPR;
+
+            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) {
+                jit.load32(
+                    CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + TagOffset),
+                    valueRegs.tagGPR());
+            }
+            jit.load32(
+                CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + PayloadOffset),
+                loadedValueGPR);
+#endif
+        }
+
+        // Stuff for custom getters.
+        CCallHelpers::Call operationCall;
+        CCallHelpers::Call handlerCall;
+
+        // Stuff for JS getters.
+        CCallHelpers::DataLabelPtr addressOfLinkFunctionCheck;
+        CCallHelpers::Call fastPathCall;
+        CCallHelpers::Call slowPathCall;
+
+        CCallHelpers::Jump success;
+        CCallHelpers::Jump fail;
+        if (m_type != Load &amp;&amp; m_type != Miss) {
+            // Need to make sure that whenever this call is made in the future, we remember the
+            // place that we made it from.
+            jit.store32(
+                CCallHelpers::TrustedImm32(stubInfo.callSiteIndex.bits()),
+                CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(JSStack::ArgumentCount)));
+
+            if (m_type == Getter || m_type == Setter) {
+                // 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.
+
+                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 = JSStack::CallFrameHeaderSize + 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(JSStack::ArgumentCount * sizeof(Register) + PayloadOffset));
+
+                jit.storeCell(
+                    loadedValueGPR, calleeFrame.withOffset(JSStack::Callee * sizeof(Register)));
+
+                jit.storeCell(
+                    baseForGetGPR,
+                    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();
+
+                jit.addPtr(
+                    CCallHelpers::TrustedImm32(alignedNumberOfBytesForCall),
+                    CCallHelpers::stackPointerRegister);
+                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();
+
+                jit.addPtr(
+                    CCallHelpers::TrustedImm32(alignedNumberOfBytesForCall),
+                    CCallHelpers::stackPointerRegister);
+                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);
+
+                state.callbacks.append(
+                    [=, &amp;vm] (LinkBuffer&amp; linkBuffer) {
+                        m_rareData-&gt;callLinkInfo-&gt;setCallLocations(
+                            linkBuffer.locationOfNearCall(slowPathCall),
+                            linkBuffer.locationOf(addressOfLinkFunctionCheck),
+                            linkBuffer.locationOfNearCall(fastPathCall));
+
+                        linkBuffer.link(
+                            slowPathCall,
+                            CodeLocationLabel(vm.getCTIStub(linkCallThunkGenerator).code()));
+                    });
+            } else {
+                // getter: EncodedJSValue (*GetValueFunc)(ExecState*, JSObject* slotBase, EncodedJSValue thisValue, PropertyName);
+                // setter: void (*PutValueFunc)(ExecState*, JSObject* base, EncodedJSValue thisObject, EncodedJSValue value);
+#if USE(JSVALUE64)
+                if (m_type == CustomGetter) {
+                    jit.setupArgumentsWithExecState(
+                        baseForAccessGPR, baseForGetGPR,
+                        CCallHelpers::TrustedImmPtr(ident.impl()));
+                } else
+                    jit.setupArgumentsWithExecState(baseForAccessGPR, baseForGetGPR, valueRegs.gpr());
+#else
+                if (m_type == CustomGetter) {
+                    jit.setupArgumentsWithExecState(
+                        baseForAccessGPR, baseForGetGPR,
+                        CCallHelpers::TrustedImm32(JSValue::CellTag),
+                        CCallHelpers::TrustedImmPtr(ident.impl()));
+                } else {
+                    jit.setupArgumentsWithExecState(
+                        baseForAccessGPR, baseForGetGPR,
+                        CCallHelpers::TrustedImm32(JSValue::CellTag),
+                        valueRegs.payloadGPR(), valueRegs.tagGPR());
+                }
+#endif
+                jit.storePtr(GPRInfo::callFrameRegister, &amp;vm.topCallFrame);
+
+                operationCall = jit.call();
+                if (m_type == CustomGetter)
+                    jit.setupResults(valueRegs);
+                CCallHelpers::Jump noException =
+                    jit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck);
+
+                jit.copyCalleeSavesToVMCalleeSavesBuffer();
+                jit.setupArguments(CCallHelpers::TrustedImmPtr(&amp;vm), GPRInfo::callFrameRegister);
+                handlerCall = jit.call();
+                jit.jumpToExceptionHandler();
+            
+                noException.link(&amp;jit);
+
+                state.callbacks.append(
+                    [=] (LinkBuffer&amp; linkBuffer) {
+                        linkBuffer.link(operationCall, FunctionPtr(m_rareData-&gt;customAccessor.opaque));
+                        linkBuffer.link(handlerCall, lookupExceptionHandler);
+                    });
+            }
+        }
+        state.succeed();
+        return;
+    }
+
+    case Replace: {
+        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.
+        RELEASE_ASSERT(GPRInfo::numberOfRegisters &gt;= 6 || !structure()-&gt;outOfLineCapacity() || structure()-&gt;outOfLineCapacity() == newStructure()-&gt;outOfLineCapacity());
+        RELEASE_ASSERT(!structure()-&gt;couldHaveIndexingHeader());
+
+        CCallHelpers::JumpList slowPath;
+
+        ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
+        allocator.lock(baseGPR);
+        allocator.lock(valueRegs);
+        allocator.lock(scratchGPR);
+
+        GPRReg scratchGPR2 = allocator.allocateScratchGPR();
+        GPRReg scratchGPR3;
+        if (newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity()
+            &amp;&amp; structure()-&gt;outOfLineCapacity())
+            scratchGPR3 = allocator.allocateScratchGPR();
+        else
+            scratchGPR3 = InvalidGPRReg;
+
+        size_t numberOfPaddingBytes = allocator.preserveReusedRegistersByPushing(jit);
+
+        ASSERT(structure()-&gt;transitionWatchpointSetHasBeenInvalidated());
+
+        bool scratchGPRHasStorage = false;
+
+        if (newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity()) {
+            size_t newSize = newStructure()-&gt;outOfLineCapacity() * sizeof(JSValue);
+            CopiedAllocator* copiedAllocator = &amp;vm.heap.storageAllocator();
+
+            if (!structure()-&gt;outOfLineCapacity()) {
+                jit.loadPtr(&amp;copiedAllocator-&gt;m_currentRemaining, scratchGPR);
+                slowPath.append(
+                    jit.branchSubPtr(
+                        CCallHelpers::Signed, CCallHelpers::TrustedImm32(newSize), scratchGPR));
+                jit.storePtr(scratchGPR, &amp;copiedAllocator-&gt;m_currentRemaining);
+                jit.negPtr(scratchGPR);
+                jit.addPtr(
+                    CCallHelpers::AbsoluteAddress(&amp;copiedAllocator-&gt;m_currentPayloadEnd), scratchGPR);
+                jit.addPtr(CCallHelpers::TrustedImm32(sizeof(JSValue)), scratchGPR);
+            } else {
+                size_t oldSize = structure()-&gt;outOfLineCapacity() * sizeof(JSValue);
+                ASSERT(newSize &gt; oldSize);
+            
+                jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR3);
+                jit.loadPtr(&amp;copiedAllocator-&gt;m_currentRemaining, scratchGPR);
+                slowPath.append(
+                    jit.branchSubPtr(
+                        CCallHelpers::Signed, CCallHelpers::TrustedImm32(newSize), scratchGPR));
+                jit.storePtr(scratchGPR, &amp;copiedAllocator-&gt;m_currentRemaining);
+                jit.negPtr(scratchGPR);
+                jit.addPtr(
+                    CCallHelpers::AbsoluteAddress(&amp;copiedAllocator-&gt;m_currentPayloadEnd), scratchGPR);
+                jit.addPtr(CCallHelpers::TrustedImm32(sizeof(JSValue)), scratchGPR);
+                // 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*))));
+                }
+            }
+
+            jit.storePtr(scratchGPR, CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()));
+            scratchGPRHasStorage = true;
+        }
+
+        uint32_t structureBits = bitwise_cast&lt;uint32_t&gt;(newStructure()-&gt;id());
+        jit.store32(
+            CCallHelpers::TrustedImm32(structureBits),
+            CCallHelpers::Address(baseGPR, JSCell::structureIDOffset()));
+
+        if (isInlineOffset(m_offset)) {
+            jit.storeValue(
+                valueRegs,
+                CCallHelpers::Address(
+                    baseGPR,
+                    JSObject::offsetOfInlineStorage() +
+                    offsetInInlineStorage(m_offset) * sizeof(JSValue)));
+        } else {
+            if (!scratchGPRHasStorage)
+                jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR);
+            jit.storeValue(
+                valueRegs,
+                CCallHelpers::Address(scratchGPR, offsetInButterfly(m_offset) * sizeof(JSValue)));
+        }
+
+        ScratchBuffer* scratchBuffer = nullptr;
+        if (newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity())
+            scratchBuffer = vm.scratchBufferForSize(allocator.desiredScratchBufferSizeForCall());
+
+#if ENABLE(GGC)
+        if (newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity()) {
+            CCallHelpers::Call callFlushWriteBarrierBuffer;
+            CCallHelpers::Jump ownerIsRememberedOrInEden = jit.jumpIfIsRememberedOrInEden(baseGPR);
+            WriteBarrierBuffer&amp; writeBarrierBuffer = jit.vm()-&gt;heap.writeBarrierBuffer();
+            jit.load32(writeBarrierBuffer.currentIndexAddress(), scratchGPR2);
+            CCallHelpers::Jump needToFlush =
+                jit.branch32(
+                    CCallHelpers::AboveOrEqual, scratchGPR2,
+                    CCallHelpers::TrustedImm32(writeBarrierBuffer.capacity()));
+
+            jit.add32(CCallHelpers::TrustedImm32(1), scratchGPR2);
+            jit.store32(scratchGPR2, writeBarrierBuffer.currentIndexAddress());
+
+            jit.move(CCallHelpers::TrustedImmPtr(writeBarrierBuffer.buffer()), scratchGPR);
+            // We use an offset of -sizeof(void*) because we already added 1 to scratchGPR2.
+            jit.storePtr(
+                baseGPR,
+                CCallHelpers::BaseIndex(
+                    scratchGPR, scratchGPR2, CCallHelpers::ScalePtr,
+                    static_cast&lt;int32_t&gt;(-sizeof(void*))));
+
+            CCallHelpers::Jump doneWithBarrier = jit.jump();
+            needToFlush.link(&amp;jit);
+
+            // FIXME: We should restoreReusedRegistersByPopping() before this. Then, we wouldn't need
+            // padding in preserveReusedRegistersByPushing(). Or, maybe it would be even better if the
+            // barrier slow path was just the normal slow path, below.
+            // https://bugs.webkit.org/show_bug.cgi?id=149030
+            allocator.preserveUsedRegistersToScratchBufferForCall(jit, scratchBuffer, scratchGPR2);
+            jit.setupArgumentsWithExecState(baseGPR);
+            callFlushWriteBarrierBuffer = jit.call();
+            allocator.restoreUsedRegistersFromScratchBufferForCall(
+                jit, scratchBuffer, scratchGPR2);
+
+            doneWithBarrier.link(&amp;jit);
+            ownerIsRememberedOrInEden.link(&amp;jit);
+
+            state.callbacks.append(
+                [=] (LinkBuffer&amp; linkBuffer) {
+                    linkBuffer.link(callFlushWriteBarrierBuffer, operationFlushWriteBarrierBuffer);
+                });
+        }
+#endif // ENABLE(GGC)
+        
+        allocator.restoreReusedRegistersByPopping(jit, numberOfPaddingBytes);
+        state.succeed();
+
+        if (newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity()) {
+            slowPath.link(&amp;jit);
+            allocator.restoreReusedRegistersByPopping(jit, numberOfPaddingBytes);
+            allocator.preserveUsedRegistersToScratchBufferForCall(jit, scratchBuffer, scratchGPR);
+#if USE(JSVALUE64)
+            jit.setupArgumentsWithExecState(
+                baseGPR,
+                CCallHelpers::TrustedImmPtr(newStructure()),
+                CCallHelpers::TrustedImm32(m_offset),
+                valueRegs.gpr());
+#else
+            jit.setupArgumentsWithExecState(
+                baseGPR,
+                CCallHelpers::TrustedImmPtr(newStructure()),
+                CCallHelpers::TrustedImm32(m_offset),
+                valueRegs.payloadGPR(), valueRegs.tagGPR());
+#endif
+            CCallHelpers::Call operationCall = jit.call();
+            allocator.restoreUsedRegistersFromScratchBufferForCall(jit, scratchBuffer, scratchGPR);
+            state.succeed();
+
+            state.callbacks.append(
+                [=] (LinkBuffer&amp; linkBuffer) {
+                    linkBuffer.link(operationCall, operationReallocateStorageAndFinishPut);
+                });
+        }
+        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;
+    } }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+PolymorphicAccess::PolymorphicAccess() { }
+PolymorphicAccess::~PolymorphicAccess() { }
+
+MacroAssemblerCodePtr PolymorphicAccess::regenerateWithCases(
+    VM&amp; vm, CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo, const Identifier&amp; ident,
+    Vector&lt;std::unique_ptr&lt;AccessCase&gt;&gt; originalCasesToAdd)
+{
+    // This method will add the originalCasesToAdd to the list one at a time while preserving the
+    // invariants:
+    // - If a newly added case canReplace() any existing case, then the existing case is removed before
+    //   the new case is added. Removal doesn't change order of the list. Any number of existing cases
+    //   can be removed via the canReplace() rule.
+    // - Cases in the list always appear in ascending order of time of addition. Therefore, if you
+    //   cascade through the cases in reverse order, you will get the most recent cases first.
+    // - If this method fails (returns null, doesn't add the cases), then both the previous case list
+    //   and the previous stub are kept intact and the new cases are destroyed. It's OK to attempt to
+    //   add more things after failure.
+    
+    // First, verify that we can generate code for all of the new cases while eliminating any of the
+    // new cases that replace each other.
+    Vector&lt;std::unique_ptr&lt;AccessCase&gt;&gt; casesToAdd;
+    for (unsigned i = 0; i &lt; originalCasesToAdd.size(); ++i) {
+        std::unique_ptr&lt;AccessCase&gt; myCase = WTF::move(originalCasesToAdd[i]);
+
+        // Add it only if it is not replaced by the subsequent cases in the list.
+        bool found = false;
+        for (unsigned j = i + 1; j &lt; originalCasesToAdd.size(); ++j) {
+            if (originalCasesToAdd[j]-&gt;canReplace(*myCase)) {
+                found = true;
+                break;
+            }
+        }
+
+        if (found)
+            continue;
+        
+        if (myCase-&gt;doesCalls() &amp;&amp; stubInfo.patch.spillMode == NeedToSpill)
+            return MacroAssemblerCodePtr();
+
+        casesToAdd.append(WTF::move(myCase));
+    }
+
+    if (verbose)
+        dataLog(&quot;casesToAdd: &quot;, listDump(casesToAdd), &quot;\n&quot;);
+
+    // If there aren't any cases to add, then fail on the grounds that there's no point to generating a
+    // new stub that will be identical to the old one. Returning null should tell the caller to just
+    // keep doing what they were doing before.
+    if (casesToAdd.isEmpty())
+        return MacroAssemblerCodePtr();
+
+    // Now construct the list of cases as they should appear if we are successful. This means putting
+    // all of the previous cases in this list in order but excluding those that can be replaced, and
+    // then adding the new cases.
+    ListType newCases;
+    for (auto&amp; oldCase : m_list) {
+        bool found = false;
+        for (auto&amp; caseToAdd : casesToAdd) {
+            if (caseToAdd-&gt;canReplace(*oldCase)) {
+                found = true;
+                break;
+            }
+        }
+        if (!found)
+            newCases.append(oldCase-&gt;clone());
+    }
+    for (auto&amp; caseToAdd : casesToAdd)
+        newCases.append(WTF::move(caseToAdd));
+
+    if (verbose)
+        dataLog(&quot;newCases: &quot;, listDump(newCases), &quot;\n&quot;);
+
+    if (newCases.size() &gt; Options::maxAccessVariantListSize()) {
+        if (verbose)
+            dataLog(&quot;Too many cases.\n&quot;);
+        return MacroAssemblerCodePtr();
+    }
+
+    MacroAssemblerCodePtr result = regenerate(vm, codeBlock, stubInfo, ident, newCases);
+    if (!result)
+        return MacroAssemblerCodePtr();
+
+    m_list = WTF::move(newCases);
+    return result;
+}
+
+MacroAssemblerCodePtr PolymorphicAccess::regenerateWithCase(
+    VM&amp; vm, CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo, const Identifier&amp; ident,
+    std::unique_ptr&lt;AccessCase&gt; newAccess)
+{
+    Vector&lt;std::unique_ptr&lt;AccessCase&gt;&gt; newAccesses;
+    newAccesses.append(WTF::move(newAccess));
+    return regenerateWithCases(vm, codeBlock, stubInfo, ident, WTF::move(newAccesses));
+}
+
+bool PolymorphicAccess::visitWeak(VM&amp; vm) const
+{
+    for (unsigned i = 0; i &lt; size(); ++i) {
+        if (!at(i).visitWeak(vm))
+            return false;
+    }
+    return true;
+}
+
+void PolymorphicAccess::dump(PrintStream&amp; out) const
+{
+    out.print(RawPointer(this), &quot;:[&quot;);
+    CommaPrinter comma;
+    for (auto&amp; entry : m_list)
+        out.print(comma, *entry);
+    out.print(&quot;]&quot;);
+}
+
+MacroAssemblerCodePtr PolymorphicAccess::regenerate(
+    VM&amp; vm, CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo, const Identifier&amp; ident,
+    PolymorphicAccess::ListType&amp; cases)
+{
+    if (verbose)
+        dataLog(&quot;Generating code for cases: &quot;, listDump(cases), &quot;\n&quot;);
+    
+    AccessGenerationState state;
+
+    state.access = this;
+    state.stubInfo = &amp;stubInfo;
+    state.ident = &amp;ident;
+    
+    state.baseGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.baseGPR);
+    state.valueRegs = JSValueRegs(
+#if USE(JSVALUE32_64)
+        static_cast&lt;GPRReg&gt;(stubInfo.patch.valueTagGPR),
+#endif
+        static_cast&lt;GPRReg&gt;(stubInfo.patch.valueGPR));
+
+    ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
+    state.allocator = &amp;allocator;
+    allocator.lock(state.baseGPR);
+    allocator.lock(state.valueRegs);
+
+    state.scratchGPR = allocator.allocateScratchGPR();
+    
+    CCallHelpers jit(&amp;vm, codeBlock);
+    state.jit = &amp;jit;
+
+    state.numberOfPaddingBytes = allocator.preserveReusedRegistersByPushing(jit);
+
+    bool allGuardedByStructureCheck = true;
+    for (auto&amp; entry : cases)
+        allGuardedByStructureCheck &amp;= entry-&gt;guardedByStructureCheck();
+
+    if (cases.isEmpty()) {
+        // This is super unlikely, but we make it legal anyway.
+        state.failAndRepatch.append(jit.jump());
+    } else if (!allGuardedByStructureCheck || cases.size() == 1) {
+        // If there are any proxies in the list, we cannot just use a binary switch over the structure.
+        // We need to resort to a cascade. A cascade also happens to be optimal if we only have just
+        // one case.
+        CCallHelpers::JumpList fallThrough;
+
+        // Cascade through the list, preferring newer entries.
+        for (unsigned i = cases.size(); i--;) {
+            fallThrough.link(&amp;jit);
+            cases[i]-&gt;generateWithGuard(state, fallThrough);
+        }
+        state.failAndRepatch.append(fallThrough);
+    } else {
+        jit.load32(
+            CCallHelpers::Address(state.baseGPR, JSCell::structureIDOffset()),
+            state.scratchGPR);
+        
+        Vector&lt;int64_t&gt; caseValues(cases.size());
+        for (unsigned i = 0; i &lt; cases.size(); ++i)
+            caseValues[i] = bitwise_cast&lt;int32_t&gt;(cases[i]-&gt;structure()-&gt;id());
+        
+        BinarySwitch binarySwitch(state.scratchGPR, caseValues, BinarySwitch::Int32);
+        while (binarySwitch.advance(jit))
+            cases[binarySwitch.caseIndex()]-&gt;generate(state);
+        state.failAndRepatch.append(binarySwitch.fallThrough());
+    }
+
+    state.failAndIgnore.link(&amp;jit);
+
+    // Make sure that the inline cache optimization code knows that we are taking slow path because
+    // of something that isn't patchable. &quot;seen&quot; being false means that we bypass patching. This is
+    // pretty gross but it means that we don't need to have two slow path entrypoints - one for
+    // patching and one for normal slow stuff.
+    jit.store8(CCallHelpers::TrustedImm32(false), &amp;stubInfo.seen);
+
+    CCallHelpers::JumpList failure;
+    if (allocator.didReuseRegisters()) {
+        state.failAndRepatch.link(&amp;jit);
+        state.restoreScratch();
+    } else
+        failure = state.failAndRepatch;
+    failure.append(jit.jump());
+
+    LinkBuffer linkBuffer(vm, jit, codeBlock, JITCompilationCanFail);
+    if (linkBuffer.didFailToAllocate()) {
+        if (verbose)
+            dataLog(&quot;Did fail to allocate.\n&quot;);
+        return MacroAssemblerCodePtr();
+    }
+
+    CodeLocationLabel successLabel =
+        stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone);
+        
+    linkBuffer.link(state.success, successLabel);
+
+    linkBuffer.link(
+        failure,
+        stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase));
+    
+    for (auto callback : state.callbacks)
+        callback(linkBuffer);
+    
+    MacroAssemblerCodeRef code = FINALIZE_CODE_FOR(
+        codeBlock, linkBuffer,
+        (&quot;%s&quot;, toCString(&quot;Access stub for &quot;, *codeBlock, &quot; &quot;, stubInfo.codeOrigin, &quot; with return point &quot;, successLabel, &quot;: &quot;, listDump(cases)).data()));
+
+    bool doesCalls = false;
+    for (auto&amp; entry : cases)
+        doesCalls |= entry-&gt;doesCalls();
+    
+    m_stubRoutine = createJITStubRoutine(code, vm, codeBlock-&gt;ownerExecutable(), doesCalls);
+    m_watchpoints = WTF::move(state.watchpoints);
+    if (verbose)
+        dataLog(&quot;Returning: &quot;, code.code(), &quot;\n&quot;);
+    return code.code();
+}
+
+} // namespace JSC
+
+namespace WTF {
+
+using namespace JSC;
+
+void printInternal(PrintStream&amp; out, AccessCase::AccessType type)
+{
+    switch (type) {
+    case AccessCase::Load:
+        out.print(&quot;Load&quot;);
+        return;
+    case AccessCase::Transition:
+        out.print(&quot;Transition&quot;);
+        return;
+    case AccessCase::Replace:
+        out.print(&quot;Replace&quot;);
+        return;
+    case AccessCase::Miss:
+        out.print(&quot;Miss&quot;);
+        return;
+    case AccessCase::Getter:
+        out.print(&quot;Getter&quot;);
+        return;
+    case AccessCase::Setter:
+        out.print(&quot;Setter&quot;);
+        return;
+    case AccessCase::CustomGetter:
+        out.print(&quot;CustomGetter&quot;);
+        return;
+    case AccessCase::CustomSetter:
+        out.print(&quot;CustomSetter&quot;);
+        return;
+    case AccessCase::InHit:
+        out.print(&quot;InHit&quot;);
+        return;
+    case AccessCase::InMiss:
+        out.print(&quot;InMiss&quot;);
+        return;
+    case AccessCase::ArrayLength:
+        out.print(&quot;ArrayLength&quot;);
+        return;
+    case AccessCase::StringLength:
+        out.print(&quot;StringLength&quot;);
+        return;
+    }
+
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(JIT)
+
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccesshfromrev189324trunkSourceJavaScriptCorebytecodePolymorphicGetByIdListh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h (from rev 189324, trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h) (0 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -0,0 +1,317 @@
</span><ins>+/*
+ * Copyright (C) 2014, 2015 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. 
+ */
+
+#ifndef PolymorphicAccess_h
+#define PolymorphicAccess_h
+
+#if ENABLE(JIT)
+
+#include &quot;CodeOrigin.h&quot;
+#include &quot;MacroAssembler.h&quot;
+#include &quot;ObjectPropertyConditionSet.h&quot;
+#include &quot;Opcode.h&quot;
+#include &quot;Structure.h&quot;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC {
+
+class CodeBlock;
+class PolymorphicAccess;
+class WatchpointsOnStructureStubInfo;
+struct StructureStubInfo;
+
+struct AccessGenerationState;
+
+class AccessCase {
+    WTF_MAKE_NONCOPYABLE(AccessCase);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    enum AccessType {
+        Load,
+        Transition,
+        Replace,
+        Miss,
+        Getter,
+        Setter,
+        CustomGetter,
+        CustomSetter,
+        InHit,
+        InMiss,
+        ArrayLength,
+        StringLength
+    };
+
+    static bool isGet(AccessType type)
+    {
+        switch (type) {
+        case Transition:
+        case Replace:
+        case Setter:
+        case CustomSetter:
+        case InHit:
+        case InMiss:
+            return false;
+        case Load:
+        case Miss:
+        case Getter:
+        case CustomGetter:
+        case ArrayLength:
+        case StringLength:
+            return true;
+        }
+    }
+
+    static bool isPut(AccessType type)
+    {
+        switch (type) {
+        case Load:
+        case Miss:
+        case Getter:
+        case CustomGetter:
+        case InHit:
+        case InMiss:
+        case ArrayLength:
+        case StringLength:
+            return false;
+        case Transition:
+        case Replace:
+        case Setter:
+        case CustomSetter:
+            return true;
+        }
+    }
+
+    static bool isIn(AccessType type)
+    {
+        switch (type) {
+        case Load:
+        case Miss:
+        case Getter:
+        case CustomGetter:
+        case Transition:
+        case Replace:
+        case Setter:
+        case CustomSetter:
+        case ArrayLength:
+        case StringLength:
+            return false;
+        case InHit:
+        case InMiss:
+            return true;
+        }
+    }
+
+    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);
+
+    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; fromStructureStubInfo(VM&amp;, JSCell* owner, StructureStubInfo&amp;);
+
+    ~AccessCase();
+    
+    std::unique_ptr&lt;AccessCase&gt; clone() const;
+    
+    AccessType type() const { return m_type; }
+    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; }
+
+    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;
+    
+    bool doesCalls() const
+    {
+        switch (type()) {
+        case Getter:
+        case Setter:
+        case CustomGetter:
+        case CustomSetter:
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    CallLinkInfo* callLinkInfo() const
+    {
+        if (!m_rareData)
+            return nullptr;
+        return m_rareData-&gt;callLinkInfo.get();
+    }
+
+    // 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);
+
+    void dump(PrintStream&amp; out) const;
+    
+private:
+    friend class CodeBlock;
+    friend class PolymorphicAccess;
+
+    AccessCase();
+
+    bool visitWeak(VM&amp;) const;
+
+    // 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;);
+    
+    AccessType m_type { Load };
+    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)
+        {
+            customAccessor.opaque = nullptr;
+        }
+        
+        bool viaProxy;
+        RefPtr&lt;WatchpointSet&gt; additionalSet;
+        std::unique_ptr&lt;CallLinkInfo&gt; callLinkInfo;
+        union {
+            PropertySlot::GetValueFunc getter;
+            PutPropertySlot::PutValueFunc setter;
+            void* opaque;
+        } customAccessor;
+        WriteBarrier&lt;JSObject&gt; customSlotBase;
+    };
+
+    std::unique_ptr&lt;RareData&gt; m_rareData;
+};
+
+class PolymorphicAccess {
+    WTF_MAKE_NONCOPYABLE(PolymorphicAccess);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    PolymorphicAccess();
+    ~PolymorphicAccess();
+
+    // This may return null, in which case the old stub routine is left intact. You are required to
+    // pass a vector of non-null access cases. This will prune the access cases by rejecting any case
+    // in the list that is subsumed by a later case in the list.
+    MacroAssemblerCodePtr regenerateWithCases(
+        VM&amp;, CodeBlock*, StructureStubInfo&amp;, const Identifier&amp;, Vector&lt;std::unique_ptr&lt;AccessCase&gt;&gt;);
+
+    MacroAssemblerCodePtr regenerateWithCase(
+        VM&amp;, CodeBlock*, StructureStubInfo&amp;, const Identifier&amp;, std::unique_ptr&lt;AccessCase&gt;);
+    
+    bool isEmpty() const { return m_list.isEmpty(); }
+    unsigned size() const { return m_list.size(); }
+    const AccessCase&amp; at(unsigned i) const { return *m_list[i]; }
+    const AccessCase&amp; operator[](unsigned i) const { return *m_list[i]; }
+
+    // If this returns false then we are requesting a reset of the owning StructureStubInfo.
+    bool visitWeak(VM&amp;) const;
+
+    void dump(PrintStream&amp; out) const;
+
+private:
+    friend class AccessCase;
+    friend class CodeBlock;
+    friend struct AccessGenerationState;
+    
+    typedef Vector&lt;std::unique_ptr&lt;AccessCase&gt;, 2&gt; ListType;
+
+    MacroAssemblerCodePtr regenerate(
+        VM&amp;, CodeBlock*, StructureStubInfo&amp;, const Identifier&amp;, ListType&amp; cases);
+
+    ListType m_list;
+    RefPtr&lt;JITStubRoutine&gt; m_stubRoutine;
+    std::unique_ptr&lt;WatchpointsOnStructureStubInfo&gt; m_watchpoints;
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+void printInternal(PrintStream&amp;, JSC::AccessCase::AccessType);
+
+} // namespace WTF
+
+#endif // ENABLE(JIT)
+
+#endif // PolymorphicAccess_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccessStructureListh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccessStructureList.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccessStructureList.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccessStructureList.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,112 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 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. 
- */
-
-#ifndef PolymorphicAccessStructureList_h
-#define PolymorphicAccessStructureList_h
-
-#include &quot;JITStubRoutine.h&quot;
-#include &quot;Structure.h&quot;
-#include &quot;StructureChain.h&quot;
-
-#define POLYMORPHIC_LIST_CACHE_SIZE 8
-
-namespace JSC {
-
-// *Sigh*, If the JIT is enabled we need to track the stubRountine (of type CodeLocationLabel),
-// If the JIT is not in use we don't actually need the variable (that said, if the JIT is not in use we don't
-// curently actually use PolymorphicAccessStructureLists, which we should).  Anyway, this seems like the best
-// solution for now - will need to something smarter if/when we actually want mixed-mode operation.
-
-#if ENABLE(JIT)
-// Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream.
-struct PolymorphicAccessStructureList {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    struct PolymorphicStubInfo {
-        bool isDirect : 1;
-        unsigned count : 31;
-        RefPtr&lt;JITStubRoutine&gt; stubRoutine;
-        WriteBarrier&lt;Structure&gt; base;
-        WriteBarrier&lt;StructureChain&gt; chain;
-
-        PolymorphicStubInfo()
-        {
-        }
-
-        void set(VM&amp; vm, JSCell* owner, PassRefPtr&lt;JITStubRoutine&gt; _stubRoutine, Structure* _base, bool _isDirect)
-        {
-            stubRoutine = _stubRoutine;
-            base.set(vm, owner, _base);
-            isDirect = _isDirect;
-            count = 0;
-        }
-        
-        void set(VM&amp; vm, JSCell* owner, PassRefPtr&lt;JITStubRoutine&gt; _stubRoutine, Structure* _base, StructureChain* _chain, bool _isDirect, unsigned _count)
-        {
-            stubRoutine = _stubRoutine;
-            base.set(vm, owner, _base);
-            chain.set(vm, owner, _chain);
-            isDirect = _isDirect;
-            count = _count;
-        }
-    } list[POLYMORPHIC_LIST_CACHE_SIZE];
-    
-    PolymorphicAccessStructureList()
-    {
-    }
-    
-    PolymorphicAccessStructureList(VM&amp; vm, JSCell* owner, PassRefPtr&lt;JITStubRoutine&gt; stubRoutine, Structure* firstBase, bool isDirect)
-    {
-        list[0].set(vm, owner, stubRoutine, firstBase, isDirect);
-    }
-
-    PolymorphicAccessStructureList(VM&amp; vm, JSCell* owner, PassRefPtr&lt;JITStubRoutine&gt; stubRoutine, Structure* firstBase, StructureChain* firstChain, bool isDirect, unsigned count)
-    {
-        list[0].set(vm, owner, stubRoutine, firstBase, firstChain, isDirect, count);
-    }
-
-    bool visitWeak(int count)
-    {
-        for (int i = 0; i &lt; count; ++i) {
-            PolymorphicStubInfo&amp; info = list[i];
-            if (!info.base)
-                continue;
-                
-            if (!Heap::isMarked(info.base.get()))
-                return false;
-            if (info.chain &amp;&amp; !Heap::isMarked(info.chain.get()))
-                return false;
-        }
-            
-        return true;
-    }
-};
-
-#endif // ENABLE(JIT)
-
-} // namespace JSC
-
-#endif // PolymorphicAccessStructureList_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicGetByIdListcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,155 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014, 2015 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;PolymorphicGetByIdList.h&quot;
-
-#if ENABLE(JIT)
-
-#include &quot;CodeBlock.h&quot;
-#include &quot;Heap.h&quot;
-#include &quot;JSCInlines.h&quot;
-#include &quot;StructureStubInfo.h&quot;
-
-namespace JSC {
-
-GetByIdAccess::GetByIdAccess(
-    VM&amp; vm, JSCell* owner, AccessType type, PassRefPtr&lt;JITStubRoutine&gt; stubRoutine,
-    Structure* structure, const ObjectPropertyConditionSet&amp; conditionSet)
-    : m_type(type)
-    , m_structure(vm, owner, structure)
-    , m_conditionSet(conditionSet)
-    , m_stubRoutine(stubRoutine)
-{
-}
-
-GetByIdAccess::~GetByIdAccess()
-{
-}
-
-GetByIdAccess GetByIdAccess::fromStructureStubInfo(StructureStubInfo&amp; stubInfo)
-{
-    MacroAssemblerCodePtr initialSlowPath =
-        stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase);
-    
-    GetByIdAccess result;
-    
-    RELEASE_ASSERT(stubInfo.accessType == access_get_by_id_self);
-    
-    result.m_type = SimpleInline;
-    result.m_structure.copyFrom(stubInfo.u.getByIdSelf.baseObjectStructure);
-    result.m_stubRoutine = JITStubRoutine::createSelfManagedRoutine(initialSlowPath);
-    
-    return result;
-}
-
-bool GetByIdAccess::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_stubRoutine-&gt;visitWeak(vm))
-        return false;
-    return true;
-}
-
-PolymorphicGetByIdList::PolymorphicGetByIdList(StructureStubInfo&amp; stubInfo)
-{
-    if (stubInfo.accessType == access_unset)
-        return;
-    
-    m_list.append(GetByIdAccess::fromStructureStubInfo(stubInfo));
-}
-
-PolymorphicGetByIdList* PolymorphicGetByIdList::from(StructureStubInfo&amp; stubInfo)
-{
-    if (stubInfo.accessType == access_get_by_id_list)
-        return stubInfo.u.getByIdList.list;
-    
-    ASSERT(
-        stubInfo.accessType == access_get_by_id_self
-        || stubInfo.accessType == access_unset);
-    
-    PolymorphicGetByIdList* result = new PolymorphicGetByIdList(stubInfo);
-    
-    stubInfo.initGetByIdList(result);
-    
-    return result;
-}
-
-PolymorphicGetByIdList::~PolymorphicGetByIdList() { }
-
-MacroAssemblerCodePtr PolymorphicGetByIdList::currentSlowPathTarget(
-    StructureStubInfo&amp; stubInfo) const
-{
-    if (isEmpty())
-        return stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase);
-    return m_list.last().stubRoutine()-&gt;code().code();
-}
-
-void PolymorphicGetByIdList::addAccess(const GetByIdAccess&amp; access)
-{
-    ASSERT(!isFull());
-    // Make sure that the resizing optimizes for space, not time.
-    m_list.resizeToFit(m_list.size() + 1);
-    m_list.last() = access;
-}
-
-bool PolymorphicGetByIdList::isFull() const
-{
-    ASSERT(size() &lt;= POLYMORPHIC_LIST_CACHE_SIZE);
-    return size() == POLYMORPHIC_LIST_CACHE_SIZE;
-}
-
-bool PolymorphicGetByIdList::isAlmostFull() const
-{
-    ASSERT(size() &lt;= POLYMORPHIC_LIST_CACHE_SIZE);
-    return size() &gt;= POLYMORPHIC_LIST_CACHE_SIZE - 1;
-}
-
-bool PolymorphicGetByIdList::didSelfPatching() const
-{
-    for (unsigned i = size(); i--;) {
-        if (at(i).type() == GetByIdAccess::SimpleInline)
-            return true;
-    }
-    return false;
-}
-
-bool PolymorphicGetByIdList::visitWeak(VM&amp; vm) const
-{
-    for (unsigned i = size(); i--;) {
-        if (!at(i).visitWeak(vm))
-            return false;
-    }
-    return true;
-}
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicGetByIdListh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,133 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014, 2015 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. 
- */
-
-#ifndef PolymorphicGetByIdList_h
-#define PolymorphicGetByIdList_h
-
-#if ENABLE(JIT)
-
-#include &quot;CodeOrigin.h&quot;
-#include &quot;MacroAssembler.h&quot;
-#include &quot;ObjectPropertyConditionSet.h&quot;
-#include &quot;Opcode.h&quot;
-#include &quot;Structure.h&quot;
-#include &lt;wtf/Vector.h&gt;
-
-namespace JSC {
-
-class CodeBlock;
-struct StructureStubInfo;
-
-class GetByIdAccess {
-public:
-    enum AccessType {
-        Invalid,
-        SimpleInline, // This is the patched inline access.
-        SimpleStub, // This is a stub.
-        WatchedStub,
-        Getter,
-        CustomGetter,
-        SimpleMiss,
-    };
-    
-    GetByIdAccess()
-        : m_type(Invalid)
-    {
-    }
-    
-    GetByIdAccess(
-        VM&amp;, JSCell* owner, AccessType, PassRefPtr&lt;JITStubRoutine&gt;, Structure*,
-        const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet());
-    
-    ~GetByIdAccess();
-    
-    static GetByIdAccess fromStructureStubInfo(StructureStubInfo&amp;);
-    
-    bool isSet() const { return m_type != Invalid; }
-    bool operator!() const { return !isSet(); }
-    
-    AccessType type() const { return m_type; }
-    
-    Structure* structure() const { return m_structure.get(); }
-    
-    const ObjectPropertyConditionSet&amp; conditionSet() const { return m_conditionSet; }
-    
-    JITStubRoutine* stubRoutine() const
-    {
-        ASSERT(isSet());
-        return m_stubRoutine.get();
-    }
-    
-    bool doesCalls() const { return type() == Getter || type() == CustomGetter; }
-    
-    bool visitWeak(VM&amp;) const;
-
-private:
-    friend class CodeBlock;
-    
-    AccessType m_type;
-    WriteBarrier&lt;Structure&gt; m_structure;
-    ObjectPropertyConditionSet m_conditionSet;
-    RefPtr&lt;JITStubRoutine&gt; m_stubRoutine;
-};
-
-class PolymorphicGetByIdList {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    // Either creates a new polymorphic get list, or returns the one that is already in
-    // place.
-    static PolymorphicGetByIdList* from(StructureStubInfo&amp;);
-    
-    ~PolymorphicGetByIdList();
-    
-    MacroAssemblerCodePtr currentSlowPathTarget(StructureStubInfo&amp; stubInfo) const;
-    
-    void addAccess(const GetByIdAccess&amp;);
-    
-    bool isEmpty() const { return m_list.isEmpty(); }
-    unsigned size() const { return m_list.size(); }
-    bool isFull() const;
-    bool isAlmostFull() const; // True if adding an element would make isFull() true.
-    const GetByIdAccess&amp; at(unsigned i) const { return m_list[i]; }
-    const GetByIdAccess&amp; operator[](unsigned i) const { return m_list[i]; }
-    
-    bool didSelfPatching() const; // Are any of the accesses SimpleInline?
-    
-    bool visitWeak(VM&amp;) const;
-
-private:
-    friend class CodeBlock;
-    
-    PolymorphicGetByIdList(StructureStubInfo&amp;);
-    
-    Vector&lt;GetByIdAccess, 2&gt; m_list;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
-#endif // PolymorphicGetByIdList_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicPutByIdListcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,156 +0,0 @@
</span><del>-/*
- * Copyright (C) 2012, 2014, 2015 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;PolymorphicPutByIdList.h&quot;
-
-#if ENABLE(JIT)
-
-#include &quot;StructureStubInfo.h&quot;
-
-namespace JSC {
-
-PutByIdAccess PutByIdAccess::fromStructureStubInfo(StructureStubInfo&amp; stubInfo)
-{
-    MacroAssemblerCodePtr initialSlowPath =
-        stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase);
-    
-    PutByIdAccess result;
-    
-    switch (stubInfo.accessType) {
-    case access_put_by_id_replace:
-        result.m_type = Replace;
-        result.m_oldStructure.copyFrom(stubInfo.u.putByIdReplace.baseObjectStructure);
-        result.m_stubRoutine = JITStubRoutine::createSelfManagedRoutine(initialSlowPath);
-        break;
-        
-    case access_put_by_id_transition_direct:
-    case access_put_by_id_transition_normal:
-        result.m_type = Transition;
-        result.m_oldStructure.copyFrom(stubInfo.u.putByIdTransition.previousStructure);
-        result.m_newStructure.copyFrom(stubInfo.u.putByIdTransition.structure);
-        result.m_conditionSet = ObjectPropertyConditionSet::adoptRawPointer(
-            stubInfo.u.putByIdTransition.rawConditionSet);
-        result.m_stubRoutine = stubInfo.stubRoutine;
-        break;
-        
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-    
-    return result;
-}
-
-bool PutByIdAccess::visitWeak(VM&amp; vm) const
-{
-    if (!m_conditionSet.areStillLive())
-        return false;
-    
-    switch (m_type) {
-    case Replace:
-        if (!Heap::isMarked(m_oldStructure.get()))
-            return false;
-        break;
-    case Transition:
-        if (!Heap::isMarked(m_oldStructure.get()))
-            return false;
-        if (!Heap::isMarked(m_newStructure.get()))
-            return false;
-        break;
-    case Setter:
-    case CustomSetter:
-        if (!Heap::isMarked(m_oldStructure.get()))
-            return false;
-        break;
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-        return false;
-    }
-    if (!m_stubRoutine-&gt;visitWeak(vm))
-        return false;
-    return true;
-}
-
-PolymorphicPutByIdList::PolymorphicPutByIdList(
-    PutKind putKind, StructureStubInfo&amp; stubInfo)
-    : m_kind(putKind)
-{
-    if (stubInfo.accessType != access_unset)
-        m_list.append(PutByIdAccess::fromStructureStubInfo(stubInfo));
-}
-
-PolymorphicPutByIdList* PolymorphicPutByIdList::from(
-    PutKind putKind, StructureStubInfo&amp; stubInfo)
-{
-    if (stubInfo.accessType == access_put_by_id_list)
-        return stubInfo.u.putByIdList.list;
-    
-    ASSERT(stubInfo.accessType == access_put_by_id_replace
-        || stubInfo.accessType == access_put_by_id_transition_normal
-        || stubInfo.accessType == access_put_by_id_transition_direct
-        || stubInfo.accessType == access_unset);
-    
-    PolymorphicPutByIdList* result =
-        new PolymorphicPutByIdList(putKind, stubInfo);
-    
-    stubInfo.initPutByIdList(result);
-    
-    return result;
-}
-
-PolymorphicPutByIdList::~PolymorphicPutByIdList() { }
-
-bool PolymorphicPutByIdList::isFull() const
-{
-    ASSERT(size() &lt;= POLYMORPHIC_LIST_CACHE_SIZE);
-    return size() == POLYMORPHIC_LIST_CACHE_SIZE;
-}
-
-bool PolymorphicPutByIdList::isAlmostFull() const
-{
-    ASSERT(size() &lt;= POLYMORPHIC_LIST_CACHE_SIZE);
-    return size() &gt;= POLYMORPHIC_LIST_CACHE_SIZE - 1;
-}
-
-void PolymorphicPutByIdList::addAccess(const PutByIdAccess&amp; putByIdAccess)
-{
-    ASSERT(!isFull());
-    // Make sure that the resizing optimizes for space, not time.
-    m_list.resizeToFit(m_list.size() + 1);
-    m_list.last() = putByIdAccess;
-}
-
-bool PolymorphicPutByIdList::visitWeak(VM&amp; vm) const
-{
-    for (unsigned i = 0; i &lt; size(); ++i) {
-        if (!at(i).visitWeak(vm))
-            return false;
-    }
-    return true;
-}
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicPutByIdListh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,216 +0,0 @@
</span><del>-/*
- * Copyright (C) 2012, 2014, 2015 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. 
- */
-
-#ifndef PolymorphicPutByIdList_h
-#define PolymorphicPutByIdList_h
-
-#if ENABLE(JIT)
-
-#include &quot;CodeOrigin.h&quot;
-#include &quot;MacroAssembler.h&quot;
-#include &quot;ObjectPropertyConditionSet.h&quot;
-#include &quot;Opcode.h&quot;
-#include &quot;PutKind.h&quot;
-#include &quot;PutPropertySlot.h&quot;
-#include &quot;Structure.h&quot;
-#include &lt;wtf/Vector.h&gt;
-
-namespace JSC {
-
-class CodeBlock;
-struct StructureStubInfo;
-
-class PutByIdAccess {
-public:
-    enum AccessType {
-        Invalid,
-        Transition,
-        Replace,
-        Setter,
-        CustomSetter
-    };
-    
-    PutByIdAccess()
-        : m_type(Invalid)
-    {
-    }
-    
-    static PutByIdAccess transition(
-        VM&amp; vm,
-        JSCell* owner,
-        Structure* oldStructure,
-        Structure* newStructure,
-        const ObjectPropertyConditionSet&amp; conditionSet,
-        PassRefPtr&lt;JITStubRoutine&gt; stubRoutine)
-    {
-        PutByIdAccess result;
-        result.m_type = Transition;
-        result.m_oldStructure.set(vm, owner, oldStructure);
-        result.m_newStructure.set(vm, owner, newStructure);
-        result.m_conditionSet = conditionSet;
-        result.m_customSetter = 0;
-        result.m_stubRoutine = stubRoutine;
-        return result;
-    }
-
-    static PutByIdAccess replace(
-        VM&amp; vm,
-        JSCell* owner,
-        Structure* structure,
-        PassRefPtr&lt;JITStubRoutine&gt; stubRoutine)
-    {
-        PutByIdAccess result;
-        result.m_type = Replace;
-        result.m_oldStructure.set(vm, owner, structure);
-        result.m_customSetter = 0;
-        result.m_stubRoutine = stubRoutine;
-        return result;
-    }
-
-
-    static PutByIdAccess setter(
-        VM&amp; vm,
-        JSCell* owner,
-        AccessType accessType,
-        Structure* structure,
-        const ObjectPropertyConditionSet&amp; conditionSet,
-        PutPropertySlot::PutValueFunc customSetter,
-        PassRefPtr&lt;JITStubRoutine&gt; stubRoutine)
-    {
-        RELEASE_ASSERT(accessType == Setter || accessType == CustomSetter);
-        PutByIdAccess result;
-        result.m_oldStructure.set(vm, owner, structure);
-        result.m_type = accessType;
-        result.m_conditionSet = conditionSet;
-        result.m_customSetter = customSetter;
-        result.m_stubRoutine = stubRoutine;
-        return result;
-    }
-    
-    static PutByIdAccess fromStructureStubInfo(StructureStubInfo&amp;);
-    
-    bool isSet() const { return m_type != Invalid; }
-    bool operator!() const { return !isSet(); }
-    
-    AccessType type() const { return m_type; }
-    
-    bool isTransition() const { return m_type == Transition; }
-    bool isReplace() const { return m_type == Replace; }
-    bool isSetter() const { return m_type == Setter; }
-    bool isCustom() const { return m_type == CustomSetter; }
-    
-    Structure* oldStructure() const
-    {
-        // Using this instead of isSet() to make this assertion robust against the possibility
-        // of additional access types being added.
-        ASSERT(isTransition() || isReplace() || isSetter() || isCustom());
-        
-        return m_oldStructure.get();
-    }
-    
-    Structure* structure() const
-    {
-        ASSERT(isReplace() || isSetter() || isCustom());
-        return m_oldStructure.get();
-    }
-    
-    Structure* newStructure() const
-    {
-        ASSERT(isTransition());
-        return m_newStructure.get();
-    }
-    
-    const ObjectPropertyConditionSet&amp; conditionSet() const { return m_conditionSet; }
-    
-    JITStubRoutine* stubRoutine() const
-    {
-        ASSERT(isTransition() || isReplace() || isSetter() || isCustom());
-        return m_stubRoutine.get();
-    }
-
-    PutPropertySlot::PutValueFunc customSetter() const
-    {
-        ASSERT(isCustom());
-        return m_customSetter;
-    }
-
-    bool visitWeak(VM&amp;) const;
-    
-private:
-    friend class CodeBlock;
-    
-    AccessType m_type;
-    WriteBarrier&lt;Structure&gt; m_oldStructure;
-    WriteBarrier&lt;Structure&gt; m_newStructure;
-    ObjectPropertyConditionSet m_conditionSet;
-    PutPropertySlot::PutValueFunc m_customSetter;
-    RefPtr&lt;JITStubRoutine&gt; m_stubRoutine;
-};
-
-class PolymorphicPutByIdList {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    // Either creates a new polymorphic put list, or returns the one that is already
-    // in place.
-    static PolymorphicPutByIdList* from(PutKind, StructureStubInfo&amp;);
-    
-    ~PolymorphicPutByIdList();
-    
-    MacroAssemblerCodePtr currentSlowPathTarget() const
-    {
-        return m_list.last().stubRoutine()-&gt;code().code();
-    }
-    
-    void addAccess(const PutByIdAccess&amp;);
-    
-    bool isEmpty() const { return m_list.isEmpty(); }
-    unsigned size() const { return m_list.size(); }
-    bool isFull() const;
-    bool isAlmostFull() const; // True if adding an element would make isFull() true.
-    const PutByIdAccess&amp; at(unsigned i) const { return m_list[i]; }
-    const PutByIdAccess&amp; operator[](unsigned i) const { return m_list[i]; }
-    
-    PutKind kind() const { return m_kind; }
-    
-    bool visitWeak(VM&amp;) const;
-    
-private:
-    friend class CodeBlock;
-    
-    // Initialize from a stub info; this will place one element in the list and it will
-    // be created by converting the stub info's put by id access information into our
-    // PutByIdAccess.
-    PolymorphicPutByIdList(PutKind, StructureStubInfo&amp;);
-
-    Vector&lt;PutByIdAccess, 2&gt; m_list;
-    PutKind m_kind;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
-#endif // PolymorphicPutByIdList_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePutByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -26,13 +26,12 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;PutByIdStatus.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;AccessorCallJITStubRoutine.h&quot;
</del><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;ComplexGetStatus.h&quot;
</span><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><del>-#include &quot;PolymorphicPutByIdList.h&quot;
</del><ins>+#include &quot;PolymorphicAccess.h&quot;
</ins><span class="cx"> #include &quot;Structure.h&quot;
</span><span class="cx"> #include &quot;StructureChain.h&quot;
</span><span class="cx"> #include &lt;wtf/ListDump.h&gt;
</span><span class="lines">@@ -154,66 +153,43 @@
</span><span class="cx">     if (!stubInfo-&gt;seen)
</span><span class="cx">         return PutByIdStatus();
</span><span class="cx">     
</span><del>-    switch (stubInfo-&gt;accessType) {
-    case access_unset:
</del><ins>+    switch (stubInfo-&gt;cacheType) {
+    case CacheType::Unset:
</ins><span class="cx">         // If the JIT saw it but didn't optimize it, then assume that this takes slow path.
</span><span class="cx">         return PutByIdStatus(TakesSlowPath);
</span><span class="cx">         
</span><del>-    case access_put_by_id_replace: {
</del><ins>+    case CacheType::PutByIdReplace: {
</ins><span class="cx">         PropertyOffset offset =
</span><del>-            stubInfo-&gt;u.putByIdReplace.baseObjectStructure-&gt;getConcurrently(uid);
</del><ins>+            stubInfo-&gt;u.byIdSelf.baseObjectStructure-&gt;getConcurrently(uid);
</ins><span class="cx">         if (isValidOffset(offset)) {
</span><span class="cx">             return PutByIdVariant::replace(
</span><del>-                stubInfo-&gt;u.putByIdReplace.baseObjectStructure.get(), offset);
</del><ins>+                stubInfo-&gt;u.byIdSelf.baseObjectStructure.get(), offset);
</ins><span class="cx">         }
</span><span class="cx">         return PutByIdStatus(TakesSlowPath);
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    case access_put_by_id_transition_normal:
-    case access_put_by_id_transition_direct: {
-        ASSERT(stubInfo-&gt;u.putByIdTransition.previousStructure-&gt;transitionWatchpointSetHasBeenInvalidated());
-        PropertyOffset offset = 
-            stubInfo-&gt;u.putByIdTransition.structure-&gt;getConcurrently(uid);
-        if (isValidOffset(offset)) {
-            ObjectPropertyConditionSet conditionSet = ObjectPropertyConditionSet::fromRawPointer(
-                stubInfo-&gt;u.putByIdTransition.rawConditionSet);
-            if (!conditionSet.structuresEnsureValidity())
-                return PutByIdStatus(TakesSlowPath);
-            return PutByIdVariant::transition(
-                stubInfo-&gt;u.putByIdTransition.previousStructure.get(),
-                stubInfo-&gt;u.putByIdTransition.structure.get(),
-                conditionSet, offset);
-        }
-        return PutByIdStatus(TakesSlowPath);
-    }
</del><ins>+    case CacheType::Stub: {
+        PolymorphicAccess* list = stubInfo-&gt;u.stub;
</ins><span class="cx">         
</span><del>-    case access_put_by_id_list: {
-        PolymorphicPutByIdList* list = stubInfo-&gt;u.putByIdList.list;
-        
</del><span class="cx">         PutByIdStatus result;
</span><span class="cx">         result.m_state = Simple;
</span><span class="cx">         
</span><span class="cx">         State slowPathState = TakesSlowPath;
</span><span class="cx">         for (unsigned i = 0; i &lt; list-&gt;size(); ++i) {
</span><del>-            const PutByIdAccess&amp; access = list-&gt;at(i);
-            
-            switch (access.type()) {
-            case PutByIdAccess::Setter:
-            case PutByIdAccess::CustomSetter:
</del><ins>+            const AccessCase&amp; access = list-&gt;at(i);
+            if (access.doesCalls())
</ins><span class="cx">                 slowPathState = MakesCalls;
</span><del>-                break;
-            default:
-                break;
-            }
</del><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         for (unsigned i = 0; i &lt; list-&gt;size(); ++i) {
</span><del>-            const PutByIdAccess&amp; access = list-&gt;at(i);
</del><ins>+            const AccessCase&amp; access = list-&gt;at(i);
+            if (access.viaProxy())
+                return PutByIdStatus(slowPathState);
</ins><span class="cx">             
</span><span class="cx">             PutByIdVariant variant;
</span><span class="cx">             
</span><span class="cx">             switch (access.type()) {
</span><del>-            case PutByIdAccess::Replace: {
</del><ins>+            case AccessCase::Replace: {
</ins><span class="cx">                 Structure* structure = access.structure();
</span><span class="cx">                 PropertyOffset offset = structure-&gt;getConcurrently(uid);
</span><span class="cx">                 if (!isValidOffset(offset))
</span><span class="lines">@@ -222,7 +198,7 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">                 
</span><del>-            case PutByIdAccess::Transition: {
</del><ins>+            case AccessCase::Transition: {
</ins><span class="cx">                 PropertyOffset offset =
</span><span class="cx">                     access.newStructure()-&gt;getConcurrently(uid);
</span><span class="cx">                 if (!isValidOffset(offset))
</span><span class="lines">@@ -231,11 +207,11 @@
</span><span class="cx">                 if (!conditionSet.structuresEnsureValidity())
</span><span class="cx">                     return PutByIdStatus(slowPathState);
</span><span class="cx">                 variant = PutByIdVariant::transition(
</span><del>-                    access.oldStructure(), access.newStructure(), conditionSet, offset);
</del><ins>+                    access.structure(), access.newStructure(), conditionSet, offset);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">                 
</span><del>-            case PutByIdAccess::Setter: {
</del><ins>+            case AccessCase::Setter: {
</ins><span class="cx">                 Structure* structure = access.structure();
</span><span class="cx">                 
</span><span class="cx">                 ComplexGetStatus complexGetStatus = ComplexGetStatus::computeFor(
</span><span class="lines">@@ -249,12 +225,12 @@
</span><span class="cx">                     return PutByIdStatus(slowPathState);
</span><span class="cx">                     
</span><span class="cx">                 case ComplexGetStatus::Inlineable: {
</span><del>-                    AccessorCallJITStubRoutine* stub = static_cast&lt;AccessorCallJITStubRoutine*&gt;(
-                        access.stubRoutine());
</del><ins>+                    CallLinkInfo* callLinkInfo = access.callLinkInfo();
+                    ASSERT(callLinkInfo);
</ins><span class="cx">                     std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus =
</span><span class="cx">                         std::make_unique&lt;CallLinkStatus&gt;(
</span><span class="cx">                             CallLinkStatus::computeFor(
</span><del>-                                locker, profiledBlock, *stub-&gt;m_callLinkInfo, callExitSiteData));
</del><ins>+                                locker, profiledBlock, *callLinkInfo, callExitSiteData));
</ins><span class="cx">                     
</span><span class="cx">                     variant = PutByIdVariant::setter(
</span><span class="cx">                         structure, complexGetStatus.offset(), complexGetStatus.conditionSet(),
</span><span class="lines">@@ -263,7 +239,7 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">                 
</span><del>-            case PutByIdAccess::CustomSetter:
</del><ins>+            case AccessCase::CustomSetter:
</ins><span class="cx">                 return PutByIdStatus(MakesCalls);
</span><span class="cx"> 
</span><span class="cx">             default:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureStubInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -27,8 +27,7 @@
</span><span class="cx"> #include &quot;StructureStubInfo.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSObject.h&quot;
</span><del>-#include &quot;PolymorphicGetByIdList.h&quot;
-#include &quot;PolymorphicPutByIdList.h&quot;
</del><ins>+#include &quot;PolymorphicAccess.h&quot;
</ins><span class="cx"> #include &quot;Repatch.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -36,37 +35,53 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> void StructureStubInfo::deref()
</span><span class="cx"> {
</span><del>-    switch (accessType) {
-    case access_get_by_id_list: {
-        delete u.getByIdList.list;
</del><ins>+    switch (cacheType) {
+    case CacheType::Stub:
+        delete u.stub;
</ins><span class="cx">         return;
</span><del>-    }
-    case access_put_by_id_list:
-        delete u.putByIdList.list;
</del><ins>+    case CacheType::Unset:
+    case CacheType::GetByIdSelf:
+    case CacheType::PutByIdReplace:
</ins><span class="cx">         return;
</span><del>-    case access_in_list: {
-        PolymorphicAccessStructureList* polymorphicStructures = u.inList.structureList;
-        delete polymorphicStructures;
-        return;
</del><span class="cx">     }
</span><del>-    case access_put_by_id_transition_normal:
-    case access_put_by_id_transition_direct:
-        ObjectPropertyConditionSet::adoptRawPointer(u.putByIdTransition.rawConditionSet);
-        u.putByIdTransition.rawConditionSet = nullptr;
-        return;
-    case access_get_by_id_self:
-    case access_put_by_id_replace:
-    case access_unset:
-        // These instructions don't have to release any allocated memory
-        return;
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
</del><ins>+
+    RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+MacroAssemblerCodePtr StructureStubInfo::addAccessCase(
+    VM&amp; vm, CodeBlock* codeBlock, const Identifier&amp; ident, std::unique_ptr&lt;AccessCase&gt; accessCase)
+{
+    if (!accessCase)
+        return MacroAssemblerCodePtr();
+    
+    if (cacheType == CacheType::Stub)
+        return u.stub-&gt;regenerateWithCase(vm, codeBlock, *this, ident, WTF::move(accessCase));
+
+    std::unique_ptr&lt;PolymorphicAccess&gt; access = std::make_unique&lt;PolymorphicAccess&gt;();
+    
+    Vector&lt;std::unique_ptr&lt;AccessCase&gt;&gt; accessCases;
+    
+    std::unique_ptr&lt;AccessCase&gt; previousCase =
+        AccessCase::fromStructureStubInfo(vm, codeBlock-&gt;ownerExecutable(), *this);
+    if (previousCase)
+        accessCases.append(WTF::move(previousCase));
+
+    accessCases.append(WTF::move(accessCase));
+
+    MacroAssemblerCodePtr result =
+        access-&gt;regenerateWithCases(vm, codeBlock, *this, ident, WTF::move(accessCases));
+
+    if (!result)
+        return MacroAssemblerCodePtr();
+
+    cacheType = CacheType::Stub;
+    u.stub = access.release();
+    return result;
+}
+
</ins><span class="cx"> void StructureStubInfo::reset(CodeBlock* codeBlock)
</span><span class="cx"> {
</span><del>-    if (accessType == access_unset)
</del><ins>+    if (cacheType == CacheType::Unset)
</ins><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     if (Options::verboseOSR()) {
</span><span class="lines">@@ -74,60 +89,38 @@
</span><span class="cx">         // of the CodeBlock.
</span><span class="cx">         dataLog(&quot;Clearing structure cache (kind &quot;, static_cast&lt;int&gt;(accessType), &quot;) in &quot;, RawPointer(codeBlock), &quot;.\n&quot;);
</span><span class="cx">     }
</span><del>-    
-    if (isGetByIdAccess(static_cast&lt;AccessType&gt;(accessType)))
</del><ins>+
+    switch (accessType) {
+    case AccessType::Get:
</ins><span class="cx">         resetGetByID(codeBlock, *this);
</span><del>-    else if (isPutByIdAccess(static_cast&lt;AccessType&gt;(accessType)))
</del><ins>+        break;
+    case AccessType::Put:
</ins><span class="cx">         resetPutByID(codeBlock, *this);
</span><del>-    else {
-        RELEASE_ASSERT(isInAccess(static_cast&lt;AccessType&gt;(accessType)));
</del><ins>+        break;
+    case AccessType::In:
</ins><span class="cx">         resetIn(codeBlock, *this);
</span><ins>+        break;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     deref();
</span><del>-    accessType = access_unset;
-    stubRoutine = nullptr;
-    watchpoints = nullptr;
</del><ins>+    cacheType = CacheType::Unset;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StructureStubInfo::visitWeakReferences(CodeBlock* codeBlock)
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = *codeBlock-&gt;vm();
</span><del>-    
-    switch (accessType) {
-    case access_get_by_id_self:
-        if (Heap::isMarked(u.getByIdSelf.baseObjectStructure.get()))
</del><ins>+
+    switch (cacheType) {
+    case CacheType::GetByIdSelf:
+    case CacheType::PutByIdReplace:
+        if (Heap::isMarked(u.byIdSelf.baseObjectStructure.get()))
</ins><span class="cx">             return;
</span><span class="cx">         break;
</span><del>-    case access_get_by_id_list: {
-        if (u.getByIdList.list-&gt;visitWeak(vm))
</del><ins>+    case CacheType::Stub:
+        if (u.stub-&gt;visitWeak(vm))
</ins><span class="cx">             return;
</span><span class="cx">         break;
</span><del>-    }
-    case access_put_by_id_transition_normal:
-    case access_put_by_id_transition_direct:
-        if (Heap::isMarked(u.putByIdTransition.previousStructure.get())
-            &amp;&amp; Heap::isMarked(u.putByIdTransition.structure.get())
-            &amp;&amp; ObjectPropertyConditionSet::fromRawPointer(u.putByIdTransition.rawConditionSet).areStillLive())
-            return;
-        break;
-    case access_put_by_id_replace:
-        if (Heap::isMarked(u.putByIdReplace.baseObjectStructure.get()))
-            return;
-        break;
-    case access_put_by_id_list:
-        if (u.putByIdList.list-&gt;visitWeak(vm))
-            return;
-        break;
-    case access_in_list: {
-        PolymorphicAccessStructureList* polymorphicStructures = u.inList.structureList;
-        if (polymorphicStructures-&gt;visitWeak(u.inList.listSize))
-            return;
-        break;
-    }
</del><span class="cx">     default:
</span><del>-        // The rest of the instructions don't require references, so there is no need to
-        // do anything.
</del><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureStubInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> #include &quot;MacroAssembler.h&quot;
</span><span class="cx"> #include &quot;ObjectPropertyConditionSet.h&quot;
</span><span class="cx"> #include &quot;Opcode.h&quot;
</span><del>-#include &quot;PolymorphicAccessStructureList.h&quot;
</del><ins>+#include &quot;PolymorphicAccess.h&quot;
</ins><span class="cx"> #include &quot;RegisterSet.h&quot;
</span><span class="cx"> #include &quot;SpillRegistersMode.h&quot;
</span><span class="cx"> #include &quot;Structure.h&quot;
</span><span class="lines">@@ -42,57 +42,25 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> 
</span><del>-class PolymorphicGetByIdList;
-class PolymorphicPutByIdList;
</del><ins>+class PolymorphicAccess;
</ins><span class="cx"> 
</span><del>-enum AccessType {
-    access_get_by_id_self,
-    access_get_by_id_list,
-    access_put_by_id_transition_normal,
-    access_put_by_id_transition_direct,
-    access_put_by_id_replace,
-    access_put_by_id_list,
-    access_unset,
-    access_in_list
</del><ins>+enum class AccessType : int8_t {
+    Get,
+    Put,
+    In
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline bool isGetByIdAccess(AccessType accessType)
-{
-    switch (accessType) {
-    case access_get_by_id_self:
-    case access_get_by_id_list:
-        return true;
-    default:
-        return false;
-    }
-}
-    
-inline bool isPutByIdAccess(AccessType accessType)
-{
-    switch (accessType) {
-    case access_put_by_id_transition_normal:
-    case access_put_by_id_transition_direct:
-    case access_put_by_id_replace:
-    case access_put_by_id_list:
-        return true;
-    default:
-        return false;
-    }
-}
</del><ins>+enum class CacheType : int8_t {
+    Unset,
+    GetByIdSelf,
+    PutByIdReplace,
+    Stub
+};
</ins><span class="cx"> 
</span><del>-inline bool isInAccess(AccessType accessType)
-{
-    switch (accessType) {
-    case access_in_list:
-        return true;
-    default:
-        return false;
-    }
-}
-
</del><span class="cx"> struct StructureStubInfo {
</span><del>-    StructureStubInfo()
-        : accessType(access_unset)
</del><ins>+    StructureStubInfo(AccessType accessType)
+        : accessType(accessType)
+        , cacheType(CacheType::Unset)
</ins><span class="cx">         , seen(false)
</span><span class="cx">         , resetByGC(false)
</span><span class="cx">         , tookSlowPath(false)
</span><span class="lines">@@ -100,53 +68,31 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void initGetByIdSelf(VM&amp; vm, JSCell* owner, Structure* baseObjectStructure)
</del><ins>+    void initGetByIdSelf(VM&amp; vm, JSCell* owner, Structure* baseObjectStructure, PropertyOffset offset)
</ins><span class="cx">     {
</span><del>-        accessType = access_get_by_id_self;
</del><ins>+        cacheType = CacheType::GetByIdSelf;
</ins><span class="cx"> 
</span><del>-        u.getByIdSelf.baseObjectStructure.set(vm, owner, baseObjectStructure);
</del><ins>+        u.byIdSelf.baseObjectStructure.set(vm, owner, baseObjectStructure);
+        u.byIdSelf.offset = offset;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void initGetByIdList(PolymorphicGetByIdList* list)
</del><ins>+    void initPutByIdReplace(VM&amp; vm, JSCell* owner, Structure* baseObjectStructure, PropertyOffset offset)
</ins><span class="cx">     {
</span><del>-        accessType = access_get_by_id_list;
-        u.getByIdList.list = list;
-    }
</del><ins>+        cacheType = CacheType::PutByIdReplace;
</ins><span class="cx"> 
</span><del>-    // PutById*
-
-    void initPutByIdTransition(VM&amp; vm, JSCell* owner, Structure* previousStructure, Structure* structure, ObjectPropertyConditionSet conditionSet, bool isDirect)
-    {
-        if (isDirect)
-            accessType = access_put_by_id_transition_direct;
-        else
-            accessType = access_put_by_id_transition_normal;
-
-        u.putByIdTransition.previousStructure.set(vm, owner, previousStructure);
-        u.putByIdTransition.structure.set(vm, owner, structure);
-        u.putByIdTransition.rawConditionSet = conditionSet.releaseRawPointer();
</del><ins>+        u.byIdSelf.baseObjectStructure.set(vm, owner, baseObjectStructure);
+        u.byIdSelf.offset = offset;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void initPutByIdReplace(VM&amp; vm, JSCell* owner, Structure* baseObjectStructure)
</del><ins>+    void initStub(std::unique_ptr&lt;PolymorphicAccess&gt; stub)
</ins><span class="cx">     {
</span><del>-        accessType = access_put_by_id_replace;
-    
-        u.putByIdReplace.baseObjectStructure.set(vm, owner, baseObjectStructure);
</del><ins>+        cacheType = CacheType::Stub;
+        u.stub = stub.release();
</ins><span class="cx">     }
</span><del>-        
-    void initPutByIdList(PolymorphicPutByIdList* list)
-    {
-        accessType = access_put_by_id_list;
-        u.putByIdList.list = list;
-    }
-    
-    void initInList(PolymorphicAccessStructureList* list, int listSize)
-    {
-        accessType = access_in_list;
-        u.inList.structureList = list;
-        u.inList.listSize = listSize;
-    }
-        
</del><ins>+
+    MacroAssemblerCodePtr addAccessCase(
+        VM&amp;, CodeBlock*, const Identifier&amp;, std::unique_ptr&lt;AccessCase&gt;);
+
</ins><span class="cx">     void reset(CodeBlock*);
</span><span class="cx"> 
</span><span class="cx">     void deref();
</span><span class="lines">@@ -165,15 +111,9 @@
</span><span class="cx">         seen = true;
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    StructureStubClearingWatchpoint* addWatchpoint(
-        CodeBlock* codeBlock, const ObjectPropertyCondition&amp; condition = ObjectPropertyCondition())
-    {
-        return WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint(
-            watchpoints, codeBlock, this, condition);
-    }
-    
-    int8_t accessType;
-    bool seen : 1;
</del><ins>+    AccessType accessType;
+    CacheType cacheType;
+    bool seen;
</ins><span class="cx">     bool resetByGC : 1;
</span><span class="cx">     bool tookSlowPath : 1;
</span><span class="cx"> 
</span><span class="lines">@@ -203,34 +143,13 @@
</span><span class="cx"> 
</span><span class="cx">     union {
</span><span class="cx">         struct {
</span><del>-            // It would be unwise to put anything here, as it will surely be overwritten.
-        } unset;
-        struct {
</del><span class="cx">             WriteBarrierBase&lt;Structure&gt; baseObjectStructure;
</span><del>-        } getByIdSelf;
-        struct {
-            PolymorphicGetByIdList* list;
-        } getByIdList;
-        struct {
-            WriteBarrierBase&lt;Structure&gt; previousStructure;
-            WriteBarrierBase&lt;Structure&gt; structure;
-            void* rawConditionSet;
-        } putByIdTransition;
-        struct {
-            WriteBarrierBase&lt;Structure&gt; baseObjectStructure;
-        } putByIdReplace;
-        struct {
-            PolymorphicPutByIdList* list;
-        } putByIdList;
-        struct {
-            PolymorphicAccessStructureList* structureList;
-            int listSize;
-        } inList;
</del><ins>+            PropertyOffset offset;
+        } byIdSelf;
+        PolymorphicAccess* stub;
</ins><span class="cx">     } u;
</span><span class="cx"> 
</span><del>-    RefPtr&lt;JITStubRoutine&gt; stubRoutine;
</del><span class="cx">     CodeLocationCall callReturnLocation;
</span><del>-    std::unique_ptr&lt;WatchpointsOnStructureStubInfo&gt; watchpoints;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline CodeOrigin getStructureStubInfoCodeOrigin(StructureStubInfo&amp; structureStubInfo)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -935,7 +935,7 @@
</span><span class="cx">     
</span><span class="cx">     if (JSString* string = node-&gt;child1()-&gt;dynamicCastConstant&lt;JSString*&gt;()) {
</span><span class="cx">         if (string-&gt;tryGetValueImpl() &amp;&amp; string-&gt;tryGetValueImpl()-&gt;isAtomic()) {
</span><del>-            StructureStubInfo* stubInfo = m_jit.codeBlock()-&gt;addStubInfo();
</del><ins>+            StructureStubInfo* stubInfo = m_jit.codeBlock()-&gt;addStubInfo(AccessType::In);
</ins><span class="cx">             
</span><span class="cx">             GPRTemporary result(this);
</span><span class="cx">             GPRReg resultGPR = result.gpr();
</span><span class="lines">@@ -956,6 +956,9 @@
</span><span class="cx">             stubInfo-&gt;codeOrigin = node-&gt;origin.semantic;
</span><span class="cx">             stubInfo-&gt;patch.baseGPR = static_cast&lt;int8_t&gt;(baseGPR);
</span><span class="cx">             stubInfo-&gt;patch.valueGPR = static_cast&lt;int8_t&gt;(resultGPR);
</span><ins>+#if USE(JSVALUE32_64)
+            stubInfo-&gt;patch.valueTagGPR = static_cast&lt;int8_t&gt;(InvalidGPRReg);
+#endif
</ins><span class="cx">             stubInfo-&gt;patch.usedRegisters = usedRegisters();
</span><span class="cx">             stubInfo-&gt;patch.spillMode = NeedToSpill;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -539,7 +539,7 @@
</span><span class="cx">                 RegisterSet usedRegisters = usedRegistersFor(record);
</span><span class="cx">                 GPRReg result = record.locations[0].directGPR();
</span><span class="cx">                 GPRReg obj = record.locations[1].directGPR();
</span><del>-                StructureStubInfo* stubInfo = codeBlock-&gt;addStubInfo(); 
</del><ins>+                StructureStubInfo* stubInfo = codeBlock-&gt;addStubInfo(AccessType::In); 
</ins><span class="cx">                 stubInfo-&gt;codeOrigin = codeOrigin;
</span><span class="cx">                 stubInfo-&gt;callSiteIndex = checkIn.callSiteIndex();
</span><span class="cx">                 stubInfo-&gt;patch.baseGPR = static_cast&lt;int8_t&gt;(obj);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAccessorCallJITStubRoutinecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/jit/AccessorCallJITStubRoutine.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AccessorCallJITStubRoutine.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/AccessorCallJITStubRoutine.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,55 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014, 2015 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;AccessorCallJITStubRoutine.h&quot;
-
-#if ENABLE(JIT)
-
-#include &quot;CallLinkInfo.h&quot;
-
-namespace JSC {
-
-AccessorCallJITStubRoutine::AccessorCallJITStubRoutine(
-    const MacroAssemblerCodeRef&amp; code, VM&amp; vm, std::unique_ptr&lt;CallLinkInfo&gt; info)
-    : GCAwareJITStubRoutine(code, vm)
-    , m_callLinkInfo(WTF::move(info))
-{
-}
-
-AccessorCallJITStubRoutine::~AccessorCallJITStubRoutine()
-{
-}
-
-bool AccessorCallJITStubRoutine::visitWeak(VM&amp; vm)
-{
-    m_callLinkInfo-&gt;visitWeak(vm);
-    return true;
-}
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAccessorCallJITStubRoutineh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/jit/AccessorCallJITStubRoutine.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AccessorCallJITStubRoutine.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/AccessorCallJITStubRoutine.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,57 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014, 2015 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. 
- */
-
-#ifndef AccessorCallJITStubRoutine_h
-#define AccessorCallJITStubRoutine_h
-
-#if ENABLE(JIT)
-
-#include &quot;GCAwareJITStubRoutine.h&quot;
-
-namespace JSC {
-
-class CallLinkInfo;
-
-// JIT stub routine for use by JavaScript accessors. These will be making a JS
-// call that requires inline caching. 
-
-class AccessorCallJITStubRoutine : public GCAwareJITStubRoutine {
-public:
-    AccessorCallJITStubRoutine(
-        const MacroAssemblerCodeRef&amp;, VM&amp;, std::unique_ptr&lt;CallLinkInfo&gt;);
-    
-    virtual ~AccessorCallJITStubRoutine();
-    
-    virtual bool visitWeak(VM&amp;) override;
-    
-    std::unique_ptr&lt;CallLinkInfo&gt; m_callLinkInfo;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(JIT)
-
-#endif // AccessorCallJITStubRoutine_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -718,7 +718,7 @@
</span><span class="cx">         return branch32(Equal, regs.tagGPR(), TrustedImm32(JSValue::EmptyValueTag));
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     template&lt;typename T&gt;
</span><span class="cx">     Jump branchStructure(RelationalCondition condition, T leftHandSide, Structure* structure)
</span><span class="cx">     {
</span><span class="lines">@@ -987,6 +987,15 @@
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void boxBooleanPayload(bool value, GPRReg payloadGPR)
+    {
+#if USE(JSVALUE64)
+        move(TrustedImm32(ValueFalse + value), payloadGPR);
+#else
+        move(TrustedImm32(value), payloadGPR);
+#endif
+    }
+
</ins><span class="cx">     void boxBoolean(GPRReg boolGPR, JSValueRegs boxedRegs)
</span><span class="cx">     {
</span><span class="cx">         boxBooleanPayload(boolGPR, boxedRegs.payloadGPR());
</span><span class="lines">@@ -994,6 +1003,17 @@
</span><span class="cx">         move(TrustedImm32(JSValue::BooleanTag), boxedRegs.tagGPR());
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><ins>+
+    void boxInt32(GPRReg intGPR, JSValueRegs boxedRegs)
+    {
+#if USE(JSVALUE64)
+        move(intGPR, boxedRegs.gpr());
+        or64(TrustedImm64(TagTypeNumber), boxedRegs.gpr());
+#else
+        move(intGPR, boxedRegs.payloadGPR());
+        move(TrustedImm32(JSValue::Int32Tag), boxedRegs.tagGPR());
+#endif
+    }
</ins><span class="cx">     
</span><span class="cx">     void callExceptionFuzz();
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitBinarySwitchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/BinarySwitch.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/BinarySwitch.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/BinarySwitch.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -29,9 +29,12 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &lt;wtf/ListDump.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+static const bool verbose = false;
+
</ins><span class="cx"> static unsigned globalCounter; // We use a different seed every time we are invoked.
</span><span class="cx"> 
</span><span class="cx"> BinarySwitch::BinarySwitch(GPRReg value, const Vector&lt;int64_t&gt;&amp; cases, Type type)
</span><span class="lines">@@ -43,11 +46,17 @@
</span><span class="cx"> {
</span><span class="cx">     if (cases.isEmpty())
</span><span class="cx">         return;
</span><ins>+
+    if (verbose)
+        dataLog(&quot;Original cases: &quot;, listDump(cases), &quot;\n&quot;);
</ins><span class="cx">     
</span><span class="cx">     for (unsigned i = 0; i &lt; cases.size(); ++i)
</span><span class="cx">         m_cases.append(Case(cases[i], i));
</span><span class="cx">     
</span><span class="cx">     std::sort(m_cases.begin(), m_cases.end());
</span><ins>+
+    if (verbose)
+        dataLog(&quot;Sorted cases: &quot;, listDump(m_cases), &quot;\n&quot;);
</ins><span class="cx">     
</span><span class="cx">     for (unsigned i = 1; i &lt; m_cases.size(); ++i)
</span><span class="cx">         RELEASE_ASSERT(m_cases[i - 1] &lt; m_cases[i]);
</span><span class="lines">@@ -128,6 +137,15 @@
</span><span class="cx"> 
</span><span class="cx"> void BinarySwitch::build(unsigned start, bool hardStart, unsigned end)
</span><span class="cx"> {
</span><ins>+    if (verbose)
+        dataLog(&quot;Building with start = &quot;, start, &quot;, hardStart = &quot;, hardStart, &quot;, end = &quot;, end, &quot;\n&quot;);
+
+    auto append = [&amp;] (const BranchCode&amp; code) {
+        if (verbose)
+            dataLog(&quot;==&gt; &quot;, code, &quot;\n&quot;);
+        m_branches.append(code);
+    };
+    
</ins><span class="cx">     unsigned size = end - start;
</span><span class="cx">     
</span><span class="cx">     RELEASE_ASSERT(size);
</span><span class="lines">@@ -141,6 +159,9 @@
</span><span class="cx">     const unsigned leafThreshold = 3;
</span><span class="cx">     
</span><span class="cx">     if (size &lt;= leafThreshold) {
</span><ins>+        if (verbose)
+            dataLog(&quot;It's a leaf.\n&quot;);
+        
</ins><span class="cx">         // It turns out that for exactly three cases or less, it's better to just compare each
</span><span class="cx">         // case individually. This saves 1/6 of a branch on average, and up to 1/3 of a branch in
</span><span class="cx">         // extreme cases where the divide-and-conquer bottoms out in a lot of 3-case subswitches.
</span><span class="lines">@@ -158,12 +179,15 @@
</span><span class="cx">             &amp;&amp; m_cases[start + size - 1].value == m_cases[start + size].value - 1) {
</span><span class="cx">             allConsecutive = true;
</span><span class="cx">             for (unsigned i = 0; i &lt; size - 1; ++i) {
</span><del>-                if (m_cases[i].value + 1 != m_cases[i + 1].value) {
</del><ins>+                if (m_cases[start + i].value + 1 != m_cases[start + i + 1].value) {
</ins><span class="cx">                     allConsecutive = false;
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">         }
</span><ins>+
+        if (verbose)
+            dataLog(&quot;allConsecutive = &quot;, allConsecutive, &quot;\n&quot;);
</ins><span class="cx">         
</span><span class="cx">         Vector&lt;unsigned, 3&gt; localCaseIndices;
</span><span class="cx">         for (unsigned i = 0; i &lt; size; ++i)
</span><span class="lines">@@ -178,17 +202,20 @@
</span><span class="cx">             });
</span><span class="cx">         
</span><span class="cx">         for (unsigned i = 0; i &lt; size - 1; ++i) {
</span><del>-            m_branches.append(BranchCode(NotEqualToPush, localCaseIndices[i]));
-            m_branches.append(BranchCode(ExecuteCase, localCaseIndices[i]));
-            m_branches.append(BranchCode(Pop));
</del><ins>+            append(BranchCode(NotEqualToPush, localCaseIndices[i]));
+            append(BranchCode(ExecuteCase, localCaseIndices[i]));
+            append(BranchCode(Pop));
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         if (!allConsecutive)
</span><del>-            m_branches.append(BranchCode(NotEqualToFallThrough, localCaseIndices.last()));
</del><ins>+            append(BranchCode(NotEqualToFallThrough, localCaseIndices.last()));
</ins><span class="cx">         
</span><del>-        m_branches.append(BranchCode(ExecuteCase, localCaseIndices.last()));
</del><ins>+        append(BranchCode(ExecuteCase, localCaseIndices.last()));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+
+    if (verbose)
+        dataLog(&quot;It's not a leaf.\n&quot;);
</ins><span class="cx">         
</span><span class="cx">     // There are two different strategies we could consider here:
</span><span class="cx">     //
</span><span class="lines">@@ -286,7 +313,10 @@
</span><span class="cx">     // and get a 1/6 speed-up on average for taking an explicit case.
</span><span class="cx">         
</span><span class="cx">     unsigned medianIndex = (start + end) / 2;
</span><del>-        
</del><ins>+
+    if (verbose)
+        dataLog(&quot;medianIndex = &quot;, medianIndex, &quot;\n&quot;);
+
</ins><span class="cx">     // We want medianIndex to point to the thing we will do a less-than compare against. We want
</span><span class="cx">     // this less-than compare to split the current sublist into equal-sized sublists, or
</span><span class="cx">     // nearly-equal-sized with some randomness if we're in the odd case. With the above
</span><span class="lines">@@ -317,12 +347,44 @@
</span><span class="cx">     RELEASE_ASSERT(medianIndex &gt; start);
</span><span class="cx">     RELEASE_ASSERT(medianIndex + 1 &lt; end);
</span><span class="cx">         
</span><del>-    m_branches.append(BranchCode(LessThanToPush, medianIndex));
</del><ins>+    if (verbose)
+        dataLog(&quot;fixed medianIndex = &quot;, medianIndex, &quot;\n&quot;);
+
+    append(BranchCode(LessThanToPush, medianIndex));
</ins><span class="cx">     build(medianIndex, true, end);
</span><del>-    m_branches.append(BranchCode(Pop));
</del><ins>+    append(BranchCode(Pop));
</ins><span class="cx">     build(start, hardStart, medianIndex);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void BinarySwitch::Case::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;&lt;value: &quot; , value, &quot;, index: &quot;, index, &quot;&gt;&quot;);
+}
+
+void BinarySwitch::BranchCode::dump(PrintStream&amp; out) const
+{
+    switch (kind) {
+    case NotEqualToFallThrough:
+        out.print(&quot;NotEqualToFallThrough&quot;);
+        break;
+    case NotEqualToPush:
+        out.print(&quot;NotEqualToPush&quot;);
+        break;
+    case LessThanToPush:
+        out.print(&quot;LessThanToPush&quot;);
+        break;
+    case Pop:
+        out.print(&quot;Pop&quot;);
+        break;
+    case ExecuteCase:
+        out.print(&quot;ExecuteCase&quot;);
+        break;
+    }
+
+    if (index != UINT_MAX)
+        out.print(&quot;(&quot;, index, &quot;)&quot;);
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitBinarySwitchh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/BinarySwitch.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/BinarySwitch.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/BinarySwitch.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -94,6 +94,8 @@
</span><span class="cx">         {
</span><span class="cx">             return value &lt; other.value;
</span><span class="cx">         }
</span><ins>+
+        void dump(PrintStream&amp; out) const;
</ins><span class="cx">         
</span><span class="cx">         int64_t value;
</span><span class="cx">         unsigned index;
</span><span class="lines">@@ -117,6 +119,8 @@
</span><span class="cx">             , index(index)
</span><span class="cx">         {
</span><span class="cx">         }
</span><ins>+
+        void dump(PrintStream&amp; out) const;
</ins><span class="cx">         
</span><span class="cx">         BranchKind kind;
</span><span class="cx">         unsigned index;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -66,7 +66,6 @@
</span><span class="cx"> 
</span><span class="cx">     struct Instruction;
</span><span class="cx">     struct OperandTypes;
</span><del>-    struct PolymorphicAccessStructureList;
</del><span class="cx">     struct SimpleJumpTable;
</span><span class="cx">     struct StringJumpTable;
</span><span class="cx">     struct StructureStubInfo;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITInlineCacheGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -36,22 +36,24 @@
</span><span class="cx"> 
</span><span class="cx"> static StructureStubInfo* garbageStubInfo()
</span><span class="cx"> {
</span><del>-    static StructureStubInfo* stubInfo = new StructureStubInfo();
</del><ins>+    static StructureStubInfo* stubInfo = new StructureStubInfo(AccessType::Get);
</ins><span class="cx">     return stubInfo;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JITInlineCacheGenerator::JITInlineCacheGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite)
</del><ins>+JITInlineCacheGenerator::JITInlineCacheGenerator(
+    CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, AccessType accessType)
</ins><span class="cx">     : m_codeBlock(codeBlock)
</span><span class="cx"> {
</span><del>-    m_stubInfo = m_codeBlock ? m_codeBlock-&gt;addStubInfo() : garbageStubInfo();
</del><ins>+    m_stubInfo = m_codeBlock ? m_codeBlock-&gt;addStubInfo(accessType) : garbageStubInfo();
</ins><span class="cx">     m_stubInfo-&gt;codeOrigin = codeOrigin;
</span><span class="cx">     m_stubInfo-&gt;callSiteIndex = callSite;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JITByIdGenerator::JITByIdGenerator(
</span><del>-    CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet&amp; usedRegisters,
-    JSValueRegs base, JSValueRegs value, SpillRegistersMode spillMode)
-    : JITInlineCacheGenerator(codeBlock, codeOrigin, callSite)
</del><ins>+    CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, AccessType accessType,
+    const RegisterSet&amp; usedRegisters, JSValueRegs base, JSValueRegs value,
+    SpillRegistersMode spillMode)
+    : JITInlineCacheGenerator(codeBlock, codeOrigin, callSite, accessType)
</ins><span class="cx">     , m_base(base)
</span><span class="cx">     , m_value(value)
</span><span class="cx"> {
</span><span class="lines">@@ -114,7 +116,8 @@
</span><span class="cx"> JITGetByIdGenerator::JITGetByIdGenerator(
</span><span class="cx">     CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet&amp; usedRegisters,
</span><span class="cx">     JSValueRegs base, JSValueRegs value, SpillRegistersMode spillMode)
</span><del>-    : JITByIdGenerator(codeBlock, codeOrigin, callSite, usedRegisters, base, value, spillMode)
</del><ins>+    : JITByIdGenerator(
+        codeBlock, codeOrigin, callSite, AccessType::Get, usedRegisters, base, value, spillMode)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(base.payloadGPR() != value.tagGPR());
</span><span class="cx"> }
</span><span class="lines">@@ -140,7 +143,8 @@
</span><span class="cx">     CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet&amp; usedRegisters,
</span><span class="cx">     JSValueRegs base, JSValueRegs value, GPRReg scratch, SpillRegistersMode spillMode,
</span><span class="cx">     ECMAMode ecmaMode, PutKind putKind)
</span><del>-    : JITByIdGenerator(codeBlock, codeOrigin, callSite, usedRegisters, base, value, spillMode)
</del><ins>+    : JITByIdGenerator(
+        codeBlock, codeOrigin, callSite, AccessType::Put, usedRegisters, base, value, spillMode)
</ins><span class="cx">     , m_scratch(scratch)
</span><span class="cx">     , m_ecmaMode(ecmaMode)
</span><span class="cx">     , m_putKind(putKind)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITInlineCacheGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="cx"> #include &quot;PutKind.h&quot;
</span><span class="cx"> #include &quot;RegisterSet.h&quot;
</span><ins>+#include &quot;StructureStubInfo.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -41,7 +42,7 @@
</span><span class="cx"> class JITInlineCacheGenerator {
</span><span class="cx"> protected:
</span><span class="cx">     JITInlineCacheGenerator() { }
</span><del>-    JITInlineCacheGenerator(CodeBlock*, CodeOrigin, CallSiteIndex);
</del><ins>+    JITInlineCacheGenerator(CodeBlock*, CodeOrigin, CallSiteIndex, AccessType);
</ins><span class="cx">     
</span><span class="cx"> public:
</span><span class="cx">     StructureStubInfo* stubInfo() const { return m_stubInfo; }
</span><span class="lines">@@ -56,8 +57,8 @@
</span><span class="cx">     JITByIdGenerator() { }
</span><span class="cx"> 
</span><span class="cx">     JITByIdGenerator(
</span><del>-        CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet&amp;, JSValueRegs base, JSValueRegs value,
-        SpillRegistersMode spillMode);
</del><ins>+        CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet&amp;, JSValueRegs base,
+        JSValueRegs value, SpillRegistersMode spillMode);
</ins><span class="cx">     
</span><span class="cx"> public:
</span><span class="cx">     void reportSlowPathCall(MacroAssembler::Label slowPathBegin, MacroAssembler::Call call)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -163,24 +163,6 @@
</span><span class="cx">     return JSValue::encode(baseValue.get(exec, ident, slot));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedJSValue JIT_OPERATION operationGetByIdBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
-{
-    VM* vm = &amp;exec-&gt;vm();
-    NativeCallFrameTracer tracer(vm, exec);
-
-    Identifier ident = Identifier::fromUid(vm, uid);
-    AccessType accessType = static_cast&lt;AccessType&gt;(stubInfo-&gt;accessType);
-
-    JSValue baseValue = JSValue::decode(base);
-    PropertySlot slot(baseValue);
-    bool hasResult = baseValue.getPropertySlot(exec, ident, slot);
-    
-    if (accessType == static_cast&lt;AccessType&gt;(stubInfo-&gt;accessType))
-        buildGetByIDList(exec, baseValue, ident, slot, *stubInfo);
-
-    return JSValue::encode(hasResult? slot.getValue(exec, ident) : jsUndefined());
-}
-
</del><span class="cx"> EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid)
</span><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="lines">@@ -197,7 +179,6 @@
</span><span class="cx">         stubInfo-&gt;seen = true;
</span><span class="cx">     
</span><span class="cx">     return JSValue::encode(hasResult? slot.getValue(exec, ident) : jsUndefined());
</span><del>-
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationInOptimize(ExecState* exec, StructureStubInfo* stubInfo, JSCell* base, UniquedStringImpl* key)
</span><span class="lines">@@ -394,90 +375,6 @@
</span><span class="cx">         stubInfo-&gt;seen = true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JIT_OPERATION operationPutByIdStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
-{
-    VM* vm = &amp;exec-&gt;vm();
-    NativeCallFrameTracer tracer(vm, exec);
-    
-    Identifier ident = Identifier::fromUid(vm, uid);
-    AccessType accessType = static_cast&lt;AccessType&gt;(stubInfo-&gt;accessType);
-
-    JSValue value = JSValue::decode(encodedValue);
-    JSValue baseValue = JSValue::decode(encodedBase);
-    PutPropertySlot slot(baseValue, true, exec-&gt;codeBlock()-&gt;putByIdContext());
-    
-    Structure* structure = baseValue.isCell() ? baseValue.asCell()-&gt;structure(*vm) : nullptr; 
-    baseValue.put(exec, ident, value, slot);
-
-    if (accessType != static_cast&lt;AccessType&gt;(stubInfo-&gt;accessType))
-        return;
-
-    buildPutByIdList(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
-}
-
-void JIT_OPERATION operationPutByIdNonStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
-{
-    VM* vm = &amp;exec-&gt;vm();
-    NativeCallFrameTracer tracer(vm, exec);
-    
-    Identifier ident = Identifier::fromUid(vm, uid);
-    AccessType accessType = static_cast&lt;AccessType&gt;(stubInfo-&gt;accessType);
-
-    JSValue value = JSValue::decode(encodedValue);
-    JSValue baseValue = JSValue::decode(encodedBase);
-    PutPropertySlot slot(baseValue, false, exec-&gt;codeBlock()-&gt;putByIdContext());
-
-    Structure* structure = baseValue.isCell() ? baseValue.asCell()-&gt;structure(*vm) : nullptr;
-    baseValue.put(exec, ident, value, slot);
-    
-    if (accessType != static_cast&lt;AccessType&gt;(stubInfo-&gt;accessType))
-        return;
-    
-    buildPutByIdList(exec, baseValue, structure, ident, slot, *stubInfo, NotDirect);
-}
-
-void JIT_OPERATION operationPutByIdDirectStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
-{
-    VM* vm = &amp;exec-&gt;vm();
-    NativeCallFrameTracer tracer(vm, exec);
-    
-    Identifier ident = Identifier::fromUid(vm, uid);
-    AccessType accessType = static_cast&lt;AccessType&gt;(stubInfo-&gt;accessType);
-    
-    JSValue value = JSValue::decode(encodedValue);
-    JSObject* baseObject = asObject(JSValue::decode(encodedBase));
-    PutPropertySlot slot(baseObject, true, exec-&gt;codeBlock()-&gt;putByIdContext());
-
-    Structure* structure = baseObject-&gt;structure(*vm);    
-    baseObject-&gt;putDirect(*vm, ident, value, slot);
-    
-    if (accessType != static_cast&lt;AccessType&gt;(stubInfo-&gt;accessType))
-        return;
-    
-    buildPutByIdList(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
-}
-
-void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl* uid)
-{
-    VM* vm = &amp;exec-&gt;vm();
-    NativeCallFrameTracer tracer(vm, exec);
-    
-    Identifier ident = Identifier::fromUid(vm, uid);
-    AccessType accessType = static_cast&lt;AccessType&gt;(stubInfo-&gt;accessType);
-
-    JSValue value = JSValue::decode(encodedValue);
-    JSObject* baseObject = asObject(JSValue::decode(encodedBase));
-    PutPropertySlot slot(baseObject, false, exec-&gt;codeBlock()-&gt;putByIdContext());
-
-    Structure* structure = baseObject-&gt;structure(*vm);    
-    baseObject-&gt;putDirect(*vm, ident, value, slot);
-
-    if (accessType != static_cast&lt;AccessType&gt;(stubInfo-&gt;accessType))
-        return;
-    
-    buildPutByIdList(exec, baseObject, structure, ident, slot, *stubInfo, Direct);
-}
-
</del><span class="cx"> void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value)
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/Repatch.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -28,7 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> 
</span><del>-#include &quot;AccessorCallJITStubRoutine.h&quot;
</del><span class="cx"> #include &quot;BinarySwitch.h&quot;
</span><span class="cx"> #include &quot;CCallHelpers.h&quot;
</span><span class="cx"> #include &quot;DFGOperations.h&quot;
</span><span class="lines">@@ -40,8 +39,7 @@
</span><span class="cx"> #include &quot;JITInlines.h&quot;
</span><span class="cx"> #include &quot;LinkBuffer.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><del>-#include &quot;PolymorphicGetByIdList.h&quot;
-#include &quot;PolymorphicPutByIdList.h&quot;
</del><ins>+#include &quot;PolymorphicAccess.h&quot;
</ins><span class="cx"> #include &quot;RegExpMatchesArray.h&quot;
</span><span class="cx"> #include &quot;ScratchRegisterAllocator.h&quot;
</span><span class="cx"> #include &quot;StackAlignment.h&quot;
</span><span class="lines">@@ -94,13 +92,10 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void repatchByIdSelfAccess(
</span><del>-    VM&amp; vm, CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo, Structure* structure,
-    const Identifier&amp; propertyName, PropertyOffset offset, const FunctionPtr &amp;slowPathFunction,
</del><ins>+    CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo, Structure* structure,
+    PropertyOffset offset, const FunctionPtr &amp;slowPathFunction,
</ins><span class="cx">     bool compact)
</span><span class="cx"> {
</span><del>-    if (structure-&gt;needImpurePropertyWatchpoint())
-        vm.registerWatchpointForImpureProperty(propertyName, stubInfo.addWatchpoint(codeBlock));
-    
</del><span class="cx">     // Only optimize once!
</span><span class="cx">     repatchCall(codeBlock, stubInfo.callReturnLocation, slowPathFunction);
</span><span class="cx"> 
</span><span class="lines">@@ -129,33 +124,44 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void checkObjectPropertyCondition(
-    const ObjectPropertyCondition&amp; condition, CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo,
-    CCallHelpers&amp; jit, MacroAssembler::JumpList&amp; failureCases, GPRReg scratchGPR)
</del><ins>+static void resetGetByIDCheckAndLoad(StructureStubInfo&amp; stubInfo)
</ins><span class="cx"> {
</span><del>-    if (condition.isWatchableAssumingImpurePropertyWatchpoint()) {
-        condition.object()-&gt;structure()-&gt;addTransitionWatchpoint(
-            stubInfo.addWatchpoint(codeBlock, condition));
-        return;
</del><ins>+    CodeLocationDataLabel32 structureLabel = stubInfo.callReturnLocation.dataLabel32AtOffset(-(intptr_t)stubInfo.patch.deltaCheckImmToCall);
+    if (MacroAssembler::canJumpReplacePatchableBranch32WithPatch()) {
+        MacroAssembler::revertJumpReplacementToPatchableBranch32WithPatch(
+            MacroAssembler::startOfPatchableBranch32WithPatchOnAddress(structureLabel),
+            MacroAssembler::Address(
+                static_cast&lt;MacroAssembler::RegisterID&gt;(stubInfo.patch.baseGPR),
+                JSCell::structureIDOffset()),
+            static_cast&lt;int32_t&gt;(unusedPointer));
</ins><span class="cx">     }
</span><del>-
-    Structure* structure = condition.object()-&gt;structure();
-    RELEASE_ASSERT(condition.structureEnsuresValidityAssumingImpurePropertyWatchpoint(structure));
-    jit.move(MacroAssembler::TrustedImmPtr(condition.object()), scratchGPR);
-    failureCases.append(
-        jit.branchStructure(
-            MacroAssembler::NotEqual,
-            MacroAssembler::Address(scratchGPR, JSCell::structureIDOffset()), structure));
</del><ins>+    MacroAssembler::repatchInt32(structureLabel, static_cast&lt;int32_t&gt;(unusedPointer));
+#if USE(JSVALUE64)
+    MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToLoadOrStore), 0);
+#else
+    MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToTagLoadOrStore), 0);
+    MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToPayloadLoadOrStore), 0);
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void checkObjectPropertyConditions(
-    const ObjectPropertyConditionSet&amp; set, CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo,
-    CCallHelpers&amp; jit, MacroAssembler::JumpList&amp; failureCases, GPRReg scratchGPR)
</del><ins>+static void resetPutByIDCheckAndLoad(StructureStubInfo&amp; stubInfo)
</ins><span class="cx"> {
</span><del>-    for (const ObjectPropertyCondition&amp; condition : set) {
-        checkObjectPropertyCondition(
-            condition, codeBlock, stubInfo, jit, failureCases, scratchGPR);
</del><ins>+    CodeLocationDataLabel32 structureLabel = stubInfo.callReturnLocation.dataLabel32AtOffset(-(intptr_t)stubInfo.patch.deltaCheckImmToCall);
+    if (MacroAssembler::canJumpReplacePatchableBranch32WithPatch()) {
+        MacroAssembler::revertJumpReplacementToPatchableBranch32WithPatch(
+            MacroAssembler::startOfPatchableBranch32WithPatchOnAddress(structureLabel),
+            MacroAssembler::Address(
+                static_cast&lt;MacroAssembler::RegisterID&gt;(stubInfo.patch.baseGPR),
+                JSCell::structureIDOffset()),
+            static_cast&lt;int32_t&gt;(unusedPointer));
</ins><span class="cx">     }
</span><ins>+    MacroAssembler::repatchInt32(structureLabel, static_cast&lt;int32_t&gt;(unusedPointer));
+#if USE(JSVALUE64)
+    MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToLoadOrStore), 0);
+#else
+    MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToTagLoadOrStore), 0);
+    MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToPayloadLoadOrStore), 0);
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void replaceWithJump(StructureStubInfo&amp; stubInfo, const MacroAssemblerCodePtr target)
</span><span class="lines">@@ -168,6 +174,8 @@
</span><span class="cx">             CodeLocationLabel(target));
</span><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+
+    resetGetByIDCheckAndLoad(stubInfo);
</ins><span class="cx">     
</span><span class="cx">     MacroAssembler::repatchJump(
</span><span class="cx">         stubInfo.callReturnLocation.jumpAtOffset(
</span><span class="lines">@@ -175,429 +183,6 @@
</span><span class="cx">         CodeLocationLabel(target));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void emitRestoreScratch(MacroAssembler&amp; stubJit, bool needToRestoreScratch, GPRReg scratchGPR, MacroAssembler::Jump&amp; success, MacroAssembler::Jump&amp; fail, MacroAssembler::JumpList failureCases)
-{
-    if (needToRestoreScratch) {
-        stubJit.popToRestore(scratchGPR);
-        
-        success = stubJit.jump();
-        
-        // link failure cases here, so we can pop scratchGPR, and then jump back.
-        failureCases.link(&amp;stubJit);
-        
-        stubJit.popToRestore(scratchGPR);
-        
-        fail = stubJit.jump();
-        return;
-    }
-    
-    success = stubJit.jump();
-}
-
-static void linkRestoreScratch(LinkBuffer&amp; patchBuffer, bool needToRestoreScratch, MacroAssembler::Jump success, MacroAssembler::Jump fail, MacroAssembler::JumpList failureCases, CodeLocationLabel successLabel, CodeLocationLabel slowCaseBegin)
-{
-    patchBuffer.link(success, successLabel);
-        
-    if (needToRestoreScratch) {
-        patchBuffer.link(fail, slowCaseBegin);
-        return;
-    }
-    
-    // link failure cases directly back to normal path
-    patchBuffer.link(failureCases, slowCaseBegin);
-}
-
-static void linkRestoreScratch(LinkBuffer&amp; patchBuffer, bool needToRestoreScratch, StructureStubInfo&amp; stubInfo, MacroAssembler::Jump success, MacroAssembler::Jump fail, MacroAssembler::JumpList failureCases)
-{
-    linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone), stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase));
-}
-
-enum ByIdStubKind {
-    GetValue,
-    GetUndefined,
-    CallGetter,
-    CallCustomGetter,
-    CallSetter,
-    CallCustomSetter
-};
-
-static const char* toString(ByIdStubKind kind)
-{
-    switch (kind) {
-    case GetValue:
-        return &quot;GetValue&quot;;
-    case GetUndefined:
-        return &quot;GetUndefined&quot;;
-    case CallGetter:
-        return &quot;CallGetter&quot;;
-    case CallCustomGetter:
-        return &quot;CallCustomGetter&quot;;
-    case CallSetter:
-        return &quot;CallSetter&quot;;
-    case CallCustomSetter:
-        return &quot;CallCustomSetter&quot;;
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-        return nullptr;
-    }
-}
-
-static ByIdStubKind kindFor(const PropertySlot&amp; slot)
-{
-    if (slot.isCacheableValue())
-        return GetValue;
-    if (slot.isUnset())
-        return GetUndefined;
-    if (slot.isCacheableCustom())
-        return CallCustomGetter;
-    RELEASE_ASSERT(slot.isCacheableGetter());
-    return CallGetter;
-}
-
-static FunctionPtr customFor(const PropertySlot&amp; slot)
-{
-    if (!slot.isCacheableCustom())
-        return FunctionPtr();
-    return FunctionPtr(slot.customGetter());
-}
-
-static ByIdStubKind kindFor(const PutPropertySlot&amp; slot)
-{
-    RELEASE_ASSERT(!slot.isCacheablePut());
-    if (slot.isCacheableSetter())
-        return CallSetter;
-    RELEASE_ASSERT(slot.isCacheableCustom());
-    return CallCustomSetter;
-}
-
-static FunctionPtr customFor(const PutPropertySlot&amp; slot)
-{
-    if (!slot.isCacheableCustom())
-        return FunctionPtr();
-    return FunctionPtr(slot.customSetter());
-}
-
-static bool generateByIdStub(
-    ExecState* exec, ByIdStubKind kind, const Identifier&amp; propertyName,
-    FunctionPtr custom, StructureStubInfo&amp; stubInfo, const ObjectPropertyConditionSet&amp; conditionSet,
-    JSObject* alternateBase, PropertyOffset offset, Structure* structure, bool loadTargetFromProxy,
-    WatchpointSet* watchpointSet, CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel,
-    RefPtr&lt;JITStubRoutine&gt;&amp; stubRoutine)
-{
-    ASSERT(conditionSet.structuresEnsureValidityAssumingImpurePropertyWatchpoint());
-    
-    VM* vm = &amp;exec-&gt;vm();
-    GPRReg baseGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.baseGPR);
-    JSValueRegs valueRegs = JSValueRegs(
-#if USE(JSVALUE32_64)
-        static_cast&lt;GPRReg&gt;(stubInfo.patch.valueTagGPR),
-#endif
-        static_cast&lt;GPRReg&gt;(stubInfo.patch.valueGPR));
-    GPRReg scratchGPR = TempRegisterSet(stubInfo.patch.usedRegisters).getFreeGPR();
-    bool needToRestoreScratch = scratchGPR == InvalidGPRReg;
-    RELEASE_ASSERT(!needToRestoreScratch || (kind == GetValue || kind == GetUndefined));
-    
-    CCallHelpers stubJit(&amp;exec-&gt;vm(), exec-&gt;codeBlock());
-    if (needToRestoreScratch) {
-        scratchGPR = AssemblyHelpers::selectScratchGPR(
-            baseGPR, valueRegs.tagGPR(), valueRegs.payloadGPR());
-        stubJit.pushToSave(scratchGPR);
-        needToRestoreScratch = true;
-    }
-    
-    MacroAssembler::JumpList failureCases;
-
-    GPRReg baseForGetGPR;
-    if (loadTargetFromProxy) {
-        baseForGetGPR = valueRegs.payloadGPR();
-        failureCases.append(stubJit.branch8(
-            MacroAssembler::NotEqual, 
-            MacroAssembler::Address(baseGPR, JSCell::typeInfoTypeOffset()), 
-            MacroAssembler::TrustedImm32(PureForwardingProxyType)));
-
-        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSProxy::targetOffset()), scratchGPR);
-        
-        failureCases.append(stubJit.branchStructure(
-            MacroAssembler::NotEqual, 
-            MacroAssembler::Address(scratchGPR, JSCell::structureIDOffset()),
-            structure));
-    } else {
-        baseForGetGPR = baseGPR;
-
-        failureCases.append(stubJit.branchStructure(
-            MacroAssembler::NotEqual, 
-            MacroAssembler::Address(baseForGetGPR, JSCell::structureIDOffset()), 
-            structure));
-    }
-
-    CodeBlock* codeBlock = exec-&gt;codeBlock();
-    if (structure-&gt;needImpurePropertyWatchpoint() || conditionSet.needImpurePropertyWatchpoint())
-        vm-&gt;registerWatchpointForImpureProperty(propertyName, stubInfo.addWatchpoint(codeBlock));
-
-    if (watchpointSet)
-        watchpointSet-&gt;add(stubInfo.addWatchpoint(codeBlock));
-
-    checkObjectPropertyConditions(
-        conditionSet, codeBlock, stubInfo, stubJit, failureCases, scratchGPR);
-
-    if (isValidOffset(offset)) {
-        Structure* currStructure;
-        if (conditionSet.isEmpty())
-            currStructure = structure;
-        else
-            currStructure = conditionSet.slotBaseCondition().object()-&gt;structure();
-        currStructure-&gt;startWatchingPropertyForReplacements(*vm, offset);
-    }
-    
-    GPRReg baseForAccessGPR = InvalidGPRReg;
-    if (kind != GetUndefined) {
-        if (!conditionSet.isEmpty()) {
-            // We could have clobbered scratchGPR earlier, so we have to reload from baseGPR to get the target.
-            if (loadTargetFromProxy)
-                stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSProxy::targetOffset()), baseForGetGPR);
-            stubJit.move(MacroAssembler::TrustedImmPtr(alternateBase), scratchGPR);
-            baseForAccessGPR = scratchGPR;
-        } else {
-            // For proxy objects, we need to do all the Structure checks before moving the baseGPR into
-            // baseForGetGPR because if we fail any of the checks then we would have the wrong value in baseGPR
-            // on the slow path.
-            if (loadTargetFromProxy)
-                stubJit.move(scratchGPR, baseForGetGPR);
-            baseForAccessGPR = baseForGetGPR;
-        }
-    }
-
-    GPRReg loadedValueGPR = InvalidGPRReg;
-    if (kind == GetUndefined)
-        stubJit.moveTrustedValue(jsUndefined(), valueRegs);
-    else if (kind != CallCustomGetter &amp;&amp; kind != CallCustomSetter) {
-        if (kind == GetValue)
-            loadedValueGPR = valueRegs.payloadGPR();
-        else
-            loadedValueGPR = scratchGPR;
-        
-        GPRReg storageGPR;
-        if (isInlineOffset(offset))
-            storageGPR = baseForAccessGPR;
-        else {
-            stubJit.loadPtr(MacroAssembler::Address(baseForAccessGPR, JSObject::butterflyOffset()), loadedValueGPR);
-            storageGPR = loadedValueGPR;
-        }
-        
-#if USE(JSVALUE64)
-        stubJit.load64(MacroAssembler::Address(storageGPR, offsetRelativeToBase(offset)), loadedValueGPR);
-#else
-        if (kind == GetValue)
-            stubJit.load32(MacroAssembler::Address(storageGPR, offsetRelativeToBase(offset) + TagOffset), valueRegs.tagGPR());
-        stubJit.load32(MacroAssembler::Address(storageGPR, offsetRelativeToBase(offset) + PayloadOffset), loadedValueGPR);
-#endif
-    }
-
-    // Stuff for custom getters.
-    MacroAssembler::Call operationCall;
-    MacroAssembler::Call handlerCall;
-
-    // Stuff for JS getters.
-    MacroAssembler::DataLabelPtr addressOfLinkFunctionCheck;
-    MacroAssembler::Call fastPathCall;
-    MacroAssembler::Call slowPathCall;
-    std::unique_ptr&lt;CallLinkInfo&gt; callLinkInfo;
-
-    MacroAssembler::Jump success, fail;
-    if (kind != GetValue &amp;&amp; kind != GetUndefined) {
-        // Need to make sure that whenever this call is made in the future, we remember the
-        // place that we made it from. It just so happens to be the place that we are at
-        // right now!
-        stubJit.store32(MacroAssembler::TrustedImm32(stubInfo.callSiteIndex.bits()),
-            CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(JSStack::ArgumentCount)));
-
-        if (kind == CallGetter || kind == CallSetter) {
-            // 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.
-            
-            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
-            callLinkInfo-&gt;disallowStubs();
-            
-            callLinkInfo-&gt;setUpCall(CallLinkInfo::Call, stubInfo.codeOrigin, loadedValueGPR);
-            
-            MacroAssembler::JumpList done;
-            
-            // There is a 'this' argument but nothing else.
-            unsigned numberOfParameters = 1;
-            // ... unless we're calling a setter.
-            if (kind == CallSetter)
-                numberOfParameters++;
-            
-            // Get the accessor; if there ain't one then the result is jsUndefined().
-            if (kind == CallSetter) {
-                stubJit.loadPtr(
-                    MacroAssembler::Address(loadedValueGPR, GetterSetter::offsetOfSetter()),
-                    loadedValueGPR);
-            } else {
-                stubJit.loadPtr(
-                    MacroAssembler::Address(loadedValueGPR, GetterSetter::offsetOfGetter()),
-                    loadedValueGPR);
-            }
-            MacroAssembler::Jump returnUndefined = stubJit.branchTestPtr(
-                MacroAssembler::Zero, loadedValueGPR);
-            
-            unsigned numberOfRegsForCall =
-                JSStack::CallFrameHeaderSize + numberOfParameters;
-            
-            unsigned numberOfBytesForCall =
-                numberOfRegsForCall * sizeof(Register) - sizeof(CallerFrameAndPC);
-            
-            unsigned alignedNumberOfBytesForCall =
-                WTF::roundUpToMultipleOf(stackAlignmentBytes(), numberOfBytesForCall);
-            
-            stubJit.subPtr(
-                MacroAssembler::TrustedImm32(alignedNumberOfBytesForCall),
-                MacroAssembler::stackPointerRegister);
-            
-            MacroAssembler::Address calleeFrame = MacroAssembler::Address(
-                MacroAssembler::stackPointerRegister,
-                -static_cast&lt;ptrdiff_t&gt;(sizeof(CallerFrameAndPC)));
-            
-            stubJit.store32(
-                MacroAssembler::TrustedImm32(numberOfParameters),
-                calleeFrame.withOffset(
-                    JSStack::ArgumentCount * sizeof(Register) + PayloadOffset));
-            
-            stubJit.storeCell(
-                loadedValueGPR, calleeFrame.withOffset(JSStack::Callee * sizeof(Register)));
-
-            stubJit.storeCell(
-                baseForGetGPR,
-                calleeFrame.withOffset(
-                    virtualRegisterForArgument(0).offset() * sizeof(Register)));
-            
-            if (kind == CallSetter) {
-                stubJit.storeValue(
-                    valueRegs,
-                    calleeFrame.withOffset(
-                        virtualRegisterForArgument(1).offset() * sizeof(Register)));
-            }
-            
-            MacroAssembler::Jump slowCase = stubJit.branchPtrWithPatch(
-                MacroAssembler::NotEqual, loadedValueGPR, addressOfLinkFunctionCheck,
-                MacroAssembler::TrustedImmPtr(0));
-            
-            fastPathCall = stubJit.nearCall();
-
-            stubJit.addPtr(
-                MacroAssembler::TrustedImm32(codeBlock-&gt;stackPointerOffset() * sizeof(Register)),
-                GPRInfo::callFrameRegister,
-                MacroAssembler::stackPointerRegister);
-            if (kind == CallGetter)
-                stubJit.setupResults(valueRegs);
-            
-            done.append(stubJit.jump());
-            slowCase.link(&amp;stubJit);
-            
-            stubJit.move(loadedValueGPR, GPRInfo::regT0);
-#if USE(JSVALUE32_64)
-            stubJit.move(MacroAssembler::TrustedImm32(JSValue::CellTag), GPRInfo::regT1);
-#endif
-            stubJit.move(MacroAssembler::TrustedImmPtr(callLinkInfo.get()), GPRInfo::regT2);
-            slowPathCall = stubJit.nearCall();
-            
-            stubJit.addPtr(
-                MacroAssembler::TrustedImm32(codeBlock-&gt;stackPointerOffset() * sizeof(Register)),
-                GPRInfo::callFrameRegister,
-                MacroAssembler::stackPointerRegister);
-            if (kind == CallGetter)
-                stubJit.setupResults(valueRegs);
-            
-            done.append(stubJit.jump());
-            returnUndefined.link(&amp;stubJit);
-            
-            if (kind == CallGetter)
-                stubJit.moveTrustedValue(jsUndefined(), valueRegs);
-            
-            done.link(&amp;stubJit);
-        } else {
-            // getter: EncodedJSValue (*GetValueFunc)(ExecState*, JSObject* slotBase, EncodedJSValue thisValue, PropertyName);
-            // setter: void (*PutValueFunc)(ExecState*, JSObject* base, EncodedJSValue thisObject, EncodedJSValue value);
-#if USE(JSVALUE64)
-            if (kind == CallCustomGetter)
-                stubJit.setupArgumentsWithExecState(baseForAccessGPR, baseForGetGPR, MacroAssembler::TrustedImmPtr(propertyName.impl()));
-            else
-                stubJit.setupArgumentsWithExecState(baseForAccessGPR, baseForGetGPR, valueRegs.gpr());
-#else
-            if (kind == CallCustomGetter)
-                stubJit.setupArgumentsWithExecState(baseForAccessGPR, baseForGetGPR, MacroAssembler::TrustedImm32(JSValue::CellTag), MacroAssembler::TrustedImmPtr(propertyName.impl()));
-            else
-                stubJit.setupArgumentsWithExecState(baseForAccessGPR, baseForGetGPR, MacroAssembler::TrustedImm32(JSValue::CellTag), valueRegs.payloadGPR(), valueRegs.tagGPR());
-#endif
-            stubJit.storePtr(GPRInfo::callFrameRegister, &amp;vm-&gt;topCallFrame);
-
-            operationCall = stubJit.call();
-            if (kind == CallCustomGetter)
-                stubJit.setupResults(valueRegs);
-            MacroAssembler::Jump noException = stubJit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck);
-
-            stubJit.copyCalleeSavesToVMCalleeSavesBuffer();
-
-            stubJit.setupArguments(CCallHelpers::TrustedImmPtr(vm), GPRInfo::callFrameRegister);
-            handlerCall = stubJit.call();
-            stubJit.jumpToExceptionHandler();
-            
-            noException.link(&amp;stubJit);
-        }
-    }
-    emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCases);
-    
-    LinkBuffer patchBuffer(*vm, stubJit, exec-&gt;codeBlock(), JITCompilationCanFail);
-    if (patchBuffer.didFailToAllocate())
-        return false;
-    
-    linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, successLabel, slowCaseLabel);
-    if (kind == CallCustomGetter || kind == CallCustomSetter) {
-        patchBuffer.link(operationCall, custom);
-        patchBuffer.link(handlerCall, lookupExceptionHandler);
-    } else if (kind == CallGetter || kind == CallSetter) {
-        callLinkInfo-&gt;setCallLocations(patchBuffer.locationOfNearCall(slowPathCall),
-            patchBuffer.locationOf(addressOfLinkFunctionCheck),
-            patchBuffer.locationOfNearCall(fastPathCall));
-
-        patchBuffer.link(
-            slowPathCall, CodeLocationLabel(vm-&gt;getCTIStub(linkCallThunkGenerator).code()));
-    }
-    
-    MacroAssemblerCodeRef code = FINALIZE_CODE_FOR(
-        exec-&gt;codeBlock(), patchBuffer,
-        (&quot;%s access stub for %s, return point %p&quot;,
-            toString(kind), toCString(*exec-&gt;codeBlock()).data(),
-            successLabel.executableAddress()));
-    
-    if (kind == CallGetter || kind == CallSetter)
-        stubRoutine = adoptRef(new AccessorCallJITStubRoutine(code, *vm, WTF::move(callLinkInfo)));
-    else
-        stubRoutine = createJITStubRoutine(code, *vm, codeBlock-&gt;ownerExecutable(), true);
-    
-    return true;
-}
-
</del><span class="cx"> enum InlineCacheAction {
</span><span class="cx">     GiveUpOnCache,
</span><span class="cx">     RetryCacheLater,
</span><span class="lines">@@ -631,132 +216,99 @@
</span><span class="cx">     if (Options::forceICFailure())
</span><span class="cx">         return GiveUpOnCache;
</span><span class="cx">     
</span><del>-    // FIXME: Write a test that proves we need to check for recursion here just
-    // like the interpreter does, then add a check for recursion.
</del><ins>+    // FIXME: Cache property access for immediates.
+    if (!baseValue.isCell())
+        return GiveUpOnCache;
</ins><span class="cx"> 
</span><span class="cx">     CodeBlock* codeBlock = exec-&gt;codeBlock();
</span><del>-    VM* vm = &amp;exec-&gt;vm();
</del><ins>+    ScriptExecutable* owner = codeBlock-&gt;ownerScriptExecutable();
+    VM&amp; vm = exec-&gt;vm();
</ins><span class="cx"> 
</span><del>-    if ((isJSArray(baseValue) || isJSString(baseValue)) &amp;&amp; propertyName == exec-&gt;propertyNames().length) {
-        GPRReg baseGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.baseGPR);
-#if USE(JSVALUE32_64)
-        GPRReg resultTagGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.valueTagGPR);
-#endif
-        GPRReg resultGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.valueGPR);
</del><ins>+    std::unique_ptr&lt;AccessCase&gt; newCase;
</ins><span class="cx"> 
</span><del>-        MacroAssembler stubJit;
</del><ins>+    if (isJSArray(baseValue) &amp;&amp; propertyName == exec-&gt;propertyNames().length)
+        newCase = AccessCase::getLength(vm, owner, AccessCase::ArrayLength);
+    else if (isJSString(baseValue) &amp;&amp; propertyName == exec-&gt;propertyNames().length)
+        newCase = AccessCase::getLength(vm, owner, AccessCase::StringLength);
+    else {
+        if (!slot.isCacheable() &amp;&amp; !slot.isUnset())
+            return GiveUpOnCache;
</ins><span class="cx"> 
</span><del>-        if (isJSArray(baseValue)) {
-            GPRReg scratchGPR = TempRegisterSet(stubInfo.patch.usedRegisters).getFreeGPR();
-            bool needToRestoreScratch = false;
</del><ins>+        JSCell* baseCell = baseValue.asCell();
+        Structure* structure = baseCell-&gt;structure(vm);
+        
+        // Optimize self access.
+        if (stubInfo.cacheType == CacheType::Unset
+            &amp;&amp; slot.isCacheableValue()
+            &amp;&amp; slot.slotBase() == baseValue
+            &amp;&amp; !slot.watchpointSet()
+            &amp;&amp; MacroAssembler::isCompactPtrAlignedAddressOffset(maxOffsetRelativeToPatchedStorage(slot.cachedOffset()))
+            &amp;&amp; actionForCell(vm, baseCell) == AttemptToCache
+            &amp;&amp; !structure-&gt;needImpurePropertyWatchpoint()) {
+            structure-&gt;startWatchingPropertyForReplacements(vm, slot.cachedOffset());
+            repatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), operationGetByIdOptimize, true);
+            stubInfo.initGetByIdSelf(vm, codeBlock-&gt;ownerExecutable(), structure, slot.cachedOffset());
+            return RetryCacheLater;
+        }
</ins><span class="cx"> 
</span><del>-            if (scratchGPR == InvalidGPRReg) {
-#if USE(JSVALUE64)
-                scratchGPR = AssemblyHelpers::selectScratchGPR(baseGPR, resultGPR);
-#else
-                scratchGPR = AssemblyHelpers::selectScratchGPR(baseGPR, resultGPR, resultTagGPR);
-#endif
-                stubJit.pushToSave(scratchGPR);
-                needToRestoreScratch = true;
-            }
</del><ins>+        bool loadTargetFromProxy = false;
+        if (baseCell-&gt;type() == PureForwardingProxyType) {
+            baseValue = jsCast&lt;JSProxy*&gt;(baseCell)-&gt;target();
+            baseCell = baseValue.asCell();
+            structure = baseCell-&gt;structure(vm);
+            loadTargetFromProxy = true;
+        }
</ins><span class="cx"> 
</span><del>-            MacroAssembler::JumpList failureCases;
</del><ins>+        InlineCacheAction action = actionForCell(vm, baseCell);
+        if (action != AttemptToCache)
+            return action;
</ins><span class="cx"> 
</span><del>-            stubJit.load8(MacroAssembler::Address(baseGPR, JSCell::indexingTypeOffset()), scratchGPR);
-            failureCases.append(stubJit.branchTest32(MacroAssembler::Zero, scratchGPR, MacroAssembler::TrustedImm32(IsArray)));
-            failureCases.append(stubJit.branchTest32(MacroAssembler::Zero, scratchGPR, MacroAssembler::TrustedImm32(IndexingShapeMask)));
-
-            stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR);
-            stubJit.load32(MacroAssembler::Address(scratchGPR, ArrayStorage::lengthOffset()), scratchGPR);
-            failureCases.append(stubJit.branch32(MacroAssembler::LessThan, scratchGPR, MacroAssembler::TrustedImm32(0)));
-
-            stubJit.move(scratchGPR, resultGPR);
-#if USE(JSVALUE64)
-            stubJit.or64(AssemblyHelpers::TrustedImm64(TagTypeNumber), resultGPR);
-#elif USE(JSVALUE32_64)
-            stubJit.move(AssemblyHelpers::TrustedImm32(JSValue::Int32Tag), resultTagGPR);
-#endif
-
-            MacroAssembler::Jump success, fail;
-
-            emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCases);
</del><ins>+        PropertyOffset offset = slot.isUnset() ? invalidOffset : slot.cachedOffset();
+        
+        ObjectPropertyConditionSet conditionSet;
+        if (slot.isUnset() || slot.slotBase() != baseValue) {
+            if (structure-&gt;typeInfo().prohibitsPropertyCaching() || structure-&gt;isDictionary())
+                return GiveUpOnCache;
</ins><span class="cx">             
</span><del>-            LinkBuffer patchBuffer(*vm, stubJit, codeBlock, JITCompilationCanFail);
-            if (patchBuffer.didFailToAllocate())
</del><ins>+            if (slot.isUnset()) {
+                conditionSet = generateConditionsForPropertyMiss(
+                    vm, codeBlock-&gt;ownerExecutable(), exec, structure, propertyName.impl());
+            } else {
+                conditionSet = generateConditionsForPrototypePropertyHit(
+                    vm, codeBlock-&gt;ownerExecutable(), exec, structure, slot.slotBase(),
+                    propertyName.impl());
+            }
+            
+            if (!conditionSet.isValid())
</ins><span class="cx">                 return GiveUpOnCache;
</span><del>-
-            linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCases);
-
-            stubInfo.stubRoutine = FINALIZE_CODE_FOR_STUB(
-                exec-&gt;codeBlock(), patchBuffer,
-                (&quot;GetById array length stub for %s, return point %p&quot;,
-                    toCString(*exec-&gt;codeBlock()).data(), stubInfo.callReturnLocation.labelAtOffset(
-                        stubInfo.patch.deltaCallToDone).executableAddress()));
-
-            replaceWithJump(stubInfo, stubInfo.stubRoutine-&gt;code().code());
-            repatchCall(codeBlock, stubInfo.callReturnLocation, operationGetById);
-
-            return RetryCacheLater;
</del><ins>+            
+            offset = slot.isUnset() ? invalidOffset : conditionSet.slotBaseCondition().offset();
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        // String.length case
-        MacroAssembler::Jump failure = stubJit.branch8(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(StringType));
</del><ins>+        AccessCase::AccessType type;
+        if (slot.isCacheableValue())
+            type = AccessCase::Load;
+        else if (slot.isUnset())
+            type = AccessCase::Miss;
+        else if (slot.isCacheableGetter())
+            type = AccessCase::Getter;
+        else
+            type = AccessCase::CustomGetter;
</ins><span class="cx"> 
</span><del>-        stubJit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
-
-#if USE(JSVALUE64)
-        stubJit.or64(AssemblyHelpers::TrustedImm64(TagTypeNumber), resultGPR);
-#elif USE(JSVALUE32_64)
-        stubJit.move(AssemblyHelpers::TrustedImm32(JSValue::Int32Tag), resultTagGPR);
-#endif
-
-        MacroAssembler::Jump success = stubJit.jump();
-
-        LinkBuffer patchBuffer(*vm, stubJit, codeBlock, JITCompilationCanFail);
-        if (patchBuffer.didFailToAllocate())
-            return GiveUpOnCache;
-        
-        patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone));
-        patchBuffer.link(failure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase));
-
-        stubInfo.stubRoutine = FINALIZE_CODE_FOR_STUB(
-            exec-&gt;codeBlock(), patchBuffer,
-            (&quot;GetById string length stub for %s, return point %p&quot;,
-                toCString(*exec-&gt;codeBlock()).data(), stubInfo.callReturnLocation.labelAtOffset(
-                    stubInfo.patch.deltaCallToDone).executableAddress()));
-
-        replaceWithJump(stubInfo, stubInfo.stubRoutine-&gt;code().code());
-        repatchCall(codeBlock, stubInfo.callReturnLocation, operationGetById);
-
-        return RetryCacheLater;
</del><ins>+        newCase = AccessCase::get(
+            vm, owner, type, offset, structure, conditionSet, loadTargetFromProxy,
+            slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr,
+            slot.isCacheableCustom() ? slot.slotBase() : nullptr);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME: Cache property access for immediates.
-    if (!baseValue.isCell())
-        return GiveUpOnCache;
</del><ins>+    MacroAssemblerCodePtr codePtr = stubInfo.addAccessCase(
+        vm, codeBlock, propertyName, WTF::move(newCase));
</ins><span class="cx"> 
</span><del>-    if (!slot.isCacheable() &amp;&amp; !slot.isUnset())
</del><ins>+    if (!codePtr)
</ins><span class="cx">         return GiveUpOnCache;
</span><span class="cx"> 
</span><del>-    JSCell* baseCell = baseValue.asCell();
-    Structure* structure = baseCell-&gt;structure(*vm);
-
-    InlineCacheAction action = actionForCell(*vm, baseCell);
-    if (action != AttemptToCache)
-        return action;
-
-    // Optimize self access.
-    if (slot.isCacheableValue()
-        &amp;&amp; slot.slotBase() == baseValue
-        &amp;&amp; !slot.watchpointSet()
-        &amp;&amp; MacroAssembler::isCompactPtrAlignedAddressOffset(maxOffsetRelativeToPatchedStorage(slot.cachedOffset()))) {
-        structure-&gt;startWatchingPropertyForReplacements(*vm, slot.cachedOffset());
-        repatchByIdSelfAccess(*vm, codeBlock, stubInfo, structure, propertyName, slot.cachedOffset(), operationGetByIdBuildList, true);
-        stubInfo.initGetByIdSelf(*vm, codeBlock-&gt;ownerExecutable(), structure);
-        return RetryCacheLater;
-    }
-
-    repatchCall(codeBlock, stubInfo.callReturnLocation, operationGetByIdBuildList);
</del><ins>+    replaceWithJump(stubInfo, codePtr);
+    
</ins><span class="cx">     return RetryCacheLater;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -768,112 +320,6 @@
</span><span class="cx">         repatchCall(exec-&gt;codeBlock(), stubInfo.callReturnLocation, operationGetById);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void patchJumpToGetByIdStub(StructureStubInfo&amp; stubInfo, JITStubRoutine* stubRoutine)
-{
-    RELEASE_ASSERT(stubInfo.accessType == access_get_by_id_list);
-    if (stubInfo.u.getByIdList.list-&gt;didSelfPatching()) {
-        MacroAssembler::repatchJump(
-            stubInfo.callReturnLocation.jumpAtOffset(
-                stubInfo.patch.deltaCallToJump),
-            CodeLocationLabel(stubRoutine-&gt;code().code()));
-        return;
-    }
-    
-    replaceWithJump(stubInfo, stubRoutine-&gt;code().code());
-}
-
-static InlineCacheAction tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identifier&amp; ident, const PropertySlot&amp; slot, StructureStubInfo&amp; stubInfo)
-{
-    if (!baseValue.isCell()
-        || (!slot.isCacheable() &amp;&amp; !slot.isUnset()))
-        return GiveUpOnCache;
-
-    JSCell* baseCell = baseValue.asCell();
-    bool loadTargetFromProxy = false;
-    if (baseCell-&gt;type() == PureForwardingProxyType) {
-        baseValue = jsCast&lt;JSProxy*&gt;(baseCell)-&gt;target();
-        baseCell = baseValue.asCell();
-        loadTargetFromProxy = true;
-    }
-
-    VM* vm = &amp;exec-&gt;vm();
-    CodeBlock* codeBlock = exec-&gt;codeBlock();
-
-    InlineCacheAction action = actionForCell(*vm, baseCell);
-    if (action != AttemptToCache)
-        return action;
-
-    Structure* structure = baseCell-&gt;structure(*vm);
-    TypeInfo typeInfo = structure-&gt;typeInfo();
-
-    if (stubInfo.patch.spillMode == NeedToSpill) {
-        // We cannot do as much inline caching if the registers were not flushed prior to this GetById. In particular,
-        // non-Value cached properties require planting calls, which requires registers to have been flushed. Thus,
-        // if registers were not flushed, don't do non-Value caching.
-        if (!slot.isCacheableValue() &amp;&amp; !slot.isUnset())
-            return GiveUpOnCache;
-    }
-
-    PropertyOffset offset = slot.isUnset() ? invalidOffset : slot.cachedOffset();
-    
-    ObjectPropertyConditionSet conditionSet;
-    if (slot.isUnset() || slot.slotBase() != baseValue) {
-        if (typeInfo.prohibitsPropertyCaching() || structure-&gt;isDictionary())
-            return GiveUpOnCache;
-
-        if (slot.isUnset())
-            conditionSet = generateConditionsForPropertyMiss(*vm, codeBlock-&gt;ownerExecutable(), exec, structure, ident.impl());
-        else
-            conditionSet = generateConditionsForPrototypePropertyHit(*vm, codeBlock-&gt;ownerExecutable(), exec, structure, slot.slotBase(), ident.impl());
-
-        if (!conditionSet.isValid())
-            return GiveUpOnCache;
-
-        offset = slot.isUnset() ? invalidOffset : conditionSet.slotBaseCondition().offset();
-    }
-    
-    PolymorphicGetByIdList* list = PolymorphicGetByIdList::from(stubInfo);
-    if (list-&gt;isFull()) {
-        // We need this extra check because of recursion.
-        return GiveUpOnCache;
-    }
-    
-    RefPtr&lt;JITStubRoutine&gt; stubRoutine;
-    bool result = generateByIdStub(
-        exec, kindFor(slot), ident, customFor(slot), stubInfo, conditionSet, slot.slotBase(), offset, 
-        structure, loadTargetFromProxy, slot.watchpointSet(), 
-        stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone),
-        CodeLocationLabel(list-&gt;currentSlowPathTarget(stubInfo)), stubRoutine);
-    if (!result)
-        return GiveUpOnCache;
-    
-    GetByIdAccess::AccessType accessType;
-    if (slot.isCacheableValue())
-        accessType = slot.watchpointSet() ? GetByIdAccess::WatchedStub : GetByIdAccess::SimpleStub;
-    else if (slot.isUnset())
-        accessType = GetByIdAccess::SimpleMiss;
-    else if (slot.isCacheableGetter())
-        accessType = GetByIdAccess::Getter;
-    else
-        accessType = GetByIdAccess::CustomGetter;
-    
-    list-&gt;addAccess(GetByIdAccess(
-        *vm, codeBlock-&gt;ownerExecutable(), accessType, stubRoutine, structure,
-        conditionSet));
-    
-    patchJumpToGetByIdStub(stubInfo, stubRoutine.get());
-    
-    return list-&gt;isFull() ? GiveUpOnCache : RetryCacheLater;
-}
-
-void buildGetByIDList(ExecState* exec, JSValue baseValue, const Identifier&amp; propertyName, const PropertySlot&amp; slot, StructureStubInfo&amp; stubInfo)
-{
-    GCSafeConcurrentJITLocker locker(exec-&gt;codeBlock()-&gt;m_lock, exec-&gt;vm().heap);
-    
-    if (tryBuildGetByIDList(exec, baseValue, propertyName, slot, stubInfo) == GiveUpOnCache)
-        repatchCall(exec-&gt;codeBlock(), stubInfo.callReturnLocation, operationGetById);
-}
-
</del><span class="cx"> static V_JITOperation_ESsiJJI appropriateGenericPutByIdFunction(const PutPropertySlot &amp;slot, PutKind putKind)
</span><span class="cx"> {
</span><span class="cx">     if (slot.isStrictMode()) {
</span><span class="lines">@@ -886,368 +332,26 @@
</span><span class="cx">     return operationPutByIdNonStrict;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static V_JITOperation_ESsiJJI appropriateListBuildingPutByIdFunction(const PutPropertySlot &amp;slot, PutKind putKind)
</del><ins>+static V_JITOperation_ESsiJJI appropriateOptimizingPutByIdFunction(const PutPropertySlot &amp;slot, PutKind putKind)
</ins><span class="cx"> {
</span><span class="cx">     if (slot.isStrictMode()) {
</span><span class="cx">         if (putKind == Direct)
</span><del>-            return operationPutByIdDirectStrictBuildList;
-        return operationPutByIdStrictBuildList;
</del><ins>+            return operationPutByIdDirectStrictOptimize;
+        return operationPutByIdStrictOptimize;
</ins><span class="cx">     }
</span><span class="cx">     if (putKind == Direct)
</span><del>-        return operationPutByIdDirectNonStrictBuildList;
-    return operationPutByIdNonStrictBuildList;
</del><ins>+        return operationPutByIdDirectNonStrictOptimize;
+    return operationPutByIdNonStrictOptimize;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool emitPutReplaceStub(
-    ExecState* exec,
-    const Identifier&amp;,
-    const PutPropertySlot&amp; slot,
-    StructureStubInfo&amp; stubInfo,
-    Structure* structure,
-    CodeLocationLabel failureLabel,
-    RefPtr&lt;JITStubRoutine&gt;&amp; stubRoutine)
-{
-    VM* vm = &amp;exec-&gt;vm();
-    GPRReg baseGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.baseGPR);
-#if USE(JSVALUE32_64)
-    GPRReg valueTagGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.valueTagGPR);
-#endif
-    GPRReg valueGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.valueGPR);
-
-    ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
-    allocator.lock(baseGPR);
-#if USE(JSVALUE32_64)
-    allocator.lock(valueTagGPR);
-#endif
-    allocator.lock(valueGPR);
-    
-    GPRReg scratchGPR1 = allocator.allocateScratchGPR();
-
-    CCallHelpers stubJit(vm, exec-&gt;codeBlock());
-
-    size_t numberOfPaddingBytes = allocator.preserveReusedRegistersByPushing(stubJit);
-
-    MacroAssembler::Jump badStructure = stubJit.branchStructure(
-        MacroAssembler::NotEqual,
-        MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()),
-        structure);
-
-#if USE(JSVALUE64)
-    if (isInlineOffset(slot.cachedOffset()))
-        stubJit.store64(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue)));
-    else {
-        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR1);
-        stubJit.store64(valueGPR, MacroAssembler::Address(scratchGPR1, offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue)));
-    }
-#elif USE(JSVALUE32_64)
-    if (isInlineOffset(slot.cachedOffset())) {
-        stubJit.store32(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-        stubJit.store32(valueTagGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
-    } else {
-        stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR1);
-        stubJit.store32(valueGPR, MacroAssembler::Address(scratchGPR1, offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-        stubJit.store32(valueTagGPR, MacroAssembler::Address(scratchGPR1, offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
-    }
-#endif
-    
-    MacroAssembler::Jump success;
-    MacroAssembler::Jump failure;
-    
-    if (allocator.didReuseRegisters()) {
-        allocator.restoreReusedRegistersByPopping(stubJit, numberOfPaddingBytes);
-        success = stubJit.jump();
-        
-        badStructure.link(&amp;stubJit);
-        allocator.restoreReusedRegistersByPopping(stubJit, numberOfPaddingBytes);
-        failure = stubJit.jump();
-    } else {
-        success = stubJit.jump();
-        failure = badStructure;
-    }
-    
-    LinkBuffer patchBuffer(*vm, stubJit, exec-&gt;codeBlock(), JITCompilationCanFail);
-    if (patchBuffer.didFailToAllocate())
-        return false;
-    
-    patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone));
-    patchBuffer.link(failure, failureLabel);
-            
-    stubRoutine = FINALIZE_CODE_FOR_STUB(
-        exec-&gt;codeBlock(), patchBuffer,
-        (&quot;PutById replace stub for %s, return point %p&quot;,
-            toCString(*exec-&gt;codeBlock()).data(), stubInfo.callReturnLocation.labelAtOffset(
-                stubInfo.patch.deltaCallToDone).executableAddress()));
-    
-    return true;
-}
-
-static bool emitPutTransitionStub(
-    ExecState* exec, VM* vm, Structure*&amp; structure, const Identifier&amp; ident, 
-    const PutPropertySlot&amp; slot, StructureStubInfo&amp; stubInfo, PutKind putKind,
-    Structure*&amp; oldStructure, ObjectPropertyConditionSet&amp; conditionSet)
-{
-    PropertyName pname(ident);
-    oldStructure = structure;
-    if (!oldStructure-&gt;isObject() || oldStructure-&gt;isDictionary() || parseIndex(pname))
-        return false;
-
-    PropertyOffset propertyOffset;
-    structure = Structure::addPropertyTransitionToExistingStructureConcurrently(oldStructure, ident.impl(), 0, propertyOffset);
-
-    if (!structure || !structure-&gt;isObject() || structure-&gt;isDictionary() || !structure-&gt;propertyAccessesAreCacheable())
-        return false;
-
-    // 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() != structure-&gt;outOfLineCapacity()
-        &amp;&amp; oldStructure-&gt;outOfLineCapacity()) {
-        return false;
-    }
-
-    // Skip optimizing the case where we need realloc, and the structure has
-    // indexing storage.
-    // FIXME: We shouldn't skip this! Implement it!
-    // https://bugs.webkit.org/show_bug.cgi?id=130914
-    if (oldStructure-&gt;couldHaveIndexingHeader())
-        return false;
-
-    if (putKind == NotDirect) {
-        conditionSet = generateConditionsForPropertySetterMiss(
-            *vm, exec-&gt;codeBlock()-&gt;ownerExecutable(), exec, structure, ident.impl());
-        if (!conditionSet.isValid())
-            return false;
-    }
-
-    CodeLocationLabel failureLabel = stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase);
-    RefPtr&lt;JITStubRoutine&gt;&amp; stubRoutine = stubInfo.stubRoutine;
-
-    GPRReg baseGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.baseGPR);
-#if USE(JSVALUE32_64)
-    GPRReg valueTagGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.valueTagGPR);
-#endif
-    GPRReg valueGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.valueGPR);
-    
-    ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
-    allocator.lock(baseGPR);
-#if USE(JSVALUE32_64)
-    allocator.lock(valueTagGPR);
-#endif
-    allocator.lock(valueGPR);
-    
-    CCallHelpers stubJit(vm);
-    
-    bool needThirdScratch = false;
-    if (structure-&gt;outOfLineCapacity() != oldStructure-&gt;outOfLineCapacity()
-        &amp;&amp; oldStructure-&gt;outOfLineCapacity()) {
-        needThirdScratch = true;
-    }
-
-    GPRReg scratchGPR1 = allocator.allocateScratchGPR();
-    ASSERT(scratchGPR1 != baseGPR);
-    ASSERT(scratchGPR1 != valueGPR);
-    
-    GPRReg scratchGPR2 = allocator.allocateScratchGPR();
-    ASSERT(scratchGPR2 != baseGPR);
-    ASSERT(scratchGPR2 != valueGPR);
-    ASSERT(scratchGPR2 != scratchGPR1);
-
-    GPRReg scratchGPR3;
-    if (needThirdScratch) {
-        scratchGPR3 = allocator.allocateScratchGPR();
-        ASSERT(scratchGPR3 != baseGPR);
-        ASSERT(scratchGPR3 != valueGPR);
-        ASSERT(scratchGPR3 != scratchGPR1);
-        ASSERT(scratchGPR3 != scratchGPR2);
-    } else
-        scratchGPR3 = InvalidGPRReg;
-    
-    size_t numberOfPaddingBytes = allocator.preserveReusedRegistersByPushing(stubJit);
-
-    MacroAssembler::JumpList failureCases;
-            
-    ASSERT(oldStructure-&gt;transitionWatchpointSetHasBeenInvalidated());
-    
-    failureCases.append(stubJit.branchStructure(
-        MacroAssembler::NotEqual, 
-        MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), 
-        oldStructure));
-    
-    checkObjectPropertyConditions(
-        conditionSet, exec-&gt;codeBlock(), stubInfo, stubJit, failureCases, scratchGPR1);
-
-    MacroAssembler::JumpList slowPath;
-    
-    bool scratchGPR1HasStorage = false;
-    
-    if (structure-&gt;outOfLineCapacity() != oldStructure-&gt;outOfLineCapacity()) {
-        size_t newSize = structure-&gt;outOfLineCapacity() * sizeof(JSValue);
-        CopiedAllocator* copiedAllocator = &amp;vm-&gt;heap.storageAllocator();
-        
-        if (!oldStructure-&gt;outOfLineCapacity()) {
-            stubJit.loadPtr(&amp;copiedAllocator-&gt;m_currentRemaining, scratchGPR1);
-            slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize), scratchGPR1));
-            stubJit.storePtr(scratchGPR1, &amp;copiedAllocator-&gt;m_currentRemaining);
-            stubJit.negPtr(scratchGPR1);
-            stubJit.addPtr(MacroAssembler::AbsoluteAddress(&amp;copiedAllocator-&gt;m_currentPayloadEnd), scratchGPR1);
-            stubJit.addPtr(MacroAssembler::TrustedImm32(sizeof(JSValue)), scratchGPR1);
-        } else {
-            size_t oldSize = oldStructure-&gt;outOfLineCapacity() * sizeof(JSValue);
-            ASSERT(newSize &gt; oldSize);
-            
-            stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR3);
-            stubJit.loadPtr(&amp;copiedAllocator-&gt;m_currentRemaining, scratchGPR1);
-            slowPath.append(stubJit.branchSubPtr(MacroAssembler::Signed, MacroAssembler::TrustedImm32(newSize), scratchGPR1));
-            stubJit.storePtr(scratchGPR1, &amp;copiedAllocator-&gt;m_currentRemaining);
-            stubJit.negPtr(scratchGPR1);
-            stubJit.addPtr(MacroAssembler::AbsoluteAddress(&amp;copiedAllocator-&gt;m_currentPayloadEnd), scratchGPR1);
-            stubJit.addPtr(MacroAssembler::TrustedImm32(sizeof(JSValue)), scratchGPR1);
-            // We have scratchGPR1 = new storage, scratchGPR3 = old storage, scratchGPR2 = available
-            for (size_t offset = 0; offset &lt; oldSize; offset += sizeof(void*)) {
-                stubJit.loadPtr(MacroAssembler::Address(scratchGPR3, -static_cast&lt;ptrdiff_t&gt;(offset + sizeof(JSValue) + sizeof(void*))), scratchGPR2);
-                stubJit.storePtr(scratchGPR2, MacroAssembler::Address(scratchGPR1, -static_cast&lt;ptrdiff_t&gt;(offset + sizeof(JSValue) + sizeof(void*))));
-            }
-        }
-        
-        stubJit.storePtr(scratchGPR1, MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()));
-        scratchGPR1HasStorage = true;
-    }
-
-    ASSERT(oldStructure-&gt;typeInfo().type() == structure-&gt;typeInfo().type());
-    ASSERT(oldStructure-&gt;typeInfo().inlineTypeFlags() == structure-&gt;typeInfo().inlineTypeFlags());
-    ASSERT(oldStructure-&gt;indexingType() == structure-&gt;indexingType());
-#if USE(JSVALUE64)
-    uint32_t val = structure-&gt;id();
-#else
-    uint32_t val = reinterpret_cast&lt;uint32_t&gt;(structure-&gt;id());
-#endif
-    stubJit.store32(MacroAssembler::TrustedImm32(val), MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()));
-#if USE(JSVALUE64)
-    if (isInlineOffset(slot.cachedOffset()))
-        stubJit.store64(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue)));
-    else {
-        if (!scratchGPR1HasStorage)
-            stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR1);
-        stubJit.store64(valueGPR, MacroAssembler::Address(scratchGPR1, offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue)));
-    }
-#elif USE(JSVALUE32_64)
-    if (isInlineOffset(slot.cachedOffset())) {
-        stubJit.store32(valueGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-        stubJit.store32(valueTagGPR, MacroAssembler::Address(baseGPR, JSObject::offsetOfInlineStorage() + offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
-    } else {
-        if (!scratchGPR1HasStorage)
-            stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR1);
-        stubJit.store32(valueGPR, MacroAssembler::Address(scratchGPR1, offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
-        stubJit.store32(valueTagGPR, MacroAssembler::Address(scratchGPR1, offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
-    }
-#endif
-    
-    ScratchBuffer* scratchBuffer = nullptr;
-
-#if ENABLE(GGC)
-    MacroAssembler::Call callFlushWriteBarrierBuffer;
-    if (structure-&gt;outOfLineCapacity() != oldStructure-&gt;outOfLineCapacity()) {
-        MacroAssembler::Jump ownerIsRememberedOrInEden = stubJit.jumpIfIsRememberedOrInEden(baseGPR);
-        WriteBarrierBuffer&amp; writeBarrierBuffer = stubJit.vm()-&gt;heap.writeBarrierBuffer();
-        stubJit.load32(writeBarrierBuffer.currentIndexAddress(), scratchGPR2);
-        MacroAssembler::Jump needToFlush =
-            stubJit.branch32(MacroAssembler::AboveOrEqual, scratchGPR2, MacroAssembler::TrustedImm32(writeBarrierBuffer.capacity()));
-
-        stubJit.add32(MacroAssembler::TrustedImm32(1), scratchGPR2);
-        stubJit.store32(scratchGPR2, writeBarrierBuffer.currentIndexAddress());
-
-        stubJit.move(MacroAssembler::TrustedImmPtr(writeBarrierBuffer.buffer()), scratchGPR1);
-        // We use an offset of -sizeof(void*) because we already added 1 to scratchGPR2.
-        stubJit.storePtr(baseGPR, MacroAssembler::BaseIndex(scratchGPR1, scratchGPR2, MacroAssembler::ScalePtr, static_cast&lt;int32_t&gt;(-sizeof(void*))));
-
-        MacroAssembler::Jump doneWithBarrier = stubJit.jump();
-        needToFlush.link(&amp;stubJit);
-
-        scratchBuffer = vm-&gt;scratchBufferForSize(allocator.desiredScratchBufferSizeForCall());
-        allocator.preserveUsedRegistersToScratchBufferForCall(stubJit, scratchBuffer, scratchGPR2);
-        stubJit.setupArgumentsWithExecState(baseGPR);
-        callFlushWriteBarrierBuffer = stubJit.call();
-        allocator.restoreUsedRegistersFromScratchBufferForCall(stubJit, scratchBuffer, scratchGPR2);
-
-        doneWithBarrier.link(&amp;stubJit);
-        ownerIsRememberedOrInEden.link(&amp;stubJit);
-    }
-#endif
-
-    MacroAssembler::Jump success;
-    MacroAssembler::Jump failure;
-            
-    if (allocator.didReuseRegisters()) {
-        allocator.restoreReusedRegistersByPopping(stubJit, numberOfPaddingBytes);
-        success = stubJit.jump();
-
-        failureCases.link(&amp;stubJit);
-        allocator.restoreReusedRegistersByPopping(stubJit, numberOfPaddingBytes);
-        failure = stubJit.jump();
-    } else
-        success = stubJit.jump();
-    
-    MacroAssembler::Call operationCall;
-    MacroAssembler::Jump successInSlowPath;
-    
-    if (structure-&gt;outOfLineCapacity() != oldStructure-&gt;outOfLineCapacity()) {
-        slowPath.link(&amp;stubJit);
-        
-        allocator.restoreReusedRegistersByPopping(stubJit, numberOfPaddingBytes);
-        if (!scratchBuffer)
-            scratchBuffer = vm-&gt;scratchBufferForSize(allocator.desiredScratchBufferSizeForCall());
-        allocator.preserveUsedRegistersToScratchBufferForCall(stubJit, scratchBuffer, scratchGPR1);
-#if USE(JSVALUE64)
-        stubJit.setupArgumentsWithExecState(baseGPR, MacroAssembler::TrustedImmPtr(structure), MacroAssembler::TrustedImm32(slot.cachedOffset()), valueGPR);
-#else
-        stubJit.setupArgumentsWithExecState(baseGPR, MacroAssembler::TrustedImmPtr(structure), MacroAssembler::TrustedImm32(slot.cachedOffset()), valueGPR, valueTagGPR);
-#endif
-        operationCall = stubJit.call();
-        allocator.restoreUsedRegistersFromScratchBufferForCall(stubJit, scratchBuffer, scratchGPR1);
-        successInSlowPath = stubJit.jump();
-    }
-    
-    LinkBuffer patchBuffer(*vm, stubJit, exec-&gt;codeBlock(), JITCompilationCanFail);
-    if (patchBuffer.didFailToAllocate())
-        return false;
-    
-    patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone));
-    if (allocator.didReuseRegisters())
-        patchBuffer.link(failure, failureLabel);
-    else
-        patchBuffer.link(failureCases, failureLabel);
-    if (structure-&gt;outOfLineCapacity() != oldStructure-&gt;outOfLineCapacity()) {
-        patchBuffer.link(operationCall, operationReallocateStorageAndFinishPut);
-        patchBuffer.link(successInSlowPath, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone));
-#if ENABLE(GGC)
-        patchBuffer.link(callFlushWriteBarrierBuffer, operationFlushWriteBarrierBuffer);
-#endif
-    }
-    
-    stubRoutine =
-        createJITStubRoutine(
-            FINALIZE_CODE_FOR(
-                exec-&gt;codeBlock(), patchBuffer,
-                (&quot;PutById %stransition stub (%p -&gt; %p) for %s, return point %p&quot;,
-                    structure-&gt;outOfLineCapacity() != oldStructure-&gt;outOfLineCapacity() ? &quot;reallocating &quot; : &quot;&quot;,
-                    oldStructure, structure,
-                    toCString(*exec-&gt;codeBlock()).data(), stubInfo.callReturnLocation.labelAtOffset(
-                        stubInfo.patch.deltaCallToDone).executableAddress())),
-            *vm,
-            exec-&gt;codeBlock()-&gt;ownerExecutable(),
-            structure-&gt;outOfLineCapacity() != oldStructure-&gt;outOfLineCapacity(),
-            structure);
-    
-    return true;
-}
-
</del><span class="cx"> static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier&amp; ident, const PutPropertySlot&amp; slot, StructureStubInfo&amp; stubInfo, PutKind putKind)
</span><span class="cx"> {
</span><span class="cx">     if (Options::forceICFailure())
</span><span class="cx">         return GiveUpOnCache;
</span><span class="cx">     
</span><span class="cx">     CodeBlock* codeBlock = exec-&gt;codeBlock();
</span><del>-    VM* vm = &amp;exec-&gt;vm();
</del><ins>+    ScriptExecutable* owner = codeBlock-&gt;ownerScriptExecutable();
+    VM&amp; vm = exec-&gt;vm();
</ins><span class="cx"> 
</span><span class="cx">     if (!baseValue.isCell())
</span><span class="cx">         return GiveUpOnCache;
</span><span class="lines">@@ -1258,210 +362,108 @@
</span><span class="cx">     if (!structure-&gt;propertyAccessesAreCacheable())
</span><span class="cx">         return GiveUpOnCache;
</span><span class="cx"> 
</span><del>-    // Optimize self access.
</del><ins>+    std::unique_ptr&lt;AccessCase&gt; newCase;
+
</ins><span class="cx">     if (slot.base() == baseValue &amp;&amp; slot.isCacheablePut()) {
</span><del>-        if (slot.type() == PutPropertySlot::NewProperty) {
</del><ins>+        if (slot.type() == PutPropertySlot::ExistingProperty) {
+            structure-&gt;didCachePropertyReplacement(vm, slot.cachedOffset());
+        
+            ptrdiff_t offsetToPatchedStorage = offsetRelativeToPatchedStorage(slot.cachedOffset());
+            if (stubInfo.cacheType == CacheType::Unset
+                &amp;&amp; MacroAssembler::isPtrAlignedAddressOffset(offsetToPatchedStorage)
+                &amp;&amp; !structure-&gt;needImpurePropertyWatchpoint()) {
+                
+                repatchByIdSelfAccess(
+                    codeBlock, stubInfo, structure, slot.cachedOffset(),
+                    appropriateOptimizingPutByIdFunction(slot, putKind), false);
+                stubInfo.initPutByIdReplace(
+                    vm, codeBlock-&gt;ownerExecutable(), structure, slot.cachedOffset());
+                return RetryCacheLater;
+            }
</ins><span class="cx"> 
</span><del>-            Structure* oldStructure;
-            ObjectPropertyConditionSet conditionSet;
-            if (!emitPutTransitionStub(exec, vm, structure, ident, slot, stubInfo, putKind, oldStructure, conditionSet))
</del><ins>+            newCase = AccessCase::replace(vm, owner, structure, slot.cachedOffset());
+        } else {
+            ASSERT(slot.type() == PutPropertySlot::NewProperty);
+
+            if (!structure-&gt;isObject() || structure-&gt;isDictionary())
</ins><span class="cx">                 return GiveUpOnCache;
</span><span class="cx"> 
</span><del>-            MacroAssembler::repatchJump(
-                stubInfo.callReturnLocation.jumpAtOffset(
-                    stubInfo.patch.deltaCallToJump),
-                CodeLocationLabel(stubInfo.stubRoutine-&gt;code().code()));
-            repatchCall(codeBlock, stubInfo.callReturnLocation, appropriateListBuildingPutByIdFunction(slot, putKind));
</del><ins>+            PropertyOffset offset;
+            Structure* newStructure =
+                Structure::addPropertyTransitionToExistingStructureConcurrently(
+                    structure, ident.impl(), 0, offset);
+            if (!newStructure || !newStructure-&gt;propertyAccessesAreCacheable())
+                return GiveUpOnCache;
+
+            ASSERT(newStructure-&gt;previousID() == structure);
+            ASSERT(!newStructure-&gt;isDictionary());
+            ASSERT(newStructure-&gt;isObject());
</ins><span class="cx">             
</span><del>-            stubInfo.initPutByIdTransition(*vm, codeBlock-&gt;ownerExecutable(), oldStructure, structure, conditionSet, putKind == Direct);
-            
-            return RetryCacheLater;
</del><ins>+            ObjectPropertyConditionSet conditionSet;
+            if (putKind == NotDirect) {
+                conditionSet =
+                    generateConditionsForPropertySetterMiss(
+                        vm, owner, exec, newStructure, ident.impl());
+                if (!conditionSet.isValid())
+                    return GiveUpOnCache;
+            }
+
+            newCase = AccessCase::transition(vm, owner, structure, newStructure, offset, conditionSet);
</ins><span class="cx">         }
</span><ins>+    } else if (slot.isCacheableCustom() || slot.isCacheableSetter()) {
+        if (slot.isCacheableCustom()) {
+            ObjectPropertyConditionSet conditionSet;
</ins><span class="cx"> 
</span><del>-        if (!MacroAssembler::isPtrAlignedAddressOffset(offsetRelativeToPatchedStorage(slot.cachedOffset())))
-            return GiveUpOnCache;
-
-        structure-&gt;didCachePropertyReplacement(*vm, slot.cachedOffset());
-        repatchByIdSelfAccess(*vm, codeBlock, stubInfo, structure, ident, slot.cachedOffset(), appropriateListBuildingPutByIdFunction(slot, putKind), false);
-        stubInfo.initPutByIdReplace(*vm, codeBlock-&gt;ownerExecutable(), structure);
-        return RetryCacheLater;
-    }
-
-    if ((slot.isCacheableCustom() || slot.isCacheableSetter())
-        &amp;&amp; stubInfo.patch.spillMode == DontSpill) {
-        RefPtr&lt;JITStubRoutine&gt; stubRoutine;
-
-        ObjectPropertyConditionSet conditionSet;
-        PropertyOffset offset;
-        if (slot.base() != baseValue) {
-            if (slot.isCacheableCustom()) {
</del><ins>+            if (slot.base() != baseValue) {
</ins><span class="cx">                 conditionSet =
</span><span class="cx">                     generateConditionsForPrototypePropertyHitCustom(
</span><del>-                        *vm, codeBlock-&gt;ownerExecutable(), exec, structure, slot.base(),
-                        ident.impl());
-            } else {
-                conditionSet =
-                    generateConditionsForPrototypePropertyHit(
-                        *vm, codeBlock-&gt;ownerExecutable(), exec, structure, slot.base(),
-                        ident.impl());
</del><ins>+                        vm, owner, exec, structure, slot.base(), ident.impl());
+                if (!conditionSet.isValid())
+                    return GiveUpOnCache;
</ins><span class="cx">             }
</span><del>-            if (!conditionSet.isValid())
-                return GiveUpOnCache;
-            offset = slot.isCacheableCustom() ? invalidOffset : conditionSet.slotBaseCondition().offset();
-        } else
-            offset = slot.cachedOffset();
</del><span class="cx"> 
</span><del>-        PolymorphicPutByIdList* list;
-        list = PolymorphicPutByIdList::from(putKind, stubInfo);
</del><ins>+            newCase = AccessCase::setter(
+                vm, owner, AccessCase::CustomSetter, structure, invalidOffset, conditionSet,
+                slot.customSetter(), slot.base());
+        } else {
+            ObjectPropertyConditionSet conditionSet;
+            PropertyOffset offset;
</ins><span class="cx"> 
</span><del>-        bool result = generateByIdStub(
-            exec, kindFor(slot), ident, customFor(slot), stubInfo, conditionSet, slot.base(),
-            offset, structure, false, nullptr,
-            stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone),
-            stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase),
-            stubRoutine);
-        if (!result)
-            return GiveUpOnCache;
-        
-        list-&gt;addAccess(PutByIdAccess::setter(
-            *vm, codeBlock-&gt;ownerExecutable(),
-            slot.isCacheableSetter() ? PutByIdAccess::Setter : PutByIdAccess::CustomSetter,
-            structure, conditionSet, slot.customSetter(), stubRoutine));
</del><ins>+            if (slot.base() != baseValue) {
+                conditionSet =
+                    generateConditionsForPrototypePropertyHit(
+                        vm, owner, exec, structure, slot.base(), ident.impl());
+                if (!conditionSet.isValid())
+                    return GiveUpOnCache;
+                offset = conditionSet.slotBaseCondition().offset();
+            } else
+                offset = slot.cachedOffset();
</ins><span class="cx"> 
</span><del>-        MacroAssembler::repatchJump(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), CodeLocationLabel(stubRoutine-&gt;code().code()));
-        repatchCall(codeBlock, stubInfo.callReturnLocation, appropriateListBuildingPutByIdFunction(slot, putKind));
-        RELEASE_ASSERT(!list-&gt;isFull());
-        return RetryCacheLater;
</del><ins>+            newCase = AccessCase::setter(
+                vm, owner, AccessCase::Setter, structure, offset, conditionSet);
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return GiveUpOnCache;
-}
-
-void repatchPutByID(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier&amp; propertyName, const PutPropertySlot&amp; slot, StructureStubInfo&amp; stubInfo, PutKind putKind)
-{
-    GCSafeConcurrentJITLocker locker(exec-&gt;codeBlock()-&gt;m_lock, exec-&gt;vm().heap);
</del><ins>+    MacroAssemblerCodePtr codePtr = stubInfo.addAccessCase(
+        vm, codeBlock, ident, WTF::move(newCase));
</ins><span class="cx">     
</span><del>-    if (tryCachePutByID(exec, baseValue, structure, propertyName, slot, stubInfo, putKind) == GiveUpOnCache)
-        repatchCall(exec-&gt;codeBlock(), stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind));
-}
-
-static InlineCacheAction tryBuildPutByIdList(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier&amp; propertyName, const PutPropertySlot&amp; slot, StructureStubInfo&amp; stubInfo, PutKind putKind)
-{
-    CodeBlock* codeBlock = exec-&gt;codeBlock();
-    VM* vm = &amp;exec-&gt;vm();
-
-    if (!baseValue.isCell())
</del><ins>+    if (!codePtr)
</ins><span class="cx">         return GiveUpOnCache;
</span><span class="cx"> 
</span><del>-    if (!slot.isCacheablePut() &amp;&amp; !slot.isCacheableCustom() &amp;&amp; !slot.isCacheableSetter())
-        return GiveUpOnCache;
-
-    if (!structure-&gt;propertyAccessesAreCacheable())
-        return GiveUpOnCache;
-
-    // Optimize self access.
-    if (slot.base() == baseValue &amp;&amp; slot.isCacheablePut()) {
-        PolymorphicPutByIdList* list;
-        RefPtr&lt;JITStubRoutine&gt; stubRoutine;
-        
-        if (slot.type() == PutPropertySlot::NewProperty) {
-            list = PolymorphicPutByIdList::from(putKind, stubInfo);
-            if (list-&gt;isFull())
-                return GiveUpOnCache; // Will get here due to recursion.
-
-            Structure* oldStructure;
-            ObjectPropertyConditionSet conditionSet;
-            if (!emitPutTransitionStub(exec, vm, structure, propertyName, slot, stubInfo, putKind, oldStructure, conditionSet))
-                return GiveUpOnCache;
-
-            stubRoutine = stubInfo.stubRoutine;
-            list-&gt;addAccess(
-                PutByIdAccess::transition(
-                    *vm, codeBlock-&gt;ownerExecutable(),
-                    oldStructure, structure, conditionSet,
-                    stubRoutine));
-
-        } else {
-            list = PolymorphicPutByIdList::from(putKind, stubInfo);
-            if (list-&gt;isFull())
-                return GiveUpOnCache; // Will get here due to recursion.
-            
-            structure-&gt;didCachePropertyReplacement(*vm, slot.cachedOffset());
-            
-            // We're now committed to creating the stub. Mogrify the meta-data accordingly.
-            bool result = emitPutReplaceStub(
-                exec, propertyName, slot, stubInfo, 
-                structure, CodeLocationLabel(list-&gt;currentSlowPathTarget()), stubRoutine);
-            if (!result)
-                return GiveUpOnCache;
-            
-            list-&gt;addAccess(
-                PutByIdAccess::replace(
-                    *vm, codeBlock-&gt;ownerExecutable(),
-                    structure, stubRoutine));
-        }
-        MacroAssembler::repatchJump(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), CodeLocationLabel(stubRoutine-&gt;code().code()));
-        if (list-&gt;isFull())
-            repatchCall(codeBlock, stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind));
-
-        return RetryCacheLater;
-    }
-
-    if ((slot.isCacheableCustom() || slot.isCacheableSetter())
-        &amp;&amp; stubInfo.patch.spillMode == DontSpill) {
-        RefPtr&lt;JITStubRoutine&gt; stubRoutine;
-        
-        ObjectPropertyConditionSet conditionSet;
-        PropertyOffset offset;
-        if (slot.base() != baseValue) {
-            if (slot.isCacheableCustom()) {
-                conditionSet =
-                    generateConditionsForPrototypePropertyHitCustom(
-                        *vm, codeBlock-&gt;ownerExecutable(), exec, structure, slot.base(),
-                        propertyName.impl());
-            } else {
-                conditionSet =
-                    generateConditionsForPrototypePropertyHit(
-                        *vm, codeBlock-&gt;ownerExecutable(), exec, structure, slot.base(),
-                        propertyName.impl());
-            }
-            if (!conditionSet.isValid())
-                return GiveUpOnCache;
-            offset = slot.isCacheableCustom() ? invalidOffset : conditionSet.slotBaseCondition().offset();
-        } else
-            offset = slot.cachedOffset();
-
-        PolymorphicPutByIdList* list;
-        list = PolymorphicPutByIdList::from(putKind, stubInfo);
-
-        bool result = generateByIdStub(
-            exec, kindFor(slot), propertyName, customFor(slot), stubInfo, conditionSet, slot.base(),
-            offset, structure, false, nullptr,
-            stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone),
-            CodeLocationLabel(list-&gt;currentSlowPathTarget()),
-            stubRoutine);
-        if (!result)
-            return GiveUpOnCache;
-        
-        list-&gt;addAccess(PutByIdAccess::setter(
-            *vm, codeBlock-&gt;ownerExecutable(),
-            slot.isCacheableSetter() ? PutByIdAccess::Setter : PutByIdAccess::CustomSetter,
-            structure, conditionSet, slot.customSetter(), stubRoutine));
-
-        MacroAssembler::repatchJump(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), CodeLocationLabel(stubRoutine-&gt;code().code()));
-        if (list-&gt;isFull())
-            repatchCall(codeBlock, stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind));
-
-        return RetryCacheLater;
-    }
-    return GiveUpOnCache;
</del><ins>+    resetPutByIDCheckAndLoad(stubInfo);
+    MacroAssembler::repatchJump(
+        stubInfo.callReturnLocation.jumpAtOffset(
+            stubInfo.patch.deltaCallToJump),
+        CodeLocationLabel(codePtr));
+    
+    return RetryCacheLater;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void buildPutByIdList(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier&amp; propertyName, const PutPropertySlot&amp; slot, StructureStubInfo&amp; stubInfo, PutKind putKind)
</del><ins>+void repatchPutByID(ExecState* exec, JSValue baseValue, Structure* structure, const Identifier&amp; propertyName, const PutPropertySlot&amp; slot, StructureStubInfo&amp; stubInfo, PutKind putKind)
</ins><span class="cx"> {
</span><span class="cx">     GCSafeConcurrentJITLocker locker(exec-&gt;codeBlock()-&gt;m_lock, exec-&gt;vm().heap);
</span><span class="cx">     
</span><del>-    if (tryBuildPutByIdList(exec, baseValue, structure, propertyName, slot, stubInfo, putKind) == GiveUpOnCache)
</del><ins>+    if (tryCachePutByID(exec, baseValue, structure, propertyName, slot, stubInfo, putKind) == GiveUpOnCache)
</ins><span class="cx">         repatchCall(exec-&gt;codeBlock(), stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1481,106 +483,35 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     CodeBlock* codeBlock = exec-&gt;codeBlock();
</span><del>-    VM* vm = &amp;exec-&gt;vm();
-    Structure* structure = base-&gt;structure(*vm);
</del><ins>+    ScriptExecutable* owner = codeBlock-&gt;ownerScriptExecutable();
+    VM&amp; vm = exec-&gt;vm();
+    Structure* structure = base-&gt;structure(vm);
</ins><span class="cx">     
</span><span class="cx">     ObjectPropertyConditionSet conditionSet;
</span><span class="cx">     if (wasFound) {
</span><span class="cx">         if (slot.slotBase() != base) {
</span><span class="cx">             conditionSet = generateConditionsForPrototypePropertyHit(
</span><del>-                *vm, codeBlock-&gt;ownerExecutable(), exec, structure, slot.slotBase(), ident.impl());
</del><ins>+                vm, codeBlock-&gt;ownerExecutable(), exec, structure, slot.slotBase(), ident.impl());
</ins><span class="cx">         }
</span><span class="cx">     } else {
</span><span class="cx">         conditionSet = generateConditionsForPropertyMiss(
</span><del>-            *vm, codeBlock-&gt;ownerExecutable(), exec, structure, ident.impl());
</del><ins>+            vm, codeBlock-&gt;ownerExecutable(), exec, structure, ident.impl());
</ins><span class="cx">     }
</span><span class="cx">     if (!conditionSet.isValid())
</span><span class="cx">         return GiveUpOnCache;
</span><del>-    
-    PolymorphicAccessStructureList* polymorphicStructureList;
-    int listIndex;
-    
-    CodeLocationLabel successLabel = stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone);
-    CodeLocationLabel slowCaseLabel;
-    
-    if (stubInfo.accessType == access_unset) {
-        polymorphicStructureList = new PolymorphicAccessStructureList();
-        stubInfo.initInList(polymorphicStructureList, 0);
-        slowCaseLabel = stubInfo.callReturnLocation.labelAtOffset(
-            stubInfo.patch.deltaCallToSlowCase);
-        listIndex = 0;
-    } else {
-        RELEASE_ASSERT(stubInfo.accessType == access_in_list);
-        polymorphicStructureList = stubInfo.u.inList.structureList;
-        listIndex = stubInfo.u.inList.listSize;
-        slowCaseLabel = CodeLocationLabel(polymorphicStructureList-&gt;list[listIndex - 1].stubRoutine-&gt;code().code());
-        
-        if (listIndex == POLYMORPHIC_LIST_CACHE_SIZE)
-            return GiveUpOnCache;
-    }
-    
-    RefPtr&lt;JITStubRoutine&gt; stubRoutine;
-    
-    {
-        GPRReg baseGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.baseGPR);
-        GPRReg resultGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.valueGPR);
-        GPRReg scratchGPR = TempRegisterSet(stubInfo.patch.usedRegisters).getFreeGPR();
-        
-        CCallHelpers stubJit(vm);
-        
-        bool needToRestoreScratch;
-        if (scratchGPR == InvalidGPRReg) {
-            scratchGPR = AssemblyHelpers::selectScratchGPR(baseGPR, resultGPR);
-            stubJit.pushToSave(scratchGPR);
-            needToRestoreScratch = true;
-        } else
-            needToRestoreScratch = false;
-        
-        MacroAssembler::JumpList failureCases;
-        failureCases.append(stubJit.branchStructure(
-            MacroAssembler::NotEqual,
-            MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()),
-            structure));
</del><span class="cx"> 
</span><del>-        CodeBlock* codeBlock = exec-&gt;codeBlock();
-        if (structure-&gt;typeInfo().newImpurePropertyFiresWatchpoints())
-            vm-&gt;registerWatchpointForImpureProperty(ident, stubInfo.addWatchpoint(codeBlock));
</del><ins>+    std::unique_ptr&lt;AccessCase&gt; newCase = AccessCase::in(
+        vm, owner, wasFound ? AccessCase::InHit : AccessCase::InMiss, structure, conditionSet);
</ins><span class="cx"> 
</span><del>-        if (slot.watchpointSet())
-            slot.watchpointSet()-&gt;add(stubInfo.addWatchpoint(codeBlock));
</del><ins>+    MacroAssemblerCodePtr codePtr = stubInfo.addAccessCase(vm, codeBlock, ident, WTF::move(newCase));
+    if (!codePtr)
+        return GiveUpOnCache;
</ins><span class="cx"> 
</span><del>-        checkObjectPropertyConditions(
-            conditionSet, exec-&gt;codeBlock(), stubInfo, stubJit, failureCases, scratchGPR);
-        
-#if USE(JSVALUE64)
-        stubJit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(wasFound))), resultGPR);
-#else
-        stubJit.move(MacroAssembler::TrustedImm32(wasFound), resultGPR);
-#endif
-        
-        MacroAssembler::Jump success, fail;
-        
-        emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCases);
-        
-        LinkBuffer patchBuffer(*vm, stubJit, exec-&gt;codeBlock(), JITCompilationCanFail);
-        if (patchBuffer.didFailToAllocate())
-            return GiveUpOnCache;
-        
-        linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, successLabel, slowCaseLabel);
-        
-        stubRoutine = FINALIZE_CODE_FOR_STUB(
-            exec-&gt;codeBlock(), patchBuffer,
-            (&quot;In (found = %s) stub for %s, return point %p&quot;,
-                wasFound ? &quot;yes&quot; : &quot;no&quot;, toCString(*exec-&gt;codeBlock()).data(),
-                successLabel.executableAddress()));
-    }
</del><ins>+    MacroAssembler::repatchJump(
+        stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump),
+        CodeLocationLabel(codePtr));
</ins><span class="cx">     
</span><del>-    polymorphicStructureList-&gt;list[listIndex].set(*vm, codeBlock-&gt;ownerExecutable(), stubRoutine, structure, true);
-    stubInfo.u.inList.listSize++;
-    
-    MacroAssembler::repatchJump(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), CodeLocationLabel(stubRoutine-&gt;code().code()));
-    
-    return listIndex &lt; (POLYMORPHIC_LIST_CACHE_SIZE - 1) ? RetryCacheLater : GiveUpOnCache;
</del><ins>+    return RetryCacheLater;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void repatchIn(
</span><span class="lines">@@ -1930,22 +861,7 @@
</span><span class="cx"> void resetGetByID(CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo)
</span><span class="cx"> {
</span><span class="cx">     repatchCall(codeBlock, stubInfo.callReturnLocation, operationGetByIdOptimize);
</span><del>-    CodeLocationDataLabel32 structureLabel = stubInfo.callReturnLocation.dataLabel32AtOffset(-(intptr_t)stubInfo.patch.deltaCheckImmToCall);
-    if (MacroAssembler::canJumpReplacePatchableBranch32WithPatch()) {
-        MacroAssembler::revertJumpReplacementToPatchableBranch32WithPatch(
-            MacroAssembler::startOfPatchableBranch32WithPatchOnAddress(structureLabel),
-            MacroAssembler::Address(
-                static_cast&lt;MacroAssembler::RegisterID&gt;(stubInfo.patch.baseGPR),
-                JSCell::structureIDOffset()),
-            static_cast&lt;int32_t&gt;(unusedPointer));
-    }
-    MacroAssembler::repatchInt32(structureLabel, static_cast&lt;int32_t&gt;(unusedPointer));
-#if USE(JSVALUE64)
-    MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToLoadOrStore), 0);
-#else
-    MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToTagLoadOrStore), 0);
-    MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToPayloadLoadOrStore), 0);
-#endif
</del><ins>+    resetGetByIDCheckAndLoad(stubInfo);
</ins><span class="cx">     MacroAssembler::repatchJump(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1953,33 +869,18 @@
</span><span class="cx"> {
</span><span class="cx">     V_JITOperation_ESsiJJI unoptimizedFunction = bitwise_cast&lt;V_JITOperation_ESsiJJI&gt;(readCallTarget(codeBlock, stubInfo.callReturnLocation).executableAddress());
</span><span class="cx">     V_JITOperation_ESsiJJI optimizedFunction;
</span><del>-    if (unoptimizedFunction == operationPutByIdStrict || unoptimizedFunction == operationPutByIdStrictBuildList)
</del><ins>+    if (unoptimizedFunction == operationPutByIdStrict || unoptimizedFunction == operationPutByIdStrictOptimize)
</ins><span class="cx">         optimizedFunction = operationPutByIdStrictOptimize;
</span><del>-    else if (unoptimizedFunction == operationPutByIdNonStrict || unoptimizedFunction == operationPutByIdNonStrictBuildList)
</del><ins>+    else if (unoptimizedFunction == operationPutByIdNonStrict || unoptimizedFunction == operationPutByIdNonStrictOptimize)
</ins><span class="cx">         optimizedFunction = operationPutByIdNonStrictOptimize;
</span><del>-    else if (unoptimizedFunction == operationPutByIdDirectStrict || unoptimizedFunction == operationPutByIdDirectStrictBuildList)
</del><ins>+    else if (unoptimizedFunction == operationPutByIdDirectStrict || unoptimizedFunction == operationPutByIdDirectStrictOptimize)
</ins><span class="cx">         optimizedFunction = operationPutByIdDirectStrictOptimize;
</span><span class="cx">     else {
</span><del>-        ASSERT(unoptimizedFunction == operationPutByIdDirectNonStrict || unoptimizedFunction == operationPutByIdDirectNonStrictBuildList);
</del><ins>+        ASSERT(unoptimizedFunction == operationPutByIdDirectNonStrict || unoptimizedFunction == operationPutByIdDirectNonStrictOptimize);
</ins><span class="cx">         optimizedFunction = operationPutByIdDirectNonStrictOptimize;
</span><span class="cx">     }
</span><span class="cx">     repatchCall(codeBlock, stubInfo.callReturnLocation, optimizedFunction);
</span><del>-    CodeLocationDataLabel32 structureLabel = stubInfo.callReturnLocation.dataLabel32AtOffset(-(intptr_t)stubInfo.patch.deltaCheckImmToCall);
-    if (MacroAssembler::canJumpReplacePatchableBranch32WithPatch()) {
-        MacroAssembler::revertJumpReplacementToPatchableBranch32WithPatch(
-            MacroAssembler::startOfPatchableBranch32WithPatchOnAddress(structureLabel),
-            MacroAssembler::Address(
-                static_cast&lt;MacroAssembler::RegisterID&gt;(stubInfo.patch.baseGPR),
-                JSCell::structureIDOffset()),
-            static_cast&lt;int32_t&gt;(unusedPointer));
-    }
-    MacroAssembler::repatchInt32(structureLabel, static_cast&lt;int32_t&gt;(unusedPointer));
-#if USE(JSVALUE64)
-    MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToLoadOrStore), 0);
-#else
-    MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToTagLoadOrStore), 0);
-    MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToPayloadLoadOrStore), 0);
-#endif
</del><ins>+    resetPutByIDCheckAndLoad(stubInfo);
</ins><span class="cx">     MacroAssembler::repatchJump(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitScratchRegisterAllocatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -44,6 +44,8 @@
</span><span class="cx"> 
</span><span class="cx"> void ScratchRegisterAllocator::lock(GPRReg reg)
</span><span class="cx"> {
</span><ins>+    if (reg == InvalidGPRReg)
+        return;
</ins><span class="cx">     unsigned index = GPRInfo::toIndex(reg);
</span><span class="cx">     if (index == GPRInfo::InvalidIndex)
</span><span class="cx">         return;
</span><span class="lines">@@ -52,12 +54,20 @@
</span><span class="cx"> 
</span><span class="cx"> void ScratchRegisterAllocator::lock(FPRReg reg)
</span><span class="cx"> {
</span><ins>+    if (reg == InvalidFPRReg)
+        return;
</ins><span class="cx">     unsigned index = FPRInfo::toIndex(reg);
</span><span class="cx">     if (index == FPRInfo::InvalidIndex)
</span><span class="cx">         return;
</span><span class="cx">     m_lockedRegisters.setFPRByIndex(index);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ScratchRegisterAllocator::lock(JSValueRegs regs)
+{
+    lock(regs.tagGPR());
+    lock(regs.payloadGPR());
+}
+
</ins><span class="cx"> template&lt;typename BankInfo&gt;
</span><span class="cx"> typename BankInfo::RegisterType ScratchRegisterAllocator::allocateScratch()
</span><span class="cx"> {
</span><span class="lines">@@ -71,7 +81,7 @@
</span><span class="cx">             return reg;
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-        
</del><ins>+    
</ins><span class="cx">     // Since that failed, try to allocate a register that is not yet
</span><span class="cx">     // locked or used for scratch.
</span><span class="cx">     for (unsigned i = 0; i &lt; BankInfo::numberOfRegisters; ++i) {
</span><span class="lines">@@ -117,6 +127,8 @@
</span><span class="cx">     size_t totalStackAdjustmentBytes = numberOfBytesPushed + maxFrameExtentForSlowPathCall;
</span><span class="cx">     totalStackAdjustmentBytes = WTF::roundUpToMultipleOf(stackAlignmentBytes(), totalStackAdjustmentBytes);
</span><span class="cx"> 
</span><ins>+    // FIXME: We shouldn't have to do this.
+    // https://bugs.webkit.org/show_bug.cgi?id=149030
</ins><span class="cx">     size_t numberOfPaddingBytes = totalStackAdjustmentBytes - numberOfBytesPushed;
</span><span class="cx">     jit.subPtr(MacroAssembler::TrustedImm32(numberOfPaddingBytes), MacroAssembler::stackPointerRegister);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitScratchRegisterAllocatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -40,11 +40,13 @@
</span><span class="cx"> 
</span><span class="cx"> class ScratchRegisterAllocator {
</span><span class="cx"> public:
</span><ins>+    ScratchRegisterAllocator() { }
</ins><span class="cx">     ScratchRegisterAllocator(const RegisterSet&amp; usedRegisters);
</span><span class="cx">     ~ScratchRegisterAllocator();
</span><span class="cx"> 
</span><del>-    void lock(GPRReg reg);
-    void lock(FPRReg reg);
</del><ins>+    void lock(GPRReg);
+    void lock(FPRReg);
+    void lock(JSValueRegs);
</ins><span class="cx">     
</span><span class="cx">     template&lt;typename BankInfo&gt;
</span><span class="cx">     typename BankInfo::RegisterType allocateScratch();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -480,6 +480,7 @@
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionReoptimizationRetryCount(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState*);
</span><span class="cx"> static NO_RETURN_WITH_VALUE EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*);
</span><ins>+static NO_RETURN_DUE_TO_CRASH EncodedJSValue JSC_HOST_CALL functionAbort(ExecState*);
</ins><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionFalse1(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*);
</span><span class="lines">@@ -615,6 +616,7 @@
</span><span class="cx">         addFunction(vm, &quot;describeArray&quot;, functionDescribeArray, 1);
</span><span class="cx">         addFunction(vm, &quot;print&quot;, functionPrint, 1);
</span><span class="cx">         addFunction(vm, &quot;quit&quot;, functionQuit, 0);
</span><ins>+        addFunction(vm, &quot;abort&quot;, functionAbort, 0);
</ins><span class="cx">         addFunction(vm, &quot;gc&quot;, functionGCAndSweep, 0);
</span><span class="cx">         addFunction(vm, &quot;fullGC&quot;, functionFullGC, 0);
</span><span class="cx">         addFunction(vm, &quot;edenGC&quot;, functionEdenGC, 0);
</span><span class="lines">@@ -1333,6 +1335,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+EncodedJSValue JSC_HOST_CALL functionAbort(ExecState*)
+{
+    CRASH();
+}
+
</ins><span class="cx"> EncodedJSValue JSC_HOST_CALL functionFalse1(ExecState*) { return JSValue::encode(jsBoolean(false)); }
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*) { return JSValue::encode(jsBoolean(false)); }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -188,6 +188,7 @@
</span><span class="cx">     v(bool, clobberAllRegsInFTLICSlowPath, !ASSERT_DISABLED, nullptr) \
</span><span class="cx">     v(bool, assumeAllRegsInFTLICAreLive, false, nullptr) \
</span><span class="cx">     v(bool, enableAccessInlining, true, nullptr) \
</span><ins>+    v(unsigned, maxAccessVariantListSize, 8, nullptr) \
</ins><span class="cx">     v(bool, enablePolyvariantDevirtualization, true, nullptr) \
</span><span class="cx">     v(bool, enablePolymorphicAccessInlining, true, nullptr) \
</span><span class="cx">     v(bool, enablePolymorphicCallInlining, true, nullptr) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressarraymessagepassingjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/array-message-passing.js (0 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/array-message-passing.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/array-message-passing.js        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -0,0 +1,249 @@
</span><ins>+// This test was originally for message passing of typed arrays. But it turns out that it is a good
+// stress of JSC inline caches as well. So, this is a DOMless version of the test.
+
+var window;
+
+(function() {
+    var listeners = [];
+    var messages = [];
+    
+    window = {
+        addEventListener: function(type, listener) {
+            listeners.push(listener);
+        },
+        postMessage: function(message) {
+            messages.push(message);
+        },
+        _handleEvents: function() {
+            for (var i = 0; i &lt; messages.length; ++i) {
+                for (var j = 0; j &lt; listeners.length; ++j)
+                    listeners[j]({data: messages[i]});
+            }
+            messages = [];
+        }
+    };
+})();
+
+window.jsTestIsAsync = true;
+
+window.testsComplete = 0;
+
+function testPassed() { }
+
+function testFailed(string) {
+    try {
+        throw new Error(&quot;Test failed: &quot; + string);
+    } catch (e) {
+        print(e.message);
+        print(e.stack);
+        abort();
+    }
+}
+
+function classCompare(testName, got, sent) {
+    var classString = Object.prototype.toString;
+    var gotClass = classString.call(got);
+    var sentClass = classString.call(sent);
+    if (gotClass !== sentClass) {
+        testFailed(testName + &quot;: class &quot; + sentClass + &quot; became &quot; + gotClass);
+        return false;
+    } else {
+        testPassed(testName + &quot;: classes are &quot; + sentClass);
+        return true;
+    }
+}
+
+function bufferCompare(testName, got, sent) {
+    if (!classCompare(testName, got, sent)) {
+        return false;
+    }
+    if (got.byteLength !== sent.byteLength) {
+        testFailed(testName + &quot;: expected byteLength &quot; + sent.byteLength + &quot; bytes, got &quot; + got.byteLength);
+        return false;
+    } else {
+        testPassed(testName + &quot;: buffer lengths are &quot; + sent.byteLength);
+    }
+    var gotReader = new Uint8Array(got);
+    var sentReader = new Uint8Array(sent);
+    for (var i = 0; i &lt; sent.byteLength; ++i) {
+        if (gotReader[i] !== sentReader[i]) {
+            testFailed(testName + &quot;: buffers differ starting at byte &quot; + i);
+            return false;
+        }
+    }
+    testPassed(testName + &quot;: buffers have the same contents&quot;);
+    return true;
+}
+
+function viewCompare(testName, got, sent) {
+    if (!classCompare(testName, got, sent)) {
+        return false;
+    }
+    if (!bufferCompare(testName, got.buffer, sent.buffer)) {
+        return false;
+    }
+    if (got.byteOffset !== sent.byteOffset) {
+        testFailed(testName + &quot;: offset &quot; + sent.byteOffset + &quot; became &quot; + got.byteOffset);
+        return false;
+    } else {
+        testPassed(testName + &quot;: offset is &quot; + sent.byteOffset);
+    }
+    if (got.byteLength !== sent.byteLength) {
+        testFailed(testName + &quot;: length &quot; + sent.byteLength + &quot; became &quot; + got.byteLength);
+        return false;
+    } else {
+        testPassed(testName + &quot;: length is &quot; + sent.byteLength);
+    }
+    return true;
+}
+
+function typedArrayCompare(testName, got, sent) {
+    if (!viewCompare(testName, got, sent)) {
+        return false;
+    }
+    if (got.BYTES_PER_ELEMENT !== sent.BYTES_PER_ELEMENT) {
+        // Sanity checking.
+        testFailed(testName + &quot;: expected BYTES_PER_ELEMENT &quot; + sent.BYTES_PER_ELEMENT + &quot;, saw &quot; + got.BYTES_PER_ELEMENT);
+        return false;
+    }
+    return true;
+}
+
+function dataViewCompare(testName, got, sent) {
+    return viewCompare(testName, got, sent);
+}
+
+function dataViewCompare2(testName, got, sent) {
+    for (var i = 0; i &lt; 2; ++i) {
+        if (!dataViewCompare(testName, got[i], sent[i])) {
+            return false;
+        }
+    }
+    if (got[0].buffer !== got[1].buffer) {
+        testFailed(testName + &quot;: expected the same ArrayBuffer for both views&quot;);
+        return false;
+    }
+    return true;
+}
+function dataViewCompare3(testName, got, sent) {
+    for (var i = 0; i &lt; 3; i += 2) {
+        if (!dataViewCompare(testName, got[i], sent[i])) {
+            return false;
+        }
+    }
+    if (got[1].x !== sent[1].x || got[1].y !== sent[1].y) {
+        testFailed(testName + &quot;: {x:1, y:1} was not transferred properly&quot;);
+        return false;
+    }
+    if (got[0].buffer !== got[2].buffer) {
+        testFailed(testName + &quot;: expected the same ArrayBuffer for both views&quot;);
+        return false;
+    }
+    return false;
+}
+
+
+function createBuffer(length) {
+    var buffer = new ArrayBuffer(length);
+    var view = new Uint8Array(buffer);
+    for (var i = 0; i &lt; length; ++i) {
+        view[i] = i + 1;
+    }
+    return buffer;
+}
+
+function createTypedArray(typedArrayType, length) {
+    var view = new typedArrayType(length);
+    for (var i = 0; i &lt; length; ++i) {
+        view[i] = i + 1;
+    }
+    return view;
+}
+
+function createTypedArrayOverBuffer(typedArrayType, typedArrayElementSize, length, subStart, subLength) {
+    var buffer = new ArrayBuffer(length * typedArrayElementSize);
+    if (subStart === undefined) {
+        subStart = 0;
+        subLength = length;
+    }
+    return new typedArrayType(buffer, subStart * typedArrayElementSize, subLength);
+}
+
+var basicBufferTypes = [
+    [&quot;Int32&quot;, Int32Array, 4],
+    [&quot;Uint32&quot;, Uint32Array, 4],
+    [&quot;Int8&quot;, Int8Array, 1],
+    [&quot;Uint8&quot;, Uint8Array, 1],
+    [&quot;Uint8Clamped&quot;, Uint8ClampedArray, 1],
+    [&quot;Int16&quot;, Int16Array, 2],
+    [&quot;Uint16&quot;, Uint16Array, 2],
+    [&quot;Float32&quot;, Float32Array, 4],
+    [&quot;Float64&quot;, Float64Array, 8]
+];
+
+var arrayBuffer1 = createBuffer(1);
+
+var testList = [
+    ['ArrayBuffer0', new ArrayBuffer(0), bufferCompare],
+    ['ArrayBuffer1', createBuffer(1), bufferCompare],
+    ['ArrayBuffer128', createBuffer(128), bufferCompare],
+    ['DataView0', new DataView(new ArrayBuffer(0)), dataViewCompare],
+    ['DataView1', new DataView(createBuffer(1)), dataViewCompare],
+    ['DataView1-dup', [new DataView(arrayBuffer1), new DataView(arrayBuffer1)], dataViewCompare2],
+    ['DataView1-dup2', [new DataView(arrayBuffer1), {x:1, y:1}, new DataView(arrayBuffer1)], dataViewCompare3],
+    ['DataView128', new DataView(createBuffer(128)), dataViewCompare],
+    ['DataView1_offset_at_end', new DataView(createBuffer(1), 1, 0), dataViewCompare],
+    ['DataView128_offset_at_end', new DataView(createBuffer(128), 128, 0), dataViewCompare],
+    ['DataView128_offset_slice_length_0', new DataView(createBuffer(128), 64, 0), dataViewCompare],
+    ['DataView128_offset_slice_length_1', new DataView(createBuffer(128), 64, 1), dataViewCompare],
+    ['DataView128_offset_slice_length_16', new DataView(createBuffer(128), 64, 16), dataViewCompare],
+    ['DataView128_offset_slice_unaligned', new DataView(createBuffer(128), 63, 15), dataViewCompare]
+];
+
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_0&quot;, createTypedArray(t[1], 0), typedArrayCompare];}));
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_1&quot;, createTypedArray(t[1], 1), typedArrayCompare];}));
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_128&quot;, createTypedArray(t[1], 128), typedArrayCompare];}));
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_0_buffer&quot;, createTypedArrayOverBuffer(t[1], t[2], 0), typedArrayCompare];}));
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_1_buffer&quot;, createTypedArrayOverBuffer(t[1], t[2], 1), typedArrayCompare];}));
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_128_buffer&quot;, createTypedArrayOverBuffer(t[1], t[2], 128), typedArrayCompare];}));
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_1_buffer_offset_at_end&quot;, createTypedArrayOverBuffer(t[1], t[2], 1, 1, 0), typedArrayCompare];}));
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_128_buffer_offset_at_end&quot;, createTypedArrayOverBuffer(t[1], t[2], 128, 128, 0), typedArrayCompare];}));
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_128_buffer_offset_slice_length_0&quot;, createTypedArrayOverBuffer(t[1], t[2], 128, 64, 0), typedArrayCompare];}));
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_128_buffer_offset_slice_length_1&quot;, createTypedArrayOverBuffer(t[1], t[2], 128, 64, 1), typedArrayCompare];}));
+testList = testList.concat(basicBufferTypes.map(function(t)
+    {return [t[0] + &quot;_128_buffer_offset_slice_length_16&quot;, createTypedArrayOverBuffer(t[1], t[2], 128, 64, 16), typedArrayCompare];}));
+
+function doneTest() {
+    if (++window.testsComplete == testList.length) {
+    }
+}
+
+function windowHandleMessage(e) {
+    var currentTest = testList[e.data.testNum];
+    var expectedResult = currentTest[1];
+    try {
+        currentTest[2](currentTest[0], e.data.testData, expectedResult);
+    } catch(e) {
+        testFailed(currentTest[0] + &quot;: unexpected exception &quot; + e);
+    }
+    doneTest();
+}
+window.addEventListener('message', windowHandleMessage);
+
+for (var t = 0; t &lt; testList.length; ++t) {
+    var currentTest = testList[t];
+    var message = {testNum: t, testData: currentTest[1]};
+    window.postMessage(message, '*');
+}
+
+window._handleEvents();
</ins></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/WTF/ChangeLog        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2015-09-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        There should be one stub hanging off an inline cache that contains code for all of the cases, rather than forming a linked list consisting of one stub per case
+        https://bugs.webkit.org/show_bug.cgi?id=148717
+
+        Reviewed by Michael Saboff.
+
+        Beef up dumping a bit.
+
+        * wtf/PrintStream.h:
+        (WTF::pointerDump):
+        (WTF::printInternal):
+
</ins><span class="cx"> 2015-09-08  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         GC stack scan should include ABI red zone.
</span></span></pre></div>
<a id="trunkSourceWTFwtfPrintStreamh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/PrintStream.h (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/PrintStream.h        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Source/WTF/wtf/PrintStream.h        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #ifndef PrintStream_h
</span><span class="cx"> #define PrintStream_h
</span><span class="cx"> 
</span><ins>+#include &lt;memory&gt;
</ins><span class="cx"> #include &lt;stdarg.h&gt;
</span><span class="cx"> #include &lt;wtf/FastMalloc.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="lines">@@ -162,6 +163,12 @@
</span><span class="cx"> template&lt;typename T&gt;
</span><span class="cx"> PointerDump&lt;T&gt; pointerDump(const T* ptr) { return PointerDump&lt;T&gt;(ptr); }
</span><span class="cx"> 
</span><ins>+template&lt;typename T&gt;
+void printInternal(PrintStream&amp; out, const std::unique_ptr&lt;T&gt;&amp; value)
+{
+    out.print(pointerDump(value.get()));
+}
+
</ins><span class="cx"> template&lt;typename T, typename U&gt;
</span><span class="cx"> class ValueInContext {
</span><span class="cx"> public:
</span></span></pre></div>
<a id="trunkToolsScriptsrunjscstresstests"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/run-jsc-stress-tests (189585 => 189586)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-jsc-stress-tests        2015-09-10 19:36:42 UTC (rev 189585)
+++ trunk/Tools/Scripts/run-jsc-stress-tests        2015-09-10 19:49:36 UTC (rev 189586)
</span><span class="lines">@@ -226,7 +226,7 @@
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> unless jscArg
</span><del>-    $stderr.puts &quot;Error: must specify -jsc &lt;path&gt;&quot;
</del><ins>+    $stderr.puts &quot;Error: must specify --jsc &lt;path&gt;&quot;
</ins><span class="cx">     exit 1
</span><span class="cx"> end
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>