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

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

<h3>Log Message</h3>
<pre>Fold constant typed arrays
https://bugs.webkit.org/show_bug.cgi?id=125205

Source/JavaScriptCore: 

Reviewed by Oliver Hunt and Mark Hahnenberg.
        
If by some other mechanism we have a typed array access on a compile-time constant
typed array pointer, then fold:
        
- Array bounds checks. Specifically, fold the load of length.
        
- Loading the vector.
        
This needs to install a watchpoint on the array itself because of the possibility of
neutering. Neutering is ridiculous. We do this without bloating the size of
ArrayBuffer or JSArrayBufferView in the common case (i.e. the case where you
allocated an array that didn't end up becoming a compile-time constant). To install
the watchpoint, we slowDownAndWasteMemory and then create an incoming reference to
the ArrayBuffer, where that incoming reference is from a watchpoint object. The
ArrayBuffer already knows about such incoming references and can fire the
watchpoints that way.
        
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* dfg/DFGDesiredWatchpoints.cpp:
(JSC::DFG::ArrayBufferViewWatchpointAdaptor::add):
(JSC::DFG::DesiredWatchpoints::addLazily):
* dfg/DFGDesiredWatchpoints.h:
(JSC::DFG::GenericSetAdaptor::add):
(JSC::DFG::GenericSetAdaptor::hasBeenInvalidated):
(JSC::DFG::ArrayBufferViewWatchpointAdaptor::hasBeenInvalidated):
(JSC::DFG::GenericDesiredWatchpoints::reallyAdd):
(JSC::DFG::GenericDesiredWatchpoints::areStillValid):
(JSC::DFG::GenericDesiredWatchpoints::isStillValid):
(JSC::DFG::GenericDesiredWatchpoints::shouldAssumeMixedState):
(JSC::DFG::DesiredWatchpoints::isStillValid):
(JSC::DFG::DesiredWatchpoints::shouldAssumeMixedState):
(JSC::DFG::DesiredWatchpoints::isValidOrMixed):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::tryGetFoldableView):
* dfg/DFGGraph.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::jumpForTypedArrayOutOfBounds):
(JSC::DFG::SpeculativeJIT::emitTypedArrayBoundsCheck):
(JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
(JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
(JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
(JSC::DFG::SpeculativeJIT::compileConstantIndexedPropertyStorage):
(JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGWatchpointCollectionPhase.cpp:
(JSC::DFG::WatchpointCollectionPhase::handle):
(JSC::DFG::WatchpointCollectionPhase::addLazily):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileGetIndexedPropertyStorage):
(JSC::FTL::LowerDFGToLLVM::compileGetByVal):
(JSC::FTL::LowerDFGToLLVM::compilePutByVal):
(JSC::FTL::LowerDFGToLLVM::typedArrayLength):
* runtime/ArrayBuffer.cpp:
(JSC::ArrayBuffer::transfer):
* runtime/ArrayBufferNeuteringWatchpoint.cpp: Added.
(JSC::ArrayBufferNeuteringWatchpoint::ArrayBufferNeuteringWatchpoint):
(JSC::ArrayBufferNeuteringWatchpoint::~ArrayBufferNeuteringWatchpoint):
(JSC::ArrayBufferNeuteringWatchpoint::finishCreation):
(JSC::ArrayBufferNeuteringWatchpoint::destroy):
(JSC::ArrayBufferNeuteringWatchpoint::create):
(JSC::ArrayBufferNeuteringWatchpoint::createStructure):
* runtime/ArrayBufferNeuteringWatchpoint.h: Added.
(JSC::ArrayBufferNeuteringWatchpoint::set):
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

LayoutTests: 

Reviewed by Oliver Hunt and Mark Hahnenberg.

* js/regress/fixed-typed-array-storage-expected.txt: Added.
* js/regress/fixed-typed-array-storage-var-index-expected.txt: Added.
* js/regress/fixed-typed-array-storage-var-index.html: Added.
* js/regress/fixed-typed-array-storage.html: Added.
* js/regress/script-tests/fixed-typed-array-storage-var-index.js: Added.
(foo):
* js/regress/script-tests/fixed-typed-array-storage.js: Added.
(foo):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<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="#trunkSourceJavaScriptCoredfgDFGDesiredWatchpointscpp">trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDesiredWatchpointsh">trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayBuffercpp">trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressfixedtypedarraystorageexpectedtxt">trunk/LayoutTests/js/regress/fixed-typed-array-storage-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressfixedtypedarraystoragevarindexexpectedtxt">trunk/LayoutTests/js/regress/fixed-typed-array-storage-var-index-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressfixedtypedarraystoragevarindexhtml">trunk/LayoutTests/js/regress/fixed-typed-array-storage-var-index.html</a></li>
<li><a href="#trunkLayoutTestsjsregressfixedtypedarraystoragehtml">trunk/LayoutTests/js/regress/fixed-typed-array-storage.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsfixedtypedarraystoragevarindexjs">trunk/LayoutTests/js/regress/script-tests/fixed-typed-array-storage-var-index.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsfixedtypedarraystoragejs">trunk/LayoutTests/js/regress/script-tests/fixed-typed-array-storage.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayBufferNeuteringWatchpointcpp">trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayBufferNeuteringWatchpointh">trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/LayoutTests/ChangeLog        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2013-12-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Fold constant typed arrays
+        https://bugs.webkit.org/show_bug.cgi?id=125205
+
+        Reviewed by Oliver Hunt and Mark Hahnenberg.
+
+        * js/regress/fixed-typed-array-storage-expected.txt: Added.
+        * js/regress/fixed-typed-array-storage-var-index-expected.txt: Added.
+        * js/regress/fixed-typed-array-storage-var-index.html: Added.
+        * js/regress/fixed-typed-array-storage.html: Added.
+        * js/regress/script-tests/fixed-typed-array-storage-var-index.js: Added.
+        (foo):
+        * js/regress/script-tests/fixed-typed-array-storage.js: Added.
+        (foo):
+
</ins><span class="cx"> 2013-12-04  Zoltan Horvath  &lt;zoltan@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Shapes] Support inset for shape-outside
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressfixedtypedarraystorageexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/fixed-typed-array-storage-expected.txt (0 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/fixed-typed-array-storage-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/fixed-typed-array-storage-expected.txt        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/fixed-typed-array-storage
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressfixedtypedarraystoragevarindexexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/fixed-typed-array-storage-var-index-expected.txt (0 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/fixed-typed-array-storage-var-index-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/fixed-typed-array-storage-var-index-expected.txt        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/fixed-typed-array-storage-var-index
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressfixedtypedarraystoragevarindexhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/fixed-typed-array-storage-var-index.html (0 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/fixed-typed-array-storage-var-index.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/fixed-typed-array-storage-var-index.html        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/fixed-typed-array-storage-var-index.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressfixedtypedarraystoragehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/fixed-typed-array-storage.html (0 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/fixed-typed-array-storage.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/fixed-typed-array-storage.html        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/fixed-typed-array-storage.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsfixedtypedarraystoragevarindexjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/fixed-typed-array-storage-var-index.js (0 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/fixed-typed-array-storage-var-index.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/fixed-typed-array-storage-var-index.js        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+var array = new Int8Array(new ArrayBuffer(100));
+
+function foo(i) {
+    return array[i];
+}
+
+for (var i = 0; i &lt; 100000; ++i) {
+    if (foo(i % 100) != 0)
+        throw &quot;Error&quot;;
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsfixedtypedarraystoragejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/fixed-typed-array-storage.js (0 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/fixed-typed-array-storage.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/fixed-typed-array-storage.js        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+var array = new Int8Array(new ArrayBuffer(100));
+
+function foo() {
+    return array[0];
+}
+
+for (var i = 0; i &lt; 100000; ++i) {
+    if (foo() != 0)
+        throw &quot;Error&quot;;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -281,6 +281,7 @@
</span><span class="cx">     runtime/ArgumentsIteratorConstructor.cpp
</span><span class="cx">     runtime/ArgumentsIteratorPrototype.cpp
</span><span class="cx">     runtime/ArrayBuffer.cpp
</span><ins>+    runtime/ArrayBufferNeuteringWatchpoint.cpp
</ins><span class="cx">     runtime/ArrayBufferView.cpp
</span><span class="cx">     runtime/ArrayConstructor.cpp
</span><span class="cx">     runtime/ArrayIteratorConstructor.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/ChangeLog        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -1,3 +1,80 @@
</span><ins>+2013-12-04  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Fold constant typed arrays
+        https://bugs.webkit.org/show_bug.cgi?id=125205
+
+        Reviewed by Oliver Hunt and Mark Hahnenberg.
+        
+        If by some other mechanism we have a typed array access on a compile-time constant
+        typed array pointer, then fold:
+        
+        - Array bounds checks. Specifically, fold the load of length.
+        
+        - Loading the vector.
+        
+        This needs to install a watchpoint on the array itself because of the possibility of
+        neutering. Neutering is ridiculous. We do this without bloating the size of
+        ArrayBuffer or JSArrayBufferView in the common case (i.e. the case where you
+        allocated an array that didn't end up becoming a compile-time constant). To install
+        the watchpoint, we slowDownAndWasteMemory and then create an incoming reference to
+        the ArrayBuffer, where that incoming reference is from a watchpoint object. The
+        ArrayBuffer already knows about such incoming references and can fire the
+        watchpoints that way.
+        
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGDesiredWatchpoints.cpp:
+        (JSC::DFG::ArrayBufferViewWatchpointAdaptor::add):
+        (JSC::DFG::DesiredWatchpoints::addLazily):
+        * dfg/DFGDesiredWatchpoints.h:
+        (JSC::DFG::GenericSetAdaptor::add):
+        (JSC::DFG::GenericSetAdaptor::hasBeenInvalidated):
+        (JSC::DFG::ArrayBufferViewWatchpointAdaptor::hasBeenInvalidated):
+        (JSC::DFG::GenericDesiredWatchpoints::reallyAdd):
+        (JSC::DFG::GenericDesiredWatchpoints::areStillValid):
+        (JSC::DFG::GenericDesiredWatchpoints::isStillValid):
+        (JSC::DFG::GenericDesiredWatchpoints::shouldAssumeMixedState):
+        (JSC::DFG::DesiredWatchpoints::isStillValid):
+        (JSC::DFG::DesiredWatchpoints::shouldAssumeMixedState):
+        (JSC::DFG::DesiredWatchpoints::isValidOrMixed):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::tryGetFoldableView):
+        * dfg/DFGGraph.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::jumpForTypedArrayOutOfBounds):
+        (JSC::DFG::SpeculativeJIT::emitTypedArrayBoundsCheck):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
+        (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+        (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
+        (JSC::DFG::SpeculativeJIT::compileConstantIndexedPropertyStorage):
+        (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        (JSC::DFG::WatchpointCollectionPhase::addLazily):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetIndexedPropertyStorage):
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
+        (JSC::FTL::LowerDFGToLLVM::typedArrayLength):
+        * runtime/ArrayBuffer.cpp:
+        (JSC::ArrayBuffer::transfer):
+        * runtime/ArrayBufferNeuteringWatchpoint.cpp: Added.
+        (JSC::ArrayBufferNeuteringWatchpoint::ArrayBufferNeuteringWatchpoint):
+        (JSC::ArrayBufferNeuteringWatchpoint::~ArrayBufferNeuteringWatchpoint):
+        (JSC::ArrayBufferNeuteringWatchpoint::finishCreation):
+        (JSC::ArrayBufferNeuteringWatchpoint::destroy):
+        (JSC::ArrayBufferNeuteringWatchpoint::create):
+        (JSC::ArrayBufferNeuteringWatchpoint::createStructure):
+        * runtime/ArrayBufferNeuteringWatchpoint.h: Added.
+        (JSC::ArrayBufferNeuteringWatchpoint::set):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
</ins><span class="cx"> 2013-12-04  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r160116.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/GNUmakefile.list.am (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/GNUmakefile.list.am        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/GNUmakefile.list.am        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -782,6 +782,8 @@
</span><span class="cx">     Source/JavaScriptCore/runtime/ArgumentsIteratorPrototype.h \
</span><span class="cx">         Source/JavaScriptCore/runtime/ArrayBuffer.cpp \
</span><span class="cx">         Source/JavaScriptCore/runtime/ArrayBuffer.h \
</span><ins>+        Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp \
+        Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h \
</ins><span class="cx">         Source/JavaScriptCore/runtime/ArrayBufferView.cpp \
</span><span class="cx">         Source/JavaScriptCore/runtime/ArrayBufferView.h \
</span><span class="cx">         Source/JavaScriptCore/runtime/ArrayConstructor.cpp \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -524,6 +524,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\ArgumentsIteratorConstructor.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\ArgumentsIteratorPrototype.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\ArrayBuffer.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\runtime\ArrayBufferNeuteringWatchpoint.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\ArrayBufferView.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\ArrayConstructor.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\runtime\ArrayIteratorConstructor.cpp&quot; /&gt;
</span><span class="lines">@@ -1090,6 +1091,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\ArgList.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\Arguments.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\ArrayBuffer.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\runtime\ArrayBufferNeuteringWatchpoint.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\ArrayBufferView.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\ArrayConstructor.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\runtime\ArrayConventions.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -541,6 +541,8 @@
</span><span class="cx">                 0FFB921E16D02F470055A5DB /* DFGVariadicFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F85A31E16AB76AE0077571E /* DFGVariadicFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FFB921F16D033050055A5DB /* (null) in Headers */ = {isa = PBXBuildFile; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FFB922016D033B70055A5DB /* NodeConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 930DAD030FB1EB1A0082D205 /* NodeConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0FFC99D4184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFC99D2184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp */; };
+                0FFC99D5184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0FFC99D1184EC8AD009C10AB /* ConstantMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFC99D0184EC8AD009C10AB /* ConstantMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */; };
</span><span class="cx">                 0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -1846,6 +1848,8 @@
</span><span class="cx">                 0FF729A1166AD347000F5BA3 /* ProfilerOriginStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerOriginStack.cpp; path = profiler/ProfilerOriginStack.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FF729A2166AD347000F5BA3 /* ProfilerOriginStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOriginStack.h; path = profiler/ProfilerOriginStack.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = &quot;compiled.mach-o.executable&quot;; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
</span><ins>+                0FFC99D2184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBufferNeuteringWatchpoint.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayBufferNeuteringWatchpoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FFC99D0184EC8AD009C10AB /* ConstantMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCFAPhase.cpp; path = dfg/DFGCFAPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFAPhase.h; path = dfg/DFGCFAPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3366,6 +3370,8 @@
</span><span class="cx">                                 A76140CA182982CB00750624 /* ArgumentsIteratorPrototype.h */,
</span><span class="cx">                                 A7A8AF2517ADB5F2005AB174 /* ArrayBuffer.cpp */,
</span><span class="cx">                                 A7A8AF2617ADB5F3005AB174 /* ArrayBuffer.h */,
</span><ins>+                                0FFC99D2184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp */,
+                                0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h */,
</ins><span class="cx">                                 A7A8AF2717ADB5F3005AB174 /* ArrayBufferView.cpp */,
</span><span class="cx">                                 A7A8AF2817ADB5F3005AB174 /* ArrayBufferView.h */,
</span><span class="cx">                                 BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */,
</span><span class="lines">@@ -4478,6 +4484,7 @@
</span><span class="cx">                                 A7A8AF3817ADB5F3005AB174 /* Float32Array.h in Headers */,
</span><span class="cx">                                 A7A8AF3917ADB5F3005AB174 /* Float64Array.h in Headers */,
</span><span class="cx">                                 0F24E54317EA9F5900ABB217 /* FPRInfo.h in Headers */,
</span><ins>+                                0FFC99D5184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h in Headers */,
</ins><span class="cx">                                 0FDB2CC9173DA520007B3C1B /* FTLAbbreviatedTypes.h in Headers */,
</span><span class="cx">                                 0FEA0A08170513DB00BB722C /* FTLAbbreviations.h in Headers */,
</span><span class="cx">                                 0FEA0A1D1708B00700BB722C /* FTLAbstractHeap.h in Headers */,
</span><span class="lines">@@ -5641,6 +5648,7 @@
</span><span class="cx">                                 1428083A107EC0750013E7B2 /* JSStack.cpp in Sources */,
</span><span class="cx">                                 147F39D5107EC37600427A48 /* JSString.cpp in Sources */,
</span><span class="cx">                                 2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */,
</span><ins>+                                0FFC99D4184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp in Sources */,
</ins><span class="cx">                                 1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
</span><span class="cx">                                 146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
</span><span class="cx">                                 0F919D0C157EE09F004A4E7D /* JSSymbolTableObject.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDesiredWatchpointscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -28,8 +28,22 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;ArrayBufferNeuteringWatchpoint.h&quot;
+#include &quot;CodeBlock.h&quot;
+#include &quot;Operations.h&quot;
+
</ins><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><ins>+void ArrayBufferViewWatchpointAdaptor::add(
+    CodeBlock* codeBlock, JSArrayBufferView* view, Watchpoint* watchpoint)
+{
+    ArrayBufferNeuteringWatchpoint* neuteringWatchpoint =
+        ArrayBufferNeuteringWatchpoint::create(*codeBlock-&gt;vm());
+    neuteringWatchpoint-&gt;set()-&gt;add(watchpoint);
+    codeBlock-&gt;addConstant(neuteringWatchpoint);
+    codeBlock-&gt;vm()-&gt;heap.addReference(neuteringWatchpoint, view-&gt;buffer());
+}
+
</ins><span class="cx"> DesiredWatchpoints::DesiredWatchpoints() { }
</span><span class="cx"> DesiredWatchpoints::~DesiredWatchpoints() { }
</span><span class="cx"> 
</span><span class="lines">@@ -43,6 +57,11 @@
</span><span class="cx">     m_inlineSets.addLazily(&amp;set);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void DesiredWatchpoints::addLazily(JSArrayBufferView* view)
+{
+    m_bufferViews.addLazily(view);
+}
+
</ins><span class="cx"> void DesiredWatchpoints::addLazily(CodeOrigin codeOrigin, ExitKind exitKind, WatchpointSet* set)
</span><span class="cx"> {
</span><span class="cx">     m_sets.addLazily(codeOrigin, exitKind, set);
</span><span class="lines">@@ -57,11 +76,14 @@
</span><span class="cx"> {
</span><span class="cx">     m_sets.reallyAdd(codeBlock, commonData);
</span><span class="cx">     m_inlineSets.reallyAdd(codeBlock, commonData);
</span><ins>+    m_bufferViews.reallyAdd(codeBlock, commonData);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool DesiredWatchpoints::areStillValid() const
</span><span class="cx"> {
</span><del>-    return m_sets.areStillValid() &amp;&amp; m_inlineSets.areStillValid();
</del><ins>+    return m_sets.areStillValid()
+        &amp;&amp; m_inlineSets.areStillValid()
+        &amp;&amp; m_bufferViews.areStillValid();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDesiredWatchpointsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeOrigin.h&quot;
</span><span class="cx"> #include &quot;DFGCommonData.h&quot;
</span><ins>+#include &quot;JSArrayBufferView.h&quot;
</ins><span class="cx"> #include &quot;Watchpoint.h&quot;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="lines">@@ -61,7 +62,26 @@
</span><span class="cx">     WatchpointSetType* m_set;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template&lt;typename WatchpointSetType&gt;
</del><ins>+template&lt;typename T&gt;
+struct GenericSetAdaptor {
+    static void add(CodeBlock*, T* set, Watchpoint* watchpoint)
+    {
+        return set-&gt;add(watchpoint);
+    }
+    static bool hasBeenInvalidated(T* set) { return set-&gt;hasBeenInvalidated(); }
+};
+
+struct ArrayBufferViewWatchpointAdaptor {
+    static void add(CodeBlock*, JSArrayBufferView*, Watchpoint*);
+    static bool hasBeenInvalidated(JSArrayBufferView* view)
+    {
+        bool result = !view-&gt;length();
+        WTF::loadLoadFence();
+        return result;
+    }
+};
+
+template&lt;typename WatchpointSetType, typename Adaptor = GenericSetAdaptor&lt;WatchpointSetType&gt;&gt;
</ins><span class="cx"> class GenericDesiredWatchpoints {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(GenericDesiredWatchpoints);
</span><span class="cx"> #if !ASSERT_DISABLED
</span><span class="lines">@@ -92,7 +112,7 @@
</span><span class="cx">         typename HashSet&lt;WatchpointSetType*&gt;::iterator end = m_sets.end();
</span><span class="cx">         for (; iter != end; ++iter) {
</span><span class="cx">             common.watchpoints.append(CodeBlockJettisoningWatchpoint(codeBlock));
</span><del>-            (*iter)-&gt;add(&amp;common.watchpoints.last());
</del><ins>+            Adaptor::add(codeBlock, *iter, &amp;common.watchpoints.last());
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         for (unsigned i = m_profiledWatchpoints.size(); i--;) {
</span><span class="lines">@@ -100,7 +120,7 @@
</span><span class="cx">                 m_profiledWatchpoints[i];
</span><span class="cx">             common.profiledWatchpoints.append(
</span><span class="cx">                 ProfiledCodeBlockJettisoningWatchpoint(watchpoint.m_codeOrigin, watchpoint.m_exitKind, codeBlock));
</span><del>-            watchpoint.m_set-&gt;add(&amp;common.profiledWatchpoints.last());
</del><ins>+            Adaptor::add(codeBlock, watchpoint.m_set, &amp;common.profiledWatchpoints.last());
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         m_reallyAdded = true;
</span><span class="lines">@@ -111,12 +131,12 @@
</span><span class="cx">         typename HashSet&lt;WatchpointSetType*&gt;::iterator iter = m_sets.begin();
</span><span class="cx">         typename HashSet&lt;WatchpointSetType*&gt;::iterator end = m_sets.end();
</span><span class="cx">         for (; iter != end; ++iter) {
</span><del>-            if ((*iter)-&gt;hasBeenInvalidated())
</del><ins>+            if (Adaptor::hasBeenInvalidated(*iter))
</ins><span class="cx">                 return false;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         for (unsigned i = m_profiledWatchpoints.size(); i--;) {
</span><del>-            if (m_profiledWatchpoints[i].m_set-&gt;hasBeenInvalidated())
</del><ins>+            if (Adaptor::hasBeenInvalidated(m_profiledWatchpoints[i].m_set))
</ins><span class="cx">                 return false;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -126,7 +146,7 @@
</span><span class="cx"> #if ASSERT_DISABLED
</span><span class="cx">     bool isStillValid(WatchpointSetType* set)
</span><span class="cx">     {
</span><del>-        return set-&gt;isStillValid();
</del><ins>+        return !Adaptor::hasBeenInvalidated(set);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     bool shouldAssumeMixedState(WatchpointSetType*)
</span><span class="lines">@@ -136,7 +156,7 @@
</span><span class="cx"> #else
</span><span class="cx">     bool isStillValid(WatchpointSetType* set)
</span><span class="cx">     {
</span><del>-        bool result = set-&gt;isStillValid();
</del><ins>+        bool result = !Adaptor::hasBeenInvalidated(set);
</ins><span class="cx">         m_firstKnownState.add(set, result);
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="lines">@@ -147,7 +167,7 @@
</span><span class="cx">         if (iter == m_firstKnownState.end())
</span><span class="cx">             return false;
</span><span class="cx">         
</span><del>-        return iter-&gt;value != set-&gt;isStillValid();
</del><ins>+        return iter-&gt;value != !Adaptor::hasBeenInvalidated(set);
</ins><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx">     
</span><span class="lines">@@ -172,6 +192,7 @@
</span><span class="cx">     
</span><span class="cx">     void addLazily(WatchpointSet*);
</span><span class="cx">     void addLazily(InlineWatchpointSet&amp;);
</span><ins>+    void addLazily(JSArrayBufferView*);
</ins><span class="cx">     void addLazily(CodeOrigin, ExitKind, WatchpointSet*);
</span><span class="cx">     void addLazily(CodeOrigin, ExitKind, InlineWatchpointSet&amp;);
</span><span class="cx">     
</span><span class="lines">@@ -187,6 +208,10 @@
</span><span class="cx">     {
</span><span class="cx">         return m_inlineSets.isStillValid(&amp;set);
</span><span class="cx">     }
</span><ins>+    bool isStillValid(JSArrayBufferView* view)
+    {
+        return m_bufferViews.isStillValid(view);
+    }
</ins><span class="cx">     bool shouldAssumeMixedState(WatchpointSet* set)
</span><span class="cx">     {
</span><span class="cx">         return m_sets.shouldAssumeMixedState(set);
</span><span class="lines">@@ -195,6 +220,10 @@
</span><span class="cx">     {
</span><span class="cx">         return m_inlineSets.shouldAssumeMixedState(&amp;set);
</span><span class="cx">     }
</span><ins>+    bool shouldAssumeMixedState(JSArrayBufferView* view)
+    {
+        return m_bufferViews.shouldAssumeMixedState(view);
+    }
</ins><span class="cx">     bool isValidOrMixed(WatchpointSet* set)
</span><span class="cx">     {
</span><span class="cx">         return m_sets.isValidOrMixed(set);
</span><span class="lines">@@ -203,10 +232,15 @@
</span><span class="cx">     {
</span><span class="cx">         return m_inlineSets.isValidOrMixed(&amp;set);
</span><span class="cx">     }
</span><ins>+    bool isValidOrMixed(JSArrayBufferView* view)
+    {
+        return m_bufferViews.isValidOrMixed(view);
+    }
</ins><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     GenericDesiredWatchpoints&lt;WatchpointSet&gt; m_sets;
</span><span class="cx">     GenericDesiredWatchpoints&lt;InlineWatchpointSet&gt; m_inlineSets;
</span><ins>+    GenericDesiredWatchpoints&lt;JSArrayBufferView, ArrayBufferViewWatchpointAdaptor&gt; m_bufferViews;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -740,6 +740,20 @@
</span><span class="cx">     return activation-&gt;registers();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSArrayBufferView* Graph::tryGetFoldableView(Node* node, ArrayMode arrayMode)
+{
+    if (arrayMode.typedArrayType() == NotTypedArray)
+        return 0;
+    if (!node-&gt;hasConstant())
+        return 0;
+    JSArrayBufferView* view = jsDynamicCast&lt;JSArrayBufferView*&gt;(valueOfJSConstant(node));
+    if (!view)
+        return 0;
+    if (!watchpoints().isStillValid(view))
+        return 0;
+    return view;
+}
+
</ins><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -794,6 +794,8 @@
</span><span class="cx">     JSActivation* tryGetActivation(Node*);
</span><span class="cx">     WriteBarrierBase&lt;Unknown&gt;* tryGetRegisters(Node*);
</span><span class="cx">     
</span><ins>+    JSArrayBufferView* tryGetFoldableView(Node*, ArrayMode);
+    
</ins><span class="cx">     VM&amp; m_vm;
</span><span class="cx">     Plan&amp; m_plan;
</span><span class="cx">     CodeBlock* m_codeBlock;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -2325,6 +2325,31 @@
</span><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JITCompiler::Jump SpeculativeJIT::jumpForTypedArrayOutOfBounds(Node* node, GPRReg baseGPR, GPRReg indexGPR)
+{
+    if (node-&gt;op() == PutByValAlias)
+        return JITCompiler::Jump();
+    if (JSArrayBufferView* view = m_jit.graph().tryGetFoldableView(m_jit.graph().child(node, 0).node(), node-&gt;arrayMode())) {
+        uint32_t length = view-&gt;length();
+        Node* indexNode = m_jit.graph().child(node, 1).node();
+        if (m_jit.graph().isInt32Constant(indexNode) &amp;&amp; static_cast&lt;uint32_t&gt;(m_jit.graph().valueOfInt32Constant(indexNode)) &lt; length)
+            return JITCompiler::Jump();
+        return m_jit.branch32(
+            MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Imm32(length));
+    }
+    return m_jit.branch32(
+        MacroAssembler::AboveOrEqual, indexGPR,
+        MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfLength()));
+}
+
+void SpeculativeJIT::emitTypedArrayBoundsCheck(Node* node, GPRReg baseGPR, GPRReg indexGPR)
+{
+    JITCompiler::Jump jump = jumpForTypedArrayOutOfBounds(node, baseGPR, indexGPR);
+    if (!jump.isSet())
+        return;
+    speculationCheck(OutOfBounds, JSValueRegs(), 0, jump);
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileGetByValOnIntTypedArray(Node* node, TypedArrayType type)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isInt(type));
</span><span class="lines">@@ -2342,11 +2367,7 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(node-&gt;arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(node-&gt;child1())));
</span><span class="cx"> 
</span><del>-    speculationCheck(
-        Uncountable, JSValueRegs(), 0,
-        m_jit.branch32(
-            MacroAssembler::AboveOrEqual, propertyReg,
-            MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfLength())));
</del><ins>+    emitTypedArrayBoundsCheck(node, baseReg, propertyReg);
</ins><span class="cx">     switch (elementSize(type)) {
</span><span class="cx">     case 1:
</span><span class="cx">         if (isSigned(type))
</span><span class="lines">@@ -2509,9 +2530,7 @@
</span><span class="cx">     ASSERT_UNUSED(valueGPR, valueGPR != property);
</span><span class="cx">     ASSERT(valueGPR != base);
</span><span class="cx">     ASSERT(valueGPR != storageReg);
</span><del>-    MacroAssembler::Jump outOfBounds;
-    if (node-&gt;op() == PutByVal)
-        outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, JSArrayBufferView::offsetOfLength()));
</del><ins>+    MacroAssembler::Jump outOfBounds = jumpForTypedArrayOutOfBounds(node, base, property);
</ins><span class="cx"> 
</span><span class="cx">     switch (elementSize(type)) {
</span><span class="cx">     case 1:
</span><span class="lines">@@ -2526,7 +2545,7 @@
</span><span class="cx">     default:
</span><span class="cx">         CRASH();
</span><span class="cx">     }
</span><del>-    if (node-&gt;op() == PutByVal)
</del><ins>+    if (outOfBounds.isSet())
</ins><span class="cx">         outOfBounds.link(&amp;m_jit);
</span><span class="cx">     noResult(node);
</span><span class="cx"> }
</span><span class="lines">@@ -2547,11 +2566,7 @@
</span><span class="cx"> 
</span><span class="cx">     FPRTemporary result(this);
</span><span class="cx">     FPRReg resultReg = result.fpr();
</span><del>-    speculationCheck(
-        Uncountable, JSValueRegs(), 0,
-        m_jit.branch32(
-            MacroAssembler::AboveOrEqual, propertyReg,
-            MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfLength())));
</del><ins>+    emitTypedArrayBoundsCheck(node, baseReg, propertyReg);
</ins><span class="cx">     switch (elementSize(type)) {
</span><span class="cx">     case 4:
</span><span class="cx">         m_jit.loadFloat(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesFour), resultReg);
</span><span class="lines">@@ -2590,12 +2605,7 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT_UNUSED(baseUse, node-&gt;arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(baseUse)));
</span><span class="cx">     
</span><del>-    MacroAssembler::Jump outOfBounds;
-    if (node-&gt;op() == PutByVal) {
-        outOfBounds = m_jit.branch32(
-            MacroAssembler::AboveOrEqual, property,
-            MacroAssembler::Address(base, JSArrayBufferView::offsetOfLength()));
-    }
</del><ins>+    MacroAssembler::Jump outOfBounds = jumpForTypedArrayOutOfBounds(node, base, property);
</ins><span class="cx">     
</span><span class="cx">     switch (elementSize(type)) {
</span><span class="cx">     case 4: {
</span><span class="lines">@@ -2610,7 +2620,7 @@
</span><span class="cx">     default:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><del>-    if (node-&gt;op() == PutByVal)
</del><ins>+    if (outOfBounds.isSet())
</ins><span class="cx">         outOfBounds.link(&amp;m_jit);
</span><span class="cx">     noResult(node);
</span><span class="cx"> }
</span><span class="lines">@@ -4035,8 +4045,27 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool SpeculativeJIT::compileConstantIndexedPropertyStorage(Node* node)
+{
+    JSArrayBufferView* view = m_jit.graph().tryGetFoldableView(
+        node-&gt;child1().node(), node-&gt;arrayMode());
+    if (!view)
+        return false;
+    if (view-&gt;mode() == FastTypedArray)
+        return false;
+    
+    GPRTemporary storage(this);
+    GPRReg storageGPR = storage.gpr();
+    m_jit.move(TrustedImmPtr(view-&gt;vector()), storageGPR);
+    storageResult(storageGPR, node);
+    return true;
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileGetIndexedPropertyStorage(Node* node)
</span><span class="cx"> {
</span><ins>+    if (compileConstantIndexedPropertyStorage(node))
+        return;
+    
</ins><span class="cx">     SpeculateCellOperand base(this, node-&gt;child1());
</span><span class="cx">     GPRReg baseReg = base.gpr();
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -2027,7 +2027,10 @@
</span><span class="cx">     void compileArithIMul(Node*);
</span><span class="cx">     void compileArithDiv(Node*);
</span><span class="cx">     void compileArithMod(Node*);
</span><ins>+    bool compileConstantIndexedPropertyStorage(Node*);
</ins><span class="cx">     void compileGetIndexedPropertyStorage(Node*);
</span><ins>+    JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
+    void emitTypedArrayBoundsCheck(Node*, GPRReg baseGPR, GPRReg indexGPR);
</ins><span class="cx">     void compileGetTypedArrayByteOffset(Node*);
</span><span class="cx">     void compileGetByValOnIntTypedArray(Node*, TypedArrayType);
</span><span class="cx">     void compilePutByValForIntTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -94,8 +94,21 @@
</span><span class="cx">             
</span><span class="cx">             if (m_node-&gt;arrayMode().type() == Array::String)
</span><span class="cx">                 handleStringGetByVal();
</span><ins>+
+            if (JSArrayBufferView* view = m_graph.tryGetFoldableView(m_node-&gt;child1().node(), m_node-&gt;arrayMode()))
+                addLazily(view);
</ins><span class="cx">             break;
</span><span class="cx">             
</span><ins>+        case PutByVal:
+            if (JSArrayBufferView* view = m_graph.tryGetFoldableView(m_graph.varArgChild(m_node, 0).node(), m_node-&gt;arrayMode()))
+                addLazily(view);
+            break;
+            
+        case GetArrayLength:
+            if (JSArrayBufferView* view = m_graph.tryGetFoldableView(m_node-&gt;child1().node(), m_node-&gt;arrayMode()))
+                addLazily(view);
+            break;
+            
</ins><span class="cx">         case StringCharAt:
</span><span class="cx">             handleStringGetByVal();
</span><span class="cx">             break;
</span><span class="lines">@@ -130,6 +143,18 @@
</span><span class="cx">             addLazily(m_node-&gt;symbolTable()-&gt;m_functionEnteredOnce);
</span><span class="cx">             break;
</span><span class="cx">             
</span><ins>+        case GetIndexedPropertyStorage:
+            if (JSArrayBufferView* view = m_graph.tryGetFoldableView(m_node-&gt;child1().node(), m_node-&gt;arrayMode())) {
+                // FIXME: It would be awesome to be able to fold the property storage for
+                // these GC-allocated typed arrays. For now it doesn't matter because the
+                // most common use-cases for constant typed arrays involve large arrays with
+                // aliased buffer views.
+                if (view-&gt;mode() == FastTypedArray)
+                    break;
+                addLazily(view);
+            }
+            break;
+            
</ins><span class="cx">         default:
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -179,6 +204,10 @@
</span><span class="cx">     {
</span><span class="cx">         m_graph.watchpoints().addLazily(set);
</span><span class="cx">     }
</span><ins>+    void addLazily(JSArrayBufferView* view)
+    {
+        m_graph.watchpoints().addLazily(view);
+    }
</ins><span class="cx">     
</span><span class="cx">     JSGlobalObject* globalObject()
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -1335,6 +1335,13 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><ins>+        if (JSArrayBufferView* view = m_graph.tryGetFoldableView(m_node-&gt;child1().node(), m_node-&gt;arrayMode())) {
+            if (view-&gt;mode() != FastTypedArray) {
+                setStorage(m_out.constIntPtr(view-&gt;vector()));
+                return;
+            }
+        }
+        
</ins><span class="cx">         setStorage(m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector));
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -1451,12 +1458,10 @@
</span><span class="cx">             TypedArrayType type = m_node-&gt;arrayMode().typedArrayType();
</span><span class="cx">             
</span><span class="cx">             if (isTypedView(type)) {
</span><del>-                LValue array = lowCell(m_node-&gt;child1());
-                
</del><span class="cx">                 speculate(
</span><span class="cx">                     OutOfBounds, noValue(), 0,
</span><span class="cx">                     m_out.aboveOrEqual(
</span><del>-                        index, m_out.load32(array, m_heaps.JSArrayBufferView_length)));
</del><ins>+                        index, typedArrayLength(m_node-&gt;child1(), m_node-&gt;arrayMode())));
</ins><span class="cx">                 
</span><span class="cx">                 TypedPointer pointer = TypedPointer(
</span><span class="cx">                     m_heaps.typedArrayProperties,
</span><span class="lines">@@ -1624,7 +1629,8 @@
</span><span class="cx">                     speculate(
</span><span class="cx">                         OutOfBounds, noValue(), 0,
</span><span class="cx">                         m_out.aboveOrEqual(
</span><del>-                            index, m_out.load32(base, m_heaps.JSArrayBufferView_length)));
</del><ins>+                            index,
+                            typedArrayLength(child1.node(), m_node-&gt;arrayMode(), base)));
</ins><span class="cx">                 }
</span><span class="cx">                 
</span><span class="cx">                 TypedPointer pointer = TypedPointer(
</span><span class="lines">@@ -2765,6 +2771,18 @@
</span><span class="cx">             m_out.phi(m_out.intPtr, fastButterfly, slowButterfly));
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    LValue typedArrayLength(Node* baseNode, ArrayMode arrayMode, LValue base)
+    {
+        if (JSArrayBufferView* view = m_graph.tryGetFoldableView(baseNode, arrayMode))
+            return m_out.constInt32(view-&gt;length());
+        return m_out.load32(base, m_heaps.JSArrayBufferView_length);
+    }
+    
+    LValue typedArrayLength(Edge baseEdge, ArrayMode arrayMode)
+    {
+        return typedArrayLength(baseEdge.node(), arrayMode, lowCell(baseEdge));
+    }
+    
</ins><span class="cx">     LValue boolify(Edge edge)
</span><span class="cx">     {
</span><span class="cx">         switch (edge.useKind()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayBuffercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;ArrayBuffer.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;ArrayBufferNeuteringWatchpoint.h&quot;
</ins><span class="cx"> #include &quot;JSArrayBufferView.h&quot;
</span><span class="cx"> #include &quot;Operations.h&quot;
</span><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><span class="lines">@@ -52,9 +53,11 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (size_t i = numberOfIncomingReferences(); i--;) {
</span><del>-        JSArrayBufferView* view = jsDynamicCast&lt;JSArrayBufferView*&gt;(incomingReferenceAt(i));
-        if (view)
</del><ins>+        JSCell* cell = incomingReferenceAt(i);
+        if (JSArrayBufferView* view = jsDynamicCast&lt;JSArrayBufferView*&gt;(cell))
</ins><span class="cx">             view-&gt;neuter();
</span><ins>+        else if (ArrayBufferNeuteringWatchpoint* watchpoint = jsDynamicCast&lt;ArrayBufferNeuteringWatchpoint*&gt;(cell))
+            watchpoint-&gt;set()-&gt;fireAll();
</ins><span class="cx">     }
</span><span class="cx">     return true;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayBufferNeuteringWatchpointcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp (0 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;ArrayBufferNeuteringWatchpoint.h&quot;
+
+#include &quot;Operations.h&quot;
+
+namespace JSC {
+
+const ClassInfo ArrayBufferNeuteringWatchpoint::s_info = {
+    &quot;ArrayBufferNeuteringWatchpoint&quot;, 0, 0, 0,
+    CREATE_METHOD_TABLE(ArrayBufferNeuteringWatchpoint)
+};
+
+ArrayBufferNeuteringWatchpoint::ArrayBufferNeuteringWatchpoint(VM&amp; vm)
+    : Base(vm, vm.arrayBufferNeuteringWatchpointStructure.get())
+    , m_set(adoptRef(new WatchpointSet(IsWatched)))
+{
+}
+
+void ArrayBufferNeuteringWatchpoint::destroy(JSCell* cell)
+{
+    static_cast&lt;ArrayBufferNeuteringWatchpoint*&gt;(cell)-&gt;ArrayBufferNeuteringWatchpoint::~ArrayBufferNeuteringWatchpoint();
+}
+
+ArrayBufferNeuteringWatchpoint* ArrayBufferNeuteringWatchpoint::create(VM&amp; vm)
+{
+    ArrayBufferNeuteringWatchpoint* result = new
+        (NotNull, allocateCell&lt;ArrayBufferNeuteringWatchpoint&gt;(vm.heap))
+        ArrayBufferNeuteringWatchpoint(vm);
+    result-&gt;finishCreation(vm);
+    return result;
+}
+
+Structure* ArrayBufferNeuteringWatchpoint::createStructure(VM&amp; vm)
+{
+    return Structure::create(vm, 0, jsNull(), TypeInfo(CompoundType, StructureFlags), info());
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayBufferNeuteringWatchpointh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h (0 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ArrayBufferNeuteringWatchpoint_h
+#define ArrayBufferNeuteringWatchpoint_h
+
+#include &quot;JSCell.h&quot;
+#include &quot;Watchpoint.h&quot;
+
+namespace JSC {
+
+class ArrayBufferNeuteringWatchpoint : public JSCell {
+public:
+    typedef JSCell Base;
+    
+private:
+    ArrayBufferNeuteringWatchpoint(VM&amp;);
+    
+public:
+    DECLARE_INFO;
+    
+    static ArrayBufferNeuteringWatchpoint* create(VM&amp;);
+
+    static const bool needsDestruction = true;
+    static const bool hasImmortalStructure = true;
+    static void destroy(JSCell*);
+    
+    static Structure* createStructure(VM&amp;);
+    
+    WatchpointSet* set() { return m_set.get(); }
+
+private:
+    RefPtr&lt;WatchpointSet&gt; m_set;
+};
+
+} // namespace JSC
+
+#endif // ArrayBufferNeuteringWatchpoint_h
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;VM.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ArgList.h&quot;
</span><ins>+#include &quot;ArrayBufferNeuteringWatchpoint.h&quot;
</ins><span class="cx"> #include &quot;CallFrameInlines.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;CodeCache.h&quot;
</span><span class="lines">@@ -248,6 +249,7 @@
</span><span class="cx">     symbolTableStructure.set(*this, SymbolTable::createStructure(*this, 0, jsNull()));
</span><span class="cx">     structureChainStructure.set(*this, StructureChain::createStructure(*this, 0, jsNull()));
</span><span class="cx">     sparseArrayValueMapStructure.set(*this, SparseArrayValueMap::createStructure(*this, 0, jsNull()));
</span><ins>+    arrayBufferNeuteringWatchpointStructure.set(*this, ArrayBufferNeuteringWatchpoint::createStructure(*this));
</ins><span class="cx">     withScopeStructure.set(*this, JSWithScope::createStructure(*this, 0, jsNull()));
</span><span class="cx">     unlinkedFunctionExecutableStructure.set(*this, UnlinkedFunctionExecutable::createStructure(*this, 0, jsNull()));
</span><span class="cx">     unlinkedProgramCodeBlockStructure.set(*this, UnlinkedProgramCodeBlock::createStructure(*this, 0, jsNull()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (160149 => 160150)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2013-12-05 02:03:52 UTC (rev 160149)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2013-12-05 02:05:35 UTC (rev 160150)
</span><span class="lines">@@ -267,6 +267,7 @@
</span><span class="cx">         Strong&lt;Structure&gt; symbolTableStructure;
</span><span class="cx">         Strong&lt;Structure&gt; structureChainStructure;
</span><span class="cx">         Strong&lt;Structure&gt; sparseArrayValueMapStructure;
</span><ins>+        Strong&lt;Structure&gt; arrayBufferNeuteringWatchpointStructure;
</ins><span class="cx">         Strong&lt;Structure&gt; withScopeStructure;
</span><span class="cx">         Strong&lt;Structure&gt; unlinkedFunctionExecutableStructure;
</span><span class="cx">         Strong&lt;Structure&gt; unlinkedProgramCodeBlockStructure;
</span></span></pre>
</div>
</div>

</body>
</html>