<!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>[201363] trunk/Source</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/201363">201363</a></dd>
<dt>Author</dt> <dd>keith_miller@apple.com</dd>
<dt>Date</dt> <dd>2016-05-24 16:49:57 -0700 (Tue, 24 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>LLInt should be able to cache prototype loads for values in GetById
https://bugs.webkit.org/show_bug.cgi?id=158032

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

This patch adds prototype value caching to the LLInt for op_get_by_id.
Two previously unused words in the op_get_by_id bytecode have been
repurposed to hold extra information for the cache. The first is a
counter that records the number of get_by_ids that hit a cacheable value
on a prototype. When the counter is decremented from one to zero we
attempt to cache the prototype load, which will be discussed further
below. The second word is used to hold the prototype object when we have
started caching.

When the counter is decremented to zero we first attempt to generate and
watch the property conditions needed to ensure the validity of prototype
load. If the watchpoints are successfully created and installed we
replace the op_get_by_id opcode with the new op_get_by_id_proto_load
opcode, which tells the LLInt to use the cache prototype object for the
load rather than the base value.

Prior to this patch there was not LLInt specific data onCodeBlocks.
Since the CodeBlock needs to own the Watchpoints for the cache, a weak
map from each base structure to a bag of Watchpoints created for that
structure by some op_get_by_id has been added to the CodeBlock. During
GC, if we find that the a structure in the map has not been marked we
free the associated bag on the CodeBlock.

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::printGetByIdOp):
(JSC::CodeBlock::printGetByIdCacheStatus):
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::finalizeLLIntInlineCaches):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::llintGetByIdWatchpointMap):
(JSC::clearLLIntGetByIdCache):
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeFromLLInt):
* bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp: Added.
(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint):
(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::install):
(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal):
* bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h: Added.
* bytecode/ObjectPropertyConditionSet.cpp:
(JSC::ObjectPropertyConditionSet::isValidAndWatchable):
* bytecode/ObjectPropertyConditionSet.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitGetById):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setupGetByIdPrototypeCache):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/Options.h:
* tests/stress/llint-get-by-id-cache-prototype-load-from-dictionary.js: Added.
(test):

Source/WTF:

Add move constructors/initializers to Bags.

* wtf/Bag.h:
(WTF::Bag::Bag):
(WTF::Bag::operator=):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeListjson">trunk/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefh">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.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="#trunkSourceJavaScriptCorebytecodeObjectPropertyConditionSetcpp">trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeObjectPropertyConditionSeth">trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathsh">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</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="#trunkSourceWTFwtfBagh">trunk/Source/WTF/wtf/Bag.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorebytecodeLLIntPrototypeLoadAdaptiveStructureWatchpointcpp">trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeLLIntPrototypeLoadAdaptiveStructureWatchpointh">trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressllintgetbyidcacheprototypeloadfromdictionaryjs">trunk/Source/JavaScriptCore/tests/stress/llint-get-by-id-cache-prototype-load-from-dictionary.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 (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -202,6 +202,7 @@
</span><span class="cx">     bytecode/InlineCallFrame.cpp
</span><span class="cx">     bytecode/InlineCallFrameSet.cpp
</span><span class="cx">     bytecode/JumpTable.cpp
</span><ins>+    bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp
</ins><span class="cx">     bytecode/LazyOperandValueProfile.cpp
</span><span class="cx">     bytecode/MethodOfGettingAValueProfile.cpp
</span><span class="cx">     bytecode/ObjectPropertyCondition.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -1,5 +1,77 @@
</span><span class="cx"> 2016-05-24  Keith Miller  &lt;keith_miller@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        LLInt should be able to cache prototype loads for values in GetById
+        https://bugs.webkit.org/show_bug.cgi?id=158032
+
+        Reviewed by Filip Pizlo.
+
+        This patch adds prototype value caching to the LLInt for op_get_by_id.
+        Two previously unused words in the op_get_by_id bytecode have been
+        repurposed to hold extra information for the cache. The first is a
+        counter that records the number of get_by_ids that hit a cacheable value
+        on a prototype. When the counter is decremented from one to zero we
+        attempt to cache the prototype load, which will be discussed further
+        below. The second word is used to hold the prototype object when we have
+        started caching.
+
+        When the counter is decremented to zero we first attempt to generate and
+        watch the property conditions needed to ensure the validity of prototype
+        load. If the watchpoints are successfully created and installed we
+        replace the op_get_by_id opcode with the new op_get_by_id_proto_load
+        opcode, which tells the LLInt to use the cache prototype object for the
+        load rather than the base value.
+
+        Prior to this patch there was not LLInt specific data onCodeBlocks.
+        Since the CodeBlock needs to own the Watchpoints for the cache, a weak
+        map from each base structure to a bag of Watchpoints created for that
+        structure by some op_get_by_id has been added to the CodeBlock. During
+        GC, if we find that the a structure in the map has not been marked we
+        free the associated bag on the CodeBlock.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::printGetByIdOp):
+        (JSC::CodeBlock::printGetByIdCacheStatus):
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::finalizeLLIntInlineCaches):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::llintGetByIdWatchpointMap):
+        (JSC::clearLLIntGetByIdCache):
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeFromLLInt):
+        * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp: Added.
+        (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint):
+        (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::install):
+        (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal):
+        * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h: Added.
+        * bytecode/ObjectPropertyConditionSet.cpp:
+        (JSC::ObjectPropertyConditionSet::isValidAndWatchable):
+        * bytecode/ObjectPropertyConditionSet.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetById):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::setupGetByIdPrototypeCache):
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/Options.h:
+        * tests/stress/llint-get-by-id-cache-prototype-load-from-dictionary.js: Added.
+        (test):
+
+2016-05-24  Keith Miller  &lt;keith_miller@apple.com&gt;
+
</ins><span class="cx">         We should be able to use the sampling profiler with DRT/WTR.
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=158041
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -1181,6 +1181,8 @@
</span><span class="cx">                 5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
</span><span class="cx">                 53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
</span><span class="cx">                 53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                53FA2AE11CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                53FA2AE31CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */; };
</ins><span class="cx">                 5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
</span><span class="cx">                 5DBB151B131D0B310056AD36 /* testapi.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 14D857740A4696C80032146C /* testapi.js */; };
</span><span class="cx">                 5DBB1525131D0BD70056AD36 /* minidom.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 1412110D0A48788700480255 /* minidom.js */; };
</span><span class="lines">@@ -3321,6 +3323,8 @@
</span><span class="cx">                 53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
</span><span class="cx">                 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = &quot;compiled.mach-o.dylib&quot;; name = libedit.dylib; path = /usr/lib/libedit.dylib; sourceTree = &quot;&lt;absolute&gt;&quot;; };
</span><span class="cx">                 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = JSC.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -6575,6 +6579,8 @@
</span><span class="cx">                                 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */,
</span><span class="cx">                                 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */,
</span><span class="cx">                                 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */,
</span><ins>+                                53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */,
+                                53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */,
</ins><span class="cx">                                 0FB5467C14F5CFD3002C2989 /* MethodOfGettingAValueProfile.cpp */,
</span><span class="cx">                                 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */,
</span><span class="cx">                                 14CA958C16AB50FA00938A06 /* ObjectAllocationProfile.h */,
</span><span class="lines">@@ -7910,6 +7916,7 @@
</span><span class="cx">                                 0FF7168C15A3B235008F5DAA /* PropertyOffset.h in Headers */,
</span><span class="cx">                                 BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */,
</span><span class="cx">                                 0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */,
</span><ins>+                                53FA2AE11CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h in Headers */,
</ins><span class="cx">                                 BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
</span><span class="cx">                                 1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */,
</span><span class="cx">                                 0F5780A218FE1E98001E72D9 /* PureNaN.h in Headers */,
</span><span class="lines">@@ -8635,6 +8642,7 @@
</span><span class="cx">                                 65C02850171795E200351E35 /* ARMv7Disassembler.cpp in Sources */,
</span><span class="cx">                                 65C0285C1717966800351E35 /* ARMv7DOpcode.cpp in Sources */,
</span><span class="cx">                                 0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */,
</span><ins>+                                53FA2AE31CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp in Sources */,
</ins><span class="cx">                                 A7A8AF3417ADB5F3005AB174 /* ArrayBuffer.cpp in Sources */,
</span><span class="cx">                                 0FFC99D4184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp in Sources */,
</span><span class="cx">                                 A7A8AF3617ADB5F3005AB174 /* ArrayBufferView.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -58,11 +58,12 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_is_object_or_null&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_is_function&quot;, &quot;length&quot; : 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_in&quot;, &quot;length&quot; : 4 },
</span><del>-            { &quot;name&quot; : &quot;op_try_get_by_id&quot;, &quot;length&quot; : 4 },
</del><ins>+            { &quot;name&quot; : &quot;op_get_array_length&quot;, &quot;length&quot; : 9 },
</ins><span class="cx">             { &quot;name&quot; : &quot;op_get_by_id&quot;, &quot;length&quot; : 9  },
</span><ins>+            { &quot;name&quot; : &quot;op_get_by_id_proto_load&quot;, &quot;length&quot; : 9 },
</ins><span class="cx">             { &quot;name&quot; : &quot;op_get_by_id_with_this&quot;, &quot;length&quot; : 5 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_get_by_val_with_this&quot;, &quot;length&quot; : 5 },
</span><del>-            { &quot;name&quot; : &quot;op_get_array_length&quot;, &quot;length&quot; : 9 },
</del><ins>+            { &quot;name&quot; : &quot;op_try_get_by_id&quot;, &quot;length&quot; : 4 },
</ins><span class="cx">             { &quot;name&quot; : &quot;op_put_by_id&quot;, &quot;length&quot; : 9 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_put_by_id_with_this&quot;, &quot;length&quot; : 5 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_del_by_id&quot;, &quot;length&quot; : 4 },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -158,6 +158,7 @@
</span><span class="cx">     case op_to_primitive:
</span><span class="cx">     case op_try_get_by_id:
</span><span class="cx">     case op_get_by_id:
</span><ins>+    case op_get_by_id_proto_load:
</ins><span class="cx">     case op_get_array_length:
</span><span class="cx">     case op_typeof:
</span><span class="cx">     case op_is_empty:
</span><span class="lines">@@ -392,6 +393,7 @@
</span><span class="cx">     case op_construct:
</span><span class="cx">     case op_try_get_by_id:
</span><span class="cx">     case op_get_by_id:
</span><ins>+    case op_get_by_id_proto_load:
</ins><span class="cx">     case op_get_by_id_with_this:
</span><span class="cx">     case op_get_by_val_with_this:
</span><span class="cx">     case op_get_array_length:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx"> #include &quot;JSLexicalEnvironment.h&quot;
</span><span class="cx"> #include &quot;JSModuleEnvironment.h&quot;
</span><span class="cx"> #include &quot;LLIntEntrypoint.h&quot;
</span><ins>+#include &quot;LLIntPrototypeLoadAdaptiveStructureWatchpoint.h&quot;
</ins><span class="cx"> #include &quot;LowLevelInterpreter.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;PCToCodeOriginMap.h&quot;
</span><span class="lines">@@ -345,6 +346,9 @@
</span><span class="cx">     case op_get_by_id:
</span><span class="cx">         op = &quot;get_by_id&quot;;
</span><span class="cx">         break;
</span><ins>+    case op_get_by_id_proto_load:
+        op = &quot;get_by_id_proto_load&quot;;
+        break;
</ins><span class="cx">     case op_get_array_length:
</span><span class="cx">         op = &quot;array_length&quot;;
</span><span class="cx">         break;
</span><span class="lines">@@ -405,6 +409,8 @@
</span><span class="cx">         out.printf(&quot; llint(&quot;);
</span><span class="cx">         dumpStructure(out, &quot;struct&quot;, structure, ident);
</span><span class="cx">         out.printf(&quot;)&quot;);
</span><ins>+        if (exec-&gt;interpreter()-&gt;getOpcodeID(instruction[0].u.opcode) == op_get_by_id_proto_load)
+            out.printf(&quot; proto(%p)&quot;, instruction[6].u.pointer);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="lines">@@ -1112,6 +1118,7 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case op_get_by_id:
</span><ins>+        case op_get_by_id_proto_load:
</ins><span class="cx">         case op_get_array_length: {
</span><span class="cx">             printGetByIdOp(out, exec, location, it);
</span><span class="cx">             printGetByIdCacheStatus(out, exec, location, stubInfos);
</span><span class="lines">@@ -2798,14 +2805,14 @@
</span><span class="cx">     for (size_t size = propertyAccessInstructions.size(), i = 0; i &lt; size; ++i) {
</span><span class="cx">         Instruction* curInstruction = &amp;instructions()[propertyAccessInstructions[i]];
</span><span class="cx">         switch (interpreter-&gt;getOpcodeID(curInstruction[0].u.opcode)) {
</span><del>-        case op_get_by_id: {
</del><ins>+        case op_get_by_id:
+        case op_get_by_id_proto_load: {
</ins><span class="cx">             StructureID oldStructureID = curInstruction[4].u.structureID;
</span><span class="cx">             if (!oldStructureID || Heap::isMarked(m_vm-&gt;heap.structureIDTable().get(oldStructureID)))
</span><span class="cx">                 break;
</span><span class="cx">             if (Options::verboseOSR())
</span><span class="cx">                 dataLogF(&quot;Clearing LLInt property access.\n&quot;);
</span><del>-            curInstruction[4].u.structureID = 0;
-            curInstruction[5].u.operand = 0;
</del><ins>+            clearLLIntGetByIdCache(curInstruction);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case op_put_by_id: {
</span><span class="lines">@@ -2879,6 +2886,12 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // We can't just remove all the sets when we clear the caches since we might have created a watchpoint set
+    // then cleared the cache without GCing in between.
+    m_llintGetByIdWatchpointMap.removeIf([](const StructureWatchpointMap::KeyValuePairType&amp; pair) -&gt; bool {
+        return !Heap::isMarked(pair.key);
+    });
+
</ins><span class="cx">     for (unsigned i = 0; i &lt; m_llintCallLinkInfos.size(); ++i) {
</span><span class="cx">         if (m_llintCallLinkInfos[i].isLinked() &amp;&amp; !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
</span><span class="cx">             if (Options::verboseOSR())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.h (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.h        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -56,6 +56,7 @@
</span><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="cx"> #include &quot;JumpTable.h&quot;
</span><span class="cx"> #include &quot;LLIntCallLinkInfo.h&quot;
</span><ins>+#include &quot;LLIntPrototypeLoadAdaptiveStructureWatchpoint.h&quot;
</ins><span class="cx"> #include &quot;LazyOperandValueProfile.h&quot;
</span><span class="cx"> #include &quot;ObjectAllocationProfile.h&quot;
</span><span class="cx"> #include &quot;Options.h&quot;
</span><span class="lines">@@ -678,6 +679,9 @@
</span><span class="cx">         return m_llintExecuteCounter;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    typedef HashMap&lt;Structure*, Bag&lt;LLIntPrototypeLoadAdaptiveStructureWatchpoint&gt;&gt; StructureWatchpointMap;
+    StructureWatchpointMap&amp; llintGetByIdWatchpointMap() { return m_llintGetByIdWatchpointMap; }
+
</ins><span class="cx">     // Functions for controlling when tiered compilation kicks in. This
</span><span class="cx">     // controls both when the optimizing compiler is invoked and when OSR
</span><span class="cx">     // entry happens. Two triggers exist: the loop trigger and the return
</span><span class="lines">@@ -1019,6 +1023,7 @@
</span><span class="cx"> 
</span><span class="cx">     RefCountedArray&lt;LLIntCallLinkInfo&gt; m_llintCallLinkInfos;
</span><span class="cx">     SentinelLinkedList&lt;LLIntCallLinkInfo, BasicRawSentinelNode&lt;LLIntCallLinkInfo&gt;&gt; m_incomingLLIntCalls;
</span><ins>+    StructureWatchpointMap m_llintGetByIdWatchpointMap;
</ins><span class="cx">     RefPtr&lt;JITCode&gt; m_jitCode;
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx">     std::unique_ptr&lt;RegisterAtOffsetList&gt; m_calleeSaveRegisters;
</span><span class="lines">@@ -1309,6 +1314,14 @@
</span><span class="cx"> };
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+inline void clearLLIntGetByIdCache(Instruction* instruction)
+{
+    instruction[0].u.opcode = LLInt::getOpcode(op_get_by_id);
+    instruction[4].u.pointer = nullptr;
+    instruction[5].u.pointer = nullptr;
+    instruction[6].u.pointer = nullptr;
+}
+
</ins><span class="cx"> inline Register&amp; ExecState::r(int index)
</span><span class="cx"> {
</span><span class="cx">     CodeBlock* codeBlock = this-&gt;codeBlock();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -75,8 +75,12 @@
</span><span class="cx">     VM&amp; vm = *profiledBlock-&gt;vm();
</span><span class="cx">     
</span><span class="cx">     Instruction* instruction = profiledBlock-&gt;instructions().begin() + bytecodeIndex;
</span><del>-    
-    if (instruction[0].u.opcode == LLInt::getOpcode(op_get_array_length) || instruction[0].u.opcode == LLInt::getOpcode(op_try_get_by_id))
</del><ins>+
+    Opcode opcode = instruction[0].u.opcode;
+
+    // FIXME: We should not just bail if we see a try_get_by_id or a get_by_id_proto_load.
+    // https://bugs.webkit.org/show_bug.cgi?id=158039
+    if (opcode == LLInt::getOpcode(op_get_array_length) || opcode == LLInt::getOpcode(op_try_get_by_id) || opcode == LLInt::getOpcode(op_get_by_id_proto_load))
</ins><span class="cx">         return GetByIdStatus(NoInformation, false);
</span><span class="cx"> 
</span><span class="cx">     StructureID structureID = instruction[4].u.structureID;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeLLIntPrototypeLoadAdaptiveStructureWatchpointcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp (0 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;LLIntPrototypeLoadAdaptiveStructureWatchpoint.h&quot;
+
+#include &quot;CodeBlock.h&quot;
+#include &quot;Instruction.h&quot;
+#include &quot;StructureInlines.h&quot;
+
+namespace JSC {
+
+LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint(const ObjectPropertyCondition&amp; key, Instruction* getByIdInstruction)
+    : m_key(key)
+    , m_getByIdInstruction(getByIdInstruction)
+{
+    RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());
+    RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
+}
+
+void LLIntPrototypeLoadAdaptiveStructureWatchpoint::install()
+{
+    RELEASE_ASSERT(m_key.isWatchable());
+
+    m_key.object()-&gt;structure()-&gt;addTransitionWatchpoint(this);
+}
+
+void LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal(const FireDetail&amp; detail)
+{
+    if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
+        install();
+        return;
+    }
+
+    StringPrintStream out;
+    out.print(&quot;ObjectToStringValue Adaptation of &quot;, m_key, &quot; failed: &quot;, detail);
+
+    StringFireDetail stringDetail(out.toCString().data());
+
+    clearLLIntGetByIdCache(m_getByIdInstruction);
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeLLIntPrototypeLoadAdaptiveStructureWatchpointh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h (0 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LLIntPrototypeLoadAdaptiveStructureWatchpoint_h
+#define LLIntPrototypeLoadAdaptiveStructureWatchpoint_h
+
+#include &quot;Instruction.h&quot;
+#include &quot;ObjectPropertyCondition.h&quot;
+#include &quot;Watchpoint.h&quot;
+
+namespace JSC {
+
+class LLIntPrototypeLoadAdaptiveStructureWatchpoint : public Watchpoint {
+public:
+    LLIntPrototypeLoadAdaptiveStructureWatchpoint(const ObjectPropertyCondition&amp;, Instruction*);
+
+    void install();
+
+protected:
+    void fireInternal(const FireDetail&amp;) override;
+
+private:
+    ObjectPropertyCondition m_key;
+    Instruction* m_getByIdInstruction;
+};
+
+} // namespace JSC
+
+#endif /* LLIntPrototypeLoadAdaptiveStructureWatchpoint_h */
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeObjectPropertyConditionSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -167,6 +167,18 @@
</span><span class="cx">     dumpInContext(out, nullptr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool ObjectPropertyConditionSet::isValidAndWatchable() const
+{
+    if (!isValid())
+        return false;
+
+    for (ObjectPropertyCondition condition : m_data-&gt;vector) {
+        if (!condition.isWatchable())
+            return false;
+    }
+    return true;
+}
+
</ins><span class="cx"> namespace {
</span><span class="cx"> 
</span><span class="cx"> bool verbose = false;
</span><span class="lines">@@ -254,9 +266,11 @@
</span><span class="cx">         // Since we're accessing a prototype repeatedly, it's a good bet that it should not be
</span><span class="cx">         // treated as a dictionary.
</span><span class="cx">         if (structure-&gt;isDictionary()) {
</span><del>-            if (concurrency == MainThread)
</del><ins>+            if (concurrency == MainThread) {
+                if (verbose)
+                    dataLog(&quot;Flattening &quot;, pointerDump(structure));
</ins><span class="cx">                 structure-&gt;flattenDictionaryStructure(vm, object);
</span><del>-            else {
</del><ins>+            } else {
</ins><span class="cx">                 if (verbose)
</span><span class="cx">                     dataLog(&quot;Cannot flatten dictionary when not on main thread, so invalid.\n&quot;);
</span><span class="cx">                 return ObjectPropertyConditionSet::invalid();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeObjectPropertyConditionSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -67,6 +67,8 @@
</span><span class="cx">     {
</span><span class="cx">         return !m_data || !m_data-&gt;vector.isEmpty();
</span><span class="cx">     }
</span><ins>+
+    bool isValidAndWatchable() const;
</ins><span class="cx">     
</span><span class="cx">     bool isEmpty() const
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -2431,7 +2431,7 @@
</span><span class="cx">     instructions().append(0);
</span><span class="cx">     instructions().append(0);
</span><span class="cx">     instructions().append(0);
</span><del>-    instructions().append(0);
</del><ins>+    instructions().append(Options::prototypeHitCountForLLIntCaching());
</ins><span class="cx">     instructions().append(profile);
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -4081,6 +4081,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case op_get_by_id:
</span><ins>+        case op_get_by_id_proto_load:
</ins><span class="cx">         case op_get_array_length: {
</span><span class="cx">             SpeculatedType prediction = getPrediction();
</span><span class="cx">             
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -154,6 +154,7 @@
</span><span class="cx">     case op_put_by_val_direct:
</span><span class="cx">     case op_try_get_by_id:
</span><span class="cx">     case op_get_by_id:
</span><ins>+    case op_get_by_id_proto_load:
</ins><span class="cx">     case op_get_by_id_with_this:
</span><span class="cx">     case op_get_by_val_with_this:
</span><span class="cx">     case op_get_array_length:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -240,6 +240,7 @@
</span><span class="cx">         DEFINE_OP(op_eq_null)
</span><span class="cx">         DEFINE_OP(op_try_get_by_id)
</span><span class="cx">         case op_get_array_length:
</span><ins>+        case op_get_by_id_proto_load:
</ins><span class="cx">         DEFINE_OP(op_get_by_id)
</span><span class="cx">         DEFINE_OP(op_get_by_id_with_this)
</span><span class="cx">         DEFINE_OP(op_get_by_val)
</span><span class="lines">@@ -422,6 +423,7 @@
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_eq)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_try_get_by_id)
</span><span class="cx">         case op_get_array_length:
</span><ins>+        case op_get_by_id_proto_load:
</ins><span class="cx">         DEFINE_SLOWCASE_OP(op_get_by_id)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_get_by_val)
</span><span class="cx">         DEFINE_SLOWCASE_OP(op_instanceof)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -52,6 +52,7 @@
</span><span class="cx"> #include &quot;LLIntExceptions.h&quot;
</span><span class="cx"> #include &quot;LowLevelInterpreter.h&quot;
</span><span class="cx"> #include &quot;ObjectConstructor.h&quot;
</span><ins>+#include &quot;ObjectPropertyConditionSet.h&quot;
</ins><span class="cx"> #include &quot;ProtoCallFrame.h&quot;
</span><span class="cx"> #include &quot;ShadowChicken.h&quot;
</span><span class="cx"> #include &quot;StructureRareDataInlines.h&quot;
</span><span class="lines">@@ -580,6 +581,43 @@
</span><span class="cx">     LLINT_RETURN(slot.getPureResult());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void setupGetByIdPrototypeCache(ExecState* exec, VM&amp; vm, Instruction* pc, JSCell* baseCell, PropertySlot&amp; slot, const Identifier&amp; ident)
+{
+    CodeBlock* codeBlock = exec-&gt;codeBlock();
+    Structure* structure = baseCell-&gt;structure();
+
+    if (structure-&gt;typeInfo().prohibitsPropertyCaching() || structure-&gt;isDictionary())
+        return;
+
+    ObjectPropertyConditionSet conditions = generateConditionsForPrototypePropertyHit(vm, codeBlock, exec, structure, slot.slotBase(), ident.impl());
+
+    if (!conditions.isValid())
+        return;
+
+    PropertyOffset offset = invalidOffset;
+    CodeBlock::StructureWatchpointMap&amp; watchpointMap = codeBlock-&gt;llintGetByIdWatchpointMap();
+    auto result = watchpointMap.add(structure, Bag&lt;LLIntPrototypeLoadAdaptiveStructureWatchpoint&gt;());
+    for (ObjectPropertyCondition condition : conditions) {
+        if (!condition.isWatchable())
+            return;
+        if (condition.condition().kind() == PropertyCondition::Presence)
+            offset = condition.condition().offset();
+        result.iterator-&gt;value.add(condition, pc)-&gt;install();
+    }
+    ASSERT(offset != invalidOffset);
+
+    ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
+
+    pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_proto_load);
+    pc[4].u.structureID = structure-&gt;id();
+    pc[5].u.operand = offset;
+    // We know that this pointer will remain valid because it is the prototype of some structure, s,
+    // watchpointed above. If any object with structure s were to change prototypes then the conditions
+    // for this cache would fail and this value will never be used again.
+    pc[6].u.pointer = slot.slotBase();
+}
+
+
</ins><span class="cx"> LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
</span><span class="cx"> {
</span><span class="cx">     LLINT_BEGIN();
</span><span class="lines">@@ -594,37 +632,43 @@
</span><span class="cx">     
</span><span class="cx">     if (!LLINT_ALWAYS_ACCESS_SLOW
</span><span class="cx">         &amp;&amp; baseValue.isCell()
</span><del>-        &amp;&amp; slot.isCacheable()
-        &amp;&amp; slot.slotBase() == baseValue
</del><span class="cx">         &amp;&amp; slot.isCacheableValue()) {
</span><del>-        
</del><ins>+
</ins><span class="cx">         JSCell* baseCell = baseValue.asCell();
</span><span class="cx">         Structure* structure = baseCell-&gt;structure();
</span><ins>+        if (slot.slotBase() == baseValue) {
+            // Start out by clearing out the old cache.
+            pc[0].u.opcode = LLInt::getOpcode(op_get_by_id);
+            pc[4].u.pointer = nullptr; // old structure
+            pc[5].u.pointer = nullptr; // offset
+
+            // Prevent the prototype cache from ever happening.
+            pc[7].u.operand = 0;
</ins><span class="cx">         
</span><del>-        // Start out by clearing out the old cache.
-        pc[0].u.opcode = LLInt::getOpcode(op_get_by_id);
-        pc[4].u.pointer = nullptr; // old structure
-        pc[5].u.pointer = nullptr; // offset
-        
-        if (!structure-&gt;isUncacheableDictionary()
-            &amp;&amp; !structure-&gt;typeInfo().prohibitsPropertyCaching()
-            &amp;&amp; !structure-&gt;typeInfo().newImpurePropertyFiresWatchpoints()) {
-            vm.heap.writeBarrier(codeBlock);
-            
-            ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
</del><ins>+            if (structure-&gt;propertyAccessesAreCacheable()) {
+                vm.heap.writeBarrier(codeBlock);
+                
+                ConcurrentJITLocker locker(codeBlock-&gt;m_lock);
</ins><span class="cx"> 
</span><del>-            pc[4].u.structureID = structure-&gt;id();
-            pc[5].u.operand = slot.cachedOffset();
</del><ins>+                pc[4].u.structureID = structure-&gt;id();
+                pc[5].u.operand = slot.cachedOffset();
+            }
+        } else if (UNLIKELY(pc[7].u.operand)) {
+            ASSERT(slot.slotBase() != baseValue);
+
+            if (!(--pc[7].u.operand))
+                setupGetByIdPrototypeCache(exec, vm, pc, baseCell, slot, ident);
</ins><span class="cx">         }
</span><del>-    }
-
-    if (!LLINT_ALWAYS_ACCESS_SLOW
</del><ins>+    } else if (!LLINT_ALWAYS_ACCESS_SLOW
</ins><span class="cx">         &amp;&amp; isJSArray(baseValue)
</span><span class="cx">         &amp;&amp; ident == exec-&gt;propertyNames().length) {
</span><span class="cx">         pc[0].u.opcode = LLInt::getOpcode(op_get_array_length);
</span><span class="cx">         ArrayProfile* arrayProfile = codeBlock-&gt;getOrAddArrayProfile(pc - codeBlock-&gt;instructions().begin());
</span><span class="cx">         arrayProfile-&gt;observeStructure(baseValue.asCell()-&gt;structure());
</span><span class="cx">         pc[4].u.arrayProfile = arrayProfile;
</span><ins>+
+        // Prevent the prototype cache from ever happening.
+        pc[7].u.operand = 0;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile-&gt;m_buckets[0] = JSValue::encode(result);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -71,6 +71,7 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_instanceof_custom);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_try_get_by_id);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id);
</span><ins>+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id_proto_load);
</ins><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_arguments_length);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_id);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_del_by_id);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -1334,10 +1334,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> # We only do monomorphic get_by_id caching for now, and we do not modify the
</span><del>-# opcode. We do, however, allow for the cache to change anytime if fails, since
-# ping-ponging is free. At best we get lucky and the get_by_id will continue
</del><ins>+# opcode for own properties. We also allow for the cache to change anytime it fails,
+# since ping-ponging is free. At best we get lucky and the get_by_id will continue
</ins><span class="cx"> # to take fast path on the new cache. At worst we take slow path, which is what
</span><del>-# we would have been doing anyway.
</del><ins>+# we would have been doing anyway. For prototype properties, we will attempt to
+# convert opcode into a get_by_id_proto_load after a execution counter hits zero.
</ins><span class="cx"> 
</span><span class="cx"> _llint_op_get_by_id:
</span><span class="cx">     traceExecution()
</span><span class="lines">@@ -1358,6 +1359,27 @@
</span><span class="cx">     dispatch(9)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
+_llint_op_get_by_id_proto_load:
+    traceExecution()
+    loadi 8[PC], t0
+    loadi 16[PC], t1
+    loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdProtoSlow)
+    loadi 20[PC], t2
+    bineq JSCell::m_structureID[t3], t1, .opGetByIdProtoSlow
+    loadpFromInstruction(6, t3)
+    loadPropertyAtVariableOffset(t2, t3, t0, t1)
+    loadi 4[PC], t2
+    storei t0, TagOffset[cfr, t2, 8]
+    storei t1, PayloadOffset[cfr, t2, 8]
+    valueProfile(t0, t1, 32, t2)
+    dispatch(9)
+
+.opGetByIdProtoSlow:
+    callSlowPath(_llint_slow_path_get_by_id)
+    dispatch(9)
+
+
</ins><span class="cx"> _llint_op_get_array_length:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadi 8[PC], t0
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -1232,6 +1232,26 @@
</span><span class="cx">     dispatch(9)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+_llint_op_get_by_id_proto_load:
+    traceExecution()
+    loadisFromInstruction(2, t0)
+    loadConstantOrVariableCell(t0, t3, .opGetByIdProtoSlow)
+    loadi JSCell::m_structureID[t3], t1
+    loadisFromInstruction(4, t2)
+    bineq t2, t1, .opGetByIdProtoSlow
+    loadisFromInstruction(5, t1)
+    loadpFromInstruction(6, t3)
+    loadisFromInstruction(1, t2)
+    loadPropertyAtVariableOffset(t1, t3, t0)
+    storeq t0, [cfr, t2, 8]
+    valueProfile(t0, 8, t1)
+    dispatch(9)
+
+.opGetByIdProtoSlow:
+    callSlowPath(_llint_slow_path_get_by_id)
+    dispatch(9)
+
+
</ins><span class="cx"> _llint_op_get_array_length:
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadisFromInstruction(2, t0)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -362,6 +362,8 @@
</span><span class="cx">     \
</span><span class="cx">     v(bool, useICStats, false, Normal, nullptr) \
</span><span class="cx">     \
</span><ins>+    v(unsigned, prototypeHitCountForLLIntCaching, 2, Normal, &quot;Number of prototype property hits before caching a prototype in the LLInt. A count of 0 means never cache.&quot;) \
+    \
</ins><span class="cx">     v(bool, dumpModuleRecord, false, Normal, nullptr) \
</span><span class="cx">     v(bool, dumpModuleLoadingState, false, Normal, nullptr) \
</span><span class="cx">     v(bool, exposeInternalModuleLoader, false, Normal, &quot;expose the internal module loader object to the global space for debugging&quot;) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressllintgetbyidcacheprototypeloadfromdictionaryjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/llint-get-by-id-cache-prototype-load-from-dictionary.js (0 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/llint-get-by-id-cache-prototype-load-from-dictionary.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/llint-get-by-id-cache-prototype-load-from-dictionary.js        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+
+expected = Object.prototype.toString;
+foo = {foo: 1, bar: 20};
+delete foo.bar;
+
+
+function test() {
+    let toString = foo.toString;
+    if (toString !== expected)
+        throw new Error();
+}
+
+for (i = 0; i &lt; 10; i++)
+    test();
+
+foo.toString = 100;
+expected = 100;
+
+test();
</ins></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/WTF/ChangeLog        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-05-24  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        LLInt should be able to cache prototype loads for values in GetById
+        https://bugs.webkit.org/show_bug.cgi?id=158032
+
+        Reviewed by Filip Pizlo.
+
+        Add move constructors/initializers to Bags.
+
+        * wtf/Bag.h:
+        (WTF::Bag::Bag):
+        (WTF::Bag::operator=):
+
</ins><span class="cx"> 2016-05-24  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Use auto for some of our lambda function parameters
</span></span></pre></div>
<a id="trunkSourceWTFwtfBagh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Bag.h (201362 => 201363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Bag.h        2016-05-24 23:09:54 UTC (rev 201362)
+++ trunk/Source/WTF/wtf/Bag.h        2016-05-24 23:49:57 UTC (rev 201363)
</span><span class="lines">@@ -48,9 +48,22 @@
</span><span class="cx">     
</span><span class="cx"> public:
</span><span class="cx">     Bag()
</span><del>-        : m_head(nullptr)
</del><span class="cx">     {
</span><span class="cx">     }
</span><ins>+
+    Bag(Bag&lt;T&gt;&amp;&amp; other)
+    {
+        ASSERT(!m_head);
+        m_head = other.m_head;
+        other.m_head = nullptr;
+    }
+
+    Bag&amp; operator=(Bag&lt;T&gt;&amp;&amp; other)
+    {
+        m_head = other.m_head;
+        other.m_head = nullptr;
+        return *this;
+    }
</ins><span class="cx">     
</span><span class="cx">     ~Bag()
</span><span class="cx">     {
</span><span class="lines">@@ -121,7 +134,7 @@
</span><span class="cx">     bool isEmpty() const { return !m_head; }
</span><span class="cx">     
</span><span class="cx"> private:
</span><del>-    Node* m_head;
</del><ins>+    Node* m_head { nullptr };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span></span></pre>
</div>
</div>

</body>
</html>