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

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

<h3>Log Message</h3>
<pre>Add Heap verification infrastructure.
&lt;https://webkit.org/b/138851&gt;

Reviewed by Geoffrey Garen.

The verification infrastructure code is always built in but disabled by
default.  When disabled, the cost is minimal:
1. Heap has a m_verifier field.
2. GC does a few &quot;if (m_verifier)&quot; checks that should fail.
3. HeapVerifier takes up code space though not used.

When enabled:
1. The HeapVerifier will keep N number of GC cycle data.
   Each GC cycle will contain a &quot;before marking&quot; and &quot;after marking&quot; live
   object list.
   The GC cycles is a circular buffer.  Only data for the last N GC cycles
   will be retained.
2. During GC, the current GC cycle's live objects lists will be populated
   before and after marking.
3. The current GC cycle's live object lists will be validated before GC,
   after marking, and after GC.

Currently, the only validation being done is to verify that object
butterflies are allocated from valid blocks in the Storage (aka Copied)
space.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::collect):
* heap/Heap.h:
* heap/HeapVerifier.cpp: Added.
(JSC::LiveObjectList::findObject):
(JSC::HeapVerifier::HeapVerifier):
(JSC::HeapVerifier::collectionTypeName):
(JSC::HeapVerifier::phaseName):
(JSC::getButterflyDetails):
(JSC::HeapVerifier::initializeGCCycle):
(JSC::GatherLiveObjFunctor::GatherLiveObjFunctor):
(JSC::GatherLiveObjFunctor::operator()):
(JSC::HeapVerifier::gatherLiveObjects):
(JSC::HeapVerifier::liveObjectListForGathering):
(JSC::trimDeadObjectsFromList):
(JSC::HeapVerifier::trimDeadObjects):
(JSC::HeapVerifier::verifyButterflyIsInStorageSpace):
(JSC::HeapVerifier::verify):
(JSC::HeapVerifier::reportObject):
(JSC::HeapVerifier::checkIfRecorded):
* heap/HeapVerifier.h: Added.
(JSC::LiveObjectData::LiveObjectData):
(JSC::LiveObjectList::LiveObjectList):
(JSC::LiveObjectList::reset):
(JSC::HeapVerifier::GCCycle::GCCycle):
(JSC::HeapVerifier::GCCycle::collectionTypeName):
(JSC::HeapVerifier::incrementCycle):
(JSC::HeapVerifier::currentCycle):
(JSC::HeapVerifier::cycleForIndex):
* runtime/Options.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeaph">trunk/Source/JavaScriptCore/heap/Heap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreheapHeapVerifiercpp">trunk/Source/JavaScriptCore/heap/HeapVerifier.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapVerifierh">trunk/Source/JavaScriptCore/heap/HeapVerifier.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (176423 => 176424)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2014-11-20 23:26:29 UTC (rev 176423)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2014-11-20 23:28:41 UTC (rev 176424)
</span><span class="lines">@@ -265,6 +265,7 @@
</span><span class="cx">     heap/Heap.cpp
</span><span class="cx">     heap/HeapStatistics.cpp
</span><span class="cx">     heap/HeapTimer.cpp
</span><ins>+    heap/HeapVerifier.cpp
</ins><span class="cx">     heap/IncrementalSweeper.cpp
</span><span class="cx">     heap/JITStubRoutineSet.cpp
</span><span class="cx">     heap/MachineStackMarker.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (176423 => 176424)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-11-20 23:26:29 UTC (rev 176423)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-11-20 23:28:41 UTC (rev 176424)
</span><span class="lines">@@ -1,3 +1,67 @@
</span><ins>+2014-11-20  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Add Heap verification infrastructure.
+        &lt;https://webkit.org/b/138851&gt;
+
+        Reviewed by Geoffrey Garen.
+
+        The verification infrastructure code is always built in but disabled by
+        default.  When disabled, the cost is minimal:
+        1. Heap has a m_verifier field.
+        2. GC does a few &quot;if (m_verifier)&quot; checks that should fail.
+        3. HeapVerifier takes up code space though not used.
+
+        When enabled:
+        1. The HeapVerifier will keep N number of GC cycle data.
+           Each GC cycle will contain a &quot;before marking&quot; and &quot;after marking&quot; live
+           object list.
+           The GC cycles is a circular buffer.  Only data for the last N GC cycles
+           will be retained.
+        2. During GC, the current GC cycle's live objects lists will be populated
+           before and after marking.
+        3. The current GC cycle's live object lists will be validated before GC,
+           after marking, and after GC.
+
+        Currently, the only validation being done is to verify that object
+        butterflies are allocated from valid blocks in the Storage (aka Copied)
+        space.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::collect):
+        * heap/Heap.h:
+        * heap/HeapVerifier.cpp: Added.
+        (JSC::LiveObjectList::findObject):
+        (JSC::HeapVerifier::HeapVerifier):
+        (JSC::HeapVerifier::collectionTypeName):
+        (JSC::HeapVerifier::phaseName):
+        (JSC::getButterflyDetails):
+        (JSC::HeapVerifier::initializeGCCycle):
+        (JSC::GatherLiveObjFunctor::GatherLiveObjFunctor):
+        (JSC::GatherLiveObjFunctor::operator()):
+        (JSC::HeapVerifier::gatherLiveObjects):
+        (JSC::HeapVerifier::liveObjectListForGathering):
+        (JSC::trimDeadObjectsFromList):
+        (JSC::HeapVerifier::trimDeadObjects):
+        (JSC::HeapVerifier::verifyButterflyIsInStorageSpace):
+        (JSC::HeapVerifier::verify):
+        (JSC::HeapVerifier::reportObject):
+        (JSC::HeapVerifier::checkIfRecorded):
+        * heap/HeapVerifier.h: Added.
+        (JSC::LiveObjectData::LiveObjectData):
+        (JSC::LiveObjectList::LiveObjectList):
+        (JSC::LiveObjectList::reset):
+        (JSC::HeapVerifier::GCCycle::GCCycle):
+        (JSC::HeapVerifier::GCCycle::collectionTypeName):
+        (JSC::HeapVerifier::incrementCycle):
+        (JSC::HeapVerifier::currentCycle):
+        (JSC::HeapVerifier::cycleForIndex):
+        * runtime/Options.h:
+
</ins><span class="cx"> 2014-11-20  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rename String.prototype.contains to String.prototype.includes
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (176423 => 176424)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-11-20 23:26:29 UTC (rev 176423)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2014-11-20 23:28:41 UTC (rev 176424)
</span><span class="lines">@@ -547,6 +547,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\heap\Heap.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\heap\HeapStatistics.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\heap\HeapTimer.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\heap\HeapVerifier.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\heap\IncrementalSweeper.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\heap\JITStubRoutineSet.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\heap\MachineStackMarker.cpp&quot; /&gt;
</span><span class="lines">@@ -1250,6 +1251,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\heap\HeapRootVisitor.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\heap\HeapStatistics.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\heap\HeapTimer.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\heap\HeapVerifier.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\heap\IncrementalSweeper.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\heap\JITStubRoutineSet.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\heap\ListableHandler.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters (176423 => 176424)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2014-11-20 23:26:29 UTC (rev 176423)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2014-11-20 23:28:41 UTC (rev 176424)
</span><span class="lines">@@ -282,6 +282,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\heap\HeapTimer.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;heap&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\heap\HeapVerifier.cpp&quot;&gt;
+      &lt;Filter&gt;heap&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\heap\IncrementalSweeper.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;heap&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -2135,6 +2138,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\heap\HeapTimer.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;heap&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\heap\HeapVerifier.h&quot;&gt;
+      &lt;Filter&gt;heap&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\heap\IncrementalSweeper.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;heap&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (176423 => 176424)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-11-20 23:26:29 UTC (rev 176423)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-11-20 23:28:41 UTC (rev 176424)
</span><span class="lines">@@ -1595,6 +1595,8 @@
</span><span class="cx">                 FE5248F9191442D900B7FDE4 /* VariableWatchpointSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5248F8191442D900B7FDE4 /* VariableWatchpointSetInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */; };
</span><span class="cx">                 FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                FE7BA60F1A1A7CEC00F1F7B4 /* HeapVerifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */; };
+                FE7BA6101A1A7CEC00F1F7B4 /* HeapVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861E182B7A0400F6D851 /* Breakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FEA08621182B7A0400F6D851 /* DebuggerPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FEB58C14187B8B160098EF0B /* ErrorHandlingScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEB58C12187B8B160098EF0B /* ErrorHandlingScope.cpp */; };
</span><span class="lines">@@ -3311,6 +3313,8 @@
</span><span class="cx">                 FE5248F8191442D900B7FDE4 /* VariableWatchpointSetInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWatchpointSetInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMEntryScope.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMEntryScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapVerifier.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapVerifier.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 FEA0861E182B7A0400F6D851 /* Breakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakpoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FEA0861F182B7A0400F6D851 /* DebuggerPrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerPrimitives.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FEB58C12187B8B160098EF0B /* ErrorHandlingScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorHandlingScope.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3802,6 +3806,8 @@
</span><span class="cx">                 142E312A134FF0A600AFADB5 /* heap */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */,
+                                FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */,
</ins><span class="cx">                                 C2DA778218E259990066FCB6 /* HeapInlines.h */,
</span><span class="cx">                                 ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */,
</span><span class="cx">                                 2AACE63A18CA5A0300ED0191 /* GCActivityCallback.cpp */,
</span><span class="lines">@@ -5379,6 +5385,7 @@
</span><span class="cx">                                 A584032018BFFBE1005A0811 /* InspectorAgent.h in Headers */,
</span><span class="cx">                                 2AABCDE718EF294200002096 /* GCLogging.h in Headers */,
</span><span class="cx">                                 FE5248F9191442D900B7FDE4 /* VariableWatchpointSetInlines.h in Headers */,
</span><ins>+                                FE7BA6101A1A7CEC00F1F7B4 /* HeapVerifier.h in Headers */,
</ins><span class="cx">                                 A5EF9B141A1D43F600702E90 /* generate_cpp_backend_dispatcher_header.py in Headers */,
</span><span class="cx">                                 C2DA778318E259990066FCB6 /* HeapInlines.h in Headers */,
</span><span class="cx">                                 C4F4B6F41A05C944005CAB76 /* cpp_generator.py in Headers */,
</span><span class="lines">@@ -6986,6 +6993,7 @@
</span><span class="cx">                                 A513E5CA185F9624007E95AD /* InjectedScriptManager.cpp in Sources */,
</span><span class="cx">                                 A5840E20187B7B8600843B10 /* InjectedScriptModule.cpp in Sources */,
</span><span class="cx">                                 0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */,
</span><ins>+                                FE7BA60F1A1A7CEC00F1F7B4 /* HeapVerifier.cpp in Sources */,
</ins><span class="cx">                                 A5CEEE14187F3BAD00E55C99 /* InspectorAgent.cpp in Sources */,
</span><span class="cx">                                 A593CF86184038CA00BFCE27 /* InspectorAgentRegistry.cpp in Sources */,
</span><span class="cx">                                 0F2B9CF619D0BAC100B1D1B5 /* FTLExitTimeObjectMaterialization.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (176423 => 176424)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2014-11-20 23:26:29 UTC (rev 176423)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2014-11-20 23:28:41 UTC (rev 176424)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include &quot;HeapIterationScope.h&quot;
</span><span class="cx"> #include &quot;HeapRootVisitor.h&quot;
</span><span class="cx"> #include &quot;HeapStatistics.h&quot;
</span><ins>+#include &quot;HeapVerifier.h&quot;
</ins><span class="cx"> #include &quot;IncrementalSweeper.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JSGlobalObject.h&quot;
</span><span class="lines">@@ -339,6 +340,8 @@
</span><span class="cx">     , m_deferralDepth(0)
</span><span class="cx"> {
</span><span class="cx">     m_storageSpace.init();
</span><ins>+    if (Options::verifyHeap())
+        m_verifier = std::make_unique&lt;HeapVerifier&gt;(this, Options::numberOfGCCyclesToRecordForVerification());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Heap::~Heap()
</span><span class="lines">@@ -1004,7 +1007,15 @@
</span><span class="cx">     GCPHASE(Collect);
</span><span class="cx"> 
</span><span class="cx">     double gcStartTime = WTF::monotonicallyIncreasingTime();
</span><ins>+    if (m_verifier) {
+        // Verify that live objects from the last GC cycle haven't been corrupted by
+        // mutators before we begin this new GC cycle.
+        m_verifier-&gt;verify(HeapVerifier::Phase::BeforeGC);
</ins><span class="cx"> 
</span><ins>+        m_verifier-&gt;initializeGCCycle();
+        m_verifier-&gt;gatherLiveObjects(HeapVerifier::Phase::BeforeMarking);
+    }
+
</ins><span class="cx">     deleteOldCode(gcStartTime);
</span><span class="cx">     flushOldStructureIDTables();
</span><span class="cx">     stopAllocation();
</span><span class="lines">@@ -1012,6 +1023,10 @@
</span><span class="cx"> 
</span><span class="cx">     markRoots(gcStartTime);
</span><span class="cx"> 
</span><ins>+    if (m_verifier) {
+        m_verifier-&gt;gatherLiveObjects(HeapVerifier::Phase::AfterMarking);
+        m_verifier-&gt;verify(HeapVerifier::Phase::AfterMarking);
+    }
</ins><span class="cx">     JAVASCRIPTCORE_GC_MARKED();
</span><span class="cx"> 
</span><span class="cx">     if (vm()-&gt;typeProfiler())
</span><span class="lines">@@ -1035,6 +1050,11 @@
</span><span class="cx">     didFinishCollection(gcStartTime);
</span><span class="cx">     resumeCompilerThreads();
</span><span class="cx"> 
</span><ins>+    if (m_verifier) {
+        m_verifier-&gt;trimDeadObjects();
+        m_verifier-&gt;verify(HeapVerifier::Phase::AfterGC);
+    }
+
</ins><span class="cx">     if (Options::logGC()) {
</span><span class="cx">         double after = currentTimeMS();
</span><span class="cx">         dataLog(after - before, &quot; ms]\n&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.h (176423 => 176424)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.h        2014-11-20 23:26:29 UTC (rev 176423)
+++ trunk/Source/JavaScriptCore/heap/Heap.h        2014-11-20 23:28:41 UTC (rev 176424)
</span><span class="lines">@@ -57,6 +57,7 @@
</span><span class="cx"> class GlobalCodeBlock;
</span><span class="cx"> class Heap;
</span><span class="cx"> class HeapRootVisitor;
</span><ins>+class HeapVerifier;
</ins><span class="cx"> class IncrementalSweeper;
</span><span class="cx"> class JITStubRoutine;
</span><span class="cx"> class JSCell;
</span><span class="lines">@@ -234,6 +235,7 @@
</span><span class="cx">     friend class GCAwareJITStubRoutine;
</span><span class="cx">     friend class GCLogging;
</span><span class="cx">     friend class HandleSet;
</span><ins>+    friend class HeapVerifier;
</ins><span class="cx">     friend class JITStubRoutine;
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx">     friend class MarkedSpace;
</span><span class="lines">@@ -383,6 +385,8 @@
</span><span class="cx">     
</span><span class="cx">     unsigned m_deferralDepth;
</span><span class="cx">     Vector&lt;DFG::Worklist*&gt; m_suspendedCompilerWorklists;
</span><ins>+
+    std::unique_ptr&lt;HeapVerifier&gt; m_verifier;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapVerifiercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/HeapVerifier.cpp (0 => 176424)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapVerifier.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/HeapVerifier.cpp        2014-11-20 23:28:41 UTC (rev 176424)
</span><span class="lines">@@ -0,0 +1,294 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;HeapVerifier.h&quot;
+
+#include &quot;ButterflyInlines.h&quot;
+#include &quot;CopiedSpaceInlines.h&quot;
+#include &quot;HeapIterationScope.h&quot;
+#include &quot;JSCInlines.h&quot;
+#include &quot;JSObject.h&quot;
+
+namespace JSC {
+
+LiveObjectData* LiveObjectList::findObject(JSObject* obj)
+{
+    for (size_t i = 0; i &lt; liveObjects.size(); i++) {
+        LiveObjectData&amp; data = liveObjects[i];
+        if (obj == data.obj)
+            return &amp;data;
+    }
+    return nullptr;
+}
+
+HeapVerifier::HeapVerifier(Heap* heap, unsigned numberOfGCCyclesToRecord)
+    : m_heap(heap)
+    , m_currentCycle(0)
+    , m_numberOfCycles(numberOfGCCyclesToRecord)
+{
+    RELEASE_ASSERT(m_numberOfCycles &gt; 0);
+    m_cycles = std::make_unique&lt;GCCycle[]&gt;(m_numberOfCycles);
+}
+
+const char* HeapVerifier::collectionTypeName(HeapOperation type)
+{
+    switch (type) {
+    case NoOperation:
+        return &quot;NoOperation&quot;;
+    case AnyCollection:
+        return &quot;AnyCollection&quot;;
+    case Allocation:
+        return &quot;Allocation&quot;;
+    case EdenCollection:
+        return &quot;EdenCollection&quot;;
+    case FullCollection:
+        return &quot;FullCollection&quot;;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr; // Silencing a compiler warning.
+}
+
+const char* HeapVerifier::phaseName(HeapVerifier::Phase phase)
+{
+    switch (phase) {
+    case Phase::BeforeGC:
+        return &quot;BeforeGC&quot;;
+    case Phase::BeforeMarking:
+        return &quot;BeforeMarking&quot;;
+    case Phase::AfterMarking:
+        return &quot;AfterMarking&quot;;
+    case Phase::AfterGC:
+        return &quot;AfterGC&quot;;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr; // Silencing a compiler warning.
+}
+
+static void getButterflyDetails(JSObject* obj, void*&amp; butterflyBase, size_t&amp; butterflyCapacityInBytes, CopiedBlock*&amp; butterflyBlock)
+{
+    Structure* structure = obj-&gt;structure();
+    Butterfly* butterfly = obj-&gt;butterfly();
+    butterflyBase = butterfly-&gt;base(structure);
+    butterflyBlock = CopiedSpace::blockFor(butterflyBase);
+
+    size_t propertyCapacity = structure-&gt;outOfLineCapacity();
+    size_t preCapacity;
+    size_t indexingPayloadSizeInBytes;
+    bool hasIndexingHeader = obj-&gt;hasIndexingHeader();
+    if (UNLIKELY(hasIndexingHeader)) {
+        preCapacity = butterfly-&gt;indexingHeader()-&gt;preCapacity(structure);
+        indexingPayloadSizeInBytes = butterfly-&gt;indexingHeader()-&gt;indexingPayloadSizeInBytes(structure);
+    } else {
+        preCapacity = 0;
+        indexingPayloadSizeInBytes = 0;
+    }
+    butterflyCapacityInBytes = Butterfly::totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
+}
+
+void HeapVerifier::initializeGCCycle()
+{
+    Heap* heap = m_heap;
+    incrementCycle();
+    currentCycle().collectionType = heap-&gt;operationInProgress();
+}
+
+struct GatherLiveObjFunctor : MarkedBlock::CountFunctor {
+    GatherLiveObjFunctor(LiveObjectList&amp; list)
+        : m_list(list)
+    {
+        ASSERT(!list.liveObjects.size());
+    }
+
+    void operator()(JSCell* cell)
+    {
+        if (!cell-&gt;isObject())
+            return;        
+        LiveObjectData data(asObject(cell));
+        m_list.liveObjects.append(data);
+    }
+
+    LiveObjectList&amp; m_list;
+};
+
+void HeapVerifier::gatherLiveObjects(HeapVerifier::Phase phase)
+{
+    Heap* heap = m_heap;
+    LiveObjectList&amp; list = *liveObjectListForGathering(phase);
+
+    HeapIterationScope iterationScope(*heap);
+    list.reset();
+    GatherLiveObjFunctor functor(list);
+    heap-&gt;m_objectSpace.forEachLiveCell(iterationScope, functor);
+}
+
+LiveObjectList* HeapVerifier::liveObjectListForGathering(HeapVerifier::Phase phase)
+{
+    switch (phase) {
+    case Phase::BeforeMarking:
+        return &amp;currentCycle().before;
+    case Phase::AfterMarking:
+        return &amp;currentCycle().after;
+    case Phase::BeforeGC:
+    case Phase::AfterGC:
+        // We should not be gathering live objects during these phases.
+        break;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr; // Silencing a compiler warning.
+}
+
+static void trimDeadObjectsFromList(HashSet&lt;JSObject*&gt;&amp; knownLiveSet, LiveObjectList&amp; list)
+{
+    if (!list.hasLiveObjects)
+        return;
+
+    size_t liveObjectsFound = 0;
+    for (size_t i = 0; i &lt; list.liveObjects.size(); i++) {
+        LiveObjectData&amp; objData = list.liveObjects[i];
+        if (objData.isConfirmedDead)
+            continue; // Don't &quot;resurrect&quot; known dead objects.
+        if (!knownLiveSet.contains(objData.obj)) {
+            objData.isConfirmedDead = true;
+            continue;
+        }
+        liveObjectsFound++;
+    }
+    list.hasLiveObjects = !!liveObjectsFound;
+}
+
+void HeapVerifier::trimDeadObjects()
+{
+    HashSet&lt;JSObject*&gt; knownLiveSet;
+
+    LiveObjectList&amp; after = currentCycle().after;
+    for (size_t i = 0; i &lt; after.liveObjects.size(); i++) {
+        LiveObjectData&amp; objData = after.liveObjects[i];
+        knownLiveSet.add(objData.obj);
+    }
+
+    trimDeadObjectsFromList(knownLiveSet, currentCycle().before);
+
+    for (int i = -1; i &gt; -m_numberOfCycles; i--) {
+        trimDeadObjectsFromList(knownLiveSet, cycleForIndex(i).before);
+        trimDeadObjectsFromList(knownLiveSet, cycleForIndex(i).after);
+    }
+}
+
+bool HeapVerifier::verifyButterflyIsInStorageSpace(Phase phase, LiveObjectList&amp; list)
+{
+    auto&amp; liveObjects = list.liveObjects;
+
+    CopiedSpace&amp; storageSpace = m_heap-&gt;m_storageSpace;
+    bool listNamePrinted = false;
+    bool success = true;
+    for (size_t i = 0; i &lt; liveObjects.size(); i++) {
+        LiveObjectData&amp; objectData = liveObjects[i];
+        if (objectData.isConfirmedDead)
+            continue;
+
+        JSObject* obj = objectData.obj;
+        Butterfly* butterfly = obj-&gt;butterfly();
+        if (butterfly) {
+            void* butterflyBase;
+            size_t butterflyCapacityInBytes;
+            CopiedBlock* butterflyBlock;
+            getButterflyDetails(obj, butterflyBase, butterflyCapacityInBytes, butterflyBlock);
+
+            if (!storageSpace.contains(butterflyBlock)) {
+                if (!listNamePrinted) {
+                    dataLogF(&quot;Verification @ phase %s FAILED in object list '%s' (size %zu)\n&quot;,
+                        phaseName(phase), list.name, liveObjects.size());
+                    listNamePrinted = true;
+                }
+
+                Structure* structure = obj-&gt;structure();
+                const char* structureClassName = structure-&gt;classInfo()-&gt;className;
+                dataLogF(&quot;    butterfly %p (base %p size %zu block %p) NOT in StorageSpace | obj %p type '%s'\n&quot;,
+                    butterfly, butterflyBase, butterflyCapacityInBytes, butterflyBlock, obj, structureClassName);
+                success = false;
+            }
+        }
+    }
+    return success;
+}
+
+void HeapVerifier::verify(HeapVerifier::Phase phase)
+{
+    bool beforeVerified = verifyButterflyIsInStorageSpace(phase, currentCycle().before);
+    bool afterVerified = verifyButterflyIsInStorageSpace(phase, currentCycle().after);
+    RELEASE_ASSERT(beforeVerified &amp;&amp; afterVerified);
+}
+
+void HeapVerifier::reportObject(LiveObjectData&amp; objData, int cycleIndex, HeapVerifier::GCCycle&amp; cycle, LiveObjectList&amp; list)
+{
+    JSObject* obj = objData.obj;
+
+    if (objData.isConfirmedDead) {
+        dataLogF(&quot;FOUND dead obj %p in GC[%d] %s list '%s'\n&quot;,
+            obj, cycleIndex, cycle.collectionTypeName(), list.name);
+        return;
+    }
+
+    Structure* structure = obj-&gt;structure();
+    Butterfly* butterfly = obj-&gt;butterfly();
+    void* butterflyBase;
+    size_t butterflyCapacityInBytes;
+    CopiedBlock* butterflyBlock;
+    getButterflyDetails(obj, butterflyBase, butterflyCapacityInBytes, butterflyBlock);
+
+    dataLogF(&quot;FOUND obj %p type '%s' butterfly %p (base %p size %zu block %p) in GC[%d] %s list '%s'\n&quot;,
+        obj, structure-&gt;classInfo()-&gt;className,
+        butterfly, butterflyBase, butterflyCapacityInBytes, butterflyBlock,
+        cycleIndex, cycle.collectionTypeName(), list.name);
+}
+
+void HeapVerifier::checkIfRecorded(JSObject* obj)
+{
+    bool found = false;
+
+    for (int cycleIndex = 0; cycleIndex &gt; -m_numberOfCycles; cycleIndex--) {
+        GCCycle&amp; cycle = cycleForIndex(cycleIndex);
+        LiveObjectList&amp; beforeList = cycle.before; 
+        LiveObjectList&amp; afterList = cycle.after; 
+
+        LiveObjectData* objData;
+        objData = beforeList.findObject(obj);
+        if (objData) {
+            reportObject(*objData, cycleIndex, cycle, beforeList);
+            found = true;
+        }
+        objData = afterList.findObject(obj);
+        if (objData) {
+            reportObject(*objData, cycleIndex, cycle, afterList);
+            found = true;
+        }
+    }
+
+    if (!found)
+        dataLogF(&quot;obj %p NOT FOUND\n&quot;, obj);
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapVerifierh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/HeapVerifier.h (0 => 176424)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapVerifier.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/HeapVerifier.h        2014-11-20 23:28:41 UTC (rev 176424)
</span><span class="lines">@@ -0,0 +1,134 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef HeapVerifier_h
+#define HeapVerifier_h
+
+#include &quot;Heap.h&quot;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC {
+
+class JSObject;
+class MarkedBlock;
+
+struct LiveObjectData {
+    LiveObjectData(JSObject* obj, bool isConfirmedDead = false)
+        : obj(obj)
+        , isConfirmedDead(isConfirmedDead)
+    {
+    }
+
+    JSObject* obj;
+    bool isConfirmedDead;
+};
+
+struct LiveObjectList {
+    LiveObjectList(const char* name)
+        : name(name)
+        , hasLiveObjects(true)
+    {
+    }
+
+    void reset()
+    {
+        liveObjects.clear();
+        hasLiveObjects = true; // Presume to have live objects until the list is trimmed.
+    }
+
+    LiveObjectData* findObject(JSObject*);
+
+    const char* name;
+    Vector&lt;LiveObjectData&gt; liveObjects;
+    bool hasLiveObjects;
+};
+
+class HeapVerifier {
+public:
+    enum class Phase {
+        BeforeGC,
+        BeforeMarking,
+        AfterMarking,
+        AfterGC
+    };
+
+    HeapVerifier(Heap*, unsigned numberOfGCCyclesToRecord);
+
+    void initializeGCCycle();
+    void gatherLiveObjects(Phase);
+    void trimDeadObjects();
+    void verify(Phase);
+
+    // Scans all previously recorded LiveObjectLists and checks if the specified
+    // object was in any of those lists.
+    JS_EXPORT_PRIVATE void checkIfRecorded(JSObject*);
+
+    static const char* collectionTypeName(HeapOperation);
+    static const char* phaseName(Phase);
+
+private:
+    struct GCCycle {
+        GCCycle()
+            : before(&quot;Before Marking&quot;)
+            , after(&quot;After Marking&quot;)
+        {
+        }
+
+        HeapOperation collectionType;
+        LiveObjectList before;
+        LiveObjectList after;
+
+        const char* collectionTypeName() const
+        {
+            return HeapVerifier::collectionTypeName(collectionType);
+        }
+    };
+
+    void incrementCycle() { m_currentCycle = (m_currentCycle + 1) % m_numberOfCycles; }
+    GCCycle&amp; currentCycle() { return m_cycles[m_currentCycle]; }
+    GCCycle&amp; cycleForIndex(int cycleIndex)
+    {
+        ASSERT(cycleIndex &lt;= 0 &amp;&amp; cycleIndex &gt; -m_numberOfCycles);
+        cycleIndex += m_currentCycle;
+        if (cycleIndex &lt; 0)
+            cycleIndex += m_numberOfCycles;
+        ASSERT(cycleIndex &lt; m_numberOfCycles);
+        return m_cycles[cycleIndex];
+    }
+
+    LiveObjectList* liveObjectListForGathering(Phase);
+    bool verifyButterflyIsInStorageSpace(Phase, LiveObjectList&amp;);
+
+    static void reportObject(LiveObjectData&amp;, int cycleIndex, HeapVerifier::GCCycle&amp;, LiveObjectList&amp;);
+
+    Heap* m_heap;
+    int m_currentCycle;
+    int m_numberOfCycles;
+    std::unique_ptr&lt;GCCycle[]&gt; m_cycles;
+};
+
+} // namespace JSC
+
+#endif // HeapVerifier
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (176423 => 176424)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2014-11-20 23:26:29 UTC (rev 176423)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2014-11-20 23:28:41 UTC (rev 176424)
</span><span class="lines">@@ -287,6 +287,9 @@
</span><span class="cx">     v(bool, logHeapStatisticsAtExit, false) \
</span><span class="cx">     v(bool, enableTypeProfiler, false) \
</span><span class="cx">     \
</span><ins>+    v(bool, verifyHeap, true) \
+    v(unsigned, numberOfGCCyclesToRecordForVerification, 3) \
+    \
</ins><span class="cx">     v(bool, enableExceptionFuzz, false) \
</span><span class="cx">     v(unsigned, fireExceptionFuzzAt, 0)
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>