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

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

<h3>Log Message</h3>
<pre>GetById list caching should use something object-oriented rather than PolymorphicAccessStructureList
https://bugs.webkit.org/show_bug.cgi?id=129778

Reviewed by Geoffrey Garen.
        
Also deduplicate the GetById getter call caching. Also add some small tests for
get stubs.
        
This change reduces the amount of code involved in GetById access caching and it
creates data structures that can serve as an elegant scaffold for introducing other
kinds of caches or improving current caching styles. It will definitely make getter
performance improvements easier to implement.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::printGetByIdCacheStatus):
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeForStubInfo):
* bytecode/PolymorphicGetByIdList.cpp: Added.
(JSC::GetByIdAccess::GetByIdAccess):
(JSC::GetByIdAccess::~GetByIdAccess):
(JSC::GetByIdAccess::fromStructureStubInfo):
(JSC::GetByIdAccess::visitWeak):
(JSC::PolymorphicGetByIdList::PolymorphicGetByIdList):
(JSC::PolymorphicGetByIdList::from):
(JSC::PolymorphicGetByIdList::~PolymorphicGetByIdList):
(JSC::PolymorphicGetByIdList::currentSlowPathTarget):
(JSC::PolymorphicGetByIdList::addAccess):
(JSC::PolymorphicGetByIdList::isFull):
(JSC::PolymorphicGetByIdList::isAlmostFull):
(JSC::PolymorphicGetByIdList::didSelfPatching):
(JSC::PolymorphicGetByIdList::visitWeak):
* bytecode/PolymorphicGetByIdList.h: Added.
(JSC::GetByIdAccess::GetByIdAccess):
(JSC::GetByIdAccess::isSet):
(JSC::GetByIdAccess::operator!):
(JSC::GetByIdAccess::type):
(JSC::GetByIdAccess::structure):
(JSC::GetByIdAccess::chain):
(JSC::GetByIdAccess::chainCount):
(JSC::GetByIdAccess::stubRoutine):
(JSC::GetByIdAccess::doesCalls):
(JSC::PolymorphicGetByIdList::isEmpty):
(JSC::PolymorphicGetByIdList::size):
(JSC::PolymorphicGetByIdList::at):
(JSC::PolymorphicGetByIdList::operator[]):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::deref):
(JSC::StructureStubInfo::visitWeakReferences):
* bytecode/StructureStubInfo.h:
(JSC::isGetByIdAccess):
(JSC::StructureStubInfo::initGetByIdList):
* jit/Repatch.cpp:
(JSC::generateGetByIdStub):
(JSC::tryCacheGetByID):
(JSC::patchJumpToGetByIdStub):
(JSC::tryBuildGetByIDList):
(JSC::tryBuildPutByIdList):
* tests/stress/getter.js: Added.
(foo):
(.o):
* tests/stress/polymorphic-prototype-accesses.js: Added.
(Foo):
(Bar):
(foo):
* tests/stress/prototype-getter.js: Added.
(Foo):
(foo):
* tests/stress/simple-prototype-accesses.js: Added.
(Foo):
(foo):</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="#trunkSourceJavaScriptCoreGNUmakefilelistam">trunk/Source/JavaScriptCore/GNUmakefile.list.am</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.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="#trunkSourceJavaScriptCorejitRepatchcpp">trunk/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<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="#trunkSourceJavaScriptCoretestsstressgetterjs">trunk/Source/JavaScriptCore/tests/stress/getter.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresspolymorphicprototypeaccessesjs">trunk/Source/JavaScriptCore/tests/stress/polymorphic-prototype-accesses.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressprototypegetterjs">trunk/Source/JavaScriptCore/tests/stress/prototype-getter.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresssimpleprototypeaccessesjs">trunk/Source/JavaScriptCore/tests/stress/simple-prototype-accesses.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (165458 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2014-03-12 01:45:54 UTC (rev 165458)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -78,6 +78,7 @@
</span><span class="cx">     bytecode/LazyOperandValueProfile.cpp
</span><span class="cx">     bytecode/MethodOfGettingAValueProfile.cpp
</span><span class="cx">     bytecode/Opcode.cpp
</span><ins>+    bytecode/PolymorphicGetByIdList.cpp
</ins><span class="cx">     bytecode/PolymorphicPutByIdList.cpp
</span><span class="cx">     bytecode/PreciseJumpTargets.cpp
</span><span class="cx">     bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (165458 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-03-12 01:45:54 UTC (rev 165458)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -1,3 +1,80 @@
</span><ins>+2014-03-10  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        GetById list caching should use something object-oriented rather than PolymorphicAccessStructureList
+        https://bugs.webkit.org/show_bug.cgi?id=129778
+
+        Reviewed by Geoffrey Garen.
+        
+        Also deduplicate the GetById getter call caching. Also add some small tests for
+        get stubs.
+        
+        This change reduces the amount of code involved in GetById access caching and it
+        creates data structures that can serve as an elegant scaffold for introducing other
+        kinds of caches or improving current caching styles. It will definitely make getter
+        performance improvements easier to implement.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printGetByIdCacheStatus):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfo):
+        * bytecode/PolymorphicGetByIdList.cpp: Added.
+        (JSC::GetByIdAccess::GetByIdAccess):
+        (JSC::GetByIdAccess::~GetByIdAccess):
+        (JSC::GetByIdAccess::fromStructureStubInfo):
+        (JSC::GetByIdAccess::visitWeak):
+        (JSC::PolymorphicGetByIdList::PolymorphicGetByIdList):
+        (JSC::PolymorphicGetByIdList::from):
+        (JSC::PolymorphicGetByIdList::~PolymorphicGetByIdList):
+        (JSC::PolymorphicGetByIdList::currentSlowPathTarget):
+        (JSC::PolymorphicGetByIdList::addAccess):
+        (JSC::PolymorphicGetByIdList::isFull):
+        (JSC::PolymorphicGetByIdList::isAlmostFull):
+        (JSC::PolymorphicGetByIdList::didSelfPatching):
+        (JSC::PolymorphicGetByIdList::visitWeak):
+        * bytecode/PolymorphicGetByIdList.h: Added.
+        (JSC::GetByIdAccess::GetByIdAccess):
+        (JSC::GetByIdAccess::isSet):
+        (JSC::GetByIdAccess::operator!):
+        (JSC::GetByIdAccess::type):
+        (JSC::GetByIdAccess::structure):
+        (JSC::GetByIdAccess::chain):
+        (JSC::GetByIdAccess::chainCount):
+        (JSC::GetByIdAccess::stubRoutine):
+        (JSC::GetByIdAccess::doesCalls):
+        (JSC::PolymorphicGetByIdList::isEmpty):
+        (JSC::PolymorphicGetByIdList::size):
+        (JSC::PolymorphicGetByIdList::at):
+        (JSC::PolymorphicGetByIdList::operator[]):
+        * bytecode/StructureStubInfo.cpp:
+        (JSC::StructureStubInfo::deref):
+        (JSC::StructureStubInfo::visitWeakReferences):
+        * bytecode/StructureStubInfo.h:
+        (JSC::isGetByIdAccess):
+        (JSC::StructureStubInfo::initGetByIdList):
+        * jit/Repatch.cpp:
+        (JSC::generateGetByIdStub):
+        (JSC::tryCacheGetByID):
+        (JSC::patchJumpToGetByIdStub):
+        (JSC::tryBuildGetByIDList):
+        (JSC::tryBuildPutByIdList):
+        * tests/stress/getter.js: Added.
+        (foo):
+        (.o):
+        * tests/stress/polymorphic-prototype-accesses.js: Added.
+        (Foo):
+        (Bar):
+        (foo):
+        * tests/stress/prototype-getter.js: Added.
+        (Foo):
+        (foo):
+        * tests/stress/simple-prototype-accesses.js: Added.
+        (Foo):
+        (foo):
+
</ins><span class="cx"> 2014-03-11  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         MarkedBlocks that are &quot;full enough&quot; shouldn't be swept after EdenCollections
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/GNUmakefile.list.am (165458 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/GNUmakefile.list.am        2014-03-12 01:45:54 UTC (rev 165458)
+++ trunk/Source/JavaScriptCore/GNUmakefile.list.am        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -175,6 +175,8 @@
</span><span class="cx">         Source/JavaScriptCore/bytecode/Operands.h \
</span><span class="cx">         Source/JavaScriptCore/bytecode/OperandsInlines.h \
</span><span class="cx">         Source/JavaScriptCore/bytecode/PolymorphicAccessStructureList.h \
</span><ins>+        Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp \
+        Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h \
</ins><span class="cx">         Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp \
</span><span class="cx">         Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h \
</span><span class="cx">         Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (165458 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-03-12 01:45:54 UTC (rev 165458)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -333,6 +333,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\LazyOperandValueProfile.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\MethodOfGettingAValueProfile.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\Opcode.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\bytecode\PolymorphicGetByIdList.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\PolymorphicPutByIdList.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\ProfiledCodeBlockJettisoningWatchpoint.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\bytecode\PreciseJumpTargets.cpp&quot; /&gt;
</span><span class="lines">@@ -860,6 +861,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\MethodOfGettingAValueProfile.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><ins>+    &lt;ClInclude Include=&quot;..\bytecode\PolymorphicGetByIdList.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\PolymorphicPutByIdList.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\ProfiledCodeBlockJettisoningWatchpoint.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\bytecode\PreciseJumpTargets.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (165458 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-03-12 01:45:54 UTC (rev 165458)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -273,6 +273,8 @@
</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><ins>+                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, ); }; };
</ins><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">                 0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */; };
</span><span class="lines">@@ -1788,6 +1790,8 @@
</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><ins>+                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;; };
</ins><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">                 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialPointer.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4600,7 +4604,6 @@
</span><span class="cx">                 969A078F0ED1D3AE00F1F681 /* bytecode */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><del>-                                6529FB3118B2D99900C61102 /* BytecodeList.json */,
</del><span class="cx">                                 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */,
</span><span class="cx">                                 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */,
</span><span class="cx">                                 0F63945115D07051006A597C /* ArrayProfile.cpp */,
</span><span class="lines">@@ -4608,6 +4611,7 @@
</span><span class="cx">                                 C2FCAE0C17A9C24E0034C735 /* BytecodeBasicBlock.cpp */,
</span><span class="cx">                                 C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */,
</span><span class="cx">                                 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */,
</span><ins>+                                6529FB3118B2D99900C61102 /* BytecodeList.json */,
</ins><span class="cx">                                 C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */,
</span><span class="cx">                                 C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */,
</span><span class="cx">                                 0F666EBE183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h */,
</span><span class="lines">@@ -4664,6 +4668,8 @@
</span><span class="cx">                                 0F2BDC2B151FDE8B00CD8910 /* Operands.h */,
</span><span class="cx">                                 A70447E917A0BD4600F5898E /* OperandsInlines.h */,
</span><span class="cx">                                 0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */,
</span><ins>+                                0F4CED5C18CEA7AB00802FE0 /* PolymorphicGetByIdList.cpp */,
+                                0F4CED5D18CEA7AB00802FE0 /* PolymorphicGetByIdList.h */,
</ins><span class="cx">                                 0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */,
</span><span class="cx">                                 0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */,
</span><span class="cx">                                 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */,
</span><span class="lines">@@ -5115,6 +5121,7 @@
</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><ins>+                                0F4CED5F18CEA7AB00802FE0 /* PolymorphicGetByIdList.h in Headers */,
</ins><span class="cx">                                 0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */,
</span><span class="cx">                                 0FFFC95C14EF90AF00C72532 /* DFGPhase.h in Headers */,
</span><span class="cx">                                 A78A977B179738B8009DF744 /* DFGPlan.h in Headers */,
</span><span class="lines">@@ -6550,6 +6557,7 @@
</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><ins>+                                0F4CED5E18CEA7AB00802FE0 /* PolymorphicGetByIdList.cpp in Sources */,
</ins><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></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (165458 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-03-12 01:45:54 UTC (rev 165458)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -50,6 +50,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><ins>+#include &quot;PolymorphicGetByIdList.h&quot;
</ins><span class="cx"> #include &quot;PolymorphicPutByIdList.h&quot;
</span><span class="cx"> #include &quot;ReduceWhitespace.h&quot;
</span><span class="cx"> #include &quot;Repatch.h&quot;
</span><span class="lines">@@ -341,8 +342,7 @@
</span><span class="cx">             Structure* baseStructure = 0;
</span><span class="cx">             Structure* prototypeStructure = 0;
</span><span class="cx">             StructureChain* chain = 0;
</span><del>-            PolymorphicAccessStructureList* structureList = 0;
-            int listSize = 0;
</del><ins>+            PolymorphicGetByIdList* list = 0;
</ins><span class="cx">             
</span><span class="cx">             switch (stubInfo.accessType) {
</span><span class="cx">             case access_get_by_id_self:
</span><span class="lines">@@ -354,10 +354,9 @@
</span><span class="cx">                 baseStructure = stubInfo.u.getByIdChain.baseObjectStructure.get();
</span><span class="cx">                 chain = stubInfo.u.getByIdChain.chain.get();
</span><span class="cx">                 break;
</span><del>-            case access_get_by_id_self_list:
-                out.printf(&quot;self_list&quot;);
-                structureList = stubInfo.u.getByIdSelfList.structureList;
-                listSize = stubInfo.u.getByIdSelfList.listSize;
</del><ins>+            case access_get_by_id_list:
+                out.printf(&quot;list&quot;);
+                list = stubInfo.u.getByIdList.list;
</ins><span class="cx">                 break;
</span><span class="cx">             case access_unset:
</span><span class="cx">                 out.printf(&quot;unset&quot;);
</span><span class="lines">@@ -382,16 +381,16 @@
</span><span class="cx">                 dumpChain(out, exec, chain, ident);
</span><span class="cx">             }
</span><span class="cx">             
</span><del>-            if (structureList) {
-                out.printf(&quot;, list = %p: [&quot;, structureList);
-                for (int i = 0; i &lt; listSize; ++i) {
</del><ins>+            if (list) {
+                out.printf(&quot;, list = %p: [&quot;, list);
+                for (unsigned i = 0; i &lt; list-&gt;size(); ++i) {
</ins><span class="cx">                     if (i)
</span><span class="cx">                         out.printf(&quot;, &quot;);
</span><span class="cx">                     out.printf(&quot;(&quot;);
</span><del>-                    dumpStructure(out, &quot;base&quot;, exec, structureList-&gt;list[i].base.get(), ident);
-                    if (structureList-&gt;list[i].chain.get()) {
</del><ins>+                    dumpStructure(out, &quot;base&quot;, exec, list-&gt;at(i).structure(), ident);
+                    if (list-&gt;at(i).chain()) {
</ins><span class="cx">                         out.printf(&quot;, &quot;);
</span><del>-                        dumpChain(out, exec, structureList-&gt;list[i].chain.get(), ident);
</del><ins>+                        dumpChain(out, exec, list-&gt;at(i).chain(), ident);
</ins><span class="cx">                     }
</span><span class="cx">                     out.printf(&quot;)&quot;);
</span><span class="cx">                 }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (165458 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2014-03-12 01:45:54 UTC (rev 165458)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -27,10 +27,11 @@
</span><span class="cx"> #include &quot;GetByIdStatus.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><ins>+#include &quot;JSCInlines.h&quot;
</ins><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;JSCInlines.h&quot;
</del><ins>+#include &quot;PolymorphicGetByIdList.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">@@ -174,13 +175,11 @@
</span><span class="cx">     if (stubInfo-&gt;resetByGC)
</span><span class="cx">         return GetByIdStatus(TakesSlowPath, true);
</span><span class="cx"> 
</span><del>-    PolymorphicAccessStructureList* list = 0;
-    int listSize = 0;
-    if (stubInfo-&gt;accessType == access_get_by_id_self_list) {
-        list = stubInfo-&gt;u.getByIdSelfList.structureList;
-        listSize = stubInfo-&gt;u.getByIdSelfList.listSize;
-        for (int i = 0; i &lt; listSize; ++i) {
-            if (!list-&gt;list[i].isDirect)
</del><ins>+    PolymorphicGetByIdList* list = 0;
+    if (stubInfo-&gt;accessType == access_get_by_id_list) {
+        list = stubInfo-&gt;u.getByIdList.list;
+        for (unsigned i = 0; i &lt; list-&gt;size(); ++i) {
+            if (list-&gt;at(i).doesCalls())
</ins><span class="cx">                 return GetByIdStatus(MakesCalls, true);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -214,18 +213,18 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    case access_get_by_id_self_list: {
-        for (int listIndex = 0; listIndex &lt; listSize; ++listIndex) {
-            ASSERT(list-&gt;list[listIndex].isDirect);
</del><ins>+    case access_get_by_id_list: {
+        for (unsigned listIndex = 0; listIndex &lt; list-&gt;size(); ++listIndex) {
+            ASSERT(!list-&gt;at(listIndex).doesCalls());
</ins><span class="cx">             
</span><del>-            Structure* structure = list-&gt;list[listIndex].base.get();
</del><ins>+            Structure* structure = list-&gt;at(listIndex).structure();
</ins><span class="cx">             if (structure-&gt;takesSlowPathInDFGForImpureProperty())
</span><span class="cx">                 return GetByIdStatus(TakesSlowPath, true);
</span><span class="cx">             
</span><del>-            if (list-&gt;list[listIndex].chain.get()) {
</del><ins>+            if (list-&gt;at(listIndex).chain()) {
</ins><span class="cx">                 RefPtr&lt;IntendedStructureChain&gt; chain = adoptRef(new IntendedStructureChain(
</span><del>-                    profiledBlock, structure, list-&gt;list[listIndex].chain.get(),
-                    list-&gt;list[listIndex].count));
</del><ins>+                    profiledBlock, structure, list-&gt;at(listIndex).chain(),
+                    list-&gt;at(listIndex).chainCount()));
</ins><span class="cx">                 if (!result.computeForChain(profiledBlock, uid, chain))
</span><span class="cx">                     return GetByIdStatus(TakesSlowPath, true);
</span><span class="cx">                 continue;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicGetByIdListcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp (0 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.cpp        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -0,0 +1,172 @@
</span><ins>+/*
+ * Copyright (C) 2014 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, StructureChain* chain, unsigned chainCount)
+    : m_type(type)
+    , m_chainCount(chainCount)
+    , m_structure(vm, owner, structure)
+    , m_stubRoutine(stubRoutine)
+{
+    if (chain)
+        m_chain.set(vm, owner, chain);
+}
+
+GetByIdAccess::~GetByIdAccess()
+{
+}
+
+GetByIdAccess GetByIdAccess::fromStructureStubInfo(StructureStubInfo&amp; stubInfo)
+{
+    MacroAssemblerCodePtr initialSlowPath =
+        stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase);
+    
+    GetByIdAccess result;
+    
+    switch (stubInfo.accessType) {
+    case access_get_by_id_self:
+        result.m_type = SimpleInline;
+        result.m_structure.copyFrom(stubInfo.u.getByIdSelf.baseObjectStructure);
+        result.m_stubRoutine = JITStubRoutine::createSelfManagedRoutine(initialSlowPath);
+        break;
+        
+    case access_get_by_id_chain:
+        result.m_structure.copyFrom(stubInfo.u.getByIdChain.baseObjectStructure);
+        result.m_chain.copyFrom(stubInfo.u.getByIdChain.chain);
+        result.m_chainCount = stubInfo.u.getByIdChain.count;
+        result.m_stubRoutine = stubInfo.stubRoutine;
+        if (stubInfo.u.getByIdChain.isDirect)
+            result.m_type = SimpleStub;
+        else
+            result.m_type = Getter;
+        break;
+        
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    
+    return result;
+}
+
+bool GetByIdAccess::visitWeak() const
+{
+    if (m_structure &amp;&amp; !Heap::isMarked(m_structure.get()))
+        return false;
+    if (m_chain &amp;&amp; !Heap::isMarked(m_chain.get()))
+        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_get_by_id_chain
+        || 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.resize(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() const
+{
+    for (unsigned i = size(); i--;) {
+        if (!at(i).visitWeak())
+            return false;
+    }
+    return true;
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicGetByIdListh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h (0 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicGetByIdList.h        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -0,0 +1,132 @@
</span><ins>+/*
+ * Copyright (C) 2014 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;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.
+        Getter,
+    };
+    
+    GetByIdAccess()
+        : m_type(Invalid)
+        , m_chainCount(0)
+    {
+    }
+    
+    GetByIdAccess(
+        VM&amp;, JSCell* owner, AccessType, PassRefPtr&lt;JITStubRoutine&gt;, Structure*,
+        StructureChain* = 0, unsigned chainCount = 0);
+    
+    ~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(); }
+    
+    StructureChain* chain() const { return m_chain.get(); }
+    unsigned chainCount() const { return m_chainCount; }
+    
+    JITStubRoutine* stubRoutine() const
+    {
+        ASSERT(isSet());
+        return m_stubRoutine.get();
+    }
+    
+    bool doesCalls() const { return type() == Getter; }
+    
+    bool visitWeak() const;
+
+private:
+    friend class CodeBlock;
+    
+    AccessType m_type;
+    unsigned m_chainCount;
+    WriteBarrier&lt;Structure&gt; m_structure;
+    WriteBarrier&lt;StructureChain&gt; m_chain;
+    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() const;
+
+private:
+    friend class CodeBlock;
+    
+    PolymorphicGetByIdList(StructureStubInfo&amp;);
+    
+    Vector&lt;GetByIdAccess, 2&gt; m_list;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // PolymorphicGetByIdList_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureStubInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp (165458 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp        2014-03-12 01:45:54 UTC (rev 165458)
+++ trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2014 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">@@ -27,18 +27,17 @@
</span><span class="cx"> #include &quot;StructureStubInfo.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSObject.h&quot;
</span><ins>+#include &quot;PolymorphicGetByIdList.h&quot;
</ins><span class="cx"> #include &quot;PolymorphicPutByIdList.h&quot;
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> void StructureStubInfo::deref()
</span><span class="cx"> {
</span><span class="cx">     switch (accessType) {
</span><del>-    case access_get_by_id_self_list: {
-        PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
-        delete polymorphicStructures;
</del><ins>+    case access_get_by_id_list: {
+        delete u.getByIdList.list;
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     case access_put_by_id_list:
</span><span class="lines">@@ -74,9 +73,8 @@
</span><span class="cx">             || !Heap::isMarked(u.getByIdChain.chain.get()))
</span><span class="cx">             return false;
</span><span class="cx">         break;
</span><del>-    case access_get_by_id_self_list: {
-        PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
-        if (!polymorphicStructures-&gt;visitWeak(u.getByIdSelfList.listSize))
</del><ins>+    case access_get_by_id_list: {
+        if (!u.getByIdList.list-&gt;visitWeak())
</ins><span class="cx">             return false;
</span><span class="cx">         break;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureStubInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h (165458 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h        2014-03-12 01:45:54 UTC (rev 165458)
+++ trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -42,12 +42,13 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> 
</span><ins>+class PolymorphicGetByIdList;
</ins><span class="cx"> class PolymorphicPutByIdList;
</span><span class="cx"> 
</span><span class="cx"> enum AccessType {
</span><span class="cx">     access_get_by_id_self,
</span><span class="cx">     access_get_by_id_chain,
</span><del>-    access_get_by_id_self_list,
</del><ins>+    access_get_by_id_list,
</ins><span class="cx">     access_put_by_id_transition_normal,
</span><span class="cx">     access_put_by_id_transition_direct,
</span><span class="cx">     access_put_by_id_replace,
</span><span class="lines">@@ -61,7 +62,7 @@
</span><span class="cx">     switch (accessType) {
</span><span class="cx">     case access_get_by_id_self:
</span><span class="cx">     case access_get_by_id_chain:
</span><del>-    case access_get_by_id_self_list:
</del><ins>+    case access_get_by_id_list:
</ins><span class="cx">         return true;
</span><span class="cx">     default:
</span><span class="cx">         return false;
</span><span class="lines">@@ -116,13 +117,10 @@
</span><span class="cx">         u.getByIdChain.isDirect = isDirect;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize, bool didSelfPatching = false)
</del><ins>+    void initGetByIdList(PolymorphicGetByIdList* list)
</ins><span class="cx">     {
</span><del>-        accessType = access_get_by_id_self_list;
-
-        u.getByIdSelfList.structureList = structureList;
-        u.getByIdSelfList.listSize = listSize;
-        u.getByIdSelfList.didSelfPatching = didSelfPatching;
</del><ins>+        accessType = access_get_by_id_list;
+        u.getByIdList.list = list;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // PutById*
</span><span class="lines">@@ -233,15 +231,9 @@
</span><span class="cx">             bool isDirect : 1;
</span><span class="cx">         } getByIdChain;
</span><span class="cx">         struct {
</span><del>-            PolymorphicAccessStructureList* structureList;
-            int listSize : 31;
-            bool didSelfPatching : 1;
-        } getByIdSelfList;
</del><ins>+            PolymorphicGetByIdList* list;
+        } getByIdList;
</ins><span class="cx">         struct {
</span><del>-            PolymorphicAccessStructureList* structureList;
-            int listSize;
-        } getByIdProtoList;
-        struct {
</del><span class="cx">             WriteBarrierBase&lt;Structure&gt; previousStructure;
</span><span class="cx">             WriteBarrierBase&lt;Structure&gt; structure;
</span><span class="cx">             WriteBarrierBase&lt;StructureChain&gt; chain;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.cpp (165458 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.cpp        2014-03-12 01:45:54 UTC (rev 165458)
+++ trunk/Source/JavaScriptCore/jit/Repatch.cpp        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -37,6 +37,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><ins>+#include &quot;PolymorphicGetByIdList.h&quot;
</ins><span class="cx"> #include &quot;PolymorphicPutByIdList.h&quot;
</span><span class="cx"> #include &quot;RepatchBuffer.h&quot;
</span><span class="cx"> #include &quot;ScratchRegisterAllocator.h&quot;
</span><span class="lines">@@ -219,13 +220,11 @@
</span><span class="cx">     linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone), stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-enum ProtoChainGenerationResult {
-    ProtoChainGenerationFailed,
-    ProtoChainGenerationSucceeded
-};
-
-static ProtoChainGenerationResult generateProtoChainAccessStub(ExecState*, const PropertySlot&amp;, const Identifier&amp;, StructureStubInfo&amp;, StructureChain*, size_t, PropertyOffset, Structure*, CodeLocationLabel, CodeLocationLabel, RefPtr&lt;JITStubRoutine&gt;&amp;) WARN_UNUSED_RETURN;
-static ProtoChainGenerationResult generateProtoChainAccessStub(ExecState* exec, const PropertySlot&amp; slot, const Identifier&amp; propertyName, StructureStubInfo&amp; stubInfo, StructureChain* chain, size_t count, PropertyOffset offset, Structure* structure, CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel, RefPtr&lt;JITStubRoutine&gt;&amp; stubRoutine)
</del><ins>+static void generateGetByIdStub(
+    ExecState* exec, const PropertySlot&amp; slot, const Identifier&amp; propertyName,
+    StructureStubInfo&amp; stubInfo, StructureChain* chain, size_t count, PropertyOffset offset,
+    Structure* structure, CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel,
+    RefPtr&lt;JITStubRoutine&gt;&amp; stubRoutine)
</ins><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="cx">     GPRReg baseGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.baseGPR);
</span><span class="lines">@@ -235,8 +234,7 @@
</span><span class="cx">     GPRReg resultGPR = static_cast&lt;GPRReg&gt;(stubInfo.patch.valueGPR);
</span><span class="cx">     GPRReg scratchGPR = TempRegisterSet(stubInfo.patch.usedRegisters).getFreeGPR();
</span><span class="cx">     bool needToRestoreScratch = scratchGPR == InvalidGPRReg;
</span><del>-    if (needToRestoreScratch &amp;&amp; !slot.isCacheableValue())
-        return ProtoChainGenerationFailed;
</del><ins>+    RELEASE_ASSERT(!needToRestoreScratch || slot.isCacheableValue());
</ins><span class="cx">     
</span><span class="cx">     CCallHelpers stubJit(&amp;exec-&gt;vm(), exec-&gt;codeBlock());
</span><span class="cx">     if (needToRestoreScratch) {
</span><span class="lines">@@ -261,41 +259,51 @@
</span><span class="cx">         vm-&gt;registerWatchpointForImpureProperty(propertyName, stubInfo.addWatchpoint(codeBlock));
</span><span class="cx"> 
</span><span class="cx">     Structure* currStructure = structure;
</span><del>-    WriteBarrier&lt;Structure&gt;* it = chain-&gt;head();
</del><span class="cx">     JSObject* protoObject = 0;
</span><del>-    for (unsigned i = 0; i &lt; count; ++i, ++it) {
-        protoObject = asObject(currStructure-&gt;prototypeForLookup(exec));
-        Structure* protoStructure = protoObject-&gt;structure();
-        if (protoStructure-&gt;typeInfo().newImpurePropertyFiresWatchpoints())
-            vm-&gt;registerWatchpointForImpureProperty(propertyName, stubInfo.addWatchpoint(codeBlock));
-        addStructureTransitionCheck(
-            protoObject, protoStructure, codeBlock, stubInfo, stubJit,
-            failureCases, scratchGPR);
-        currStructure = it-&gt;get();
</del><ins>+    if (chain) {
+        WriteBarrier&lt;Structure&gt;* it = chain-&gt;head();
+        for (unsigned i = 0; i &lt; count; ++i, ++it) {
+            protoObject = asObject(currStructure-&gt;prototypeForLookup(exec));
+            Structure* protoStructure = protoObject-&gt;structure();
+            if (protoStructure-&gt;typeInfo().newImpurePropertyFiresWatchpoints())
+                vm-&gt;registerWatchpointForImpureProperty(propertyName, stubInfo.addWatchpoint(codeBlock));
+            addStructureTransitionCheck(
+                protoObject, protoStructure, codeBlock, stubInfo, stubJit,
+                failureCases, scratchGPR);
+            currStructure = it-&gt;get();
+        }
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool isAccessor = slot.isCacheableGetter() || slot.isCacheableCustom();
</span><del>-    if (isAccessor)
-        stubJit.move(baseGPR, scratchGPR);
-
</del><ins>+    
+    GPRReg baseForAccessGPR;
+    if (chain) {
+        stubJit.move(MacroAssembler::TrustedImmPtr(protoObject), scratchGPR);
+        baseForAccessGPR = scratchGPR;
+    } else
+        baseForAccessGPR = baseGPR;
+    
+    GPRReg loadedValueGPR = InvalidGPRReg;
</ins><span class="cx">     if (!slot.isCacheableCustom()) {
</span><del>-        if (isInlineOffset(offset)) {
</del><ins>+        if (slot.isCacheableValue())
+            loadedValueGPR = resultGPR;
+        else
+            loadedValueGPR = scratchGPR;
+        
+        GPRReg storageGPR;
+        if (isInlineOffset(offset))
+            storageGPR = baseForAccessGPR;
+        else {
+            stubJit.loadPtr(MacroAssembler::Address(baseForAccessGPR, JSObject::butterflyOffset()), loadedValueGPR);
+            storageGPR = loadedValueGPR;
+        }
+        
</ins><span class="cx"> #if USE(JSVALUE64)
</span><del>-            stubJit.load64(protoObject-&gt;locationForOffset(offset), resultGPR);
-#elif USE(JSVALUE32_64)
-            stubJit.move(MacroAssembler::TrustedImmPtr(protoObject-&gt;locationForOffset(offset)), resultGPR);
-            stubJit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
-            stubJit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
</del><ins>+        stubJit.load64(MacroAssembler::Address(storageGPR, offsetRelativeToBase(offset)), loadedValueGPR);
+#else
+        stubJit.load32(MacroAssembler::Address(storageGPR, offsetRelativeToBase(offset) + TagOffset), resultTagGPR);
+        stubJit.load32(MacroAssembler::Address(storageGPR, offsetRelativeToBase(offset) + PayloadOffset), loadedValueGPR);
</ins><span class="cx"> #endif
</span><del>-        } else {
-            stubJit.loadPtr(protoObject-&gt;butterflyAddress(), resultGPR);
-#if USE(JSVALUE64)
-            stubJit.load64(MacroAssembler::Address(resultGPR, offsetInButterfly(offset) * sizeof(WriteBarrier&lt;Unknown&gt;)), resultGPR);
-#elif USE(JSVALUE32_64)
-            stubJit.load32(MacroAssembler::Address(resultGPR, offsetInButterfly(offset) * sizeof(WriteBarrier&lt;Unknown&gt;) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
-            stubJit.load32(MacroAssembler::Address(resultGPR, offsetInButterfly(offset) * sizeof(WriteBarrier&lt;Unknown&gt;) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
-#endif
-        }
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     MacroAssembler::Call operationCall;
</span><span class="lines">@@ -304,14 +312,14 @@
</span><span class="cx">     MacroAssembler::Jump success, fail;
</span><span class="cx">     if (isAccessor) {
</span><span class="cx">         if (slot.isCacheableGetter()) {
</span><del>-            stubJit.setupArgumentsWithExecState(scratchGPR, resultGPR);
</del><ins>+            stubJit.setupArgumentsWithExecState(baseGPR, loadedValueGPR);
</ins><span class="cx">             operationFunction = operationCallGetter;
</span><span class="cx">         } else {
</span><span class="cx">             // EncodedJSValue (*GetValueFunc)(ExecState*, JSObject* slotBase, EncodedJSValue thisValue, PropertyName);
</span><span class="cx"> #if USE(JSVALUE64)
</span><del>-            stubJit.setupArgumentsWithExecState(MacroAssembler::TrustedImmPtr(protoObject), scratchGPR, MacroAssembler::TrustedImmPtr(propertyName.impl()));
</del><ins>+            stubJit.setupArgumentsWithExecState(baseForAccessGPR, baseGPR, MacroAssembler::TrustedImmPtr(propertyName.impl()));
</ins><span class="cx"> #else
</span><del>-            stubJit.setupArgumentsWithExecState(MacroAssembler::TrustedImmPtr(protoObject), scratchGPR, MacroAssembler::TrustedImm32(JSValue::CellTag), MacroAssembler::TrustedImmPtr(propertyName.impl()));
</del><ins>+            stubJit.setupArgumentsWithExecState(baseForAccessGPR, baseGPR, MacroAssembler::TrustedImm32(JSValue::CellTag), MacroAssembler::TrustedImmPtr(propertyName.impl()));
</ins><span class="cx"> #endif
</span><span class="cx">             operationFunction = FunctionPtr(slot.customGetter());
</span><span class="cx">         }
</span><span class="lines">@@ -349,9 +357,8 @@
</span><span class="cx">     
</span><span class="cx">     stubRoutine = FINALIZE_CODE_FOR_STUB(
</span><span class="cx">         exec-&gt;codeBlock(), patchBuffer,
</span><del>-        (&quot;Prototype chain access stub for %s, return point %p&quot;,
</del><ins>+        (&quot;Get access stub for %s, return point %p&quot;,
</ins><span class="cx">             toCString(*exec-&gt;codeBlock()).data(), successLabel.executableAddress()));
</span><del>-    return ProtoChainGenerationSucceeded;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier&amp; propertyName, const PropertySlot&amp; slot, StructureStubInfo&amp; stubInfo)
</span><span class="lines">@@ -463,10 +470,11 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     StructureChain* prototypeChain = structure-&gt;prototypeChain(exec);
</span><del>-    if (generateProtoChainAccessStub(exec, slot, propertyName, stubInfo, prototypeChain, count, offset,
-        structure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone),
-        stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase), stubInfo.stubRoutine) == ProtoChainGenerationFailed)
-        return false;
</del><ins>+    generateGetByIdStub(
+        exec, slot, propertyName, stubInfo, prototypeChain, count, offset, structure,
+        stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone),
+        stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase),
+        stubInfo.stubRoutine);
</ins><span class="cx">     
</span><span class="cx">     RepatchBuffer repatchBuffer(codeBlock);
</span><span class="cx">     replaceWithJump(repatchBuffer, stubInfo, stubInfo.stubRoutine-&gt;code().code());
</span><span class="lines">@@ -485,49 +493,11 @@
</span><span class="cx">         repatchCall(exec-&gt;codeBlock(), stubInfo.callReturnLocation, operationGetById);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool getPolymorphicStructureList(
-    VM* vm, CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo,
-    PolymorphicAccessStructureList*&amp; polymorphicStructureList, int&amp; listIndex,
-    CodeLocationLabel&amp; slowCase)
-{
-    slowCase = stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase);
-    
-    if (stubInfo.accessType == access_unset) {
-        RELEASE_ASSERT(!stubInfo.stubRoutine);
-        polymorphicStructureList = new PolymorphicAccessStructureList();
-        stubInfo.initGetByIdSelfList(polymorphicStructureList, 0, false);
-        listIndex = 0;
-    } else if (stubInfo.accessType == access_get_by_id_self) {
-        RELEASE_ASSERT(!stubInfo.stubRoutine);
-        polymorphicStructureList = new PolymorphicAccessStructureList(*vm, codeBlock-&gt;ownerExecutable(), JITStubRoutine::createSelfManagedRoutine(slowCase), stubInfo.u.getByIdSelf.baseObjectStructure.get(), true);
-        stubInfo.initGetByIdSelfList(polymorphicStructureList, 1, true);
-        listIndex = 1;
-    } else if (stubInfo.accessType == access_get_by_id_chain) {
-        RELEASE_ASSERT(!!stubInfo.stubRoutine);
-        slowCase = CodeLocationLabel(stubInfo.stubRoutine-&gt;code().code());
-        polymorphicStructureList = new PolymorphicAccessStructureList(*vm, codeBlock-&gt;ownerExecutable(), stubInfo.stubRoutine, stubInfo.u.getByIdChain.baseObjectStructure.get(), stubInfo.u.getByIdChain.chain.get(), stubInfo.u.getByIdChain.isDirect, stubInfo.u.getByIdChain.count);
-        stubInfo.stubRoutine.clear();
-        stubInfo.initGetByIdSelfList(polymorphicStructureList, 1, false);
-        listIndex = 1;
-    } else {
-        RELEASE_ASSERT(stubInfo.accessType == access_get_by_id_self_list);
-        polymorphicStructureList = stubInfo.u.getByIdSelfList.structureList;
-        listIndex = stubInfo.u.getByIdSelfList.listSize;
-        slowCase = CodeLocationLabel(polymorphicStructureList-&gt;list[listIndex - 1].stubRoutine-&gt;code().code());
-    }
-    
-    if (listIndex == POLYMORPHIC_LIST_CACHE_SIZE)
-        return false;
-    
-    RELEASE_ASSERT(listIndex &lt; POLYMORPHIC_LIST_CACHE_SIZE);
-    return true;
-}
-
</del><span class="cx"> static void patchJumpToGetByIdStub(CodeBlock* codeBlock, StructureStubInfo&amp; stubInfo, JITStubRoutine* stubRoutine)
</span><span class="cx"> {
</span><del>-    RELEASE_ASSERT(stubInfo.accessType == access_get_by_id_self_list);
</del><ins>+    RELEASE_ASSERT(stubInfo.accessType == access_get_by_id_list);
</ins><span class="cx">     RepatchBuffer repatchBuffer(codeBlock);
</span><del>-    if (stubInfo.u.getByIdSelfList.didSelfPatching) {
</del><ins>+    if (stubInfo.u.getByIdList.list-&gt;didSelfPatching()) {
</ins><span class="cx">         repatchBuffer.relink(
</span><span class="cx">             stubInfo.callReturnLocation.jumpAtOffset(
</span><span class="cx">                 stubInfo.patch.deltaCallToJump),
</span><span class="lines">@@ -550,158 +520,6 @@
</span><span class="cx">     JSCell* baseCell = baseValue.asCell();
</span><span class="cx">     Structure* structure = baseCell-&gt;structure();
</span><span class="cx">     
</span><del>-    if (slot.slotBase() == baseValue) {
-        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())
-                return false;
-        }
-    
-        PolymorphicAccessStructureList* polymorphicStructureList;
-        int listIndex;
-        CodeLocationLabel slowCase;
-
-        if (!getPolymorphicStructureList(vm, codeBlock, stubInfo, polymorphicStructureList, listIndex, slowCase))
-            return false;
-        
-        stubInfo.u.getByIdSelfList.listSize++;
-        
-        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);
-        GPRReg scratchGPR = TempRegisterSet(stubInfo.patch.usedRegisters).getFreeGPR();
-        
-        CCallHelpers stubJit(vm, codeBlock);
-        
-        MacroAssembler::Jump wrongStruct = branchStructure(stubJit,
-            MacroAssembler::NotEqual, 
-            MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), 
-            structure);
-        
-        // The strategy we use for stubs is as follows:
-        // 1) Call DFG helper that calls the getter.
-        // 2) Check if there was an exception, and if there was, call yet another
-        //    helper.
-        
-        bool isDirect = false;
-        MacroAssembler::Call operationCall;
-        MacroAssembler::Call handlerCall;
-        FunctionPtr operationFunction;
-        MacroAssembler::Jump success;
-        
-        if (slot.isCacheableGetter() || slot.isCacheableCustom()) {
-            // FIXME: This code shouldn't be assuming that the top of stack is set up for JSC
-            // JIT-style C calls, since we may be currently on top of an FTL frame.
-            // https://bugs.webkit.org/show_bug.cgi?id=125711
-            
-            if (slot.isCacheableGetter()) {
-                ASSERT(scratchGPR != InvalidGPRReg);
-                ASSERT(baseGPR != scratchGPR);
-                if (isInlineOffset(slot.cachedOffset())) {
-#if USE(JSVALUE64)
-                    stubJit.load64(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset())), scratchGPR);
-#else
-                    stubJit.load32(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset())), scratchGPR);
-#endif
-                } else {
-                    stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR);
-#if USE(JSVALUE64)
-                    stubJit.load64(MacroAssembler::Address(scratchGPR, offsetRelativeToBase(slot.cachedOffset())), scratchGPR);
-#else
-                    stubJit.load32(MacroAssembler::Address(scratchGPR, offsetRelativeToBase(slot.cachedOffset())), scratchGPR);
-#endif
-                }
-                stubJit.setupArgumentsWithExecState(baseGPR, scratchGPR);
-                operationFunction = operationCallGetter;
-            } else {
-#if USE(JSVALUE64)
-                // EncodedJSValue (*GetValueFunc)(ExecState*, JSObject* slotBase, EncodedJSValue thisValue, PropertyName);
-                stubJit.setupArgumentsWithExecState(baseGPR, baseGPR, MacroAssembler::TrustedImmPtr(ident.impl()));
-#else
-                stubJit.setupArgumentsWithExecState(baseGPR, baseGPR, MacroAssembler::TrustedImm32(JSValue::CellTag), MacroAssembler::TrustedImmPtr(ident.impl()));
-#endif
-                operationFunction = FunctionPtr(slot.customGetter());
-            }
-            
-            // 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(exec-&gt;locationAsRawBits()),
-                CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(JSStack::ArgumentCount)));
-            stubJit.storePtr(GPRInfo::callFrameRegister, &amp;vm-&gt;topCallFrame);
-            
-            operationCall = stubJit.call();
-#if USE(JSVALUE64)
-            stubJit.move(GPRInfo::returnValueGPR, resultGPR);
-#else
-            stubJit.setupResults(resultGPR, resultTagGPR);
-#endif
-            success = stubJit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck);
-            
-            stubJit.setupArguments(CCallHelpers::TrustedImmPtr(vm), GPRInfo::callFrameRegister);
-            handlerCall = stubJit.call();
-            stubJit.jumpToExceptionHandler();
-        } else {
-            if (isInlineOffset(slot.cachedOffset())) {
-#if USE(JSVALUE64)
-                stubJit.load64(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset())), resultGPR);
-#else
-                if (baseGPR == resultTagGPR) {
-                    stubJit.load32(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
-                    stubJit.load32(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
-                } else {
-                    stubJit.load32(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
-                    stubJit.load32(MacroAssembler::Address(baseGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
-                }
-#endif
-            } else {
-                stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), resultGPR);
-#if USE(JSVALUE64)
-                stubJit.load64(MacroAssembler::Address(resultGPR, offsetRelativeToBase(slot.cachedOffset())), resultGPR);
-#else
-                stubJit.load32(MacroAssembler::Address(resultGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
-                stubJit.load32(MacroAssembler::Address(resultGPR, offsetRelativeToBase(slot.cachedOffset()) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultGPR);
-#endif
-            }
-            success = stubJit.jump();
-            isDirect = true;
-        }
-
-        LinkBuffer patchBuffer(*vm, &amp;stubJit, codeBlock);
-        
-        patchBuffer.link(wrongStruct, slowCase);
-        patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone));
-        if (!isDirect) {
-            patchBuffer.link(operationCall, operationFunction);
-            patchBuffer.link(handlerCall, lookupExceptionHandler);
-        }
-        
-        RefPtr&lt;JITStubRoutine&gt; stubRoutine =
-            createJITStubRoutine(
-                FINALIZE_CODE_FOR(
-                    exec-&gt;codeBlock(), patchBuffer,
-                    (&quot;GetById polymorphic list access for %s, return point %p&quot;,
-                        toCString(*exec-&gt;codeBlock()).data(), stubInfo.callReturnLocation.labelAtOffset(
-                            stubInfo.patch.deltaCallToDone).executableAddress())),
-                *vm,
-                codeBlock-&gt;ownerExecutable(),
-                slot.isCacheableGetter() || slot.isCacheableCustom());
-        
-        polymorphicStructureList-&gt;list[listIndex].set(*vm, codeBlock-&gt;ownerExecutable(), stubRoutine, structure, isDirect);
-        
-        patchJumpToGetByIdStub(codeBlock, stubInfo, stubRoutine.get());
-        return listIndex &lt; (POLYMORPHIC_LIST_CACHE_SIZE - 1);
-    }
-    
-    if (baseValue.asCell()-&gt;structure()-&gt;typeInfo().prohibitsPropertyCaching()
-        || baseValue.asCell()-&gt;structure()-&gt;isDictionary())
-        return false;
-    
</del><span class="cx">     if (stubInfo.patch.spillMode == NeedToSpill) {
</span><span class="cx">         // We cannot do as much inline caching if the registers were not flushed prior to this GetById. In particular,
</span><span class="cx">         // non-Value cached properties require planting calls, which requires registers to have been flushed. Thus,
</span><span class="lines">@@ -710,34 +528,42 @@
</span><span class="cx">             return false;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-
</del><span class="cx">     PropertyOffset offset = slot.cachedOffset();
</span><del>-    size_t count = normalizePrototypeChainForChainAccess(exec, baseValue, slot.slotBase(), ident, offset);
-    if (count == InvalidPrototypeChain)
-        return false;
-
-    StructureChain* prototypeChain = structure-&gt;prototypeChain(exec);
</del><ins>+    StructureChain* prototypeChain = 0;
+    size_t count = 0;
</ins><span class="cx">     
</span><del>-    PolymorphicAccessStructureList* polymorphicStructureList;
-    int listIndex;
-    CodeLocationLabel slowCase;
-    if (!getPolymorphicStructureList(vm, codeBlock, stubInfo, polymorphicStructureList, listIndex, slowCase))
</del><ins>+    if (slot.slotBase() != baseValue) {
+        if (baseValue.asCell()-&gt;structure()-&gt;typeInfo().prohibitsPropertyCaching()
+            || baseValue.asCell()-&gt;structure()-&gt;isDictionary())
+            return false;
+        
+        count = normalizePrototypeChainForChainAccess(
+            exec, baseValue, slot.slotBase(), ident, offset);
+        if (count == InvalidPrototypeChain)
+            return false;
+        prototypeChain = structure-&gt;prototypeChain(exec);
+    }
+    
+    PolymorphicGetByIdList* list = PolymorphicGetByIdList::from(stubInfo);
+    if (list-&gt;isFull()) {
+        // We need this extra check because of recursion.
</ins><span class="cx">         return false;
</span><ins>+    }
</ins><span class="cx">     
</span><del>-    stubInfo.u.getByIdProtoList.listSize++;
-    
</del><span class="cx">     RefPtr&lt;JITStubRoutine&gt; stubRoutine;
</span><del>-    
-    if (generateProtoChainAccessStub(exec, slot, ident, stubInfo, prototypeChain, count, offset, structure,
</del><ins>+    generateGetByIdStub(
+        exec, slot, ident, stubInfo, prototypeChain, count, offset, structure,
</ins><span class="cx">         stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToDone),
</span><del>-        slowCase, stubRoutine) == ProtoChainGenerationFailed)
-        return false;
</del><ins>+        CodeLocationLabel(list-&gt;currentSlowPathTarget(stubInfo)), stubRoutine);
</ins><span class="cx">     
</span><del>-    polymorphicStructureList-&gt;list[listIndex].set(*vm, codeBlock-&gt;ownerExecutable(), stubRoutine, structure, prototypeChain, slot.isCacheableValue(), count);
</del><ins>+    list-&gt;addAccess(GetByIdAccess(
+        *vm, codeBlock-&gt;ownerExecutable(),
+        slot.isCacheableValue() ? GetByIdAccess::SimpleStub : GetByIdAccess::Getter,
+        stubRoutine, structure, prototypeChain, count));
</ins><span class="cx">     
</span><span class="cx">     patchJumpToGetByIdStub(codeBlock, stubInfo, stubRoutine.get());
</span><span class="cx">     
</span><del>-    return listIndex &lt; (POLYMORPHIC_LIST_CACHE_SIZE - 1);
</del><ins>+    return !list-&gt;isFull();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void buildGetByIDList(ExecState* exec, JSValue baseValue, const Identifier&amp; propertyName, const PropertySlot&amp; slot, StructureStubInfo&amp; stubInfo)
</span><span class="lines">@@ -1263,9 +1089,11 @@
</span><span class="cx">             
</span><span class="cx">             StructureChain* prototypeChain = structure-&gt;prototypeChain(exec);
</span><span class="cx">             
</span><del>-            // We're now committed to creating the stub. Mogrify the meta-data accordingly.
</del><span class="cx">             list = PolymorphicPutByIdList::from(putKind, stubInfo);
</span><ins>+            if (list-&gt;isFull())
+                return false; // Will get here due to recursion.
</ins><span class="cx">             
</span><ins>+            // We're now committed to creating the stub. Mogrify the meta-data accordingly.
</ins><span class="cx">             emitPutTransitionStub(
</span><span class="cx">                 exec, baseValue, propertyName, slot, stubInfo, putKind,
</span><span class="cx">                 structure, oldStructure, prototypeChain,
</span><span class="lines">@@ -1278,9 +1106,11 @@
</span><span class="cx">                     oldStructure, structure, prototypeChain,
</span><span class="cx">                     stubRoutine));
</span><span class="cx">         } else {
</span><del>-            // We're now committed to creating the stub. Mogrify the meta-data accordingly.
</del><span class="cx">             list = PolymorphicPutByIdList::from(putKind, stubInfo);
</span><ins>+            if (list-&gt;isFull())
+                return false; // Will get here due to recursion.
</ins><span class="cx">             
</span><ins>+            // We're now committed to creating the stub. Mogrify the meta-data accordingly.
</ins><span class="cx">             emitPutReplaceStub(
</span><span class="cx">                 exec, baseValue, propertyName, slot, stubInfo, putKind,
</span><span class="cx">                 structure, CodeLocationLabel(list-&gt;currentSlowPathTarget()), stubRoutine);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressgetterjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/getter.js (0 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/getter.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/getter.js        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+function foo(o) {
+    return o.f + o.k * 1000;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100; ++i) {
+    var o = {g_: 5};
+    o.__defineGetter__(&quot;f&quot;, function() { return 42 + this.g_; });
+    o.__defineGetter__(&quot;g&quot;, function() { return 43 + this.g_; });
+    o.__defineGetter__(&quot;h&quot;, function() { return 44 + this.g_; });
+    o.__defineGetter__(&quot;i&quot;, function() { return 45 + this.g_; });
+    o.__defineGetter__(&quot;j&quot;, function() { return 46 + this.g_; });
+    o.__defineGetter__(&quot;k&quot;, function() { return 47 + this.g_; });
+    var result = foo(o);
+    if (result != (42 + 5) + 1000 * (47 + 5))
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresspolymorphicprototypeaccessesjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/polymorphic-prototype-accesses.js (0 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/polymorphic-prototype-accesses.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/polymorphic-prototype-accesses.js        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+function Foo() {
+}
+Foo.prototype.f = 42;
+Foo.prototype.g = 43;
+Foo.prototype.h = 44;
+Foo.prototype.i = 45;
+Foo.prototype.j = 46;
+Foo.prototype.k = 47;
+
+function Bar() {
+}
+Bar.prototype.k = 23;
+Bar.prototype.f = 24;
+
+function foo(o) {
+    return o.f + o.k;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100; ++i) {
+    var result = foo(new Foo());
+    if (result != 89)
+        throw &quot;Error: bad result for Foo: &quot; + result;
+    result = foo(new Bar());
+    if (result != 47)
+        throw &quot;Error: bad result for Bar: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressprototypegetterjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/prototype-getter.js (0 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/prototype-getter.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/prototype-getter.js        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+function Foo(g) {
+    this.g_ = g;
+}
+Foo.prototype.__defineGetter__(&quot;f&quot;, function() { return this.g_ + 32; });
+Foo.prototype.__defineGetter__(&quot;g&quot;, function() { return this.g_ + 33; });
+Foo.prototype.__defineGetter__(&quot;h&quot;, function() { return this.g_ + 34; });
+Foo.prototype.__defineGetter__(&quot;i&quot;, function() { return this.g_ + 35; });
+Foo.prototype.__defineGetter__(&quot;j&quot;, function() { return this.g_ + 36; });
+Foo.prototype.__defineGetter__(&quot;k&quot;, function() { return this.g_ + 37; });
+
+function foo(o) {
+    return o.f + o.k * 1000;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100; ++i) {
+    var result = foo(new Foo(5));
+    if (result != (32 + 5) + (37 + 5) * 1000)
+        throw &quot;Error: bad result: &quot; + result;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresssimpleprototypeaccessesjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/simple-prototype-accesses.js (0 => 165459)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/simple-prototype-accesses.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/simple-prototype-accesses.js        2014-03-12 03:42:42 UTC (rev 165459)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+function Foo() {
+}
+Foo.prototype.f = 42;
+Foo.prototype.g = 43;
+Foo.prototype.h = 44;
+Foo.prototype.i = 45;
+Foo.prototype.j = 46;
+Foo.prototype.k = 47;
+
+function foo(o) {
+    return o.f + o.k;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100; ++i) {
+    var result = foo(new Foo());
+    if (result != 89)
+        throw &quot;Error: bad result for Foo: &quot; + result;
+}
</ins></span></pre>
</div>
</div>

</body>
</html>