<!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>[210868] branches/safari-603-branch</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/210868">210868</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2017-01-18 12:43:04 -0800 (Wed, 18 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/210844">r210844</a>. rdar://problem/29993906</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari603branchJSTestsChangeLog">branches/safari-603-branch/JSTests/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreCMakeListstxt">branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreChangeLog">branches/safari-603-branch/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorebytecodeObjectAllocationProfileh">branches/safari-603-branch/Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorebytecodePolymorphicAccesscpp">branches/safari-603-branch/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJITcpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreftlFTLAbstractHeapRepositoryh">branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapAllocatorAttributesh">branches/safari-603-branch/Source/JavaScriptCore/heap/AllocatorAttributes.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapGCActivityCallbackcpp">branches/safari-603-branch/Source/JavaScriptCore/heap/GCActivityCallback.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapHeapcpp">branches/safari-603-branch/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapHeaph">branches/safari-603-branch/Source/JavaScriptCore/heap/Heap.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapHeapInlinesh">branches/safari-603-branch/Source/JavaScriptCore/heap/HeapInlines.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapLargeAllocationcpp">branches/safari-603-branch/Source/JavaScriptCore/heap/LargeAllocation.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapLargeAllocationh">branches/safari-603-branch/Source/JavaScriptCore/heap/LargeAllocation.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkedAllocatorcpp">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocator.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkedAllocatorh">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocator.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkedBlockcpp">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlock.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkedBlockh">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlock.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkedBlockInlinesh">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlockInlines.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkedSpacecpp">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedSpace.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkedSpaceh">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedSpace.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkingConstraintcpp">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraint.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkingConstrainth">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraint.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkingConstraintSetcpp">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraintSet.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkingConstraintSeth">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraintSet.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapSlotVisitorcpp">branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitor.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapSlotVisitorh">branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitor.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapSlotVisitorInlinesh">branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitorInlines.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapWeakBlockcpp">branches/safari-603-branch/Source/JavaScriptCore/heap/WeakBlock.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapWeakBlockh">branches/safari-603-branch/Source/JavaScriptCore/heap/WeakBlock.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapWeakSeth">branches/safari-603-branch/Source/JavaScriptCore/heap/WeakSet.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorejitAssemblyHelpersh">branches/safari-603-branch/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorejitJITOpcodescpp">branches/safari-603-branch/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorejitJITOpcodes32_64cpp">branches/safari-603-branch/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorejsccpp">branches/safari-603-branch/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeButterflyInlinesh">branches/safari-603-branch/Source/JavaScriptCore/runtime/ButterflyInlines.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeClassInfoh">branches/safari-603-branch/Source/JavaScriptCore/runtime/ClassInfo.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeClonedArgumentscpp">branches/safari-603-branch/Source/JavaScriptCore/runtime/ClonedArguments.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeDirectArgumentscpp">branches/safari-603-branch/Source/JavaScriptCore/runtime/DirectArguments.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeGenericArgumentsInlinesh">branches/safari-603-branch/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeHashMapImplh">branches/safari-603-branch/Source/JavaScriptCore/runtime/HashMapImpl.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSArraycpp">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSArray.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSArrayBufferViewcpp">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSCellh">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSCell.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSCellInlinesh">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSCellInlines.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSDestructibleObjecth">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObject.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSObjecth">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSObject.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSObjectInlinesh">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSObjectInlines.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSSegmentedVariableObjecth">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSStringh">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSString.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeRegExpMatchesArrayh">branches/safari-603-branch/Source/JavaScriptCore/runtime/RegExpMatchesArray.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeVMcpp">branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeVMh">branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoreCMakeListstxt">branches/safari-603-branch/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#branchessafari603branchSourceWebCoreChangeLog">branches/safari-603-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceWebCoreWebCorexcodeprojprojectpbxproj">branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchessafari603branchSourceWebCorebindingsjsCommonVMcpp">branches/safari-603-branch/Source/WebCore/bindings/js/CommonVM.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCorebindingsjsCommonVMh">branches/safari-603-branch/Source/WebCore/bindings/js/CommonVM.h</a></li>
<li><a href="#branchessafari603branchSourceWebCorebindingsjsJSDOMGlobalObjectcpp">branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCorebindingsjsJSDOMWrappercpp">branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMWrapper.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCorebindingsjsJSDOMWrapperh">branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMWrapper.h</a></li>
<li><a href="#branchessafari603branchSourceWebCorebindingsjsWebCoreJSClientDatah">branches/safari-603-branch/Source/WebCore/bindings/js/WebCoreJSClientData.h</a></li>
<li><a href="#branchessafari603branchSourceWebCorebindingsjsWorkerScriptControllercpp">branches/safari-603-branch/Source/WebCore/bindings/js/WorkerScriptController.cpp</a></li>
<li><a href="#branchessafari603branchSourceWebCorebindingsscriptsCodeGeneratorJSpm">branches/safari-603-branch/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
<li><a href="#branchessafari603branchSourceWebCoredomContainerNodeAlgorithmscpp">branches/safari-603-branch/Source/WebCore/dom/ContainerNodeAlgorithms.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari603branchJSTestsmicrobenchmarksstringallocjs">branches/safari-603-branch/JSTests/microbenchmarks/stringalloc.js</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapConstraintVolatilityh">branches/safari-603-branch/Source/JavaScriptCore/heap/ConstraintVolatility.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapMarkedAllocatorInlinesh">branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocatorInlines.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapSubspacecpp">branches/safari-603-branch/Source/JavaScriptCore/heap/Subspace.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapSubspaceh">branches/safari-603-branch/Source/JavaScriptCore/heap/Subspace.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreheapSubspaceInlinesh">branches/safari-603-branch/Source/JavaScriptCore/heap/SubspaceInlines.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSDestructibleObjectSubspacecpp">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObjectSubspace.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSDestructibleObjectSubspaceh">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObjectSubspace.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSStringSubspacecpp">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSStringSubspace.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSStringSubspaceh">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSStringSubspace.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoreForwardingHeadersheapMarkedAllocatorInlinesh">branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkedAllocatorInlines.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoreForwardingHeadersheapMarkedBlockInlinesh">branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkedBlockInlines.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoreForwardingHeadersheapMarkingConstrainth">branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkingConstraint.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoreForwardingHeadersheapSubspaceInlinesh">branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/SubspaceInlines.h</a></li>
<li><a href="#branchessafari603branchSourceWebCoreForwardingHeadersheapVisitingTimeouth">branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/VisitingTimeout.h</a></li>
<li><a href="#branchessafari603branchSourceWebCorebindingsjsWebCoreJSClientDatacpp">branches/safari-603-branch/Source/WebCore/bindings/js/WebCoreJSClientData.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari603branchJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/JSTests/ChangeLog (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/ChangeLog        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/JSTests/ChangeLog        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,20 @@
</span><span class="cx"> 2017-01-18  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r210844. rdar://problem/29993906
+
+    2017-01-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+            Make opaque root scanning truly constraint-based
+            https://bugs.webkit.org/show_bug.cgi?id=165760
+
+            Reviewed by Geoffrey Garen.
+
+            Added this test, which demonstrates the benefit of having a dedicated string subspace.
+
+            * microbenchmarks/stringalloc.js: Added.
+
+2017-01-18  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r210695. rdar://problem/29913445
</span><span class="cx"> 
</span><span class="cx">     2017-01-12  Saam Barati  &lt;sbarati@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari603branchJSTestsmicrobenchmarksstringallocjs"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/JSTests/microbenchmarks/stringalloc.js (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/microbenchmarks/stringalloc.js                                (rev 0)
+++ branches/safari-603-branch/JSTests/microbenchmarks/stringalloc.js        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+var global;
+var array = [&quot;a&quot;, &quot;b&quot;];
+for (var i = 0; i &lt; 10000000; ++i)
+    global = array[i &amp; 1] + &quot;c&quot;;
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -504,6 +504,7 @@
</span><span class="cx">     heap/SlotVisitor.cpp
</span><span class="cx">     heap/SpaceTimeMutatorScheduler.cpp
</span><span class="cx">     heap/StopIfNecessaryTimer.cpp
</span><ins>+    heap/Subspace.cpp
</ins><span class="cx">     heap/SynchronousStopTheWorldMutatorScheduler.cpp
</span><span class="cx">     heap/VisitRaceKey.cpp
</span><span class="cx">     heap/Weak.cpp
</span><span class="lines">@@ -752,6 +753,7 @@
</span><span class="cx">     runtime/JSDataView.cpp
</span><span class="cx">     runtime/JSDataViewPrototype.cpp
</span><span class="cx">     runtime/JSDateMath.cpp
</span><ins>+    runtime/JSDestructibleObjectSubspace.cpp
</ins><span class="cx">     runtime/JSEnvironmentRecord.cpp
</span><span class="cx">     runtime/JSFixedArray.cpp
</span><span class="cx">     runtime/JSFunction.cpp
</span><span class="lines">@@ -790,6 +792,7 @@
</span><span class="cx">     runtime/JSString.cpp
</span><span class="cx">     runtime/JSStringIterator.cpp
</span><span class="cx">     runtime/JSStringJoiner.cpp
</span><ins>+    runtime/JSStringSubspace.cpp
</ins><span class="cx">     runtime/JSSymbolTableObject.cpp
</span><span class="cx">     runtime/JSTemplateRegistryKey.cpp
</span><span class="cx">     runtime/JSTypedArrayConstructors.cpp
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/ChangeLog (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/ChangeLog        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/ChangeLog        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,353 @@
</span><span class="cx"> 2017-01-18  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r210844. rdar://problem/29993906
+
+    2017-01-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+            Make opaque root scanning truly constraint-based
+            https://bugs.webkit.org/show_bug.cgi?id=165760
+
+            Reviewed by Geoffrey Garen.
+
+            We have bugs when visitChildren() changes its mind about what opaque root to add, since
+            we don't have barriers on opaque roots. This supposedly once worked for generational GC,
+            and I started adding more barriers to support concurrent GC. But I think that the real
+            bug here is that we want the JSObject-&gt;OpaqueRoot to be evaluated as a constraint that
+            participates in the fixpoint. I like to think of this as an *output* constraint, because it
+            is concerned with outgoing edges in the heap from the object that registered the constraint.
+            An *input* constraint is like what Weak&lt;&gt; does when deciding whether the thing it points to
+            should be live.
+
+            Whether or not an object has output constraints depends on its type. So, we want the GC to
+            have a feature where we rapidly call some function on all marked objects of some type.
+
+            It's easy to rapidly scan all marked objects in a MarkedBlock. So, we want to allocate all
+            objects that have output constraints in their own MarkedBlocks and we want to track the set
+            of MarkedBlocks with output constraints.
+
+            This patch makes it easy to have clients of JSC's internal C++ APIs create a Subspace - like
+            what we used to call MarkedSpace::Subspace but now it's in the JSC namespace - which is
+            a collection of objects that you can easily scan during GC from a MarkingConstraint. It's
+            now possible for internal C++ API clients to register their own MarkingConstraints. The DOM
+            now uses this to create two Subspaces (more on why two below) and it calls
+            JSCell::visitOutputConstraints() on all of the marked objects in those subspaces using a new
+            MarkingConstraint. That MarkingConstraint uses a new style of volatility, called
+            SeldomGreyed, which is like GreyedByExecution except it is opportunistically not executed
+            as roots in the hopes that their sole execution will be the snapshot-at-the-end. I also
+            converted the CodeBlock rescan constraint to SeldomGreyed, since that's also an output
+            constraint.
+
+            This patch also uses Subspace for something pretty obvious: knowing how to call the
+            destructor. Subspaces can specialize the sweep for their way of invoking destructors. We
+            have the following subspaces:
+
+            - auxiliary
+            - cell
+            - destructibleCell - for JSCell subclasses that have destructors and StructureIsImmortal
+            - stringSpace - inlines ~JSString into the sweep, making string allocation 7% faster
+            - destructibleObjectSpace - for JSDestructibleObject subclasses
+
+            And WebCore adds:
+
+            - outputConstraint - for JSDOMObjects that have a visitAdditionalChildren
+            - globalObjectOutputConstraint - for JSDOMGlobalObjects that have a visitAdditionalChildren,
+              since JSDOMGlobalObjects are not JSDestructibleObjects
+
+            The Subspace for a type is selected by saying JSC::subspaceFor&lt;Type&gt;(vm). This calls
+            Type::subspaceFor&lt;Type&gt;(vm). This allows cell classes to override subspaceFor&lt;&gt; and it
+            allows any subspaceFor&lt;&gt; implementation to query static flags in the type. This is how
+            JSCell::subspaceFor&lt;&gt; can select either cellSpace or destructibleCellSpace.
+
+            This patch is mostly about:
+
+            - Moving MarkedSpace::Subspace out of MarkedSpace and making it a nice class with a nice
+              API. Almost all of its functionality is just taken out of MarkedSpace.
+            - Converting users of the old API for allocating objects and getting MarkedAllocators, like
+              heap.allocatorForObjectWithoutDestructor() and its friends. That would now say
+              vm.cellSpace.allocatorFor().
+
+            Altogether, this means that we only have a small regression on Dromaeo. The regression is
+            due to the fact that we scan output constraints. Before the Subspace optimizations (see
+            r209766, which was rolled out in r209812), this regression on Dromaeo/jslib was 2x but after
+            the optimizations in this patch it's only 1.12x. Note that Dromaeo/jslib creats gigabytes of
+            DOM nodes. Compared to web pages, this is a very extreme synthetic microbenchmark. Still, we
+            like optimizing these because we don't want to presume what web pages will look like.
+
+            The use of Subspaces to specialize destructors happened not because it's super necessary but
+            because I wanted to introduce a single unified way of communicating to the GC how to treat
+            different types. Any Subspace feature that allowed us to collect some types together would
+            have to be mindful of the destructorness of objects. I could have turned this into a
+            liability where each Subspace has two subsubspaces - one for destructor objects and one for
+            non-destructor objects, which would have allowed me to keep the old sweep specialization
+            code. Just days prior, mlam wanted to do something that was hard because of that old sweep
+            specializer, so I decided to take the opportunity to fix the sweep specializer while also
+            making Subspace be the one true way of teaching the GC about types. To validate that this
+            actually does things, I added a JSStringSubspace and a test that shows that this is a 7%
+            string allocation progression.
+
+            In bug 167066, I'm getting rid of the rest of the code in JSC that would special-case for
+            JSDestructibleObject vs StructureIsImmortal by using the GC's DestructionMode. After that,
+            Subspace will be only mechanism by which JSC uses the GC to encode types.
+
+            Prior to this change, having multiple MarkedSpace::Subspaces would have been expensive
+            because they create a bunch of MarkedAllocators upfront. We now have the ability to create
+            MarkedAllocators lazily. We create them on the first allocation from that size class or when
+            a JIT asks for the MarkedAllocator. The concurrent JITs can ask for MarkedAllocators because
+            their creation is under a lock.
+
+            On my machine, this might be a 1.1% JetStream speed-up with 87% confidence and it might be
+            a 0.4% PLT3 slow-down with 92% confidence. Note that 0.4% on PLT3 is the level of systematic
+            error on PLT3 on my computer: I've seen definite 0.4% speed-ups and slow-downs that were not
+            confirmed by any bot. Let's see what the bots say.
+
+            * CMakeLists.txt:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * bytecode/ObjectAllocationProfile.h:
+            (JSC::ObjectAllocationProfile::initialize):
+            * bytecode/PolymorphicAccess.cpp:
+            (JSC::AccessCase::generateImpl):
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::emitAllocateRawObject):
+            (JSC::DFG::SpeculativeJIT::compileMakeRope):
+            (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
+            (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+            (JSC::DFG::SpeculativeJIT::compileNewTypedArray):
+            (JSC::DFG::SpeculativeJIT::emitAllocateButterfly):
+            * dfg/DFGSpeculativeJIT64.cpp:
+            (JSC::DFG::SpeculativeJIT::compile):
+            * ftl/FTLAbstractHeapRepository.h:
+            * ftl/FTLLowerDFGToB3.cpp:
+            (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray):
+            (JSC::FTL::DFG::LowerDFGToB3::compileMakeRope):
+            (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject):
+            (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorageWithSizeImpl):
+            (JSC::FTL::DFG::LowerDFGToB3::allocateObject):
+            (JSC::FTL::DFG::LowerDFGToB3::allocatorForSize):
+            (JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedObject):
+            (JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedCell):
+            (JSC::FTL::DFG::LowerDFGToB3::allocateJSArray):
+            * heap/AllocatorAttributes.h:
+            (JSC::AllocatorAttributes::AllocatorAttributes):
+            * heap/ConstraintVolatility.h: Added.
+            (WTF::printInternal):
+            * heap/GCActivityCallback.cpp:
+            * heap/Heap.cpp:
+            (JSC::Heap::Heap):
+            (JSC::Heap::lastChanceToFinalize):
+            (JSC::Heap::markToFixpoint):
+            (JSC::Heap::updateObjectCounts):
+            (JSC::Heap::collectAllGarbage):
+            (JSC::Heap::collectInThread):
+            (JSC::Heap::stopTheWorld):
+            (JSC::Heap::updateAllocationLimits):
+            (JSC::Heap::bytesVisited):
+            (JSC::Heap::addCoreConstraints):
+            (JSC::Heap::addMarkingConstraint):
+            (JSC::Heap::notifyIsSafeToCollect):
+            (JSC::Heap::preventCollection):
+            (JSC::Heap::allowCollection):
+            (JSC::Heap::setMutatorShouldBeFenced):
+            (JSC::Heap::buildConstraintSet): Deleted.
+            (JSC::Heap::writeBarrierOpaqueRootSlow): Deleted.
+            (JSC::Heap::addMutatorShouldBeFencedCache): Deleted.
+            * heap/Heap.h:
+            (JSC::Heap::mutatorExecutionVersion):
+            (JSC::Heap::numOpaqueRoots):
+            (JSC::Heap::vm): Deleted.
+            (JSC::Heap::subspaceForObjectWithoutDestructor): Deleted.
+            (JSC::Heap::subspaceForObjectDestructor): Deleted.
+            (JSC::Heap::subspaceForAuxiliaryData): Deleted.
+            (JSC::Heap::allocatorForObjectWithoutDestructor): Deleted.
+            (JSC::Heap::allocatorForObjectWithDestructor): Deleted.
+            (JSC::Heap::allocatorForAuxiliaryData): Deleted.
+            * heap/HeapInlines.h:
+            (JSC::Heap::vm):
+            (JSC::Heap::allocateWithDestructor): Deleted.
+            (JSC::Heap::allocateWithoutDestructor): Deleted.
+            (JSC::Heap::allocateObjectOfType): Deleted.
+            (JSC::Heap::subspaceForObjectOfType): Deleted.
+            (JSC::Heap::allocatorForObjectOfType): Deleted.
+            (JSC::Heap::allocateAuxiliary): Deleted.
+            (JSC::Heap::tryAllocateAuxiliary): Deleted.
+            (JSC::Heap::tryReallocateAuxiliary): Deleted.
+            (JSC::Heap::ascribeOwner): Deleted.
+            (JSC::Heap::writeBarrierOpaqueRoot): Deleted.
+            * heap/LargeAllocation.cpp:
+            (JSC::LargeAllocation::tryCreate):
+            (JSC::LargeAllocation::LargeAllocation):
+            (JSC::LargeAllocation::~LargeAllocation):
+            (JSC::LargeAllocation::sweep):
+            * heap/LargeAllocation.h:
+            * heap/MarkedAllocator.cpp:
+            (JSC::MarkedAllocator::MarkedAllocator):
+            (JSC::MarkedAllocator::tryAllocateWithoutCollecting):
+            (JSC::MarkedAllocator::tryAllocateIn):
+            (JSC::MarkedAllocator::allocateSlowCaseImpl):
+            (JSC::MarkedAllocator::tryAllocateBlock):
+            (JSC::MarkedAllocator::shrink):
+            (JSC::MarkedAllocator::markedSpace):
+            * heap/MarkedAllocator.h:
+            (JSC::MarkedAllocator::nextAllocatorInSubspace):
+            (JSC::MarkedAllocator::setNextAllocatorInSubspace):
+            (JSC::MarkedAllocator::subspace):
+            (JSC::MarkedAllocator::tryAllocate): Deleted.
+            (JSC::MarkedAllocator::allocate): Deleted.
+            (JSC::MarkedAllocator::forEachBlock): Deleted.
+            * heap/MarkedAllocatorInlines.h: Added.
+            (JSC::MarkedAllocator::tryAllocate):
+            (JSC::MarkedAllocator::allocate):
+            (JSC::MarkedAllocator::forEachBlock):
+            (JSC::MarkedAllocator::forEachNotEmptyBlock):
+            * heap/MarkedBlock.cpp:
+            (JSC::MarkedBlock::Handle::subspace):
+            (JSC::MarkedBlock::Handle::sweep):
+            (JSC::MarkedBlock::Handle::specializedSweep): Deleted.
+            (JSC::MarkedBlock::Handle::sweepHelperSelectScribbleMode): Deleted.
+            (JSC::MarkedBlock::Handle::sweepHelperSelectEmptyMode): Deleted.
+            (JSC::MarkedBlock::Handle::sweepHelperSelectHasNewlyAllocated): Deleted.
+            (JSC::MarkedBlock::Handle::sweepHelperSelectSweepMode): Deleted.
+            (JSC::MarkedBlock::Handle::sweepHelperSelectMarksMode): Deleted.
+            * heap/MarkedBlock.h:
+            (JSC::MarkedBlock::Handle::visitWeakSet):
+            * heap/MarkedBlockInlines.h:
+            (JSC::MarkedBlock::Handle::isNewlyAllocatedStale):
+            (JSC::MarkedBlock::Handle::hasAnyNewlyAllocated):
+            (JSC::MarkedBlock::heap):
+            (JSC::MarkedBlock::space):
+            (JSC::MarkedBlock::Handle::space):
+            (JSC::MarkedBlock::Handle::specializedSweep):
+            (JSC::MarkedBlock::Handle::finishSweepKnowingSubspace):
+            (JSC::MarkedBlock::Handle::sweepDestructionMode):
+            (JSC::MarkedBlock::Handle::emptyMode):
+            (JSC::MarkedBlock::Handle::scribbleMode):
+            (JSC::MarkedBlock::Handle::newlyAllocatedMode):
+            (JSC::MarkedBlock::Handle::marksMode):
+            (JSC::MarkedBlock::Handle::forEachMarkedCell):
+            * heap/MarkedSpace.cpp:
+            (JSC::MarkedSpace::initializeSizeClassForStepSize):
+            (JSC::MarkedSpace::MarkedSpace):
+            (JSC::MarkedSpace::lastChanceToFinalize):
+            (JSC::MarkedSpace::addMarkedAllocator):
+            (JSC::MarkedSpace::allocate): Deleted.
+            (JSC::MarkedSpace::tryAllocate): Deleted.
+            (JSC::MarkedSpace::allocateLarge): Deleted.
+            (JSC::MarkedSpace::tryAllocateLarge): Deleted.
+            * heap/MarkedSpace.h:
+            (JSC::MarkedSpace::heap):
+            (JSC::MarkedSpace::allocatorLock):
+            (JSC::MarkedSpace::subspaceForObjectsWithDestructor): Deleted.
+            (JSC::MarkedSpace::subspaceForObjectsWithoutDestructor): Deleted.
+            (JSC::MarkedSpace::subspaceForAuxiliaryData): Deleted.
+            (JSC::MarkedSpace::allocatorFor): Deleted.
+            (JSC::MarkedSpace::destructorAllocatorFor): Deleted.
+            (JSC::MarkedSpace::auxiliaryAllocatorFor): Deleted.
+            (JSC::MarkedSpace::allocateWithoutDestructor): Deleted.
+            (JSC::MarkedSpace::allocateWithDestructor): Deleted.
+            (JSC::MarkedSpace::allocateAuxiliary): Deleted.
+            (JSC::MarkedSpace::tryAllocateAuxiliary): Deleted.
+            (JSC::MarkedSpace::forEachSubspace): Deleted.
+            * heap/MarkingConstraint.cpp:
+            (JSC::MarkingConstraint::MarkingConstraint):
+            * heap/MarkingConstraint.h:
+            (JSC::MarkingConstraint::volatility):
+            * heap/MarkingConstraintSet.cpp:
+            (JSC::MarkingConstraintSet::resetStats):
+            (JSC::MarkingConstraintSet::add):
+            (JSC::MarkingConstraintSet::executeConvergenceImpl):
+            * heap/MarkingConstraintSet.h:
+            * heap/SlotVisitor.cpp:
+            (JSC::SlotVisitor::visitChildren):
+            (JSC::SlotVisitor::visitAsConstraint):
+            (JSC::SlotVisitor::drain):
+            (JSC::SlotVisitor::addOpaqueRoot):
+            (JSC::SlotVisitor::mergeIfNecessary):
+            (JSC::SlotVisitor::mergeOpaqueRootsIfNecessary): Deleted.
+            * heap/SlotVisitor.h:
+            (JSC::SlotVisitor::setIgnoreNewOpaqueRoots):
+            * heap/SlotVisitorInlines.h:
+            (JSC::SlotVisitor::reportExtraMemoryVisited):
+            (JSC::SlotVisitor::reportExternalMemoryVisited):
+            * heap/Subspace.cpp: Added.
+            (JSC::Subspace::Subspace):
+            (JSC::Subspace::~Subspace):
+            (JSC::Subspace::finishSweep):
+            (JSC::Subspace::destroy):
+            (JSC::Subspace::allocate):
+            (JSC::Subspace::tryAllocate):
+            (JSC::Subspace::allocatorForSlow):
+            (JSC::Subspace::allocateSlow):
+            (JSC::Subspace::tryAllocateSlow):
+            * heap/Subspace.h: Added.
+            (JSC::Subspace::tryAllocatorFor):
+            (JSC::Subspace::allocatorFor):
+            * heap/SubspaceInlines.h: Added.
+            (JSC::Subspace::forEachMarkedBlock):
+            (JSC::Subspace::forEachNotEmptyMarkedBlock):
+            (JSC::Subspace::forEachLargeAllocation):
+            (JSC::Subspace::forEachMarkedCell):
+            * heap/WeakBlock.cpp:
+            (JSC::WeakBlock::specializedVisit):
+            * heap/WeakBlock.h:
+            * heap/WeakSet.h:
+            (JSC::WeakSet::visit):
+            * jit/AssemblyHelpers.h:
+            (JSC::AssemblyHelpers::emitAllocateJSObjectWithKnownSize):
+            (JSC::AssemblyHelpers::emitAllocateVariableSized):
+            (JSC::AssemblyHelpers::emitAllocateVariableSizedCell):
+            * jit/JITOpcodes.cpp:
+            (JSC::JIT::emit_op_new_object):
+            * jsc.cpp:
+            * runtime/ButterflyInlines.h:
+            (JSC::Butterfly::createUninitialized):
+            (JSC::Butterfly::growArrayRight):
+            * runtime/ClassInfo.h:
+            * runtime/ClonedArguments.cpp:
+            (JSC::ClonedArguments::createEmpty):
+            * runtime/DirectArguments.cpp:
+            (JSC::DirectArguments::overrideThings):
+            * runtime/GenericArgumentsInlines.h:
+            (JSC::GenericArguments&lt;Type&gt;::initModifiedArgumentsDescriptor):
+            * runtime/HashMapImpl.h:
+            (JSC::HashMapBuffer::create):
+            * runtime/JSArray.cpp:
+            (JSC::JSArray::tryCreateUninitialized):
+            (JSC::JSArray::unshiftCountSlowCase):
+            * runtime/JSArrayBufferView.cpp:
+            (JSC::JSArrayBufferView::ConstructionContext::ConstructionContext):
+            * runtime/JSCell.h:
+            (JSC::subspaceFor):
+            * runtime/JSCellInlines.h:
+            (JSC::JSCell::visitOutputConstraints):
+            (JSC::JSCell::subspaceFor):
+            (JSC::allocateCell):
+            * runtime/JSDestructibleObject.h:
+            (JSC::JSDestructibleObject::subspaceFor):
+            * runtime/JSDestructibleObjectSubspace.cpp: Added.
+            (JSC::JSDestructibleObjectSubspace::JSDestructibleObjectSubspace):
+            (JSC::JSDestructibleObjectSubspace::~JSDestructibleObjectSubspace):
+            (JSC::JSDestructibleObjectSubspace::finishSweep):
+            (JSC::JSDestructibleObjectSubspace::destroy):
+            * runtime/JSDestructibleObjectSubspace.h: Added.
+            * runtime/JSObject.h:
+            (JSC::JSObject::JSObject):
+            * runtime/JSObjectInlines.h:
+            * runtime/JSSegmentedVariableObject.h:
+            * runtime/JSString.h:
+            (JSC::JSString::subspaceFor):
+            * runtime/JSStringSubspace.cpp: Added.
+            (JSC::JSStringSubspace::JSStringSubspace):
+            (JSC::JSStringSubspace::~JSStringSubspace):
+            (JSC::JSStringSubspace::finishSweep):
+            (JSC::JSStringSubspace::destroy):
+            * runtime/JSStringSubspace.h: Added.
+            * runtime/RegExpMatchesArray.h:
+            (JSC::tryCreateUninitializedRegExpMatchesArray):
+            * runtime/VM.cpp:
+            (JSC::VM::VM):
+            * runtime/VM.h:
+
+2017-01-18  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r210829. rdar://problem/30044439
</span><span class="cx"> 
</span><span class="cx">     2017-01-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -130,7 +130,7 @@
</span><span class="cx">                 0F1FB38E1E173A6500A9BE50 /* SynchronousStopTheWorldMutatorScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F1FB38A1E173A6200A9BE50 /* SynchronousStopTheWorldMutatorScheduler.cpp */; };
</span><span class="cx">                 0F1FB38F1E173A6700A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1FB38B1E173A6200A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h */; };
</span><span class="cx">                 0F1FB3901E173A6B00A9BE50 /* MutatorScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F1FB38C1E173A6200A9BE50 /* MutatorScheduler.cpp */; };
</span><del>-                0F1FB3931E177A7200A9BE50 /* VisitingTimeout.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1FB3921E177A6F00A9BE50 /* VisitingTimeout.h */; };
</del><ins>+                0F1FB3931E177A7200A9BE50 /* VisitingTimeout.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1FB3921E177A6F00A9BE50 /* VisitingTimeout.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F1FB3961E1AF7E100A9BE50 /* DFGPlanInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1FB3941E1AF7DF00A9BE50 /* DFGPlanInlines.h */; };
</span><span class="cx">                 0F1FB3971E1AF7E300A9BE50 /* DFGWorklistInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1FB3951E1AF7DF00A9BE50 /* DFGWorklistInlines.h */; };
</span><span class="cx">                 0F1FB3991E1F65FB00A9BE50 /* MutatorScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1FB3981E1F65F900A9BE50 /* MutatorScheduler.h */; };
</span><span class="lines">@@ -463,7 +463,7 @@
</span><span class="cx">                 0F64B27A1A7957B2006E4E66 /* CallEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F64B2781A7957B2006E4E66 /* CallEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F64EAF31C4ECD0600621E9B /* AirArgInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F64EAF21C4ECD0600621E9B /* AirArgInlines.h */; };
</span><span class="cx">                 0F660E371E0517B90031462C /* MarkingConstraint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F660E331E0517B70031462C /* MarkingConstraint.cpp */; };
</span><del>-                0F660E381E0517BB0031462C /* MarkingConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F660E341E0517B70031462C /* MarkingConstraint.h */; };
</del><ins>+                0F660E381E0517BB0031462C /* MarkingConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F660E341E0517B70031462C /* MarkingConstraint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F660E391E0517BF0031462C /* MarkingConstraintSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F660E351E0517B70031462C /* MarkingConstraintSet.cpp */; };
</span><span class="cx">                 0F660E3A1E0517C10031462C /* MarkingConstraintSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F660E361E0517B80031462C /* MarkingConstraintSet.h */; };
</span><span class="cx">                 0F664CE81DA304EF00B00A11 /* CodeBlockSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F664CE71DA304ED00B00A11 /* CodeBlockSetInlines.h */; };
</span><span class="lines">@@ -523,13 +523,22 @@
</span><span class="cx">                 0F7C39FB1C8F629300480151 /* RegExpInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7C39FA1C8F629300480151 /* RegExpInlines.h */; };
</span><span class="cx">                 0F7C39FD1C8F659500480151 /* RegExpObjectInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7C39FC1C8F659500480151 /* RegExpObjectInlines.h */; };
</span><span class="cx">                 0F7C39FF1C90C55B00480151 /* DFGOpInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7C39FE1C90C55B00480151 /* DFGOpInfo.h */; };
</span><del>-                0F7C5FB81D888A0C0044F5E2 /* MarkedBlockInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7C5FB71D888A010044F5E2 /* MarkedBlockInlines.h */; };
-                0F7C5FBA1D8895070044F5E2 /* MarkedSpaceInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7C5FB91D8895050044F5E2 /* MarkedSpaceInlines.h */; };
</del><ins>+                0F7C5FB81D888A0C0044F5E2 /* MarkedBlockInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7C5FB71D888A010044F5E2 /* MarkedBlockInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F7CF94F1DBEEE880098CC12 /* ReleaseHeapAccessScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7CF94E1DBEEE860098CC12 /* ReleaseHeapAccessScope.h */; };
</span><span class="cx">                 0F7CF9521DC027D90098CC12 /* StopIfNecessaryTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7CF9511DC027D70098CC12 /* StopIfNecessaryTimer.h */; };
</span><span class="cx">                 0F7CF9531DC027DB0098CC12 /* StopIfNecessaryTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7CF9501DC027D70098CC12 /* StopIfNecessaryTimer.cpp */; };
</span><span class="cx">                 0F7CF9561DC1258D0098CC12 /* AtomicsObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7CF9541DC1258B0098CC12 /* AtomicsObject.cpp */; };
</span><span class="cx">                 0F7CF9571DC125900098CC12 /* AtomicsObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7CF9551DC1258B0098CC12 /* AtomicsObject.h */; };
</span><ins>+                0F7DF1341E2970D70095951B /* ConstraintVolatility.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7DF12F1E2970D50095951B /* ConstraintVolatility.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F7DF1351E2970DC0095951B /* MarkedSpaceInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7DF1301E2970D50095951B /* MarkedSpaceInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F7DF1361E2970DF0095951B /* Subspace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7DF1311E2970D50095951B /* Subspace.cpp */; };
+                0F7DF1371E2970E10095951B /* Subspace.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7DF1321E2970D50095951B /* Subspace.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F7DF1381E2970E40095951B /* SubspaceInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7DF1331E2970D50095951B /* SubspaceInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F7DF13B1E2971110095951B /* JSDestructibleObjectSubspace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7DF1391E29710E0095951B /* JSDestructibleObjectSubspace.cpp */; };
+                0F7DF13C1E2971130095951B /* JSDestructibleObjectSubspace.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7DF13A1E29710E0095951B /* JSDestructibleObjectSubspace.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F7DF13F1E2AFC4D0095951B /* JSStringSubspace.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7DF13E1E2AFC4B0095951B /* JSStringSubspace.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F7DF1401E2AFC500095951B /* JSStringSubspace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7DF13D1E2AFC4B0095951B /* JSStringSubspace.cpp */; };
+                0F7DF1461E2BEF6A0095951B /* MarkedAllocatorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7DF1451E2BEF680095951B /* MarkedAllocatorInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F7F988B1D9596C500F4F12E /* DFGStoreBarrierClusteringPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7F98891D9596C300F4F12E /* DFGStoreBarrierClusteringPhase.cpp */; };
</span><span class="cx">                 0F7F988C1D9596C800F4F12E /* DFGStoreBarrierClusteringPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7F988A1D9596C300F4F12E /* DFGStoreBarrierClusteringPhase.h */; };
</span><span class="cx">                 0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8023E91613832300A0BA45 /* ByValInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2952,12 +2961,21 @@
</span><span class="cx">                 0F7C39FC1C8F659500480151 /* RegExpObjectInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpObjectInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7C39FE1C90C55B00480151 /* DFGOpInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOpInfo.h; path = dfg/DFGOpInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7C5FB71D888A010044F5E2 /* MarkedBlockInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedBlockInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F7C5FB91D8895050044F5E2 /* MarkedSpaceInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpaceInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F7CF94E1DBEEE860098CC12 /* ReleaseHeapAccessScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReleaseHeapAccessScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7CF9501DC027D70098CC12 /* StopIfNecessaryTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StopIfNecessaryTimer.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7CF9511DC027D70098CC12 /* StopIfNecessaryTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StopIfNecessaryTimer.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7CF9541DC1258B0098CC12 /* AtomicsObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AtomicsObject.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7CF9551DC1258B0098CC12 /* AtomicsObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicsObject.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F7DF12F1E2970D50095951B /* ConstraintVolatility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstraintVolatility.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F7DF1301E2970D50095951B /* MarkedSpaceInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpaceInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F7DF1311E2970D50095951B /* Subspace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Subspace.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F7DF1321E2970D50095951B /* Subspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Subspace.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F7DF1331E2970D50095951B /* SubspaceInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubspaceInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F7DF1391E29710E0095951B /* JSDestructibleObjectSubspace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDestructibleObjectSubspace.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F7DF13A1E29710E0095951B /* JSDestructibleObjectSubspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDestructibleObjectSubspace.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F7DF13D1E2AFC4B0095951B /* JSStringSubspace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringSubspace.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F7DF13E1E2AFC4B0095951B /* JSStringSubspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringSubspace.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F7DF1451E2BEF680095951B /* MarkedAllocatorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedAllocatorInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F7F98891D9596C300F4F12E /* DFGStoreBarrierClusteringPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStoreBarrierClusteringPhase.cpp; path = dfg/DFGStoreBarrierClusteringPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F7F988A1D9596C300F4F12E /* DFGStoreBarrierClusteringPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStoreBarrierClusteringPhase.h; path = dfg/DFGStoreBarrierClusteringPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F8023E91613832300A0BA45 /* ByValInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByValInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5672,6 +5690,7 @@
</span><span class="cx">                                 0FA762011DB9242300B7A2FD /* CollectionScope.h */,
</span><span class="cx">                                 146B14DB12EB5B12001BEC1B /* ConservativeRoots.cpp */,
</span><span class="cx">                                 149DAAF212EB559D0083B12B /* ConservativeRoots.h */,
</span><ins>+                                0F7DF12F1E2970D50095951B /* ConstraintVolatility.h */,
</ins><span class="cx">                                 2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */,
</span><span class="cx">                                 0F136D4B174AD69B0075B354 /* DeferGC.h */,
</span><span class="cx">                                 0FBB73BA1DEF8644002C009E /* DeleteAllCodeEffort.h */,
</span><span class="lines">@@ -5746,6 +5765,7 @@
</span><span class="cx">                                 14B7234012D7D0DA003BD5ED /* MachineStackMarker.h */,
</span><span class="cx">                                 C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */,
</span><span class="cx">                                 C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */,
</span><ins>+                                0F7DF1451E2BEF680095951B /* MarkedAllocatorInlines.h */,
</ins><span class="cx">                                 142D6F0613539A2800B02E86 /* MarkedBlock.cpp */,
</span><span class="cx">                                 142D6F0713539A2800B02E86 /* MarkedBlock.h */,
</span><span class="cx">                                 0F7C5FB71D888A010044F5E2 /* MarkedBlockInlines.h */,
</span><span class="lines">@@ -5752,7 +5772,7 @@
</span><span class="cx">                                 141448CA13A176EC00F5BA1A /* MarkedBlockSet.h */,
</span><span class="cx">                                 14D2F3D8139F4BE200491031 /* MarkedSpace.cpp */,
</span><span class="cx">                                 14D2F3D9139F4BE200491031 /* MarkedSpace.h */,
</span><del>-                                0F7C5FB91D8895050044F5E2 /* MarkedSpaceInlines.h */,
</del><ins>+                                0F7DF1301E2970D50095951B /* MarkedSpaceInlines.h */,
</ins><span class="cx">                                 0F660E331E0517B70031462C /* MarkingConstraint.cpp */,
</span><span class="cx">                                 0F660E341E0517B70031462C /* MarkingConstraint.h */,
</span><span class="cx">                                 0F660E351E0517B70031462C /* MarkingConstraintSet.cpp */,
</span><span class="lines">@@ -5775,6 +5795,9 @@
</span><span class="cx">                                 0F7CF9511DC027D70098CC12 /* StopIfNecessaryTimer.h */,
</span><span class="cx">                                 142E3132134FF0A600AFADB5 /* Strong.h */,
</span><span class="cx">                                 145722851437E140005FDE26 /* StrongInlines.h */,
</span><ins>+                                0F7DF1311E2970D50095951B /* Subspace.cpp */,
+                                0F7DF1321E2970D50095951B /* Subspace.h */,
+                                0F7DF1331E2970D50095951B /* SubspaceInlines.h */,
</ins><span class="cx">                                 0F1FB38A1E173A6200A9BE50 /* SynchronousStopTheWorldMutatorScheduler.cpp */,
</span><span class="cx">                                 0F1FB38B1E173A6200A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h */,
</span><span class="cx">                                 141448CC13A1783700F5BA1A /* TinyBloomFilter.h */,
</span><span class="lines">@@ -6301,9 +6324,9 @@
</span><span class="cx">                                 E178633F0D9BEC0000D74E75 /* InitializeThreading.h */,
</span><span class="cx">                                 E35E035D1B7AB43E0073AD2A /* InspectorInstrumentationObject.cpp */,
</span><span class="cx">                                 E35E035E1B7AB43E0073AD2A /* InspectorInstrumentationObject.h */,
</span><ins>+                                A7A8AF2B17ADB5F3005AB174 /* Int8Array.h */,
</ins><span class="cx">                                 A7A8AF2C17ADB5F3005AB174 /* Int16Array.h */,
</span><span class="cx">                                 A7A8AF2D17ADB5F3005AB174 /* Int32Array.h */,
</span><del>-                                A7A8AF2B17ADB5F3005AB174 /* Int8Array.h */,
</del><span class="cx">                                 BC9BB95B0E19680600DF8855 /* InternalFunction.cpp */,
</span><span class="cx">                                 BC11667A0E199C05008066DD /* InternalFunction.h */,
</span><span class="cx">                                 A1B9E2331B4E0D6700BC7FED /* IntlCollator.cpp */,
</span><span class="lines">@@ -6368,6 +6391,8 @@
</span><span class="cx">                                 9788FC221471AD0C0068CE2D /* JSDateMath.cpp */,
</span><span class="cx">                                 9788FC231471AD0C0068CE2D /* JSDateMath.h */,
</span><span class="cx">                                 C2A7F687160432D400F76B98 /* JSDestructibleObject.h */,
</span><ins>+                                0F7DF1391E29710E0095951B /* JSDestructibleObjectSubspace.cpp */,
+                                0F7DF13A1E29710E0095951B /* JSDestructibleObjectSubspace.h */,
</ins><span class="cx">                                 BC22A39A0E16E14800AF21C8 /* JSEnvironmentRecord.cpp */,
</span><span class="cx">                                 14F252560D08DD8D004ECFFF /* JSEnvironmentRecord.h */,
</span><span class="cx">                                 A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */,
</span><span class="lines">@@ -6396,9 +6421,9 @@
</span><span class="cx">                                 BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */,
</span><span class="cx">                                 BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */,
</span><span class="cx">                                 79B819921DD25CF500DDC714 /* JSGlobalObjectInlines.h */,
</span><ins>+                                0F2B66C917B6B5AB00A7AE3F /* JSInt8Array.h */,
</ins><span class="cx">                                 0F2B66CA17B6B5AB00A7AE3F /* JSInt16Array.h */,
</span><span class="cx">                                 0F2B66CB17B6B5AB00A7AE3F /* JSInt32Array.h */,
</span><del>-                                0F2B66C917B6B5AB00A7AE3F /* JSInt8Array.h */,
</del><span class="cx">                                 E33F507E1B8429A400413856 /* JSInternalPromise.cpp */,
</span><span class="cx">                                 E33F507F1B8429A400413856 /* JSInternalPromise.h */,
</span><span class="cx">                                 E33F50761B84225700413856 /* JSInternalPromiseConstructor.cpp */,
</span><span class="lines">@@ -6462,6 +6487,8 @@
</span><span class="cx">                                 70EC0EBD1AA0D7DA00B6AAFA /* JSStringIterator.h */,
</span><span class="cx">                                 2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */,
</span><span class="cx">                                 2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */,
</span><ins>+                                0F7DF13D1E2AFC4B0095951B /* JSStringSubspace.cpp */,
+                                0F7DF13E1E2AFC4B0095951B /* JSStringSubspace.h */,
</ins><span class="cx">                                 0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */,
</span><span class="cx">                                 0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */,
</span><span class="cx">                                 70ECA6001AFDBEA200449739 /* JSTemplateRegistryKey.cpp */,
</span><span class="lines">@@ -6478,10 +6505,10 @@
</span><span class="cx">                                 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */,
</span><span class="cx">                                 53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */,
</span><span class="cx">                                 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */,
</span><ins>+                                0F2B66D217B6B5AB00A7AE3F /* JSUint8Array.h */,
+                                0F2B66D317B6B5AB00A7AE3F /* JSUint8ClampedArray.h */,
</ins><span class="cx">                                 0F2B66D417B6B5AB00A7AE3F /* JSUint16Array.h */,
</span><span class="cx">                                 0F2B66D517B6B5AB00A7AE3F /* JSUint32Array.h */,
</span><del>-                                0F2B66D217B6B5AB00A7AE3F /* JSUint8Array.h */,
-                                0F2B66D317B6B5AB00A7AE3F /* JSUint8ClampedArray.h */,
</del><span class="cx">                                 A7CA3AE117DA41AE006538AF /* JSWeakMap.cpp */,
</span><span class="cx">                                 A7CA3AE217DA41AE006538AF /* JSWeakMap.h */,
</span><span class="cx">                                 709FB8611AE335C60039D069 /* JSWeakSet.cpp */,
</span><span class="lines">@@ -6618,6 +6645,7 @@
</span><span class="cx">                                 0F5B4A321C84F0D600F1B17E /* SlowPathReturnType.h */,
</span><span class="cx">                                 93303FE80E6A72B500786E6A /* SmallStrings.cpp */,
</span><span class="cx">                                 93303FEA0E6A72C000786E6A /* SmallStrings.h */,
</span><ins>+                                425BA1337E4344E1B269A671 /* SourceOrigin.h */,
</ins><span class="cx">                                 0F0CD4C315F6B6B50032F1C0 /* SparseArrayValueMap.cpp */,
</span><span class="cx">                                 0FB7F39215ED8E3800F167B2 /* SparseArrayValueMap.h */,
</span><span class="cx">                                 0F3AC751183EA1040032029F /* StackAlignment.h */,
</span><span class="lines">@@ -6686,11 +6714,11 @@
</span><span class="cx">                                 0F2D4DE019832D91007D4B19 /* TypeProfilerLog.h */,
</span><span class="cx">                                 0F2D4DE319832D91007D4B19 /* TypeSet.cpp */,
</span><span class="cx">                                 0F2D4DE419832D91007D4B19 /* TypeSet.h */,
</span><ins>+                                A7A8AF3017ADB5F3005AB174 /* Uint8Array.h */,
+                                A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */,
</ins><span class="cx">                                 A7A8AF3217ADB5F3005AB174 /* Uint16Array.h */,
</span><span class="cx">                                 866739D113BFDE710023D87C /* Uint16WithFraction.h */,
</span><span class="cx">                                 A7A8AF3317ADB5F3005AB174 /* Uint32Array.h */,
</span><del>-                                A7A8AF3017ADB5F3005AB174 /* Uint8Array.h */,
-                                A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */,
</del><span class="cx">                                 0FE050231AA9095600D33B33 /* VarOffset.cpp */,
</span><span class="cx">                                 0FE050241AA9095600D33B33 /* VarOffset.h */,
</span><span class="cx">                                 E18E3A570DF9278C00D90B34 /* VM.cpp */,
</span><span class="lines">@@ -8031,6 +8059,7 @@
</span><span class="cx">                                 BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */,
</span><span class="cx">                                 BC18C3FA0E16F5CD00B34460 /* Debugger.h in Headers */,
</span><span class="cx">                                 BC18C3FB0E16F5CD00B34460 /* DebuggerCallFrame.h in Headers */,
</span><ins>+                                0F7DF1351E2970DC0095951B /* MarkedSpaceInlines.h in Headers */,
</ins><span class="cx">                                 6AD2CB4D19B9140100065719 /* DebuggerEvalEnabler.h in Headers */,
</span><span class="cx">                                 A5FC84B21D1DDAD6006B5C46 /* DebuggerLocation.h in Headers */,
</span><span class="cx">                                 A5A1A0941D8CB33E004C2EB8 /* DebuggerParseData.h in Headers */,
</span><span class="lines">@@ -8171,6 +8200,7 @@
</span><span class="cx">                                 0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */,
</span><span class="cx">                                 0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */,
</span><span class="cx">                                 0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */,
</span><ins>+                                0F7DF13F1E2AFC4D0095951B /* JSStringSubspace.h in Headers */,
</ins><span class="cx">                                 0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */,
</span><span class="cx">                                 0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */,
</span><span class="cx">                                 0F6237981AE45CA700D402EA /* DFGPhantomInsertionPhase.h in Headers */,
</span><span class="lines">@@ -8347,8 +8377,10 @@
</span><span class="cx">                                 A54E8EB018BFFBBB00556D28 /* GCSegmentedArray.h in Headers */,
</span><span class="cx">                                 A54E8EB118BFFBBE00556D28 /* GCSegmentedArrayInlines.h in Headers */,
</span><span class="cx">                                 0F86A26F1D6F7B3300CB0C92 /* GCTypeMap.h in Headers */,
</span><ins>+                                0F7DF1381E2970E40095951B /* SubspaceInlines.h in Headers */,
</ins><span class="cx">                                 9959E9311BD18272001AA413 /* generate-combined-inspector-json.py in Headers */,
</span><span class="cx">                                 C4703CC0192844960013FBEA /* generate-inspector-protocol-bindings.py in Headers */,
</span><ins>+                                0F7DF1461E2BEF6A0095951B /* MarkedAllocatorInlines.h in Headers */,
</ins><span class="cx">                                 99DA00AF1BD5994E00F4575C /* generate-js-builtins.py in Headers */,
</span><span class="cx">                                 A5EA70EC19F5B3EA0098F5EC /* generate_cpp_alternate_backend_dispatcher_header.py in Headers */,
</span><span class="cx">                                 A5EF9B141A1D43F600702E90 /* generate_cpp_backend_dispatcher_header.py in Headers */,
</span><span class="lines">@@ -8510,6 +8542,7 @@
</span><span class="cx">                                 FE187A021BFBE5610038BBCA /* JITMulGenerator.h in Headers */,
</span><span class="cx">                                 FE99B2491C24C3D300C82159 /* JITNegGenerator.h in Headers */,
</span><span class="cx">                                 0F24E54D17EE274900ABB217 /* JITOperations.h in Headers */,
</span><ins>+                                0F7DF1371E2970E10095951B /* Subspace.h in Headers */,
</ins><span class="cx">                                 FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */,
</span><span class="cx">                                 0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */,
</span><span class="cx">                                 0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */,
</span><span class="lines">@@ -8626,6 +8659,7 @@
</span><span class="cx">                                 7C184E1F17BEE22E007CB63A /* JSPromisePrototype.h in Headers */,
</span><span class="cx">                                 996B731F1BDA08EF00331B84 /* JSPromisePrototype.lut.h in Headers */,
</span><span class="cx">                                 2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */,
</span><ins>+                                0F7DF13C1E2971130095951B /* JSDestructibleObjectSubspace.h in Headers */,
</ins><span class="cx">                                 E3EF88751B66DF23003F26CB /* JSPropertyNameIterator.h in Headers */,
</span><span class="cx">                                 862553D216136E1A009F17D0 /* JSProxy.h in Headers */,
</span><span class="cx">                                 A552C3801ADDB8FE00139726 /* JSRemoteInspector.h in Headers */,
</span><span class="lines">@@ -8635,6 +8669,7 @@
</span><span class="cx">                                 A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */,
</span><span class="cx">                                 0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
</span><span class="cx">                                 A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */,
</span><ins>+                                0F7DF1341E2970D70095951B /* ConstraintVolatility.h in Headers */,
</ins><span class="cx">                                 A790DD70182F499700588807 /* JSSetIterator.h in Headers */,
</span><span class="cx">                                 BC18C4270E16F5CD00B34460 /* JSString.h in Headers */,
</span><span class="cx">                                 86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */,
</span><span class="lines">@@ -8739,7 +8774,6 @@
</span><span class="cx">                                 0F7C5FB81D888A0C0044F5E2 /* MarkedBlockInlines.h in Headers */,
</span><span class="cx">                                 141448CB13A176EC00F5BA1A /* MarkedBlockSet.h in Headers */,
</span><span class="cx">                                 14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */,
</span><del>-                                0F7C5FBA1D8895070044F5E2 /* MarkedSpaceInlines.h in Headers */,
</del><span class="cx">                                 142D6F1213539A4100B02E86 /* MarkStack.h in Headers */,
</span><span class="cx">                                 8612E4CD152389EC00C836BE /* MatchResult.h in Headers */,
</span><span class="cx">                                 4340A4851A9051AF00D73CCA /* MathCommon.h in Headers */,
</span><span class="lines">@@ -9896,6 +9930,7 @@
</span><span class="cx">                                 0F7F988B1D9596C500F4F12E /* DFGStoreBarrierClusteringPhase.cpp in Sources */,
</span><span class="cx">                                 0F9E32631B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.cpp in Sources */,
</span><span class="cx">                                 0FC20CB51852E2C600C9E954 /* DFGStrengthReductionPhase.cpp in Sources */,
</span><ins>+                                0F7DF13B1E2971110095951B /* JSDestructibleObjectSubspace.cpp in Sources */,
</ins><span class="cx">                                 0F893BDB1936E23C001211F4 /* DFGStructureAbstractValue.cpp in Sources */,
</span><span class="cx">                                 0F79085519A290B200F6310C /* DFGStructureRegistrationPhase.cpp in Sources */,
</span><span class="cx">                                 0F2FCCFE18A60070001A27F8 /* DFGThreadData.cpp in Sources */,
</span><span class="lines">@@ -10106,6 +10141,7 @@
</span><span class="cx">                                 5B70CFDF1DB69E6600EC23F9 /* JSAsyncFunction.cpp in Sources */,
</span><span class="cx">                                 1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */,
</span><span class="cx">                                 86FA9E91142BBB2E001773B7 /* JSBoundFunction.cpp in Sources */,
</span><ins>+                                0F7DF1401E2AFC500095951B /* JSStringSubspace.cpp in Sources */,
</ins><span class="cx">                                 1440F8AF0A508D200005F061 /* JSCallbackConstructor.cpp in Sources */,
</span><span class="cx">                                 1440F8920A508B100005F061 /* JSCallbackFunction.cpp in Sources */,
</span><span class="cx">                                 14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */,
</span><span class="lines">@@ -10133,6 +10169,7 @@
</span><span class="cx">                                 A5C3A1A518C0490200C9593A /* JSGlobalObjectConsoleClient.cpp in Sources */,
</span><span class="cx">                                 A59455921824744700CC3843 /* JSGlobalObjectDebuggable.cpp in Sources */,
</span><span class="cx">                                 A57D23E91891B0770031C7FA /* JSGlobalObjectDebuggerAgent.cpp in Sources */,
</span><ins>+                                0F7DF1361E2970DF0095951B /* Subspace.cpp in Sources */,
</ins><span class="cx">                                 14E9D17B107EC469004DDA21 /* JSGlobalObjectFunctions.cpp in Sources */,
</span><span class="cx">                                 A51007C0187CC3C600B38879 /* JSGlobalObjectInspectorController.cpp in Sources */,
</span><span class="cx">                                 A50E4B6318809DD50068A46D /* JSGlobalObjectRuntimeAgent.cpp in Sources */,
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorebytecodeObjectAllocationProfileh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -82,7 +82,7 @@
</span><span class="cx">         ASSERT(inlineCapacity &lt;= JSFinalObject::maxInlineCapacity());
</span><span class="cx"> 
</span><span class="cx">         size_t allocationSize = JSFinalObject::allocationSize(inlineCapacity);
</span><del>-        MarkedAllocator* allocator = vm.heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+        MarkedAllocator* allocator = vm.cellSpace.allocatorFor(allocationSize);
</ins><span class="cx">         
</span><span class="cx">         // Take advantage of extra inline capacity available in the size class.
</span><span class="cx">         if (allocator) {
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorebytecodePolymorphicAccesscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -1264,7 +1264,7 @@
</span><span class="cx">             size_t newSize = newStructure()-&gt;outOfLineCapacity() * sizeof(JSValue);
</span><span class="cx">             
</span><span class="cx">             if (allocatingInline) {
</span><del>-                MarkedAllocator* allocator = vm.heap.allocatorForAuxiliaryData(newSize);
</del><ins>+                MarkedAllocator* allocator = vm.auxiliarySpace.allocatorFor(newSize);
</ins><span class="cx">                 
</span><span class="cx">                 if (!allocator) {
</span><span class="cx">                     // Yuck, this case would suck!
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -110,7 +110,7 @@
</span><span class="cx">     m_jit.move(TrustedImmPtr(0), storageGPR);
</span><span class="cx">     
</span><span class="cx">     if (size) {
</span><del>-        if (MarkedAllocator* allocator = m_jit.vm()-&gt;heap.allocatorForAuxiliaryData(size)) {
</del><ins>+        if (MarkedAllocator* allocator = m_jit.vm()-&gt;auxiliarySpace.allocatorFor(size)) {
</ins><span class="cx">             m_jit.move(TrustedImmPtr(allocator), scratchGPR);
</span><span class="cx">             m_jit.emitAllocate(storageGPR, allocator, scratchGPR, scratch2GPR, slowCases);
</span><span class="cx">             
</span><span class="lines">@@ -125,7 +125,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     size_t allocationSize = JSFinalObject::allocationSize(inlineCapacity);
</span><del>-    MarkedAllocator* allocatorPtr = m_jit.vm()-&gt;heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+    MarkedAllocator* allocatorPtr = subspaceFor&lt;JSFinalObject&gt;(*m_jit.vm())-&gt;allocatorFor(allocationSize);
</ins><span class="cx">     if (allocatorPtr) {
</span><span class="cx">         m_jit.move(TrustedImmPtr(allocatorPtr), scratchGPR);
</span><span class="cx">         emitAllocateJSObject(resultGPR, allocatorPtr, scratchGPR, TrustedImmPtr(structure), storageGPR, scratch2GPR, slowCases);
</span><span class="lines">@@ -3899,7 +3899,7 @@
</span><span class="cx">     GPRReg scratchGPR = scratch.gpr();
</span><span class="cx">     
</span><span class="cx">     JITCompiler::JumpList slowPath;
</span><del>-    MarkedAllocator* markedAllocator = m_jit.vm()-&gt;heap.allocatorForObjectWithDestructor(sizeof(JSRopeString));
</del><ins>+    MarkedAllocator* markedAllocator = subspaceFor&lt;JSString&gt;(*m_jit.vm())-&gt;allocatorFor(sizeof(JSRopeString));
</ins><span class="cx">     RELEASE_ASSERT(markedAllocator);
</span><span class="cx">     m_jit.move(TrustedImmPtr(markedAllocator), allocatorGPR);
</span><span class="cx">     emitAllocateJSCell(resultGPR, markedAllocator, allocatorGPR, TrustedImmPtr(m_jit.vm()-&gt;stringStructure.get()), scratchGPR, slowPath);
</span><span class="lines">@@ -7554,7 +7554,7 @@
</span><span class="cx">     
</span><span class="cx">     size_t size = initialOutOfLineCapacity * sizeof(JSValue);
</span><span class="cx"> 
</span><del>-    MarkedAllocator* allocator = m_jit.vm()-&gt;heap.allocatorForAuxiliaryData(size);
</del><ins>+    MarkedAllocator* allocator = m_jit.vm()-&gt;auxiliarySpace.allocatorFor(size);
</ins><span class="cx"> 
</span><span class="cx">     if (!allocator || node-&gt;transition()-&gt;previous-&gt;couldHaveIndexingHeader()) {
</span><span class="cx">         SpeculateCellOperand base(this, node-&gt;child1());
</span><span class="lines">@@ -7599,7 +7599,7 @@
</span><span class="cx">     size_t newSize = oldSize * outOfLineGrowthFactor;
</span><span class="cx">     ASSERT(newSize == node-&gt;transition()-&gt;next-&gt;outOfLineCapacity() * sizeof(JSValue));
</span><span class="cx">     
</span><del>-    MarkedAllocator* allocator = m_jit.vm()-&gt;heap.allocatorForAuxiliaryData(newSize);
</del><ins>+    MarkedAllocator* allocator = m_jit.vm()-&gt;auxiliarySpace.allocatorFor(newSize);
</ins><span class="cx"> 
</span><span class="cx">     if (!allocator || node-&gt;transition()-&gt;previous-&gt;couldHaveIndexingHeader()) {
</span><span class="cx">         SpeculateCellOperand base(this, node-&gt;child1());
</span><span class="lines">@@ -7985,7 +7985,7 @@
</span><span class="cx">         m_jit.and32(TrustedImm32(~7), scratchGPR);
</span><span class="cx">     }
</span><span class="cx">     m_jit.emitAllocateVariableSized(
</span><del>-        storageGPR, m_jit.vm()-&gt;heap.subspaceForAuxiliaryData(), scratchGPR, scratchGPR,
</del><ins>+        storageGPR, m_jit.vm()-&gt;auxiliarySpace, scratchGPR, scratchGPR,
</ins><span class="cx">         scratchGPR2, slowCases);
</span><span class="cx">     
</span><span class="cx">     MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, sizeGPR);
</span><span class="lines">@@ -9565,7 +9565,7 @@
</span><span class="cx">     m_jit.lshift32(TrustedImm32(3), scratch1);
</span><span class="cx">     m_jit.add32(TrustedImm32(sizeof(IndexingHeader)), scratch1, scratch2);
</span><span class="cx">     m_jit.emitAllocateVariableSized(
</span><del>-        storageResultGPR, m_jit.vm()-&gt;heap.subspaceForAuxiliaryData(), scratch2, scratch1, scratch3, slowCases);
</del><ins>+        storageResultGPR, m_jit.vm()-&gt;auxiliarySpace, scratch2, scratch1, scratch3, slowCases);
</ins><span class="cx">     m_jit.addPtr(TrustedImm32(sizeof(IndexingHeader)), storageResultGPR);
</span><span class="cx"> 
</span><span class="cx">     m_jit.store32(sizeGPR, MacroAssembler::Address(storageResultGPR, Butterfly::offsetOfPublicLength()));
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -4173,7 +4173,7 @@
</span><span class="cx">         
</span><span class="cx">         Structure* structure = node-&gt;structure();
</span><span class="cx">         size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
</span><del>-        MarkedAllocator* allocatorPtr = m_jit.vm()-&gt;heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+        MarkedAllocator* allocatorPtr = subspaceFor&lt;JSFinalObject&gt;(*m_jit.vm())-&gt;allocatorFor(allocationSize);
</ins><span class="cx"> 
</span><span class="cx">         m_jit.move(TrustedImmPtr(allocatorPtr), allocatorGPR);
</span><span class="cx">         emitAllocateJSObject(resultGPR, allocatorPtr, allocatorGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR, slowPath);
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -4145,7 +4145,7 @@
</span><span class="cx"> 
</span><span class="cx">         Structure* structure = node-&gt;structure();
</span><span class="cx">         size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
</span><del>-        MarkedAllocator* allocatorPtr = m_jit.vm()-&gt;heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+        MarkedAllocator* allocatorPtr = subspaceFor&lt;JSFinalObject&gt;(*m_jit.vm())-&gt;allocatorFor(allocationSize);
</ins><span class="cx"> 
</span><span class="cx">         m_jit.move(TrustedImmPtr(allocatorPtr), allocatorGPR);
</span><span class="cx">         emitAllocateJSObject(resultGPR, allocatorPtr, allocatorGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR, slowPath);
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreftlFTLAbstractHeapRepositoryh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -123,8 +123,8 @@
</span><span class="cx">     macro(JSEnvironmentRecord_variables, JSEnvironmentRecord::offsetOfVariables(), sizeof(EncodedJSValue)) \
</span><span class="cx">     macro(JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, 0, sizeof(WriteBarrier&lt;JSString&gt;)) \
</span><span class="cx">     macro(JSRopeString_fibers, JSRopeString::offsetOfFibers(), sizeof(WriteBarrier&lt;JSString&gt;)) \
</span><del>-    macro(MarkedSpace_Subspace_allocatorForSizeStep, OBJECT_OFFSETOF(MarkedSpace::Subspace, allocatorForSizeStep), sizeof(MarkedAllocator*)) \
</del><span class="cx">     macro(ScopedArguments_overflowStorage, ScopedArguments::overflowStorageOffset(), sizeof(EncodedJSValue)) \
</span><ins>+    macro(Subspace_allocatorForSizeStep, Subspace::offsetOfAllocatorForSizeStep(), sizeof(MarkedAllocator*)) \
</ins><span class="cx">     macro(WriteBarrierBuffer_bufferContents, 0, sizeof(JSCell*)) \
</span><span class="cx">     macro(characters8, 0, sizeof(LChar)) \
</span><span class="cx">     macro(characters16, 0, sizeof(UChar)) \
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -4750,8 +4750,7 @@
</span><span class="cx">                     m_out.constIntPtr(~static_cast&lt;intptr_t&gt;(7)));
</span><span class="cx">             }
</span><span class="cx">         
</span><del>-            LValue allocator = allocatorForSize(
-                vm().heap.subspaceForAuxiliaryData(), byteSize, slowCase);
</del><ins>+            LValue allocator = allocatorForSize(vm().auxiliarySpace, byteSize, slowCase);
</ins><span class="cx">             LValue storage = allocateHeapCell(allocator, slowCase);
</span><span class="cx">             
</span><span class="cx">             splatWords(
</span><span class="lines">@@ -4992,8 +4991,7 @@
</span><span class="cx">         
</span><span class="cx">         LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
</span><span class="cx">         
</span><del>-        MarkedAllocator* allocator =
-            vm().heap.allocatorForObjectWithDestructor(sizeof(JSRopeString));
</del><ins>+        MarkedAllocator* allocator = subspaceFor&lt;JSRopeString&gt;(vm())-&gt;allocatorFor(sizeof(JSRopeString));
</ins><span class="cx">         DFG_ASSERT(m_graph, m_node, allocator);
</span><span class="cx">         
</span><span class="cx">         LValue result = allocateCell(
</span><span class="lines">@@ -8635,7 +8633,7 @@
</span><span class="cx">             
</span><span class="cx">             if (structure-&gt;outOfLineCapacity() || hasIndexedProperties(structure-&gt;indexingType())) {
</span><span class="cx">                 size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
</span><del>-                MarkedAllocator* cellAllocator = vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+                MarkedAllocator* cellAllocator = subspaceFor&lt;JSFinalObject&gt;(vm())-&gt;allocatorFor(allocationSize);
</ins><span class="cx">                 DFG_ASSERT(m_graph, m_node, cellAllocator);
</span><span class="cx"> 
</span><span class="cx">                 bool hasIndexingHeader = hasIndexedProperties(structure-&gt;indexingType());
</span><span class="lines">@@ -8675,7 +8673,7 @@
</span><span class="cx">                 ValueFromBlock noButterfly = m_out.anchor(m_out.intPtrZero);
</span><span class="cx">                 
</span><span class="cx">                 LValue startOfStorage = allocateHeapCell(
</span><del>-                    allocatorForSize(vm().heap.subspaceForAuxiliaryData(), butterflySize, slowPath),
</del><ins>+                    allocatorForSize(vm().auxiliarySpace, butterflySize, slowPath),
</ins><span class="cx">                     slowPath);
</span><span class="cx"> 
</span><span class="cx">                 LValue fastButterflyValue = m_out.add(
</span><span class="lines">@@ -9621,7 +9619,7 @@
</span><span class="cx">         LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
</span><span class="cx"> 
</span><span class="cx">         size_t sizeInBytes = sizeInValues * sizeof(JSValue);
</span><del>-        MarkedAllocator* allocator = vm().heap.allocatorForAuxiliaryData(sizeInBytes);
</del><ins>+        MarkedAllocator* allocator = vm().auxiliarySpace.allocatorFor(sizeInBytes);
</ins><span class="cx">         LValue startOfStorage = allocateHeapCell(m_out.constIntPtr(allocator), slowPath);
</span><span class="cx">         ValueFromBlock fastButterfly = m_out.anchor(
</span><span class="cx">             m_out.add(m_out.constIntPtr(sizeInBytes + sizeof(IndexingHeader)), startOfStorage));
</span><span class="lines">@@ -10529,7 +10527,7 @@
</span><span class="cx">     LValue allocateObject(
</span><span class="cx">         size_t size, StructureType structure, LValue butterfly, LBasicBlock slowPath)
</span><span class="cx">     {
</span><del>-        MarkedAllocator* allocator = vm().heap.allocatorForObjectOfType&lt;ClassType&gt;(size);
</del><ins>+        MarkedAllocator* allocator = subspaceFor&lt;ClassType&gt;(vm())-&gt;allocatorFor(size);
</ins><span class="cx">         return allocateObject(m_out.constIntPtr(allocator), structure, butterfly, slowPath);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -10546,10 +10544,10 @@
</span><span class="cx">         
</span><span class="cx">         // Try to do some constant-folding here.
</span><span class="cx">         if (subspace-&gt;hasIntPtr() &amp;&amp; size-&gt;hasIntPtr()) {
</span><del>-            MarkedSpace::Subspace* actualSubspace = bitwise_cast&lt;MarkedSpace::Subspace*&gt;(subspace-&gt;asIntPtr());
</del><ins>+            Subspace* actualSubspace = bitwise_cast&lt;Subspace*&gt;(subspace-&gt;asIntPtr());
</ins><span class="cx">             size_t actualSize = size-&gt;asIntPtr();
</span><span class="cx">             
</span><del>-            MarkedAllocator* actualAllocator = MarkedSpace::allocatorFor(*actualSubspace, actualSize);
</del><ins>+            MarkedAllocator* actualAllocator = actualSubspace-&gt;allocatorFor(actualSize);
</ins><span class="cx">             if (!actualAllocator) {
</span><span class="cx">                 LBasicBlock continuation = m_out.newBlock();
</span><span class="cx">                 LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
</span><span class="lines">@@ -10579,11 +10577,11 @@
</span><span class="cx">         
</span><span class="cx">         return m_out.loadPtr(
</span><span class="cx">             m_out.baseIndex(
</span><del>-                m_heaps.MarkedSpace_Subspace_allocatorForSizeStep,
</del><ins>+                m_heaps.Subspace_allocatorForSizeStep,
</ins><span class="cx">                 subspace, m_out.sub(sizeClassIndex, m_out.intPtrOne)));
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    LValue allocatorForSize(MarkedSpace::Subspace&amp; subspace, LValue size, LBasicBlock slowPath)
</del><ins>+    LValue allocatorForSize(Subspace&amp; subspace, LValue size, LBasicBlock slowPath)
</ins><span class="cx">     {
</span><span class="cx">         return allocatorForSize(m_out.constIntPtr(&amp;subspace), size, slowPath);
</span><span class="cx">     }
</span><span class="lines">@@ -10593,7 +10591,7 @@
</span><span class="cx">         LValue size, Structure* structure, LValue butterfly, LBasicBlock slowPath)
</span><span class="cx">     {
</span><span class="cx">         LValue allocator = allocatorForSize(
</span><del>-            vm().heap.subspaceForObjectOfType&lt;ClassType&gt;(), size, slowPath);
</del><ins>+            *subspaceFor&lt;ClassType&gt;(vm()), size, slowPath);
</ins><span class="cx">         return allocateObject(allocator, structure, butterfly, slowPath);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -10602,7 +10600,7 @@
</span><span class="cx">         LValue size, Structure* structure, LBasicBlock slowPath)
</span><span class="cx">     {
</span><span class="cx">         LValue allocator = allocatorForSize(
</span><del>-            vm().heap.subspaceForObjectOfType&lt;ClassType&gt;(), size, slowPath);
</del><ins>+            *subspaceFor&lt;ClassType&gt;(vm()), size, slowPath);
</ins><span class="cx">         return allocateCell(allocator, structure, slowPath);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -10609,7 +10607,7 @@
</span><span class="cx">     LValue allocateObject(Structure* structure)
</span><span class="cx">     {
</span><span class="cx">         size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
</span><del>-        MarkedAllocator* allocator = vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+        MarkedAllocator* allocator = subspaceFor&lt;JSFinalObject&gt;(vm())-&gt;allocatorFor(allocationSize);
</ins><span class="cx">         
</span><span class="cx">         // FIXME: If the allocator is null, we could simply emit a normal C call to the allocator
</span><span class="cx">         // instead of putting it on the slow path.
</span><span class="lines">@@ -10711,8 +10709,7 @@
</span><span class="cx">         LValue butterflySize = m_out.add(
</span><span class="cx">             payloadSize, m_out.constIntPtr(sizeof(IndexingHeader)));
</span><span class="cx">             
</span><del>-        LValue allocator = allocatorForSize(
-            vm().heap.subspaceForAuxiliaryData(), butterflySize, failCase);
</del><ins>+        LValue allocator = allocatorForSize(vm().auxiliarySpace, butterflySize, failCase);
</ins><span class="cx">         LValue startOfStorage = allocateHeapCell(allocator, failCase);
</span><span class="cx">             
</span><span class="cx">         LValue butterfly = m_out.add(startOfStorage, m_out.constIntPtr(sizeof(IndexingHeader)));
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapAllocatorAttributesh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/AllocatorAttributes.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/AllocatorAttributes.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/AllocatorAttributes.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -25,6 +25,7 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include &quot;ConstraintVolatility.h&quot;
</ins><span class="cx"> #include &quot;DestructionMode.h&quot;
</span><span class="cx"> #include &quot;HeapCell.h&quot;
</span><span class="cx"> #include &lt;wtf/PrintStream.h&gt;
</span><span class="lines">@@ -34,6 +35,12 @@
</span><span class="cx"> struct AllocatorAttributes {
</span><span class="cx">     AllocatorAttributes() { }
</span><span class="cx">     
</span><ins>+    AllocatorAttributes(DestructionMode destruction, HeapCell::Kind cellKind)
+        : destruction(destruction)
+        , cellKind(cellKind)
+    {
+    }
+    
</ins><span class="cx">     void dump(PrintStream&amp; out) const;
</span><span class="cx">     
</span><span class="cx">     DestructionMode destruction { DoesNotNeedDestruction };
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapConstraintVolatilityh"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/JavaScriptCore/heap/ConstraintVolatility.h (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/ConstraintVolatility.h                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/ConstraintVolatility.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,73 @@
</span><ins>+/*
+ * Copyright (C) 2017 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#pragma once
+
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace JSC {
+
+enum class ConstraintVolatility : uint8_t {
+    // The constraint needs to be validated, but it is unlikely to ever produce information.
+    // It's best to run it at the bitter end.
+    SeldomGreyed,
+    
+    // FIXME: We could introduce a new kind of volatility called GreyedByResumption, which
+    // would mean running all of the times that GreyedByExecution runs except as a root in a
+    // full GC.
+    // https://bugs.webkit.org/show_bug.cgi?id=166830
+    
+    // The constraint needs to be reevaluated anytime the mutator runs: so at GC start and
+    // whenever the GC resuspends after a resumption. This is almost always something that
+    // you'd call a &quot;root&quot; in a traditional GC.
+    GreyedByExecution,
+    
+    // The constraint needs to be reevaluated any time any object is marked and anytime the
+    // mutator resumes.
+    GreyedByMarking
+};
+    
+} // namespace JSC
+
+namespace WTF {
+
+inline void printInternal(PrintStream&amp; out, JSC::ConstraintVolatility volatility)
+{
+    switch (volatility) {
+    case JSC::ConstraintVolatility::SeldomGreyed:
+        out.print(&quot;SeldomGreyed&quot;);
+        return;
+    case JSC::ConstraintVolatility::GreyedByExecution:
+        out.print(&quot;GreyedByExecuction&quot;);
+        return;
+    case JSC::ConstraintVolatility::GreyedByMarking:
+        out.print(&quot;GreyedByMarking&quot;);
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapGCActivityCallbackcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/GCActivityCallback.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/GCActivityCallback.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/GCActivityCallback.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -29,7 +29,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;GCActivityCallback.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;Heap.h&quot;
</del><ins>+#include &quot;HeapInlines.h&quot;
</ins><span class="cx"> #include &quot;JSLock.h&quot;
</span><span class="cx"> #include &quot;JSObject.h&quot;
</span><span class="cx"> #include &quot;VM.h&quot;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/Heap.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/Heap.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/Heap.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -192,7 +192,7 @@
</span><span class="cx">             double timing = after - m_before;
</span><span class="cx">             SimpleStats&amp; stats = timingStats(m_name, *m_scope);
</span><span class="cx">             stats.add(timing);
</span><del>-            dataLog(&quot;[GC:&quot;, *m_scope, &quot;] &quot;, m_name, &quot; took: &quot;, timing, &quot; ms (average &quot;, stats.mean(), &quot; ms).\n&quot;);
</del><ins>+            dataLog(&quot;[GC:&quot;, *m_scope, &quot;] &quot;, m_name, &quot; took: &quot;, timing, &quot;ms (average &quot;, stats.mean(), &quot;ms).\n&quot;);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> private:
</span><span class="lines">@@ -260,6 +260,7 @@
</span><span class="cx">     , m_collectorSlotVisitor(std::make_unique&lt;SlotVisitor&gt;(*this))
</span><span class="cx">     , m_mutatorMarkStack(std::make_unique&lt;MarkStackArray&gt;())
</span><span class="cx">     , m_raceMarkStack(std::make_unique&lt;MarkStackArray&gt;())
</span><ins>+    , m_constraintSet(std::make_unique&lt;MarkingConstraintSet&gt;())
</ins><span class="cx">     , m_handleSet(vm)
</span><span class="cx">     , m_codeBlocks(std::make_unique&lt;CodeBlockSet&gt;())
</span><span class="cx">     , m_jitStubRoutines(std::make_unique&lt;JITStubRoutineSet&gt;())
</span><span class="lines">@@ -361,6 +362,7 @@
</span><span class="cx">     
</span><span class="cx">     m_arrayBuffers.lastChanceToFinalize();
</span><span class="cx">     m_codeBlocks-&gt;lastChanceToFinalize();
</span><ins>+    m_objectSpace.stopAllocating();
</ins><span class="cx">     m_objectSpace.lastChanceToFinalize();
</span><span class="cx">     releaseDelayedReleasedObjects();
</span><span class="cx"> 
</span><span class="lines">@@ -585,13 +587,21 @@
</span><span class="cx">     // checks because bootstrap would have put things into the visitor. So, we should fall
</span><span class="cx">     // through to draining.
</span><span class="cx">     
</span><del>-    for (unsigned iteration = 1; ; ++iteration) {
</del><ins>+    unsigned iteration = 1;
+    for (;;) {
</ins><span class="cx">         if (Options::logGC())
</span><del>-            dataLog(&quot;i#&quot;, iteration, &quot; b=&quot;, m_barriersExecuted, &quot; &quot;);
</del><ins>+            dataLog(&quot;v=&quot;, bytesVisited() / 1024, &quot;kb o=&quot;, m_opaqueRoots.size(), &quot; b=&quot;, m_barriersExecuted, &quot; &quot;);
</ins><span class="cx">         
</span><span class="cx">         if (slotVisitor.didReachTermination()) {
</span><ins>+            if (Options::logGC())
+                dataLog(&quot;i#&quot;, iteration, &quot; &quot;);
+        
</ins><span class="cx">             assertSharedMarkStacksEmpty();
</span><span class="cx">             
</span><ins>+            slotVisitor.mergeIfNecessary();
+            for (auto&amp; parallelVisitor : m_parallelSlotVisitors)
+                parallelVisitor-&gt;mergeIfNecessary();
+            
</ins><span class="cx">             // FIXME: Take m_mutatorDidRun into account when scheduling constraints. Most likely,
</span><span class="cx">             // we don't have to execute root constraints again unless the mutator did run. At a
</span><span class="cx">             // minimum, we could use this for work estimates - but it's probably more than just an
</span><span class="lines">@@ -603,14 +613,15 @@
</span><span class="cx">             // when we have deep stacks or a lot of DOM stuff.
</span><span class="cx">             // https://bugs.webkit.org/show_bug.cgi?id=166831
</span><span class="cx">             
</span><del>-            bool executedEverything =
</del><ins>+            bool converged =
</ins><span class="cx">                 m_constraintSet-&gt;executeConvergence(slotVisitor, MonotonicTime::infinity());
</span><del>-            if (executedEverything &amp;&amp; slotVisitor.isEmpty()) {
</del><ins>+            if (converged &amp;&amp; slotVisitor.isEmpty()) {
</ins><span class="cx">                 assertSharedMarkStacksEmpty();
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="cx">             m_scheduler-&gt;didExecuteConstraints();
</span><ins>+            iteration++;
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         if (Options::logGC())
</span><span class="lines">@@ -628,7 +639,7 @@
</span><span class="cx">         
</span><span class="cx">         if (Options::logGC()) {
</span><span class="cx">             double thisPauseMS = (MonotonicTime::now() - m_stopTime).milliseconds();
</span><del>-            dataLog(&quot;p=&quot;, thisPauseMS, &quot; ms (max &quot;, maxPauseMS(thisPauseMS), &quot;)...]\n&quot;);
</del><ins>+            dataLog(&quot;p=&quot;, thisPauseMS, &quot;ms (max &quot;, maxPauseMS(thisPauseMS), &quot;)...]\n&quot;);
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         resumeTheWorld();
</span><span class="lines">@@ -780,9 +791,7 @@
</span><span class="cx">     if (m_collectionScope == CollectionScope::Full)
</span><span class="cx">         m_totalBytesVisited = 0;
</span><span class="cx"> 
</span><del>-    m_totalBytesVisitedThisCycle =
-        m_collectorSlotVisitor-&gt;bytesVisited() +
-        threadBytesVisited();
</del><ins>+    m_totalBytesVisitedThisCycle = bytesVisited();
</ins><span class="cx">     
</span><span class="cx">     m_totalBytesVisited += m_totalBytesVisitedThisCycle;
</span><span class="cx"> }
</span><span class="lines">@@ -1011,7 +1020,7 @@
</span><span class="cx">     else {
</span><span class="cx">         double before = 0;
</span><span class="cx">         if (Options::logGC()) {
</span><del>-            dataLog(&quot;[Full sweep: &quot;, capacity() / 1024, &quot; kb &quot;);
</del><ins>+            dataLog(&quot;[Full sweep: &quot;, capacity() / 1024, &quot;kb &quot;);
</ins><span class="cx">             before = currentTimeMS();
</span><span class="cx">         }
</span><span class="cx">         m_objectSpace.sweep();
</span><span class="lines">@@ -1018,7 +1027,7 @@
</span><span class="cx">         m_objectSpace.shrink();
</span><span class="cx">         if (Options::logGC()) {
</span><span class="cx">             double after = currentTimeMS();
</span><del>-            dataLog(&quot;=&gt; &quot;, capacity() / 1024, &quot; kb, &quot;, after - before, &quot; ms]\n&quot;);
</del><ins>+            dataLog(&quot;=&gt; &quot;, capacity() / 1024, &quot;kb, &quot;, after - before, &quot;ms]\n&quot;);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     m_objectSpace.assertNoUnswept();
</span><span class="lines">@@ -1101,7 +1110,7 @@
</span><span class="cx"> 
</span><span class="cx">     MonotonicTime before;
</span><span class="cx">     if (Options::logGC()) {
</span><del>-        dataLog(&quot;[GC: START &quot;, capacity() / 1024, &quot; kb &quot;);
</del><ins>+        dataLog(&quot;[GC: START &quot;, capacity() / 1024, &quot;kb &quot;);
</ins><span class="cx">         before = MonotonicTime::now();
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -1170,7 +1179,7 @@
</span><span class="cx">     if (Options::logGC()) {
</span><span class="cx">         MonotonicTime after = MonotonicTime::now();
</span><span class="cx">         double thisPauseMS = (after - m_stopTime).milliseconds();
</span><del>-        dataLog(&quot;p=&quot;, thisPauseMS, &quot; ms (max &quot;, maxPauseMS(thisPauseMS), &quot;), cycle &quot;, (after - before).milliseconds(), &quot; ms END]\n&quot;);
</del><ins>+        dataLog(&quot;p=&quot;, thisPauseMS, &quot;ms (max &quot;, maxPauseMS(thisPauseMS), &quot;), cycle &quot;, (after - before).milliseconds(), &quot;ms END]\n&quot;);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     {
</span><span class="lines">@@ -1196,6 +1205,12 @@
</span><span class="cx">     RELEASE_ASSERT(!m_collectorBelievesThatTheWorldIsStopped);
</span><span class="cx">     waitWhileNeedFinalize();
</span><span class="cx">     stopTheMutator();
</span><ins>+    
+    if (m_mutatorDidRun)
+        m_mutatorExecutionVersion++;
+    
+    m_mutatorDidRun = false;
+    
</ins><span class="cx">     suspendCompilerThreads();
</span><span class="cx">     m_collectorBelievesThatTheWorldIsStopped = true;
</span><span class="cx"> 
</span><span class="lines">@@ -1769,7 +1784,7 @@
</span><span class="cx">     m_bytesAllocatedThisCycle = 0;
</span><span class="cx"> 
</span><span class="cx">     if (Options::logGC())
</span><del>-        dataLog(&quot;=&gt; &quot;, currentHeapSize / 1024, &quot; kb, &quot;);
</del><ins>+        dataLog(&quot;=&gt; &quot;, currentHeapSize / 1024, &quot;kb, &quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Heap::didFinishCollection(double gcStartTime)
</span><span class="lines">@@ -1976,6 +1991,11 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+size_t Heap::bytesVisited()
+{
+    return m_collectorSlotVisitor-&gt;bytesVisited() + threadBytesVisited();
+}
+
</ins><span class="cx"> size_t Heap::threadBytesVisited()
</span><span class="cx"> {       
</span><span class="cx">     size_t result = 0;
</span><span class="lines">@@ -2125,10 +2145,8 @@
</span><span class="cx"> }
</span><span class="cx"> #endif // USE(CF)
</span><span class="cx"> 
</span><del>-void Heap::buildConstraintSet()
</del><ins>+void Heap::addCoreConstraints()
</ins><span class="cx"> {
</span><del>-    m_constraintSet = std::make_unique&lt;MarkingConstraintSet&gt;();
-    
</del><span class="cx">     m_constraintSet-&gt;add(
</span><span class="cx">         &quot;Cs&quot;, &quot;Conservative Scan&quot;,
</span><span class="cx">         [this] (SlotVisitor&amp; slotVisitor, const VisitingTimeout&amp;) {
</span><span class="lines">@@ -2141,7 +2159,7 @@
</span><span class="cx">             gatherScratchBufferRoots(conservativeRoots);
</span><span class="cx">             slotVisitor.append(conservativeRoots);
</span><span class="cx">         },
</span><del>-        MarkingConstraint::GreyedByExecution);
</del><ins>+        ConstraintVolatility::GreyedByExecution);
</ins><span class="cx">     
</span><span class="cx">     m_constraintSet-&gt;add(
</span><span class="cx">         &quot;Msr&quot;, &quot;Misc Small Roots&quot;,
</span><span class="lines">@@ -2162,7 +2180,7 @@
</span><span class="cx">             slotVisitor.appendUnbarriered(m_vm-&gt;exception());
</span><span class="cx">             slotVisitor.appendUnbarriered(m_vm-&gt;lastException());
</span><span class="cx">         },
</span><del>-        MarkingConstraint::GreyedByExecution);
</del><ins>+        ConstraintVolatility::GreyedByExecution);
</ins><span class="cx">     
</span><span class="cx">     m_constraintSet-&gt;add(
</span><span class="cx">         &quot;Sh&quot;, &quot;Strong Handles&quot;,
</span><span class="lines">@@ -2170,7 +2188,7 @@
</span><span class="cx">             m_handleSet.visitStrongHandles(slotVisitor);
</span><span class="cx">             m_handleStack.visit(slotVisitor);
</span><span class="cx">         },
</span><del>-        MarkingConstraint::GreyedByExecution);
</del><ins>+        ConstraintVolatility::GreyedByExecution);
</ins><span class="cx">     
</span><span class="cx">     m_constraintSet-&gt;add(
</span><span class="cx">         &quot;D&quot;, &quot;Debugger&quot;,
</span><span class="lines">@@ -2190,7 +2208,7 @@
</span><span class="cx">             
</span><span class="cx">             m_vm-&gt;shadowChicken().visitChildren(slotVisitor);
</span><span class="cx">         },
</span><del>-        MarkingConstraint::GreyedByExecution);
</del><ins>+        ConstraintVolatility::GreyedByExecution);
</ins><span class="cx">     
</span><span class="cx">     m_constraintSet-&gt;add(
</span><span class="cx">         &quot;Jsr&quot;, &quot;JIT Stub Routines&quot;,
</span><span class="lines">@@ -2197,18 +2215,14 @@
</span><span class="cx">         [this] (SlotVisitor&amp; slotVisitor, const VisitingTimeout&amp;) {
</span><span class="cx">             m_jitStubRoutines-&gt;traceMarkedStubRoutines(slotVisitor);
</span><span class="cx">         },
</span><del>-        MarkingConstraint::GreyedByExecution);
</del><ins>+        ConstraintVolatility::GreyedByExecution);
</ins><span class="cx">     
</span><span class="cx">     m_constraintSet-&gt;add(
</span><span class="cx">         &quot;Ws&quot;, &quot;Weak Sets&quot;,
</span><span class="cx">         [this] (SlotVisitor&amp; slotVisitor, const VisitingTimeout&amp;) {
</span><del>-            slotVisitor.mergeOpaqueRootsIfNecessary();
-            for (auto&amp; parallelVisitor : m_parallelSlotVisitors)
-                parallelVisitor-&gt;mergeOpaqueRootsIfNecessary();
-            
</del><span class="cx">             m_objectSpace.visitWeakSets(slotVisitor);
</span><span class="cx">         },
</span><del>-        MarkingConstraint::GreyedByMarking);
</del><ins>+        ConstraintVolatility::GreyedByMarking);
</ins><span class="cx">     
</span><span class="cx">     m_constraintSet-&gt;add(
</span><span class="cx">         &quot;Wrh&quot;, &quot;Weak Reference Harvesters&quot;,
</span><span class="lines">@@ -2216,7 +2230,7 @@
</span><span class="cx">             for (WeakReferenceHarvester* current = m_weakReferenceHarvesters.head(); current; current = current-&gt;next())
</span><span class="cx">                 current-&gt;visitWeakReferences(slotVisitor);
</span><span class="cx">         },
</span><del>-        MarkingConstraint::GreyedByMarking);
</del><ins>+        ConstraintVolatility::GreyedByMarking);
</ins><span class="cx">     
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">     m_constraintSet-&gt;add(
</span><span class="lines">@@ -2236,7 +2250,7 @@
</span><span class="cx">             if (Options::logGC() == GCLogging::Verbose)
</span><span class="cx">                 dataLog(&quot;DFG Worklists:\n&quot;, slotVisitor);
</span><span class="cx">         },
</span><del>-        MarkingConstraint::GreyedByMarking);
</del><ins>+        ConstraintVolatility::GreyedByMarking);
</ins><span class="cx"> #endif
</span><span class="cx">     
</span><span class="cx">     m_constraintSet-&gt;add(
</span><span class="lines">@@ -2250,7 +2264,7 @@
</span><span class="cx">                         slotVisitor.visitAsConstraint(codeBlock);
</span><span class="cx">                 });
</span><span class="cx">         },
</span><del>-        MarkingConstraint::GreyedByExecution);
</del><ins>+        ConstraintVolatility::SeldomGreyed);
</ins><span class="cx">     
</span><span class="cx">     m_constraintSet-&gt;add(
</span><span class="cx">         &quot;Mrms&quot;, &quot;Mutator+Race Mark Stack&quot;,
</span><span class="lines">@@ -2268,12 +2282,18 @@
</span><span class="cx">         [this] (SlotVisitor&amp;) -&gt; double {
</span><span class="cx">             return m_mutatorMarkStack-&gt;size() + m_raceMarkStack-&gt;size();
</span><span class="cx">         },
</span><del>-        MarkingConstraint::GreyedByExecution);
</del><ins>+        ConstraintVolatility::GreyedByExecution);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Heap::addMarkingConstraint(std::unique_ptr&lt;MarkingConstraint&gt; constraint)
+{
+    PreventCollectionScope preventCollectionScope(*this);
+    m_constraintSet-&gt;add(WTFMove(constraint));
+}
+
</ins><span class="cx"> void Heap::notifyIsSafeToCollect()
</span><span class="cx"> {
</span><del>-    buildConstraintSet();
</del><ins>+    addCoreConstraints();
</ins><span class="cx">     
</span><span class="cx">     m_isSafeToCollect = true;
</span><span class="cx">     
</span><span class="lines">@@ -2311,6 +2331,9 @@
</span><span class="cx"> 
</span><span class="cx"> void Heap::preventCollection()
</span><span class="cx"> {
</span><ins>+    if (!m_isSafeToCollect)
+        return;
+    
</ins><span class="cx">     // This prevents the collectContinuously thread from starting a collection.
</span><span class="cx">     m_collectContinuouslyLock.lock();
</span><span class="cx">     
</span><span class="lines">@@ -2327,6 +2350,9 @@
</span><span class="cx"> 
</span><span class="cx"> void Heap::allowCollection()
</span><span class="cx"> {
</span><ins>+    if (!m_isSafeToCollect)
+        return;
+    
</ins><span class="cx">     m_collectContinuouslyLock.unlock();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2339,27 +2365,10 @@
</span><span class="cx">         func(*slotVisitor);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::writeBarrierOpaqueRootSlow(void* root)
-{
-    ASSERT(mutatorShouldBeFenced());
-    
-    auto locker = holdLock(m_opaqueRootsMutex);
-    m_opaqueRoots.add(root);
-}
-
-void Heap::addMutatorShouldBeFencedCache(bool&amp; cache)
-{
-    ASSERT(hasHeapAccess());
-    cache = m_mutatorShouldBeFenced;
-    m_mutatorShouldBeFencedCaches.append(&amp;cache);
-}
-
</del><span class="cx"> void Heap::setMutatorShouldBeFenced(bool value)
</span><span class="cx"> {
</span><span class="cx">     m_mutatorShouldBeFenced = value;
</span><span class="cx">     m_barrierThreshold = value ? tautologicalThreshold : blackThreshold;
</span><del>-    for (bool* cache : m_mutatorShouldBeFencedCaches)
-        *cache = value;
</del><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapHeaph"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/Heap.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/Heap.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/Heap.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -31,7 +31,6 @@
</span><span class="cx"> #include &quot;HeapObserver.h&quot;
</span><span class="cx"> #include &quot;ListableHandler.h&quot;
</span><span class="cx"> #include &quot;MachineStackMarker.h&quot;
</span><del>-#include &quot;MarkedAllocator.h&quot;
</del><span class="cx"> #include &quot;MarkedBlock.h&quot;
</span><span class="cx"> #include &quot;MarkedBlockSet.h&quot;
</span><span class="cx"> #include &quot;MarkedSpace.h&quot;
</span><span class="lines">@@ -71,7 +70,9 @@
</span><span class="cx"> class JSValue;
</span><span class="cx"> class LLIntOffsetsExtractor;
</span><span class="cx"> class MarkStackArray;
</span><ins>+class MarkedAllocator;
</ins><span class="cx"> class MarkedArgumentBuffer;
</span><ins>+class MarkingConstraint;
</ins><span class="cx"> class MarkingConstraintSet;
</span><span class="cx"> class MutatorScheduler;
</span><span class="cx"> class SlotVisitor;
</span><span class="lines">@@ -124,17 +125,16 @@
</span><span class="cx">     // Take this if you know that from-&gt;cellState() &lt; barrierThreshold.
</span><span class="cx">     JS_EXPORT_PRIVATE void writeBarrierSlowPath(const JSCell* from);
</span><span class="cx"> 
</span><del>-    void writeBarrierOpaqueRoot(void*);
-
</del><span class="cx">     Heap(VM*, HeapType);
</span><span class="cx">     ~Heap();
</span><span class="cx">     void lastChanceToFinalize();
</span><span class="cx">     void releaseDelayedReleasedObjects();
</span><span class="cx"> 
</span><ins>+    VM* vm() const;
+
</ins><span class="cx">     // Set a hard limit where JSC will crash if live heap size exceeds it.
</span><span class="cx">     void setMaxLiveSize(size_t size) { m_maxLiveSize = size; }
</span><span class="cx"> 
</span><del>-    VM* vm() const { return m_vm; }
</del><span class="cx">     MarkedSpace&amp; objectSpace() { return m_objectSpace; }
</span><span class="cx">     MachineThreads&amp; machineThreads() { return m_machineThreads; }
</span><span class="cx"> 
</span><span class="lines">@@ -159,20 +159,6 @@
</span><span class="cx">     // helping heap.
</span><span class="cx">     JS_EXPORT_PRIVATE bool isCurrentThreadBusy();
</span><span class="cx">     
</span><del>-    MarkedSpace::Subspace&amp; subspaceForObjectWithoutDestructor() { return m_objectSpace.subspaceForObjectsWithoutDestructor(); }
-    MarkedSpace::Subspace&amp; subspaceForObjectDestructor() { return m_objectSpace.subspaceForObjectsWithDestructor(); }
-    MarkedSpace::Subspace&amp; subspaceForAuxiliaryData() { return m_objectSpace.subspaceForAuxiliaryData(); }
-    template&lt;typename ClassType&gt; MarkedSpace::Subspace&amp; subspaceForObjectOfType();
-    MarkedAllocator* allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); }
-    MarkedAllocator* allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); }
-    template&lt;typename ClassType&gt; MarkedAllocator* allocatorForObjectOfType(size_t bytes);
-    MarkedAllocator* allocatorForAuxiliaryData(size_t bytes) { return m_objectSpace.auxiliaryAllocatorFor(bytes); }
-    void* allocateAuxiliary(JSCell* intendedOwner, size_t);
-    void* tryAllocateAuxiliary(JSCell* intendedOwner, size_t);
-    void* tryAllocateAuxiliary(GCDeferralContext*, JSCell* intendedOwner, size_t);
-    void* tryReallocateAuxiliary(JSCell* intendedOwner, void* oldBase, size_t oldSize, size_t newSize);
-    void ascribeOwner(JSCell* intendedOwner, void*);
-
</del><span class="cx">     typedef void (*Finalizer)(JSCell*);
</span><span class="cx">     JS_EXPORT_PRIVATE void addFinalizer(JSCell*, Finalizer);
</span><span class="cx">     void addExecutable(ExecutableBase*);
</span><span class="lines">@@ -350,8 +336,14 @@
</span><span class="cx">     void preventCollection();
</span><span class="cx">     void allowCollection();
</span><span class="cx">     
</span><del>-    JS_EXPORT_PRIVATE void addMutatorShouldBeFencedCache(bool&amp;);
</del><ins>+    size_t bytesVisited();
</ins><span class="cx">     
</span><ins>+    uint64_t mutatorExecutionVersion() const { return m_mutatorExecutionVersion; }
+    
+    JS_EXPORT_PRIVATE void addMarkingConstraint(std::unique_ptr&lt;MarkingConstraint&gt;);
+    
+    size_t numOpaqueRoots() const { return m_opaqueRoots.size(); }
+
</ins><span class="cx"> #if USE(CF)
</span><span class="cx">     CFRunLoopRef runLoop() const { return m_runLoop.get(); }
</span><span class="cx">     JS_EXPORT_PRIVATE void setRunLoop(CFRunLoopRef);
</span><span class="lines">@@ -384,18 +376,6 @@
</span><span class="cx">     class Thread;
</span><span class="cx">     friend class Thread;
</span><span class="cx"> 
</span><del>-    template&lt;typename T&gt; friend void* allocateCell(Heap&amp;);
-    template&lt;typename T&gt; friend void* allocateCell(Heap&amp;, size_t);
-    template&lt;typename T&gt; friend void* allocateCell(Heap&amp;, GCDeferralContext*);
-    template&lt;typename T&gt; friend void* allocateCell(Heap&amp;, GCDeferralContext*, size_t);
-
-    void* allocateWithDestructor(size_t); // For use with objects with destructors.
-    void* allocateWithoutDestructor(size_t); // For use with objects without destructors.
-    void* allocateWithDestructor(GCDeferralContext*, size_t);
-    void* allocateWithoutDestructor(GCDeferralContext*, size_t);
-    template&lt;typename ClassType&gt; void* allocateObjectOfType(size_t); // Chooses one of the methods above based on type.
-    template&lt;typename ClassType&gt; void* allocateObjectOfType(GCDeferralContext*, size_t);
-
</del><span class="cx">     static const size_t minExtraMemory = 256;
</span><span class="cx">     
</span><span class="cx">     class FinalizerOwner : public WeakHandleOwner {
</span><span class="lines">@@ -490,11 +470,9 @@
</span><span class="cx">     
</span><span class="cx">     void forEachCodeBlockImpl(const ScopedLambda&lt;bool(CodeBlock*)&gt;&amp;);
</span><span class="cx">     
</span><del>-    JS_EXPORT_PRIVATE void writeBarrierOpaqueRootSlow(void*);
-    
</del><span class="cx">     void setMutatorShouldBeFenced(bool value);
</span><span class="cx">     
</span><del>-    void buildConstraintSet();
</del><ins>+    void addCoreConstraints();
</ins><span class="cx">     
</span><span class="cx">     template&lt;typename Func&gt;
</span><span class="cx">     void iterateExecutingAndCompilingCodeBlocks(const Func&amp;);
</span><span class="lines">@@ -566,7 +544,6 @@
</span><span class="cx"> 
</span><span class="cx">     bool m_mutatorShouldBeFenced { Options::forceFencedBarrier() };
</span><span class="cx">     unsigned m_barrierThreshold { Options::forceFencedBarrier() ? tautologicalThreshold : blackThreshold };
</span><del>-    Vector&lt;bool*&gt; m_mutatorShouldBeFencedCaches;
</del><span class="cx"> 
</span><span class="cx">     VM* m_vm;
</span><span class="cx">     double m_lastFullGCLength;
</span><span class="lines">@@ -610,7 +587,7 @@
</span><span class="cx">     bool m_parallelMarkersShouldExit { false };
</span><span class="cx"> 
</span><span class="cx">     Lock m_opaqueRootsMutex;
</span><del>-    HashSet&lt;void*&gt; m_opaqueRoots;
</del><ins>+    HashSet&lt;const void*&gt; m_opaqueRoots;
</ins><span class="cx"> 
</span><span class="cx">     static const size_t s_blockFragmentLength = 32;
</span><span class="cx"> 
</span><span class="lines">@@ -645,6 +622,7 @@
</span><span class="cx">     bool m_threadShouldStop { false };
</span><span class="cx">     bool m_threadIsStopping { false };
</span><span class="cx">     bool m_mutatorDidRun { true };
</span><ins>+    uint64_t m_mutatorExecutionVersion { 0 };
</ins><span class="cx">     Box&lt;Lock&gt; m_threadLock;
</span><span class="cx">     RefPtr&lt;AutomaticThreadCondition&gt; m_threadCondition; // The mutator must not wait on this. It would cause a deadlock.
</span><span class="cx">     RefPtr&lt;AutomaticThread&gt; m_thread;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapHeapInlinesh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/HeapInlines.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/HeapInlines.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/HeapInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -39,6 +39,11 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+ALWAYS_INLINE VM* Heap::vm() const
+{
+    return bitwise_cast&lt;VM*&gt;(bitwise_cast&lt;uintptr_t&gt;(this) - OBJECT_OFFSETOF(VM, heap));
+}
+
</ins><span class="cx"> ALWAYS_INLINE Heap* Heap::heap(const HeapCell* cell)
</span><span class="cx"> {
</span><span class="cx">     return cell-&gt;heap();
</span><span class="lines">@@ -175,136 +180,6 @@
</span><span class="cx">     m_handleSet.forEachStrongHandle(functor, m_protectedValues);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void* Heap::allocateWithDestructor(size_t bytes)
-{
-#if ENABLE(ALLOCATION_LOGGING)
-    dataLogF(&quot;JSC GC allocating %lu bytes with normal destructor.\n&quot;, bytes);
-#endif
-    ASSERT(isValidAllocation(bytes));
-    return m_objectSpace.allocateWithDestructor(bytes);
-}
-
-inline void* Heap::allocateWithoutDestructor(size_t bytes)
-{
-#if ENABLE(ALLOCATION_LOGGING)
-    dataLogF(&quot;JSC GC allocating %lu bytes without destructor.\n&quot;, bytes);
-#endif
-    ASSERT(isValidAllocation(bytes));
-    return m_objectSpace.allocateWithoutDestructor(bytes);
-}
-
-inline void* Heap::allocateWithDestructor(GCDeferralContext* deferralContext, size_t bytes)
-{
-    ASSERT(isValidAllocation(bytes));
-    return m_objectSpace.allocateWithDestructor(deferralContext, bytes);
-}
-
-inline void* Heap::allocateWithoutDestructor(GCDeferralContext* deferralContext, size_t bytes)
-{
-    ASSERT(isValidAllocation(bytes));
-    return m_objectSpace.allocateWithoutDestructor(deferralContext, bytes);
-}
-
-template&lt;typename ClassType&gt;
-inline void* Heap::allocateObjectOfType(size_t bytes)
-{
-    // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
-    ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags &amp; StructureIsImmortal) || std::is_convertible&lt;ClassType, JSDestructibleObject&gt;::value));
-
-    if (ClassType::needsDestruction)
-        return allocateWithDestructor(bytes);
-    return allocateWithoutDestructor(bytes);
-}
-
-template&lt;typename ClassType&gt;
-inline void* Heap::allocateObjectOfType(GCDeferralContext* deferralContext, size_t bytes)
-{
-    ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags &amp; StructureIsImmortal) || std::is_convertible&lt;ClassType, JSDestructibleObject&gt;::value));
-
-    if (ClassType::needsDestruction)
-        return allocateWithDestructor(deferralContext, bytes);
-    return allocateWithoutDestructor(deferralContext, bytes);
-}
-
-template&lt;typename ClassType&gt;
-inline MarkedSpace::Subspace&amp; Heap::subspaceForObjectOfType()
-{
-    // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
-    ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags &amp; StructureIsImmortal) || std::is_convertible&lt;ClassType, JSDestructibleObject&gt;::value));
-    
-    if (ClassType::needsDestruction)
-        return subspaceForObjectDestructor();
-    return subspaceForObjectWithoutDestructor();
-}
-
-template&lt;typename ClassType&gt;
-inline MarkedAllocator* Heap::allocatorForObjectOfType(size_t bytes)
-{
-    // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
-    ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags &amp; StructureIsImmortal) || std::is_convertible&lt;ClassType, JSDestructibleObject&gt;::value));
-
-    MarkedAllocator* result;
-    if (ClassType::needsDestruction)
-        result = allocatorForObjectWithDestructor(bytes);
-    else
-        result = allocatorForObjectWithoutDestructor(bytes);
-    
-    ASSERT(result || !ClassType::info()-&gt;isSubClassOf(JSCallee::info()));
-    return result;
-}
-
-inline void* Heap::allocateAuxiliary(JSCell* intendedOwner, size_t bytes)
-{
-    void* result = m_objectSpace.allocateAuxiliary(bytes);
-#if ENABLE(ALLOCATION_LOGGING)
-    dataLogF(&quot;JSC GC allocating %lu bytes of auxiliary for %p: %p.\n&quot;, bytes, intendedOwner, result);
-#else
-    UNUSED_PARAM(intendedOwner);
-#endif
-    return result;
-}
-
-inline void* Heap::tryAllocateAuxiliary(JSCell* intendedOwner, size_t bytes)
-{
-    void* result = m_objectSpace.tryAllocateAuxiliary(bytes);
-#if ENABLE(ALLOCATION_LOGGING)
-    dataLogF(&quot;JSC GC allocating %lu bytes of auxiliary for %p: %p.\n&quot;, bytes, intendedOwner, result);
-#else
-    UNUSED_PARAM(intendedOwner);
-#endif
-    return result;
-}
-
-inline void* Heap::tryAllocateAuxiliary(GCDeferralContext* deferralContext, JSCell* intendedOwner, size_t bytes)
-{
-    void* result = m_objectSpace.tryAllocateAuxiliary(deferralContext, bytes);
-#if ENABLE(ALLOCATION_LOGGING)
-    dataLogF(&quot;JSC GC allocating %lu bytes of auxiliary for %p: %p.\n&quot;, bytes, intendedOwner, result);
-#else
-    UNUSED_PARAM(intendedOwner);
-#endif
-    return result;
-}
-
-inline void* Heap::tryReallocateAuxiliary(JSCell* intendedOwner, void* oldBase, size_t oldSize, size_t newSize)
-{
-    void* newBase = tryAllocateAuxiliary(intendedOwner, newSize);
-    if (!newBase)
-        return nullptr;
-    memcpy(newBase, oldBase, oldSize);
-    return newBase;
-}
-
-inline void Heap::ascribeOwner(JSCell* intendedOwner, void* storage)
-{
-#if ENABLE(ALLOCATION_LOGGING)
-    dataLogF(&quot;JSC GC ascribing %p as owner of storage %p.\n&quot;, intendedOwner, storage);
-#else
-    UNUSED_PARAM(intendedOwner);
-    UNUSED_PARAM(storage);
-#endif
-}
-
</del><span class="cx"> #if USE(FOUNDATION)
</span><span class="cx"> template &lt;typename T&gt;
</span><span class="cx"> inline void Heap::releaseSoon(RetainPtr&lt;T&gt;&amp;&amp; object)
</span><span class="lines">@@ -405,10 +280,4 @@
</span><span class="cx">         stopIfNecessarySlow();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void Heap::writeBarrierOpaqueRoot(void* root)
-{
-    if (mutatorShouldBeFenced())
-        writeBarrierOpaqueRootSlow(root);
-}
-
</del><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapLargeAllocationcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/LargeAllocation.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/LargeAllocation.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/LargeAllocation.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-LargeAllocation* LargeAllocation::tryCreate(Heap&amp; heap, size_t size, const AllocatorAttributes&amp; attributes)
</del><ins>+LargeAllocation* LargeAllocation::tryCreate(Heap&amp; heap, size_t size, Subspace* subspace)
</ins><span class="cx"> {
</span><span class="cx">     void* space = tryFastAlignedMalloc(alignment, headerSize() + size);
</span><span class="cx">     if (!space)
</span><span class="lines">@@ -39,19 +39,26 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     if (scribbleFreeCells())
</span><span class="cx">         scribble(space, size);
</span><del>-    return new (NotNull, space) LargeAllocation(heap, size, attributes);
</del><ins>+    return new (NotNull, space) LargeAllocation(heap, size, subspace);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-LargeAllocation::LargeAllocation(Heap&amp; heap, size_t size, const AllocatorAttributes&amp; attributes)
</del><ins>+LargeAllocation::LargeAllocation(Heap&amp; heap, size_t size, Subspace* subspace)
</ins><span class="cx">     : m_cellSize(size)
</span><span class="cx">     , m_isNewlyAllocated(true)
</span><span class="cx">     , m_hasValidCell(true)
</span><del>-    , m_attributes(attributes)
</del><ins>+    , m_attributes(subspace-&gt;attributes())
+    , m_subspace(subspace)
</ins><span class="cx">     , m_weakSet(heap.vm(), *this)
</span><span class="cx"> {
</span><span class="cx">     m_isMarked.store(0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+LargeAllocation::~LargeAllocation()
+{
+    if (isOnList())
+        remove();
+}
+
</ins><span class="cx"> void LargeAllocation::lastChanceToFinalize()
</span><span class="cx"> {
</span><span class="cx">     m_weakSet.lastChanceToFinalize();
</span><span class="lines">@@ -92,7 +99,7 @@
</span><span class="cx">     
</span><span class="cx">     if (m_hasValidCell &amp;&amp; !isLive()) {
</span><span class="cx">         if (m_attributes.destruction == NeedsDestruction)
</span><del>-            static_cast&lt;JSCell*&gt;(cell())-&gt;callDestructor(*vm());
</del><ins>+            m_subspace-&gt;destroy(*vm(), static_cast&lt;JSCell*&gt;(cell()));
</ins><span class="cx">         m_hasValidCell = false;
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapLargeAllocationh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/LargeAllocation.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/LargeAllocation.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/LargeAllocation.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -37,10 +37,12 @@
</span><span class="cx"> // objects directly using malloc, and put the LargeAllocation header just before them. We can detect
</span><span class="cx"> // when a HeapCell* is a LargeAllocation because it will have the MarkedBlock::atomSize / 2 bit set.
</span><span class="cx"> 
</span><del>-class LargeAllocation {
</del><ins>+class LargeAllocation : public BasicRawSentinelNode&lt;LargeAllocation&gt; {
</ins><span class="cx"> public:
</span><del>-    static LargeAllocation* tryCreate(Heap&amp;, size_t, const AllocatorAttributes&amp;);
</del><ins>+    static LargeAllocation* tryCreate(Heap&amp;, size_t, Subspace*);
</ins><span class="cx">     
</span><ins>+    ~LargeAllocation();
+    
</ins><span class="cx">     static LargeAllocation* fromCell(const void* cell)
</span><span class="cx">     {
</span><span class="cx">         return bitwise_cast&lt;LargeAllocation*&gt;(bitwise_cast&lt;char*&gt;(cell) - headerSize());
</span><span class="lines">@@ -136,7 +138,7 @@
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx">     
</span><span class="cx"> private:
</span><del>-    LargeAllocation(Heap&amp;, size_t, const AllocatorAttributes&amp;);
</del><ins>+    LargeAllocation(Heap&amp;, size_t, Subspace*);
</ins><span class="cx">     
</span><span class="cx">     static const unsigned alignment = MarkedBlock::atomSize;
</span><span class="cx">     static const unsigned halfAlignment = alignment / 2;
</span><span class="lines">@@ -148,6 +150,7 @@
</span><span class="cx">     bool m_hasValidCell;
</span><span class="cx">     Atomic&lt;bool&gt; m_isMarked;
</span><span class="cx">     AllocatorAttributes m_attributes;
</span><ins>+    Subspace* m_subspace;
</ins><span class="cx">     WeakSet m_weakSet;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkedAllocatorcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocator.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocator.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocator.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;Heap.h&quot;
</span><span class="cx"> #include &quot;IncrementalSweeper.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;MarkedAllocatorInlines.h&quot;
</ins><span class="cx"> #include &quot;MarkedBlockInlines.h&quot;
</span><span class="cx"> #include &quot;SuperSampler.h&quot;
</span><span class="cx"> #include &quot;VM.h&quot;
</span><span class="lines">@@ -38,13 +39,13 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-MarkedAllocator::MarkedAllocator(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, const AllocatorAttributes&amp; attributes)
</del><ins>+MarkedAllocator::MarkedAllocator(Heap* heap, Subspace* subspace, size_t cellSize)
</ins><span class="cx">     : m_currentBlock(0)
</span><span class="cx">     , m_lastActiveBlock(0)
</span><span class="cx">     , m_cellSize(static_cast&lt;unsigned&gt;(cellSize))
</span><del>-    , m_attributes(attributes)
</del><ins>+    , m_attributes(subspace-&gt;attributes())
</ins><span class="cx">     , m_heap(heap)
</span><del>-    , m_markedSpace(markedSpace)
</del><ins>+    , m_subspace(subspace)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -112,7 +113,7 @@
</span><span class="cx">     
</span><span class="cx">     if (Options::stealEmptyBlocksFromOtherAllocators()
</span><span class="cx">         &amp;&amp; shouldStealEmptyBlocksFromOtherAllocators()) {
</span><del>-        if (MarkedBlock::Handle* block = m_markedSpace-&gt;findEmptyBlockToSteal()) {
</del><ins>+        if (MarkedBlock::Handle* block = markedSpace().findEmptyBlockToSteal()) {
</ins><span class="cx">             block-&gt;sweep();
</span><span class="cx">             
</span><span class="cx">             // It's good that this clears canAllocateButNotEmpty as well as all other bits,
</span><span class="lines">@@ -167,7 +168,7 @@
</span><span class="cx">     }
</span><span class="cx">     RELEASE_ASSERT(result);
</span><span class="cx">     setIsEden(NoLockingNecessary, m_currentBlock, true);
</span><del>-    m_markedSpace-&gt;didAllocateInBlock(m_currentBlock);
</del><ins>+    markedSpace().didAllocateInBlock(m_currentBlock);
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -207,7 +208,7 @@
</span><span class="cx">     ASSERT(m_heap-&gt;vm()-&gt;currentThreadIsHoldingAPILock());
</span><span class="cx">     doTestCollectionsIfNeeded(deferralContext);
</span><span class="cx"> 
</span><del>-    ASSERT(!m_markedSpace-&gt;isIterating());
</del><ins>+    ASSERT(!markedSpace().isIterating());
</ins><span class="cx">     m_heap-&gt;didAllocate(m_freeList.originalSize);
</span><span class="cx">     
</span><span class="cx">     didConsumeFreeList();
</span><span class="lines">@@ -255,7 +256,7 @@
</span><span class="cx">     if (!handle)
</span><span class="cx">         return nullptr;
</span><span class="cx">     
</span><del>-    m_markedSpace-&gt;didAddBlock(handle);
</del><ins>+    markedSpace().didAddBlock(handle);
</ins><span class="cx">     
</span><span class="cx">     return handle;
</span><span class="cx"> }
</span><span class="lines">@@ -445,7 +446,7 @@
</span><span class="cx"> {
</span><span class="cx">     m_empty.forEachSetBit(
</span><span class="cx">         [&amp;] (size_t index) {
</span><del>-            m_markedSpace-&gt;freeBlock(m_blocks[index]);
</del><ins>+            markedSpace().freeBlock(m_blocks[index]);
</ins><span class="cx">         });
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -487,5 +488,10 @@
</span><span class="cx">         });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+MarkedSpace&amp; MarkedAllocator::markedSpace() const
+{
+    return m_subspace-&gt;space();
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkedAllocatorh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocator.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocator.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocator.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -135,7 +135,7 @@
</span><span class="cx">     static ptrdiff_t offsetOfFreeList();
</span><span class="cx">     static ptrdiff_t offsetOfCellSize();
</span><span class="cx"> 
</span><del>-    MarkedAllocator(Heap*, MarkedSpace*, size_t cellSize, const AllocatorAttributes&amp;);
</del><ins>+    MarkedAllocator(Heap*, Subspace*, size_t cellSize);
</ins><span class="cx">     void lastChanceToFinalize();
</span><span class="cx">     void prepareForAllocation();
</span><span class="cx">     void stopAllocating();
</span><span class="lines">@@ -163,6 +163,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     template&lt;typename Functor&gt; void forEachBlock(const Functor&amp;);
</span><ins>+    template&lt;typename Functor&gt; void forEachNotEmptyBlock(const Functor&amp;);
</ins><span class="cx">     
</span><span class="cx">     void addBlock(MarkedBlock::Handle*);
</span><span class="cx">     void removeBlock(MarkedBlock::Handle*);
</span><span class="lines">@@ -200,14 +201,18 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     MarkedAllocator* nextAllocator() const { return m_nextAllocator; }
</span><ins>+    MarkedAllocator* nextAllocatorInSubspace() const { return m_nextAllocatorInSubspace; }
</ins><span class="cx">     
</span><del>-    // MarkedSpace calls this during init.
</del><span class="cx">     void setNextAllocator(MarkedAllocator* allocator) { m_nextAllocator = allocator; }
</span><ins>+    void setNextAllocatorInSubspace(MarkedAllocator* allocator) { m_nextAllocatorInSubspace = allocator; }
</ins><span class="cx">     
</span><span class="cx">     MarkedBlock::Handle* findEmptyBlockToSteal();
</span><span class="cx">     
</span><span class="cx">     MarkedBlock::Handle* findBlockToSweep();
</span><span class="cx">     
</span><ins>+    Subspace* subspace() const { return m_subspace; }
+    MarkedSpace&amp; markedSpace() const;
+    
</ins><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx">     void dumpBits(PrintStream&amp; = WTF::dataFile());
</span><span class="cx">     
</span><span class="lines">@@ -253,9 +258,12 @@
</span><span class="cx">     Lock m_lock;
</span><span class="cx">     unsigned m_cellSize;
</span><span class="cx">     AllocatorAttributes m_attributes;
</span><ins>+    // FIXME: All of these should probably be references.
+    // https://bugs.webkit.org/show_bug.cgi?id=166988
</ins><span class="cx">     Heap* m_heap;
</span><del>-    MarkedSpace* m_markedSpace;
-    MarkedAllocator* m_nextAllocator;
</del><ins>+    Subspace* m_subspace;
+    MarkedAllocator* m_nextAllocator { nullptr };
+    MarkedAllocator* m_nextAllocatorInSubspace { nullptr };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline ptrdiff_t MarkedAllocator::offsetOfFreeList()
</span><span class="lines">@@ -268,48 +276,4 @@
</span><span class="cx">     return OBJECT_OFFSETOF(MarkedAllocator, m_cellSize);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE void* MarkedAllocator::tryAllocate(GCDeferralContext* deferralContext)
-{
-    unsigned remaining = m_freeList.remaining;
-    if (remaining) {
-        unsigned cellSize = m_cellSize;
-        remaining -= cellSize;
-        m_freeList.remaining = remaining;
-        return m_freeList.payloadEnd - remaining - cellSize;
-    }
-    
-    FreeCell* head = m_freeList.head;
-    if (UNLIKELY(!head))
-        return tryAllocateSlowCase(deferralContext);
-    
-    m_freeList.head = head-&gt;next;
-    return head;
-}
-
-ALWAYS_INLINE void* MarkedAllocator::allocate(GCDeferralContext* deferralContext)
-{
-    unsigned remaining = m_freeList.remaining;
-    if (remaining) {
-        unsigned cellSize = m_cellSize;
-        remaining -= cellSize;
-        m_freeList.remaining = remaining;
-        return m_freeList.payloadEnd - remaining - cellSize;
-    }
-    
-    FreeCell* head = m_freeList.head;
-    if (UNLIKELY(!head))
-        return allocateSlowCase(deferralContext);
-    
-    m_freeList.head = head-&gt;next;
-    return head;
-}
-
-template &lt;typename Functor&gt; inline void MarkedAllocator::forEachBlock(const Functor&amp; functor)
-{
-    m_live.forEachSetBit(
-        [&amp;] (size_t index) {
-            functor(m_blocks[index]);
-        });
-}
-
</del><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkedAllocatorInlinesh"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocatorInlines.h (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocatorInlines.h                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedAllocatorInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,85 @@
</span><ins>+/*
+ * Copyright (C) 2017 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. 
+ */
+
+#pragma once
+
+#include &quot;MarkedAllocator.h&quot;
+
+namespace JSC {
+
+ALWAYS_INLINE void* MarkedAllocator::tryAllocate(GCDeferralContext* deferralContext)
+{
+    unsigned remaining = m_freeList.remaining;
+    if (remaining) {
+        unsigned cellSize = m_cellSize;
+        remaining -= cellSize;
+        m_freeList.remaining = remaining;
+        return m_freeList.payloadEnd - remaining - cellSize;
+    }
+    
+    FreeCell* head = m_freeList.head;
+    if (UNLIKELY(!head))
+        return tryAllocateSlowCase(deferralContext);
+    
+    m_freeList.head = head-&gt;next;
+    return head;
+}
+
+ALWAYS_INLINE void* MarkedAllocator::allocate(GCDeferralContext* deferralContext)
+{
+    unsigned remaining = m_freeList.remaining;
+    if (remaining) {
+        unsigned cellSize = m_cellSize;
+        remaining -= cellSize;
+        m_freeList.remaining = remaining;
+        return m_freeList.payloadEnd - remaining - cellSize;
+    }
+    
+    FreeCell* head = m_freeList.head;
+    if (UNLIKELY(!head))
+        return allocateSlowCase(deferralContext);
+    
+    m_freeList.head = head-&gt;next;
+    return head;
+}
+
+template &lt;typename Functor&gt; inline void MarkedAllocator::forEachBlock(const Functor&amp; functor)
+{
+    m_live.forEachSetBit(
+        [&amp;] (size_t index) {
+            functor(m_blocks[index]);
+        });
+}
+
+template &lt;typename Functor&gt; inline void MarkedAllocator::forEachNotEmptyBlock(const Functor&amp; functor)
+{
+    m_markingNotEmpty.forEachSetBit(
+        [&amp;] (size_t index) {
+            functor(m_blocks[index]);
+        });
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkedBlockcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlock.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlock.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlock.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -89,194 +89,6 @@
</span><span class="cx">         dataLog(RawPointer(this), &quot;: Allocated.\n&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepMode sweepMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode, MarkedBlock::Handle::NewlyAllocatedMode newlyAllocatedMode, MarkedBlock::Handle::MarksMode marksMode&gt;
-FreeList MarkedBlock::Handle::specializedSweep()
-{
-    RELEASE_ASSERT(!(destructionMode == BlockHasNoDestructors &amp;&amp; sweepMode == SweepOnly));
-    
-    SuperSamplerScope superSamplerScope(false);
-
-    MarkedBlock&amp; block = this-&gt;block();
-    
-    if (false)
-        dataLog(RawPointer(this), &quot;/&quot;, RawPointer(&amp;block), &quot;: MarkedBlock::Handle::specializedSweep!\n&quot;);
-    
-    if (Options::useBumpAllocator()
-        &amp;&amp; emptyMode == IsEmpty
-        &amp;&amp; newlyAllocatedMode == DoesNotHaveNewlyAllocated) {
-        
-        // This is an incredibly powerful assertion that checks the sanity of our block bits.
-        if (marksMode == MarksNotStale &amp;&amp; !block.m_marks.isEmpty()) {
-            WTF::dataFile().atomically(
-                [&amp;] (PrintStream&amp; out) {
-                    out.print(&quot;Block &quot;, RawPointer(&amp;block), &quot;: marks not empty!\n&quot;);
-                    out.print(&quot;Block lock is held: &quot;, block.m_lock.isHeld(), &quot;\n&quot;);
-                    out.print(&quot;Marking version of block: &quot;, block.m_markingVersion, &quot;\n&quot;);
-                    out.print(&quot;Marking version of heap: &quot;, space()-&gt;markingVersion(), &quot;\n&quot;);
-                    UNREACHABLE_FOR_PLATFORM();
-                });
-        }
-        
-        char* startOfLastCell = static_cast&lt;char*&gt;(cellAlign(block.atoms() + m_endAtom - 1));
-        char* payloadEnd = startOfLastCell + cellSize();
-        RELEASE_ASSERT(payloadEnd - MarkedBlock::blockSize &lt;= bitwise_cast&lt;char*&gt;(&amp;block));
-        char* payloadBegin = bitwise_cast&lt;char*&gt;(block.atoms() + firstAtom());
-        if (scribbleMode == Scribble)
-            scribble(payloadBegin, payloadEnd - payloadBegin);
-        if (sweepMode == SweepToFreeList)
-            setIsFreeListed();
-        else
-            m_allocator-&gt;setIsEmpty(NoLockingNecessary, this, true);
-        if (space()-&gt;isMarking())
-            block.m_lock.unlock();
-        FreeList result = FreeList::bump(payloadEnd, payloadEnd - payloadBegin);
-        if (false)
-            dataLog(&quot;Quickly swept block &quot;, RawPointer(this), &quot; with cell size &quot;, cellSize(), &quot; and attributes &quot;, m_attributes, &quot;: &quot;, result, &quot;\n&quot;);
-        return result;
-    }
-
-    // This produces a free list that is ordered in reverse through the block.
-    // This is fine, since the allocation code makes no assumptions about the
-    // order of the free list.
-    FreeCell* head = 0;
-    size_t count = 0;
-    bool isEmpty = true;
-    Vector&lt;size_t&gt; deadCells;
-    auto handleDeadCell = [&amp;] (size_t i) {
-        HeapCell* cell = reinterpret_cast_ptr&lt;HeapCell*&gt;(&amp;block.atoms()[i]);
-
-        if (destructionMode != BlockHasNoDestructors &amp;&amp; emptyMode == NotEmpty)
-            static_cast&lt;JSCell*&gt;(cell)-&gt;callDestructor(*vm());
-
-        if (sweepMode == SweepToFreeList) {
-            FreeCell* freeCell = reinterpret_cast_ptr&lt;FreeCell*&gt;(cell);
-            if (scribbleMode == Scribble)
-                scribble(freeCell, cellSize());
-            freeCell-&gt;next = head;
-            head = freeCell;
-            ++count;
-        }
-    };
-    for (size_t i = firstAtom(); i &lt; m_endAtom; i += m_atomsPerCell) {
-        if (emptyMode == NotEmpty
-            &amp;&amp; ((marksMode == MarksNotStale &amp;&amp; block.m_marks.get(i))
-                || (newlyAllocatedMode == HasNewlyAllocated &amp;&amp; m_newlyAllocated.get(i)))) {
-            isEmpty = false;
-            continue;
-        }
-        
-        if (destructionMode == BlockHasDestructorsAndCollectorIsRunning)
-            deadCells.append(i);
-        else
-            handleDeadCell(i);
-    }
-    
-    // We only want to discard the newlyAllocated bits if we're creating a FreeList,
-    // otherwise we would lose information on what's currently alive.
-    if (sweepMode == SweepToFreeList &amp;&amp; newlyAllocatedMode == HasNewlyAllocated)
-        m_newlyAllocatedVersion = MarkedSpace::nullVersion;
-    
-    if (space()-&gt;isMarking())
-        block.m_lock.unlock();
-    
-    if (destructionMode == BlockHasDestructorsAndCollectorIsRunning) {
-        for (size_t i : deadCells)
-            handleDeadCell(i);
-    }
-
-    FreeList result = FreeList::list(head, count * cellSize());
-    if (sweepMode == SweepToFreeList)
-        setIsFreeListed();
-    else if (isEmpty)
-        m_allocator-&gt;setIsEmpty(NoLockingNecessary, this, true);
-    if (false)
-        dataLog(&quot;Slowly swept block &quot;, RawPointer(&amp;block), &quot; with cell size &quot;, cellSize(), &quot; and attributes &quot;, m_attributes, &quot;: &quot;, result, &quot;\n&quot;);
-    return result;
-}
-
-FreeList MarkedBlock::Handle::sweep(SweepMode sweepMode)
-{
-    // FIXME: Maybe HelpingGCScope should just be called SweepScope?
-    HelpingGCScope helpingGCScope(*heap());
-    
-    m_allocator-&gt;setIsUnswept(NoLockingNecessary, this, false);
-    
-    m_weakSet.sweep();
-
-    if (sweepMode == SweepOnly &amp;&amp; m_attributes.destruction == DoesNotNeedDestruction)
-        return FreeList();
-
-    if (UNLIKELY(m_isFreeListed)) {
-        RELEASE_ASSERT(sweepMode == SweepToFreeList);
-        return FreeList();
-    }
-    
-    ASSERT(!m_allocator-&gt;isAllocated(NoLockingNecessary, this));
-    
-    if (space()-&gt;isMarking())
-        block().m_lock.lock();
-    
-    if (m_attributes.destruction == NeedsDestruction) {
-        if (space()-&gt;isMarking())
-            return sweepHelperSelectScribbleMode&lt;BlockHasDestructorsAndCollectorIsRunning&gt;(sweepMode);
-        return sweepHelperSelectScribbleMode&lt;BlockHasDestructors&gt;(sweepMode);
-    }
-    return sweepHelperSelectScribbleMode&lt;BlockHasNoDestructors&gt;(sweepMode);
-}
-
-template&lt;MarkedBlock::Handle::SweepDestructionMode destructionMode&gt;
-FreeList MarkedBlock::Handle::sweepHelperSelectScribbleMode(SweepMode sweepMode)
-{
-    if (scribbleFreeCells())
-        return sweepHelperSelectEmptyMode&lt;destructionMode, Scribble&gt;(sweepMode);
-    return sweepHelperSelectEmptyMode&lt;destructionMode, DontScribble&gt;(sweepMode);
-}
-
-template&lt;MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode&gt;
-FreeList MarkedBlock::Handle::sweepHelperSelectEmptyMode(SweepMode sweepMode)
-{
-    // It's not obvious, but this is the only way to know if the block is empty. It's the only
-    // bit that captures these caveats:
-    // - It's true when the block is freshly allocated.
-    // - It's true if the block had been swept in the past, all destructors were called, and that
-    //   sweep proved that the block is empty.
-    // - It's false if there are any destructors that need to be called, even if the block has no
-    //   live objects.
-    if (m_allocator-&gt;isEmpty(NoLockingNecessary, this))
-        return sweepHelperSelectHasNewlyAllocated&lt;IsEmpty, destructionMode, scribbleMode&gt;(sweepMode);
-    return sweepHelperSelectHasNewlyAllocated&lt;NotEmpty, destructionMode, scribbleMode&gt;(sweepMode);
-}
-
-template&lt;MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode&gt;
-FreeList MarkedBlock::Handle::sweepHelperSelectHasNewlyAllocated(SweepMode sweepMode)
-{
-    if (hasAnyNewlyAllocated())
-        return sweepHelperSelectSweepMode&lt;emptyMode, destructionMode, scribbleMode, HasNewlyAllocated&gt;(sweepMode);
-    return sweepHelperSelectSweepMode&lt;emptyMode, destructionMode, scribbleMode, DoesNotHaveNewlyAllocated&gt;(sweepMode);
-}
-
-template&lt;MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode, MarkedBlock::Handle::NewlyAllocatedMode newlyAllocatedMode&gt;
-FreeList MarkedBlock::Handle::sweepHelperSelectSweepMode(SweepMode sweepMode)
-{
-    if (sweepMode == SweepToFreeList)
-        return sweepHelperSelectMarksMode&lt;emptyMode, SweepToFreeList, destructionMode, scribbleMode, newlyAllocatedMode&gt;();
-    return sweepHelperSelectMarksMode&lt;emptyMode, SweepOnly, destructionMode, scribbleMode, newlyAllocatedMode&gt;();
-}
-
-template&lt;MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepMode sweepMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode, MarkedBlock::Handle::NewlyAllocatedMode newlyAllocatedMode&gt;
-FreeList MarkedBlock::Handle::sweepHelperSelectMarksMode()
-{
-    HeapVersion markingVersion = space()-&gt;markingVersion();
-    bool marksAreUseful = !block().areMarksStale(markingVersion);
-    
-    if (space()-&gt;isMarking())
-        marksAreUseful |= block().marksConveyLivenessDuringMarking(markingVersion);
-    
-    if (!marksAreUseful)
-        return specializedSweep&lt;emptyMode, sweepMode, destructionMode, scribbleMode, newlyAllocatedMode, MarksStale&gt;();
-    return specializedSweep&lt;emptyMode, sweepMode, destructionMode, scribbleMode, newlyAllocatedMode, MarksNotStale&gt;();
-}
-
</del><span class="cx"> void MarkedBlock::Handle::unsweepWithNoNewlyAllocated()
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(m_isFreeListed);
</span><span class="lines">@@ -590,6 +402,86 @@
</span><span class="cx">         });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Subspace* MarkedBlock::Handle::subspace() const
+{
+    return allocator()-&gt;subspace();
+}
+
+FreeList MarkedBlock::Handle::sweep(SweepMode sweepMode)
+{
+    // FIXME: Maybe HelpingGCScope should just be called SweepScope?
+    HelpingGCScope helpingGCScope(*heap());
+    
+    m_allocator-&gt;setIsUnswept(NoLockingNecessary, this, false);
+    
+    m_weakSet.sweep();
+
+    if (sweepMode == SweepOnly &amp;&amp; m_attributes.destruction == DoesNotNeedDestruction)
+        return FreeList();
+
+    if (UNLIKELY(m_isFreeListed)) {
+        RELEASE_ASSERT(sweepMode == SweepToFreeList);
+        return FreeList();
+    }
+    
+    ASSERT(!m_allocator-&gt;isAllocated(NoLockingNecessary, this));
+    
+    if (space()-&gt;isMarking())
+        block().m_lock.lock();
+    
+    if (m_attributes.destruction == NeedsDestruction)
+        return subspace()-&gt;finishSweep(*this, sweepMode);
+    
+    // Handle the no-destructor specializations here, since we have the most of those. This
+    // ensures that they don't get re-specialized for every destructor space.
+    
+    EmptyMode emptyMode = this-&gt;emptyMode();
+    ScribbleMode scribbleMode = this-&gt;scribbleMode();
+    NewlyAllocatedMode newlyAllocatedMode = this-&gt;newlyAllocatedMode();
+    MarksMode marksMode = this-&gt;marksMode();
+    
+    FreeList result;
+    auto trySpecialized = [&amp;] () -&gt; bool {
+        if (sweepMode != SweepToFreeList)
+            return false;
+        if (scribbleMode != DontScribble)
+            return false;
+        if (newlyAllocatedMode != DoesNotHaveNewlyAllocated)
+            return false;
+        
+        switch (emptyMode) {
+        case IsEmpty:
+            switch (marksMode) {
+            case MarksNotStale:
+                result = specializedSweep&lt;true, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale&gt;(IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, [] (VM&amp;, JSCell*) { });
+                return true;
+            case MarksStale:
+                result = specializedSweep&lt;true, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale&gt;(IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, [] (VM&amp;, JSCell*) { });
+                return true;
+            }
+            break;
+        case NotEmpty:
+            switch (marksMode) {
+            case MarksNotStale:
+                result = specializedSweep&lt;true, NotEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale&gt;(IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, [] (VM&amp;, JSCell*) { });
+                return true;
+            case MarksStale:
+                result = specializedSweep&lt;true, NotEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale&gt;(IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, [] (VM&amp;, JSCell*) { });
+                return true;
+            }
+            break;
+        }
+        
+        return false;
+    };
+    
+    if (trySpecialized())
+        return result;
+
+    // The template arguments don't matter because the first one is false.
+    return specializedSweep&lt;false, IsEmpty, SweepOnly, BlockHasNoDestructors, DontScribble, HasNewlyAllocated, MarksStale&gt;(emptyMode, sweepMode, BlockHasNoDestructors, scribbleMode, newlyAllocatedMode, marksMode, [] (VM&amp;, JSCell*) { });
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkedBlockh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlock.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlock.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlock.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003-2009, 2011, 2016 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> class MarkedAllocator;
</span><span class="cx"> class MarkedSpace;
</span><span class="cx"> class SlotVisitor;
</span><ins>+class Subspace;
</ins><span class="cx"> 
</span><span class="cx"> typedef uintptr_t Bits;
</span><span class="cx"> typedef uint32_t HeapVersion;
</span><span class="lines">@@ -110,6 +111,7 @@
</span><span class="cx">         void lastChanceToFinalize();
</span><span class="cx"> 
</span><span class="cx">         MarkedAllocator* allocator() const;
</span><ins>+        Subspace* subspace() const;
</ins><span class="cx">         Heap* heap() const;
</span><span class="cx">         inline MarkedSpace* space() const;
</span><span class="cx">         VM* vm() const;
</span><span class="lines">@@ -127,6 +129,10 @@
</span><span class="cx">         enum SweepMode { SweepOnly, SweepToFreeList };
</span><span class="cx">         FreeList sweep(SweepMode = SweepOnly);
</span><span class="cx">         
</span><ins>+        // This is to be called by Subspace.
+        template&lt;typename DestroyFunc&gt;
+        FreeList finishSweepKnowingSubspace(SweepMode, const DestroyFunc&amp;);
+        
</ins><span class="cx">         void unsweepWithNoNewlyAllocated();
</span><span class="cx">         
</span><span class="cx">         void zap(const FreeList&amp;);
</span><span class="lines">@@ -133,7 +139,7 @@
</span><span class="cx">         
</span><span class="cx">         void shrink();
</span><span class="cx">             
</span><del>-        unsigned visitWeakSet(SlotVisitor&amp;);
</del><ins>+        void visitWeakSet(SlotVisitor&amp;);
</ins><span class="cx">         void reapWeakSet();
</span><span class="cx">             
</span><span class="cx">         // While allocating from a free list, MarkedBlock temporarily has bogus
</span><span class="lines">@@ -174,8 +180,9 @@
</span><span class="cx">         template &lt;typename Functor&gt; IterationStatus forEachCell(const Functor&amp;);
</span><span class="cx">         template &lt;typename Functor&gt; inline IterationStatus forEachLiveCell(const Functor&amp;);
</span><span class="cx">         template &lt;typename Functor&gt; inline IterationStatus forEachDeadCell(const Functor&amp;);
</span><ins>+        template &lt;typename Functor&gt; inline IterationStatus forEachMarkedCell(const Functor&amp;);
</ins><span class="cx">             
</span><del>-        bool areMarksStale();
</del><ins>+        JS_EXPORT_PRIVATE bool areMarksStale();
</ins><span class="cx">         
</span><span class="cx">         void assertMarksNotStale();
</span><span class="cx">             
</span><span class="lines">@@ -194,33 +201,20 @@
</span><span class="cx">         Handle(Heap&amp;, void*);
</span><span class="cx">         
</span><span class="cx">         enum SweepDestructionMode { BlockHasNoDestructors, BlockHasDestructors, BlockHasDestructorsAndCollectorIsRunning };
</span><del>-        
-        template&lt;SweepDestructionMode&gt;
-        FreeList sweepHelperSelectScribbleMode(SweepMode = SweepOnly);
-            
</del><span class="cx">         enum ScribbleMode { DontScribble, Scribble };
</span><del>-            
-        template&lt;SweepDestructionMode, ScribbleMode&gt;
-        FreeList sweepHelperSelectEmptyMode(SweepMode = SweepOnly);
-            
</del><span class="cx">         enum EmptyMode { IsEmpty, NotEmpty };
</span><del>-        
-        template&lt;EmptyMode, SweepDestructionMode, ScribbleMode&gt;
-        FreeList sweepHelperSelectHasNewlyAllocated(SweepMode = SweepOnly);
-        
</del><span class="cx">         enum NewlyAllocatedMode { HasNewlyAllocated, DoesNotHaveNewlyAllocated };
</span><ins>+        enum MarksMode { MarksStale, MarksNotStale };
</ins><span class="cx">         
</span><del>-        template&lt;EmptyMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode&gt;
-        FreeList sweepHelperSelectSweepMode(SweepMode = SweepOnly);
</del><ins>+        SweepDestructionMode sweepDestructionMode();
+        EmptyMode emptyMode();
+        ScribbleMode scribbleMode();
+        NewlyAllocatedMode newlyAllocatedMode();
+        MarksMode marksMode();
</ins><span class="cx">         
</span><del>-        template&lt;EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode&gt;
-        FreeList sweepHelperSelectMarksMode();
</del><ins>+        template&lt;bool, EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode, MarksMode, typename DestroyFunc&gt;
+        FreeList specializedSweep(EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode, MarksMode, const DestroyFunc&amp;);
</ins><span class="cx">         
</span><del>-        enum MarksMode { MarksStale, MarksNotStale };
-        
-        template&lt;EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode, MarksMode&gt;
-        FreeList specializedSweep();
-            
</del><span class="cx">         template&lt;typename Func&gt;
</span><span class="cx">         void forEachFreeCell(const FreeList&amp;, const Func&amp;);
</span><span class="cx">         
</span><span class="lines">@@ -282,7 +276,7 @@
</span><span class="cx">         
</span><span class="cx">     WeakSet&amp; weakSet();
</span><span class="cx"> 
</span><del>-    bool areMarksStale();
</del><ins>+    JS_EXPORT_PRIVATE bool areMarksStale();
</ins><span class="cx">     bool areMarksStale(HeapVersion markingVersion);
</span><span class="cx">     struct MarksWithDependency {
</span><span class="cx">         bool areStale;
</span><span class="lines">@@ -432,7 +426,7 @@
</span><span class="cx">     m_weakSet.shrink();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline unsigned MarkedBlock::Handle::visitWeakSet(SlotVisitor&amp; visitor)
</del><ins>+inline void MarkedBlock::Handle::visitWeakSet(SlotVisitor&amp; visitor)
</ins><span class="cx"> {
</span><span class="cx">     return m_weakSet.visit(visitor);
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkedBlockInlinesh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlockInlines.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlockInlines.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedBlockInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -25,9 +25,12 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include &quot;JSCell.h&quot;
</ins><span class="cx"> #include &quot;MarkedAllocator.h&quot;
</span><span class="cx"> #include &quot;MarkedBlock.h&quot;
</span><span class="cx"> #include &quot;MarkedSpace.h&quot;
</span><ins>+#include &quot;Operations.h&quot;
+#include &quot;SuperSampler.h&quot;
</ins><span class="cx"> #include &quot;VM.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -37,6 +40,31 @@
</span><span class="cx">     return MarkedSpace::blockPayload / cellSize();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool MarkedBlock::Handle::isNewlyAllocatedStale() const
+{
+    return m_newlyAllocatedVersion != space()-&gt;newlyAllocatedVersion();
+}
+
+inline bool MarkedBlock::Handle::hasAnyNewlyAllocated()
+{
+    return !isNewlyAllocatedStale();
+}
+
+inline Heap* MarkedBlock::heap() const
+{
+    return &amp;vm()-&gt;heap;
+}
+
+inline MarkedSpace* MarkedBlock::space() const
+{
+    return &amp;heap()-&gt;objectSpace();
+}
+
+inline MarkedSpace* MarkedBlock::Handle::space() const
+{
+    return &amp;heap()-&gt;objectSpace();
+}
+
</ins><span class="cx"> inline bool MarkedBlock::marksConveyLivenessDuringMarking(HeapVersion markingVersion)
</span><span class="cx"> {
</span><span class="cx">     // This returns true if any of these is true:
</span><span class="lines">@@ -89,16 +117,229 @@
</span><span class="cx">     return isLive(markingVersion, isMarking, static_cast&lt;const HeapCell*&gt;(p));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline bool MarkedBlock::Handle::isNewlyAllocatedStale() const
</del><ins>+// The following has to be true for specialization to kick in:
+//
+// sweepMode == SweepToFreeList
+// scribbleMode == DontScribble
+// newlyAllocatedMode == DoesNotHaveNewlyAllocated
+// destructionMode != BlockHasDestrictorsAndCollectorIsRunning
+//
+// emptyMode = IsEmpty
+//     destructionMode = DoesNotNeedDestruction
+//         marksMode = MarksNotStale (1)
+//         marksMode = MarksStale (2)
+// emptyMode = NotEmpty
+//     destructionMode = DoesNotNeedDestruction
+//         marksMode = MarksNotStale (3)
+//         marksMode = MarksStale (4)
+//     destructionMode = NeedsDestruction
+//         marksMode = MarksNotStale (5)
+//         marksMode = MarksStale (6)
+//
+// Only the DoesNotNeedDestruction one should be specialized by MarkedBlock.
+
+template&lt;bool specialize, MarkedBlock::Handle::EmptyMode specializedEmptyMode, MarkedBlock::Handle::SweepMode specializedSweepMode, MarkedBlock::Handle::SweepDestructionMode specializedDestructionMode, MarkedBlock::Handle::ScribbleMode specializedScribbleMode, MarkedBlock::Handle::NewlyAllocatedMode specializedNewlyAllocatedMode, MarkedBlock::Handle::MarksMode specializedMarksMode, typename DestroyFunc&gt;
+FreeList MarkedBlock::Handle::specializedSweep(MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepMode sweepMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode, MarkedBlock::Handle::NewlyAllocatedMode newlyAllocatedMode, MarkedBlock::Handle::MarksMode marksMode, const DestroyFunc&amp; destroyFunc)
</ins><span class="cx"> {
</span><del>-    return m_newlyAllocatedVersion != space()-&gt;newlyAllocatedVersion();
</del><ins>+    if (specialize) {
+        emptyMode = specializedEmptyMode;
+        sweepMode = specializedSweepMode;
+        destructionMode = specializedDestructionMode;
+        scribbleMode = specializedScribbleMode;
+        newlyAllocatedMode = specializedNewlyAllocatedMode;
+        marksMode = specializedMarksMode;
+    }
+    
+    RELEASE_ASSERT(!(destructionMode == BlockHasNoDestructors &amp;&amp; sweepMode == SweepOnly));
+    
+    SuperSamplerScope superSamplerScope(false);
+
+    MarkedBlock&amp; block = this-&gt;block();
+    
+    if (false)
+        dataLog(RawPointer(this), &quot;/&quot;, RawPointer(&amp;block), &quot;: MarkedBlock::Handle::specializedSweep!\n&quot;);
+    
+    if (Options::useBumpAllocator()
+        &amp;&amp; emptyMode == IsEmpty
+        &amp;&amp; newlyAllocatedMode == DoesNotHaveNewlyAllocated) {
+        
+        // This is an incredibly powerful assertion that checks the sanity of our block bits.
+        if (marksMode == MarksNotStale &amp;&amp; !block.m_marks.isEmpty()) {
+            WTF::dataFile().atomically(
+                [&amp;] (PrintStream&amp; out) {
+                    out.print(&quot;Block &quot;, RawPointer(&amp;block), &quot;: marks not empty!\n&quot;);
+                    out.print(&quot;Block lock is held: &quot;, block.m_lock.isHeld(), &quot;\n&quot;);
+                    out.print(&quot;Marking version of block: &quot;, block.m_markingVersion, &quot;\n&quot;);
+                    out.print(&quot;Marking version of heap: &quot;, space()-&gt;markingVersion(), &quot;\n&quot;);
+                    UNREACHABLE_FOR_PLATFORM();
+                });
+        }
+        
+        char* startOfLastCell = static_cast&lt;char*&gt;(cellAlign(block.atoms() + m_endAtom - 1));
+        char* payloadEnd = startOfLastCell + cellSize();
+        RELEASE_ASSERT(payloadEnd - MarkedBlock::blockSize &lt;= bitwise_cast&lt;char*&gt;(&amp;block));
+        char* payloadBegin = bitwise_cast&lt;char*&gt;(block.atoms() + firstAtom());
+        if (scribbleMode == Scribble)
+            scribble(payloadBegin, payloadEnd - payloadBegin);
+        if (sweepMode == SweepToFreeList)
+            setIsFreeListed();
+        else
+            m_allocator-&gt;setIsEmpty(NoLockingNecessary, this, true);
+        if (space()-&gt;isMarking())
+            block.m_lock.unlock();
+        FreeList result = FreeList::bump(payloadEnd, payloadEnd - payloadBegin);
+        if (false)
+            dataLog(&quot;Quickly swept block &quot;, RawPointer(this), &quot; with cell size &quot;, cellSize(), &quot; and attributes &quot;, m_attributes, &quot;: &quot;, result, &quot;\n&quot;);
+        return result;
+    }
+
+    // This produces a free list that is ordered in reverse through the block.
+    // This is fine, since the allocation code makes no assumptions about the
+    // order of the free list.
+    FreeCell* head = 0;
+    size_t count = 0;
+    bool isEmpty = true;
+    Vector&lt;size_t&gt; deadCells;
+    VM&amp; vm = *this-&gt;vm();
+    auto handleDeadCell = [&amp;] (size_t i) {
+        HeapCell* cell = reinterpret_cast_ptr&lt;HeapCell*&gt;(&amp;block.atoms()[i]);
+
+        if (destructionMode != BlockHasNoDestructors &amp;&amp; emptyMode == NotEmpty) {
+            JSCell* jsCell = static_cast&lt;JSCell*&gt;(cell);
+            if (!jsCell-&gt;isZapped()) {
+                destroyFunc(vm, jsCell);
+                jsCell-&gt;zap();
+            }
+        }
+
+        if (sweepMode == SweepToFreeList) {
+            FreeCell* freeCell = reinterpret_cast_ptr&lt;FreeCell*&gt;(cell);
+            if (scribbleMode == Scribble)
+                scribble(freeCell, cellSize());
+            freeCell-&gt;next = head;
+            head = freeCell;
+            ++count;
+        }
+    };
+    for (size_t i = firstAtom(); i &lt; m_endAtom; i += m_atomsPerCell) {
+        if (emptyMode == NotEmpty
+            &amp;&amp; ((marksMode == MarksNotStale &amp;&amp; block.m_marks.get(i))
+                || (newlyAllocatedMode == HasNewlyAllocated &amp;&amp; m_newlyAllocated.get(i)))) {
+            isEmpty = false;
+            continue;
+        }
+        
+        if (destructionMode == BlockHasDestructorsAndCollectorIsRunning)
+            deadCells.append(i);
+        else
+            handleDeadCell(i);
+    }
+    
+    // We only want to discard the newlyAllocated bits if we're creating a FreeList,
+    // otherwise we would lose information on what's currently alive.
+    if (sweepMode == SweepToFreeList &amp;&amp; newlyAllocatedMode == HasNewlyAllocated)
+        m_newlyAllocatedVersion = MarkedSpace::nullVersion;
+    
+    if (space()-&gt;isMarking())
+        block.m_lock.unlock();
+    
+    if (destructionMode == BlockHasDestructorsAndCollectorIsRunning) {
+        for (size_t i : deadCells)
+            handleDeadCell(i);
+    }
+
+    FreeList result = FreeList::list(head, count * cellSize());
+    if (sweepMode == SweepToFreeList)
+        setIsFreeListed();
+    else if (isEmpty)
+        m_allocator-&gt;setIsEmpty(NoLockingNecessary, this, true);
+    if (false)
+        dataLog(&quot;Slowly swept block &quot;, RawPointer(&amp;block), &quot; with cell size &quot;, cellSize(), &quot; and attributes &quot;, m_attributes, &quot;: &quot;, result, &quot;\n&quot;);
+    return result;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline bool MarkedBlock::Handle::hasAnyNewlyAllocated()
</del><ins>+template&lt;typename DestroyFunc&gt;
+FreeList MarkedBlock::Handle::finishSweepKnowingSubspace(SweepMode sweepMode, const DestroyFunc&amp; destroyFunc)
</ins><span class="cx"> {
</span><del>-    return !isNewlyAllocatedStale();
</del><ins>+    SweepDestructionMode destructionMode = this-&gt;sweepDestructionMode();
+    EmptyMode emptyMode = this-&gt;emptyMode();
+    ScribbleMode scribbleMode = this-&gt;scribbleMode();
+    NewlyAllocatedMode newlyAllocatedMode = this-&gt;newlyAllocatedMode();
+    MarksMode marksMode = this-&gt;marksMode();
+
+    FreeList result;
+    auto trySpecialized = [&amp;] () -&gt; bool {
+        if (sweepMode != SweepToFreeList)
+            return false;
+        if (scribbleMode != DontScribble)
+            return false;
+        if (newlyAllocatedMode != DoesNotHaveNewlyAllocated)
+            return false;
+        if (destructionMode != BlockHasDestructors)
+            return false;
+        if (emptyMode == IsEmpty)
+            return false;
+        
+        switch (marksMode) {
+        case MarksNotStale:
+            result = specializedSweep&lt;true, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale&gt;(IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, destroyFunc);
+            return true;
+        case MarksStale:
+            result = specializedSweep&lt;true, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale&gt;(IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, destroyFunc);
+            return true;
+        }
+        
+        return false;
+    };
+    
+    if (trySpecialized())
+        return result;
+    
+    // The template arguments don't matter because the first one is false.
+    return specializedSweep&lt;false, IsEmpty, SweepOnly, BlockHasNoDestructors, DontScribble, HasNewlyAllocated, MarksStale&gt;(emptyMode, sweepMode, destructionMode, scribbleMode, newlyAllocatedMode, marksMode, destroyFunc);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline MarkedBlock::Handle::SweepDestructionMode MarkedBlock::Handle::sweepDestructionMode()
+{
+    if (m_attributes.destruction == NeedsDestruction) {
+        if (space()-&gt;isMarking())
+            return BlockHasDestructorsAndCollectorIsRunning;
+        return BlockHasDestructors;
+    }
+    return BlockHasNoDestructors;
+}
+
+inline MarkedBlock::Handle::EmptyMode MarkedBlock::Handle::emptyMode()
+{
+    // It's not obvious, but this is the only way to know if the block is empty. It's the only
+    // bit that captures these caveats:
+    // - It's true when the block is freshly allocated.
+    // - It's true if the block had been swept in the past, all destructors were called, and that
+    //   sweep proved that the block is empty.
+    // - It's false if there are any destructors that need to be called, even if the block has no
+    //   live objects.
+    return m_allocator-&gt;isEmpty(NoLockingNecessary, this) ? IsEmpty : NotEmpty;
+}
+
+inline MarkedBlock::Handle::ScribbleMode MarkedBlock::Handle::scribbleMode()
+{
+    return scribbleFreeCells() ? Scribble : DontScribble;
+}
+
+inline MarkedBlock::Handle::NewlyAllocatedMode MarkedBlock::Handle::newlyAllocatedMode()
+{
+    return hasAnyNewlyAllocated() ? HasNewlyAllocated : DoesNotHaveNewlyAllocated;
+}
+
+inline MarkedBlock::Handle::MarksMode MarkedBlock::Handle::marksMode()
+{
+    HeapVersion markingVersion = space()-&gt;markingVersion();
+    bool marksAreUseful = !block().areMarksStale(markingVersion);
+    if (space()-&gt;isMarking())
+        marksAreUseful |= block().marksConveyLivenessDuringMarking(markingVersion);
+    return marksAreUseful ? MarksNotStale : MarksStale;
+}
+
</ins><span class="cx"> template &lt;typename Functor&gt;
</span><span class="cx"> inline IterationStatus MarkedBlock::Handle::forEachLiveCell(const Functor&amp; functor)
</span><span class="cx"> {
</span><span class="lines">@@ -129,20 +370,25 @@
</span><span class="cx">     return IterationStatus::Continue;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline Heap* MarkedBlock::heap() const
</del><ins>+template &lt;typename Functor&gt;
+inline IterationStatus MarkedBlock::Handle::forEachMarkedCell(const Functor&amp; functor)
</ins><span class="cx"> {
</span><del>-    return &amp;vm()-&gt;heap;
-}
</del><ins>+    HeapCell::Kind kind = m_attributes.cellKind;
+    MarkedBlock&amp; block = this-&gt;block();
+    bool areMarksStale = block.areMarksStale();
+    WTF::loadLoadFence();
+    if (areMarksStale)
+        return IterationStatus::Continue;
+    for (size_t i = firstAtom(); i &lt; m_endAtom; i += m_atomsPerCell) {
+        HeapCell* cell = reinterpret_cast_ptr&lt;HeapCell*&gt;(&amp;m_block-&gt;atoms()[i]);
+        if (!block.isMarkedRaw(cell))
+            continue;
</ins><span class="cx"> 
</span><del>-inline MarkedSpace* MarkedBlock::space() const
-{
-    return &amp;heap()-&gt;objectSpace();
</del><ins>+        if (functor(cell, kind) == IterationStatus::Done)
+            return IterationStatus::Done;
+    }
+    return IterationStatus::Continue;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline MarkedSpace* MarkedBlock::Handle::space() const
-{
-    return &amp;heap()-&gt;objectSpace();
-}
-
</del><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkedSpacecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedSpace.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedSpace.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedSpace.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2016 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2007 Eric Seidel &lt;eric@webkit.org&gt;
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -25,6 +25,7 @@
</span><span class="cx"> #include &quot;IncrementalSweeper.h&quot;
</span><span class="cx"> #include &quot;JSObject.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;MarkedAllocatorInlines.h&quot;
</ins><span class="cx"> #include &quot;MarkedBlockInlines.h&quot;
</span><span class="cx"> #include &lt;wtf/ListDump.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -172,16 +173,18 @@
</span><span class="cx"> 
</span><span class="cx"> void MarkedSpace::initializeSizeClassForStepSize()
</span><span class="cx"> {
</span><del>-    // We call this multiple times and we may call it simultaneously from multiple threads. That's
-    // OK, since it always stores the same values into the table.
-    
-    buildSizeClassTable(
-        s_sizeClassForSizeStep,
-        [&amp;] (size_t sizeClass) -&gt; size_t {
-            return sizeClass;
-        },
-        [&amp;] (size_t sizeClass) -&gt; size_t {
-            return sizeClass;
</del><ins>+    static std::once_flag flag;
+    std::call_once(
+        flag,
+        [] {
+            buildSizeClassTable(
+                s_sizeClassForSizeStep,
+                [&amp;] (size_t sizeClass) -&gt; size_t {
+                    return sizeClass;
+                },
+                [&amp;] (size_t sizeClass) -&gt; size_t {
+                    return sizeClass;
+                });
</ins><span class="cx">         });
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -191,35 +194,6 @@
</span><span class="cx">     , m_isIterating(false)
</span><span class="cx"> {
</span><span class="cx">     initializeSizeClassForStepSize();
</span><del>-    
-    forEachSubspace(
-        [&amp;] (Subspace&amp; subspace, AllocatorAttributes attributes) -&gt; IterationStatus {
-            subspace.attributes = attributes;
-            
-            buildSizeClassTable(
-                subspace.allocatorForSizeStep,
-                [&amp;] (size_t sizeClass) -&gt; MarkedAllocator* {
-                    return subspace.bagOfAllocators.add(heap, this, sizeClass, attributes);
-                },
-                [&amp;] (size_t) -&gt; MarkedAllocator* {
-                    return nullptr;
-                });
-            
-            return IterationStatus::Continue;
-        });
-    
-    MarkedAllocator* previous = nullptr;
-    forEachSubspace(
-        [&amp;] (Subspace&amp; subspace, AllocatorAttributes) -&gt; IterationStatus {
-            for (MarkedAllocator* allocator : subspace.bagOfAllocators) {
-                allocator-&gt;setNextAllocator(previous);
-                previous = allocator;
-            }
-            
-            return IterationStatus::Continue;
-        });
-    m_firstAllocator = previous;
-    m_allocatorForEmptyAllocation = previous;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> MarkedSpace::~MarkedSpace()
</span><span class="lines">@@ -235,7 +209,6 @@
</span><span class="cx"> 
</span><span class="cx"> void MarkedSpace::lastChanceToFinalize()
</span><span class="cx"> {
</span><del>-    stopAllocating();
</del><span class="cx">     forEachAllocator(
</span><span class="cx">         [&amp;] (MarkedAllocator&amp; allocator) -&gt; IterationStatus {
</span><span class="cx">             allocator.lastChanceToFinalize();
</span><span class="lines">@@ -245,72 +218,6 @@
</span><span class="cx">         allocation-&gt;lastChanceToFinalize();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void* MarkedSpace::allocate(Subspace&amp; subspace, size_t bytes)
-{
-    if (false)
-        dataLog(&quot;Allocating &quot;, bytes, &quot; bytes in &quot;, subspace.attributes, &quot;.\n&quot;);
-    if (MarkedAllocator* allocator = allocatorFor(subspace, bytes)) {
-        void* result = allocator-&gt;allocate();
-        return result;
-    }
-    return allocateLarge(subspace, nullptr, bytes);
-}
-
-void* MarkedSpace::allocate(Subspace&amp; subspace, GCDeferralContext* deferralContext, size_t bytes)
-{
-    if (false)
-        dataLog(&quot;Allocating &quot;, bytes, &quot; deferred bytes in &quot;, subspace.attributes, &quot;.\n&quot;);
-    if (MarkedAllocator* allocator = allocatorFor(subspace, bytes)) {
-        void* result = allocator-&gt;allocate(deferralContext);
-        return result;
-    }
-    return allocateLarge(subspace, deferralContext, bytes);
-}
-
-void* MarkedSpace::tryAllocate(Subspace&amp; subspace, size_t bytes)
-{
-    if (false)
-        dataLog(&quot;Try-allocating &quot;, bytes, &quot; bytes in &quot;, subspace.attributes, &quot;.\n&quot;);
-    if (MarkedAllocator* allocator = allocatorFor(subspace, bytes)) {
-        void* result = allocator-&gt;tryAllocate();
-        return result;
-    }
-    return tryAllocateLarge(subspace, nullptr, bytes);
-}
-
-void* MarkedSpace::tryAllocate(Subspace&amp; subspace, GCDeferralContext* deferralContext, size_t bytes)
-{
-    if (false)
-        dataLog(&quot;Try-allocating &quot;, bytes, &quot; deferred bytes in &quot;, subspace.attributes, &quot;.\n&quot;);
-    if (MarkedAllocator* allocator = allocatorFor(subspace, bytes)) {
-        void* result = allocator-&gt;tryAllocate(deferralContext);
-        return result;
-    }
-    return tryAllocateLarge(subspace, deferralContext, bytes);
-}
-
-void* MarkedSpace::allocateLarge(Subspace&amp; subspace, GCDeferralContext* deferralContext, size_t size)
-{
-    void* result = tryAllocateLarge(subspace, deferralContext, size);
-    RELEASE_ASSERT(result);
-    return result;
-}
-
-void* MarkedSpace::tryAllocateLarge(Subspace&amp; subspace, GCDeferralContext* deferralContext, size_t size)
-{
-    m_heap-&gt;collectIfNecessaryOrDefer(deferralContext);
-    
-    size = WTF::roundUpToMultipleOf&lt;sizeStep&gt;(size);
-    LargeAllocation* allocation = LargeAllocation::tryCreate(*m_heap, size, subspace.attributes);
-    if (!allocation)
-        return nullptr;
-    
-    m_largeAllocations.append(allocation);
-    m_heap-&gt;didAllocate(size);
-    m_capacity += size;
-    return allocation-&gt;cell();
-}
-
</del><span class="cx"> void MarkedSpace::sweep()
</span><span class="cx"> {
</span><span class="cx">     m_heap-&gt;sweeper()-&gt;willFinishSweeping();
</span><span class="lines">@@ -649,4 +556,24 @@
</span><span class="cx">         });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+MarkedAllocator* MarkedSpace::addMarkedAllocator(
+    const AbstractLocker&amp;, Subspace* subspace, size_t sizeClass)
+{
+    MarkedAllocator* allocator = m_bagOfAllocators.add(heap(), subspace, sizeClass);
+    allocator-&gt;setNextAllocator(nullptr);
+    
+    WTF::storeStoreFence();
+
+    if (!m_firstAllocator) {
+        m_firstAllocator = allocator;
+        m_lastAllocator = allocator;
+        m_allocatorForEmptyAllocation = allocator;
+    } else {
+        m_lastAllocator-&gt;setNextAllocator(allocator);
+        m_lastAllocator = allocator;
+    }
+    
+    return allocator;
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkedSpaceh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedSpace.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedSpace.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkedSpace.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2016 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> class Heap;
</span><span class="cx"> class HeapIterationScope;
</span><span class="cx"> class LLIntOffsetsExtractor;
</span><ins>+class Subspace;
</ins><span class="cx"> class WeakSet;
</span><span class="cx"> 
</span><span class="cx"> typedef uint32_t HeapVersion;
</span><span class="lines">@@ -86,47 +87,15 @@
</span><span class="cx">         return (index + 1) * sizeStep;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    // Each Subspace corresponds to all of the blocks for all of the sizes for some &quot;class&quot; of
-    // objects. There are three classes: non-destructor JSCells, destructor JSCells, and auxiliary.
-    // MarkedSpace is set up to make it relatively easy to add new Subspaces.
-    struct Subspace {
-        std::array&lt;MarkedAllocator*, numSizeClasses&gt; allocatorForSizeStep;
-        
-        // Each MarkedAllocator is a size class.
-        Bag&lt;MarkedAllocator&gt; bagOfAllocators;
-        
-        AllocatorAttributes attributes;
-    };
-    
</del><span class="cx">     MarkedSpace(Heap*);
</span><span class="cx">     ~MarkedSpace();
</span><del>-    void lastChanceToFinalize();
</del><ins>+    
+    Heap* heap() const { return m_heap; }
+    
+    void lastChanceToFinalize(); // You must call stopAllocating before you call this.
</ins><span class="cx"> 
</span><span class="cx">     static size_t optimalSizeFor(size_t);
</span><span class="cx">     
</span><del>-    static MarkedAllocator* allocatorFor(Subspace&amp;, size_t);
-
-    MarkedAllocator* allocatorFor(size_t);
-    MarkedAllocator* destructorAllocatorFor(size_t);
-    MarkedAllocator* auxiliaryAllocatorFor(size_t);
-
-    JS_EXPORT_PRIVATE void* allocate(Subspace&amp;, size_t);
-    JS_EXPORT_PRIVATE void* allocate(Subspace&amp;, GCDeferralContext*, size_t);
-    JS_EXPORT_PRIVATE void* tryAllocate(Subspace&amp;, size_t);
-    JS_EXPORT_PRIVATE void* tryAllocate(Subspace&amp;, GCDeferralContext*, size_t);
-    
-    void* allocateWithDestructor(size_t);
-    void* allocateWithoutDestructor(size_t);
-    void* allocateWithDestructor(GCDeferralContext*, size_t);
-    void* allocateWithoutDestructor(GCDeferralContext*, size_t);
-    void* allocateAuxiliary(size_t);
-    void* tryAllocateAuxiliary(size_t);
-    void* tryAllocateAuxiliary(GCDeferralContext*, size_t);
-    
-    Subspace&amp; subspaceForObjectsWithDestructor() { return m_destructorSpace; }
-    Subspace&amp; subspaceForObjectsWithoutDestructor() { return m_normalSpace; }
-    Subspace&amp; subspaceForAuxiliaryData() { return m_auxiliarySpace; }
-    
</del><span class="cx">     void prepareForAllocation();
</span><span class="cx"> 
</span><span class="cx">     void visitWeakSets(SlotVisitor&amp;);
</span><span class="lines">@@ -190,20 +159,24 @@
</span><span class="cx">     
</span><span class="cx">     MarkedBlock::Handle* findEmptyBlockToSteal();
</span><span class="cx">     
</span><ins>+    Lock&amp; allocatorLock() { return m_allocatorLock; }
+    MarkedAllocator* addMarkedAllocator(const AbstractLocker&amp;, Subspace*, size_t cellSize);
+    
</ins><span class="cx">     // When this is true it means that we have flipped but the mark bits haven't converged yet.
</span><span class="cx">     bool isMarking() const { return m_isMarking; }
</span><span class="cx">     
</span><span class="cx">     void dumpBits(PrintStream&amp; = WTF::dataFile());
</span><span class="cx">     
</span><ins>+    JS_EXPORT_PRIVATE static std::array&lt;size_t, numSizeClasses&gt; s_sizeClassForSizeStep;
+    
</ins><span class="cx"> private:
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx">     friend class JIT;
</span><span class="cx">     friend class WeakSet;
</span><ins>+    friend class Subspace;
</ins><span class="cx">     
</span><del>-    JS_EXPORT_PRIVATE static std::array&lt;size_t, numSizeClasses&gt; s_sizeClassForSizeStep;
-    
-    void* allocateLarge(Subspace&amp;, GCDeferralContext*, size_t);
-    void* tryAllocateLarge(Subspace&amp;, GCDeferralContext*, size_t);
</del><ins>+    void* allocateSlow(Subspace&amp;, GCDeferralContext*, size_t);
+    void* tryAllocateSlow(Subspace&amp;, GCDeferralContext*, size_t);
</ins><span class="cx"> 
</span><span class="cx">     static void initializeSizeClassForStepSize();
</span><span class="cx">     
</span><span class="lines">@@ -210,14 +183,19 @@
</span><span class="cx">     void initializeSubspace(Subspace&amp;);
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename Functor&gt; inline void forEachAllocator(const Functor&amp;);
</span><del>-    template&lt;typename Functor&gt; inline void forEachSubspace(const Functor&amp;);
</del><span class="cx">     
</span><span class="cx">     void addActiveWeakSet(WeakSet*);
</span><span class="cx"> 
</span><del>-    Subspace m_destructorSpace;
-    Subspace m_normalSpace;
-    Subspace m_auxiliarySpace;
</del><ins>+    Vector&lt;Subspace*&gt; m_subspaces;
</ins><span class="cx"> 
</span><ins>+    Vector&lt;LargeAllocation*&gt; m_largeAllocations;
+    unsigned m_largeAllocationsNurseryOffset { 0 };
+    unsigned m_largeAllocationsOffsetForThisCollection { 0 };
+    unsigned m_largeAllocationsNurseryOffsetForSweep { 0 };
+    LargeAllocation** m_largeAllocationsForThisCollectionBegin { nullptr };
+    LargeAllocation** m_largeAllocationsForThisCollectionEnd { nullptr };
+    unsigned m_largeAllocationsForThisCollectionSize { 0 };
+
</ins><span class="cx">     Heap* m_heap;
</span><span class="cx">     HeapVersion m_markingVersion { initialVersion };
</span><span class="cx">     HeapVersion m_newlyAllocatedVersion { initialVersion };
</span><span class="lines">@@ -226,79 +204,16 @@
</span><span class="cx">     bool m_isMarking { false };
</span><span class="cx">     MarkedBlockSet m_blocks;
</span><span class="cx">     
</span><del>-    Vector&lt;LargeAllocation*&gt; m_largeAllocations;
-    unsigned m_largeAllocationsNurseryOffset { 0 };
-    unsigned m_largeAllocationsOffsetForThisCollection { 0 };
-    unsigned m_largeAllocationsNurseryOffsetForSweep { 0 };
-    LargeAllocation** m_largeAllocationsForThisCollectionBegin { nullptr };
-    LargeAllocation** m_largeAllocationsForThisCollectionEnd { nullptr };
-    unsigned m_largeAllocationsForThisCollectionSize { 0 };
-    
</del><span class="cx">     SentinelLinkedList&lt;WeakSet, BasicRawSentinelNode&lt;WeakSet&gt;&gt; m_activeWeakSets;
</span><span class="cx">     SentinelLinkedList&lt;WeakSet, BasicRawSentinelNode&lt;WeakSet&gt;&gt; m_newActiveWeakSets;
</span><del>-    
</del><ins>+
+    Lock m_allocatorLock;
+    Bag&lt;MarkedAllocator&gt; m_bagOfAllocators;
</ins><span class="cx">     MarkedAllocator* m_firstAllocator { nullptr };
</span><ins>+    MarkedAllocator* m_lastAllocator { nullptr };
</ins><span class="cx">     MarkedAllocator* m_allocatorForEmptyAllocation { nullptr };
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline MarkedAllocator* MarkedSpace::allocatorFor(Subspace&amp; space, size_t bytes)
-{
-    ASSERT(bytes);
-    if (bytes &lt;= largeCutoff)
-        return space.allocatorForSizeStep[sizeClassToIndex(bytes)];
-    return nullptr;
-}
-
-inline MarkedAllocator* MarkedSpace::allocatorFor(size_t bytes)
-{
-    return allocatorFor(m_normalSpace, bytes);
-}
-
-inline MarkedAllocator* MarkedSpace::destructorAllocatorFor(size_t bytes)
-{
-    return allocatorFor(m_destructorSpace, bytes);
-}
-
-inline MarkedAllocator* MarkedSpace::auxiliaryAllocatorFor(size_t bytes)
-{
-    return allocatorFor(m_auxiliarySpace, bytes);
-}
-
-inline void* MarkedSpace::allocateWithoutDestructor(size_t bytes)
-{
-    return allocate(m_normalSpace, bytes);
-}
-
-inline void* MarkedSpace::allocateWithDestructor(size_t bytes)
-{
-    return allocate(m_destructorSpace, bytes);
-}
-
-inline void* MarkedSpace::allocateWithoutDestructor(GCDeferralContext* deferralContext, size_t bytes)
-{
-    return allocate(m_normalSpace, deferralContext, bytes);
-}
-
-inline void* MarkedSpace::allocateWithDestructor(GCDeferralContext* deferralContext, size_t bytes)
-{
-    return allocate(m_destructorSpace, deferralContext, bytes);
-}
-
-inline void* MarkedSpace::allocateAuxiliary(size_t bytes)
-{
-    return allocate(m_auxiliarySpace, bytes);
-}
-
-inline void* MarkedSpace::tryAllocateAuxiliary(size_t bytes)
-{
-    return tryAllocate(m_auxiliarySpace, bytes);
-}
-
-inline void* MarkedSpace::tryAllocateAuxiliary(GCDeferralContext* deferralContext, size_t bytes)
-{
-    return tryAllocate(m_auxiliarySpace, deferralContext, bytes);
-}
-
</del><span class="cx"> template &lt;typename Functor&gt; inline void MarkedSpace::forEachBlock(const Functor&amp; functor)
</span><span class="cx"> {
</span><span class="cx">     forEachAllocator(
</span><span class="lines">@@ -317,26 +232,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename Functor&gt;
-inline void MarkedSpace::forEachSubspace(const Functor&amp; func)
-{
-    AllocatorAttributes attributes;
-    
-    attributes.destruction = NeedsDestruction;
-    attributes.cellKind = HeapCell::JSCell;
-    if (func(m_destructorSpace, attributes) == IterationStatus::Done)
-        return;
-    
-    attributes.destruction = DoesNotNeedDestruction;
-    attributes.cellKind = HeapCell::JSCell;
-    if (func(m_normalSpace, attributes) == IterationStatus::Done)
-        return;
-
-    attributes.destruction = DoesNotNeedDestruction;
-    attributes.cellKind = HeapCell::Auxiliary;
-    func(m_auxiliarySpace, attributes);
-}
-
</del><span class="cx"> ALWAYS_INLINE size_t MarkedSpace::optimalSizeFor(size_t bytes)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(bytes);
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkingConstraintcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraint.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraint.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraint.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> MarkingConstraint::MarkingConstraint(
</span><span class="cx">     CString abbreviatedName, CString name,
</span><span class="cx">     ::Function&lt;void(SlotVisitor&amp;, const VisitingTimeout&amp;)&gt; executeFunction,
</span><del>-    Volatility volatility)
</del><ins>+    ConstraintVolatility volatility)
</ins><span class="cx">     : m_abbreviatedName(abbreviatedName)
</span><span class="cx">     , m_name(WTFMove(name))
</span><span class="cx">     , m_executeFunction(WTFMove(executeFunction))
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx">     CString abbreviatedName, CString name,
</span><span class="cx">     ::Function&lt;void(SlotVisitor&amp;, const VisitingTimeout&amp;)&gt; executeFunction,
</span><span class="cx">     ::Function&lt;double(SlotVisitor&amp;)&gt; quickWorkEstimateFunction,
</span><del>-    Volatility volatility)
</del><ins>+    ConstraintVolatility volatility)
</ins><span class="cx">     : m_abbreviatedName(abbreviatedName)
</span><span class="cx">     , m_name(WTFMove(name))
</span><span class="cx">     , m_executeFunction(WTFMove(executeFunction))
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkingConstrainth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraint.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraint.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraint.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -25,6 +25,7 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include &quot;ConstraintVolatility.h&quot;
</ins><span class="cx"> #include &quot;VisitingTimeout.h&quot;
</span><span class="cx"> #include &lt;wtf/FastMalloc.h&gt;
</span><span class="cx"> #include &lt;wtf/Function.h&gt;
</span><span class="lines">@@ -41,34 +42,18 @@
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(MarkingConstraint);
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><del>-    enum Volatility {
-        // FIXME: We could introduce a new kind of volatility called GreyedByResumption, which
-        // would mean running all of the times that GreyedByExecution runs except as a root in a
-        // full GC.
-        // https://bugs.webkit.org/show_bug.cgi?id=166830
-        
-        // The constraint needs to be reevaluated anytime the mutator runs: so at GC start and
-        // whenever the GC resuspends after a resumption. This is almost always something that
-        // you'd call a &quot;root&quot; in a traditional GC.
-        GreyedByExecution,
-        
-        // The constraint needs to be reevaluated any time any object is marked and anytime the
-        // mutator resumes.
-        GreyedByMarking
-    };
-    
-    MarkingConstraint(
</del><ins>+    JS_EXPORT_PRIVATE MarkingConstraint(
</ins><span class="cx">         CString abbreviatedName, CString name,
</span><span class="cx">         ::Function&lt;void(SlotVisitor&amp;, const VisitingTimeout&amp;)&gt;,
</span><del>-        Volatility);
</del><ins>+        ConstraintVolatility);
</ins><span class="cx">     
</span><del>-    MarkingConstraint(
</del><ins>+    JS_EXPORT_PRIVATE MarkingConstraint(
</ins><span class="cx">         CString abbreviatedName, CString name,
</span><span class="cx">         ::Function&lt;void(SlotVisitor&amp;, const VisitingTimeout&amp;)&gt;,
</span><span class="cx">         ::Function&lt;double(SlotVisitor&amp;)&gt;,
</span><del>-        Volatility);
</del><ins>+        ConstraintVolatility);
</ins><span class="cx">     
</span><del>-    ~MarkingConstraint();
</del><ins>+    JS_EXPORT_PRIVATE ~MarkingConstraint();
</ins><span class="cx">     
</span><span class="cx">     unsigned index() const { return m_index; }
</span><span class="cx">     
</span><span class="lines">@@ -93,7 +78,7 @@
</span><span class="cx">         return lastVisitCount() + quickWorkEstimate(visitor);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Volatility volatility() const { return m_volatility; }
</del><ins>+    ConstraintVolatility volatility() const { return m_volatility; }
</ins><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     friend class MarkingConstraintSet; // So it can set m_index.
</span><span class="lines">@@ -103,7 +88,7 @@
</span><span class="cx">     CString m_name;
</span><span class="cx">     ::Function&lt;void(SlotVisitor&amp;, const VisitingTimeout&amp; timeout)&gt; m_executeFunction;
</span><span class="cx">     ::Function&lt;double(SlotVisitor&amp;)&gt; m_quickWorkEstimateFunction;
</span><del>-    Volatility m_volatility;
</del><ins>+    ConstraintVolatility m_volatility;
</ins><span class="cx">     size_t m_lastVisitCount { 0 };
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkingConstraintSetcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraintSet.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraintSet.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraintSet.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -93,17 +93,19 @@
</span><span class="cx">     for (auto&amp; constraint : m_set) {
</span><span class="cx">         constraint-&gt;resetStats();
</span><span class="cx">         switch (constraint-&gt;volatility()) {
</span><del>-        case MarkingConstraint::GreyedByExecution:
</del><ins>+        case ConstraintVolatility::GreyedByExecution:
</ins><span class="cx">             m_unexecutedRoots.set(constraint-&gt;index());
</span><span class="cx">             break;
</span><del>-        case MarkingConstraint::GreyedByMarking:
</del><ins>+        case ConstraintVolatility::GreyedByMarking:
</ins><span class="cx">             m_unexecutedOutgrowths.set(constraint-&gt;index());
</span><span class="cx">             break;
</span><ins>+        case ConstraintVolatility::SeldomGreyed:
+            break;
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MarkingConstraintSet::add(CString abbreviatedName, CString name, Function&lt;void(SlotVisitor&amp;, const VisitingTimeout&amp;)&gt; function, MarkingConstraint::Volatility volatility)
</del><ins>+void MarkingConstraintSet::add(CString abbreviatedName, CString name, Function&lt;void(SlotVisitor&amp;, const VisitingTimeout&amp;)&gt; function, ConstraintVolatility volatility)
</ins><span class="cx"> {
</span><span class="cx">     add(std::make_unique&lt;MarkingConstraint&gt;(WTFMove(abbreviatedName), WTFMove(name), WTFMove(function), volatility));
</span><span class="cx"> }
</span><span class="lines">@@ -112,7 +114,7 @@
</span><span class="cx">     CString abbreviatedName, CString name,
</span><span class="cx">     Function&lt;void(SlotVisitor&amp;, const VisitingTimeout&amp;)&gt; executeFunction,
</span><span class="cx">     Function&lt;double(SlotVisitor&amp;)&gt; quickWorkEstimateFunction,
</span><del>-    MarkingConstraint::Volatility volatility)
</del><ins>+    ConstraintVolatility volatility)
</ins><span class="cx"> {
</span><span class="cx">     add(std::make_unique&lt;MarkingConstraint&gt;(WTFMove(abbreviatedName), WTFMove(name), WTFMove(executeFunction), WTFMove(quickWorkEstimateFunction), volatility));
</span><span class="cx"> }
</span><span class="lines">@@ -122,7 +124,7 @@
</span><span class="cx"> {
</span><span class="cx">     constraint-&gt;m_index = m_set.size();
</span><span class="cx">     m_ordered.append(constraint.get());
</span><del>-    if (constraint-&gt;volatility() == MarkingConstraint::GreyedByMarking)
</del><ins>+    if (constraint-&gt;volatility() == ConstraintVolatility::GreyedByMarking)
</ins><span class="cx">         m_outgrowths.append(constraint.get());
</span><span class="cx">     m_set.append(WTFMove(constraint));
</span><span class="cx"> }
</span><span class="lines">@@ -194,14 +196,29 @@
</span><span class="cx">         m_ordered.begin(), m_ordered.end(),
</span><span class="cx">         [&amp;] (MarkingConstraint* a, MarkingConstraint* b) -&gt; bool {
</span><span class="cx">             // Remember: return true if a should come before b.
</span><del>-            if (a-&gt;volatility() != b-&gt;volatility()) {
</del><ins>+            
+            auto volatilityScore = [] (MarkingConstraint* constraint) -&gt; unsigned {
+                return constraint-&gt;volatility() == ConstraintVolatility::GreyedByMarking ? 1 : 0;
+            };
+            
+            unsigned aVolatilityScore = volatilityScore(a);
+            unsigned bVolatilityScore = volatilityScore(b);
+            
+            if (aVolatilityScore != bVolatilityScore) {
</ins><span class="cx">                 if (isWavefrontAdvancing)
</span><del>-                    return a-&gt;volatility() &gt; b-&gt;volatility(); // GreyedByMarking should come before GreyedByExecution.
</del><ins>+                    return aVolatilityScore &gt; bVolatilityScore;
</ins><span class="cx">                 else
</span><del>-                    return a-&gt;volatility() &lt; b-&gt;volatility(); // GreyedByExecution should come before GreyedByMarking.
</del><ins>+                    return aVolatilityScore &lt; bVolatilityScore;
</ins><span class="cx">             }
</span><span class="cx">             
</span><del>-            return a-&gt;workEstimate(visitor) &gt; b-&gt;workEstimate(visitor);
</del><ins>+            double aWorkEstimate = a-&gt;workEstimate(visitor);
+            double bWorkEstimate = b-&gt;workEstimate(visitor);
+            
+            if (aWorkEstimate != bWorkEstimate)
+                return aWorkEstimate &gt; bWorkEstimate;
+            
+            // This causes us to use SeldomGreyed vs GreyedByExecution as a final tie-breaker.
+            return a-&gt;volatility() &gt; b-&gt;volatility();
</ins><span class="cx">         });
</span><span class="cx">     
</span><span class="cx">     for (MarkingConstraint* constraint : m_ordered) {
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapMarkingConstraintSeth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraintSet.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraintSet.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/MarkingConstraintSet.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx">         CString abbreviatedName,
</span><span class="cx">         CString name,
</span><span class="cx">         ::Function&lt;void(SlotVisitor&amp;, const VisitingTimeout&amp;)&gt;,
</span><del>-        MarkingConstraint::Volatility);
</del><ins>+        ConstraintVolatility);
</ins><span class="cx">     
</span><span class="cx">     void add(
</span><span class="cx">         CString abbreviatedName,
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx">         CString name,
</span><span class="cx">         ::Function&lt;void(SlotVisitor&amp;, const VisitingTimeout&amp;)&gt;,
</span><span class="cx">         ::Function&lt;double(SlotVisitor&amp;)&gt;,
</span><del>-        MarkingConstraint::Volatility);
</del><ins>+        ConstraintVolatility);
</ins><span class="cx">     
</span><span class="cx">     void add(std::unique_ptr&lt;MarkingConstraint&gt;);
</span><span class="cx">     
</span><span class="lines">@@ -62,8 +62,8 @@
</span><span class="cx">     // that you'll do some draining after this and then use executeConvergence().
</span><span class="cx">     bool executeBootstrap(SlotVisitor&amp;, MonotonicTime timeout = MonotonicTime::infinity());
</span><span class="cx">     
</span><del>-    // Returns true if all constraints were executed. This assumes that you've alraedy
-    // visited roots and drained from there.
</del><ins>+    // Returns true if this executed all constraints and none of them produced new work. This
+    // assumes that you've alraedy visited roots and drained from there.
</ins><span class="cx">     bool executeConvergence(
</span><span class="cx">         SlotVisitor&amp;,
</span><span class="cx">         MonotonicTime timeout = MonotonicTime::infinity());
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapSlotVisitorcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitor.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitor.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitor.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -346,12 +346,6 @@
</span><span class="cx">     SlotVisitor&amp; m_visitor;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-void SlotVisitor::visitAsConstraint(const JSCell* cell)
-{
-    m_isVisitingMutatorStack = true;
-    visitChildren(cell);
-}
-
</del><span class="cx"> ALWAYS_INLINE void SlotVisitor::visitChildren(const JSCell* cell)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(Heap::isMarkedConcurrently(cell));
</span><span class="lines">@@ -360,8 +354,8 @@
</span><span class="cx">     
</span><span class="cx">     if (false) {
</span><span class="cx">         dataLog(&quot;Visiting &quot;, RawPointer(cell));
</span><del>-        if (m_isVisitingMutatorStack)
-            dataLog(&quot; (mutator)&quot;);
</del><ins>+        if (!m_isFirstVisit)
+            dataLog(&quot; (subsequent)&quot;);
</ins><span class="cx">         dataLog(&quot;\n&quot;);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -395,11 +389,17 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     if (UNLIKELY(m_heapSnapshotBuilder)) {
</span><del>-        if (!m_isVisitingMutatorStack)
</del><ins>+        if (m_isFirstVisit)
</ins><span class="cx">             m_heapSnapshotBuilder-&gt;appendNode(const_cast&lt;JSCell*&gt;(cell));
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SlotVisitor::visitAsConstraint(const JSCell* cell)
+{
+    m_isFirstVisit = false;
+    visitChildren(cell);
+}
+
</ins><span class="cx"> void SlotVisitor::donateKnownParallel(MarkStackArray&amp; from, MarkStackArray&amp; to)
</span><span class="cx"> {
</span><span class="cx">     // NOTE: Because we re-try often, we can afford to be conservative, and
</span><span class="lines">@@ -469,7 +469,7 @@
</span><span class="cx">         updateMutatorIsStopped(locker);
</span><span class="cx">         if (!m_collectorStack.isEmpty()) {
</span><span class="cx">             m_collectorStack.refill();
</span><del>-            m_isVisitingMutatorStack = false;
</del><ins>+            m_isFirstVisit = true;
</ins><span class="cx">             for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance(); m_collectorStack.canRemoveLast() &amp;&amp; countdown--;)
</span><span class="cx">                 visitChildren(m_collectorStack.removeLast());
</span><span class="cx">         } else if (!m_mutatorStack.isEmpty()) {
</span><span class="lines">@@ -477,7 +477,7 @@
</span><span class="cx">             // We know for sure that we are visiting objects because of the barrier, not because of
</span><span class="cx">             // marking. Marking will visit an object exactly once. The barrier will visit it
</span><span class="cx">             // possibly many times, and always after it was already marked.
</span><del>-            m_isVisitingMutatorStack = true;
</del><ins>+            m_isFirstVisit = false;
</ins><span class="cx">             for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance(); m_mutatorStack.canRemoveLast() &amp;&amp; countdown--;)
</span><span class="cx">                 visitChildren(m_mutatorStack.removeLast());
</span><span class="cx">         } else
</span><span class="lines">@@ -486,7 +486,7 @@
</span><span class="cx">         donateKnownParallel();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    mergeOpaqueRootsIfNecessary();
</del><ins>+    mergeIfNecessary();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool SlotVisitor::didReachTermination()
</span><span class="lines">@@ -614,15 +614,18 @@
</span><span class="cx">     if (!root)
</span><span class="cx">         return;
</span><span class="cx">     
</span><ins>+    if (m_ignoreNewOpaqueRoots)
+        return;
+    
</ins><span class="cx">     if (Options::numberOfGCMarkers() == 1) {
</span><span class="cx">         // Put directly into the shared HashSet.
</span><del>-        m_visitCount += m_heap.m_opaqueRoots.add(root).isNewEntry;
</del><ins>+        m_heap.m_opaqueRoots.add(root);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     // Put into the local set, but merge with the shared one every once in
</span><span class="cx">     // a while to make sure that the local sets don't grow too large.
</span><span class="cx">     mergeOpaqueRootsIfProfitable();
</span><del>-    m_visitCount += m_opaqueRoots.add(root);
</del><ins>+    m_opaqueRoots.add(root);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool SlotVisitor::containsOpaqueRoot(void* root) const
</span><span class="lines">@@ -647,13 +650,13 @@
</span><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SlotVisitor::mergeOpaqueRootsIfNecessary()
</del><ins>+void SlotVisitor::mergeIfNecessary()
</ins><span class="cx"> {
</span><span class="cx">     if (m_opaqueRoots.isEmpty())
</span><span class="cx">         return;
</span><span class="cx">     mergeOpaqueRoots();
</span><span class="cx"> }
</span><del>-    
</del><ins>+
</ins><span class="cx"> void SlotVisitor::mergeOpaqueRootsIfProfitable()
</span><span class="cx"> {
</span><span class="cx">     if (static_cast&lt;unsigned&gt;(m_opaqueRoots.size()) &lt; Options::opaqueRootMergeThreshold())
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapSlotVisitorh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitor.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitor.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitor.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -92,6 +92,7 @@
</span><span class="cx">     void append(const Weak&lt;T&gt;&amp; weak);
</span><span class="cx">     
</span><span class="cx">     JS_EXPORT_PRIVATE void addOpaqueRoot(void*);
</span><ins>+    
</ins><span class="cx">     JS_EXPORT_PRIVATE bool containsOpaqueRoot(void*) const;
</span><span class="cx">     TriState containsOpaqueRootTriState(void*) const;
</span><span class="cx"> 
</span><span class="lines">@@ -116,6 +117,8 @@
</span><span class="cx"> 
</span><span class="cx">     SharedDrainResult drainInParallel(MonotonicTime timeout = MonotonicTime::infinity());
</span><span class="cx">     SharedDrainResult drainInParallelPassively(MonotonicTime timeout = MonotonicTime::infinity());
</span><ins>+    
+    JS_EXPORT_PRIVATE void mergeIfNecessary();
</ins><span class="cx"> 
</span><span class="cx">     // This informs the GC about auxiliary of some size that we are keeping alive. If you don't do
</span><span class="cx">     // this then the space will be freed at end of GC.
</span><span class="lines">@@ -135,8 +138,6 @@
</span><span class="cx">     
</span><span class="cx">     HeapVersion markingVersion() const { return m_markingVersion; }
</span><span class="cx"> 
</span><del>-    void mergeOpaqueRootsIfNecessary();
-    
</del><span class="cx">     bool mutatorIsStopped() const { return m_mutatorIsStopped; }
</span><span class="cx">     
</span><span class="cx">     Lock&amp; rightToRun() { return m_rightToRun; }
</span><span class="lines">@@ -155,6 +156,8 @@
</span><span class="cx">     void visitAsConstraint(const JSCell*);
</span><span class="cx">     
</span><span class="cx">     bool didReachTermination();
</span><ins>+    
+    void setIgnoreNewOpaqueRoots(bool value) { m_ignoreNewOpaqueRoots = value; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class ParallelModeEnabler;
</span><span class="lines">@@ -176,7 +179,8 @@
</span><span class="cx">     
</span><span class="cx">     void noteLiveAuxiliaryCell(HeapCell*);
</span><span class="cx">     
</span><del>-    JS_EXPORT_PRIVATE void mergeOpaqueRoots();
</del><ins>+    void mergeOpaqueRoots();
+
</ins><span class="cx">     void mergeOpaqueRootsIfProfitable();
</span><span class="cx"> 
</span><span class="cx">     void visitChildren(const JSCell*);
</span><span class="lines">@@ -190,6 +194,7 @@
</span><span class="cx">     MarkStackArray m_collectorStack;
</span><span class="cx">     MarkStackArray m_mutatorStack;
</span><span class="cx">     OpaqueRootSet m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
</span><ins>+    bool m_ignoreNewOpaqueRoots { false }; // Useful as a debugging mode.
</ins><span class="cx">     
</span><span class="cx">     size_t m_bytesVisited;
</span><span class="cx">     size_t m_visitCount;
</span><span class="lines">@@ -201,7 +206,7 @@
</span><span class="cx"> 
</span><span class="cx">     HeapSnapshotBuilder* m_heapSnapshotBuilder { nullptr };
</span><span class="cx">     JSCell* m_currentCell { nullptr };
</span><del>-    bool m_isVisitingMutatorStack { false };
</del><ins>+    bool m_isFirstVisit { false };
</ins><span class="cx">     bool m_mutatorIsStopped { false };
</span><span class="cx">     bool m_canOptimizeForStoppedMutator { false };
</span><span class="cx">     Lock m_rightToRun;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapSlotVisitorInlinesh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitorInlines.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitorInlines.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/SlotVisitorInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -81,7 +81,7 @@
</span><span class="cx"> 
</span><span class="cx"> inline void SlotVisitor::reportExtraMemoryVisited(size_t size)
</span><span class="cx"> {
</span><del>-    if (!m_isVisitingMutatorStack)
</del><ins>+    if (m_isFirstVisit)
</ins><span class="cx">         heap()-&gt;reportExtraMemoryVisited(size);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -88,7 +88,7 @@
</span><span class="cx"> #if ENABLE(RESOURCE_USAGE)
</span><span class="cx"> inline void SlotVisitor::reportExternalMemoryVisited(size_t size)
</span><span class="cx"> {
</span><del>-    if (!m_isVisitingMutatorStack)
</del><ins>+    if (m_isFirstVisit)
</ins><span class="cx">         heap()-&gt;reportExternalMemoryVisited(size);
</span><span class="cx"> }
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapSubspacecpp"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/JavaScriptCore/heap/Subspace.cpp (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/Subspace.cpp                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/Subspace.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,196 @@
</span><ins>+/*
+ * Copyright (C) 2017 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;Subspace.h&quot;
+
+#include &quot;JSCInlines.h&quot;
+#include &quot;MarkedAllocatorInlines.h&quot;
+#include &quot;MarkedBlockInlines.h&quot;
+#include &quot;PreventCollectionScope.h&quot;
+#include &quot;SubspaceInlines.h&quot;
+
+namespace JSC {
+
+namespace {
+
+// Writing it this way ensures that when you pass this as a functor, the callee is specialized for
+// this callback. If you wrote this as a normal function then the callee would be specialized for
+// the function's type and it would have indirect calls to that function. And unlike a lambda, it's
+// possible to mark this ALWAYS_INLINE.
+struct DestroyFunc {
+    ALWAYS_INLINE void operator()(VM&amp; vm, JSCell* cell) const
+    {
+        ASSERT(cell-&gt;structureID());
+        ASSERT(cell-&gt;inlineTypeFlags() &amp; StructureIsImmortal);
+        Structure* structure = cell-&gt;structure(vm);
+        const ClassInfo* classInfo = structure-&gt;classInfo();
+        MethodTable::DestroyFunctionPtr destroy = classInfo-&gt;methodTable.destroy;
+        destroy(cell);
+    }
+};
+
+} // anonymous namespace
+
+Subspace::Subspace(CString name, Heap&amp; heap, AllocatorAttributes attributes)
+    : m_space(heap.objectSpace())
+    , m_name(name)
+    , m_attributes(attributes)
+{
+    // It's remotely possible that we're GCing right now even if the client is careful to only
+    // create subspaces right after VM creation, since collectContinuously (and probably other
+    // things) could cause a GC to be launched at pretty much any time and it's not 100% obvious
+    // that all clients would be able to ensure that there are zero safepoints between when they
+    // create VM and when they do this. Preventing GC while we're creating the Subspace ensures
+    // that we don't have to worry about whether it's OK for the GC to ever see a brand new
+    // subspace.
+    PreventCollectionScope preventCollectionScope(heap);
+    heap.objectSpace().m_subspaces.append(this);
+    
+    for (size_t i = MarkedSpace::numSizeClasses; i--;)
+        m_allocatorForSizeStep[i] = nullptr;
+}
+
+Subspace::~Subspace()
+{
+}
+
+FreeList Subspace::finishSweep(MarkedBlock::Handle&amp; block, MarkedBlock::Handle::SweepMode sweepMode)
+{
+    return block.finishSweepKnowingSubspace(sweepMode, DestroyFunc());
+}
+
+void Subspace::destroy(VM&amp; vm, JSCell* cell)
+{
+    DestroyFunc()(vm, cell);
+}
+
+// The reason why we distinguish between allocate and tryAllocate is to minimize the number of
+// checks on the allocation path in both cases. Likewise, the reason why we have overloads with and
+// without deferralContext is to minimize the amount of code for calling allocate when you don't
+// need the deferralContext.
+void* Subspace::allocate(size_t size)
+{
+    if (MarkedAllocator* allocator = tryAllocatorFor(size))
+        return allocator-&gt;allocate();
+    return allocateSlow(nullptr, size);
+}
+
+void* Subspace::allocate(GCDeferralContext* deferralContext, size_t size)
+{
+    if (MarkedAllocator* allocator = tryAllocatorFor(size))
+        return allocator-&gt;allocate(deferralContext);
+    return allocateSlow(deferralContext, size);
+}
+
+void* Subspace::tryAllocate(size_t size)
+{
+    if (MarkedAllocator* allocator = tryAllocatorFor(size))
+        return allocator-&gt;tryAllocate();
+    return tryAllocateSlow(nullptr, size);
+}
+
+void* Subspace::tryAllocate(GCDeferralContext* deferralContext, size_t size)
+{
+    if (MarkedAllocator* allocator = tryAllocatorFor(size))
+        return allocator-&gt;tryAllocate(deferralContext);
+    return tryAllocateSlow(deferralContext, size);
+}
+
+MarkedAllocator* Subspace::allocatorForSlow(size_t size)
+{
+    size_t index = MarkedSpace::sizeClassToIndex(size);
+    size_t sizeClass = MarkedSpace::s_sizeClassForSizeStep[index];
+    if (!sizeClass)
+        return nullptr;
+    
+    // This is written in such a way that it's OK for the JIT threads to end up here if they want
+    // to generate code that uses some allocator that hadn't been used yet. Note that a possibly-
+    // just-as-good solution would be to return null if we're in the JIT since the JIT treats null
+    // allocator as &quot;please always take the slow path&quot;. But, that could lead to performance
+    // surprises and the algorithm here is pretty easy. Only this code has to hold the lock, to
+    // prevent simultaneously MarkedAllocator creations from multiple threads. This code ensures
+    // that any &quot;forEachAllocator&quot; traversals will only see this allocator after it's initialized
+    // enough: it will have 
+    auto locker = holdLock(m_space.allocatorLock());
+    if (MarkedAllocator* allocator = m_allocatorForSizeStep[index])
+        return allocator;
+
+    if (false)
+        dataLog(&quot;Creating marked allocator for &quot;, m_name, &quot;, &quot;, m_attributes, &quot;, &quot;, sizeClass, &quot;.\n&quot;);
+    MarkedAllocator* allocator = m_space.addMarkedAllocator(locker, this, sizeClass);
+    index = MarkedSpace::sizeClassToIndex(sizeClass);
+    for (;;) {
+        if (MarkedSpace::s_sizeClassForSizeStep[index] != sizeClass)
+            break;
+
+        m_allocatorForSizeStep[index] = allocator;
+        
+        if (!index--)
+            break;
+    }
+    allocator-&gt;setNextAllocatorInSubspace(m_firstAllocator);
+    WTF::storeStoreFence();
+    m_firstAllocator = allocator;
+    return allocator;
+}
+
+void* Subspace::allocateSlow(GCDeferralContext* deferralContext, size_t size)
+{
+    void* result = tryAllocateSlow(deferralContext, size);
+    RELEASE_ASSERT(result);
+    return result;
+}
+
+void* Subspace::tryAllocateSlow(GCDeferralContext* deferralContext, size_t size)
+{
+    if (MarkedAllocator* allocator = allocatorFor(size))
+        return allocator-&gt;tryAllocate(deferralContext);
+    
+    if (size &lt;= Options::largeAllocationCutoff()
+        &amp;&amp; size &lt;= MarkedSpace::largeCutoff) {
+        dataLog(&quot;FATAL: attampting to allocate small object using large allocation.\n&quot;);
+        dataLog(&quot;Requested allocation size: &quot;, size, &quot;\n&quot;);
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    
+    m_space.heap()-&gt;collectIfNecessaryOrDefer(deferralContext);
+    
+    size = WTF::roundUpToMultipleOf&lt;MarkedSpace::sizeStep&gt;(size);
+    LargeAllocation* allocation = LargeAllocation::tryCreate(*m_space.m_heap, size, this);
+    if (!allocation)
+        return nullptr;
+    
+    m_space.m_largeAllocations.append(allocation);
+    m_space.m_heap-&gt;didAllocate(size);
+    m_space.m_capacity += size;
+    
+    m_largeAllocations.append(allocation);
+        
+    return allocation-&gt;cell();
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapSubspaceh"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/JavaScriptCore/heap/Subspace.h (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/Subspace.h                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/Subspace.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,122 @@
</span><ins>+/*
+ * Copyright (C) 2017 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. 
+ */
+
+#pragma once
+
+#include &quot;MarkedBlock.h&quot;
+#include &quot;MarkedSpace.h&quot;
+#include &lt;wtf/text/CString.h&gt;
+
+namespace JSC {
+
+// The idea of subspaces is that you can provide some custom behavior for your objects if you
+// allocate them from a custom Subspace in which you override some of the virtual methods. This
+// class is the baseclass of Subspaces and it provides a reasonable default implementation, where
+// sweeping assumes immortal structure. The common ways of overriding this are:
+//
+// - Provide customized destructor behavior. You can change how the destructor is called. You can
+//   also specialize the destructor call in the loop.
+//
+// - Use the Subspace as a quick way to iterate all of the objects in that subspace.
+class Subspace {
+    WTF_MAKE_NONCOPYABLE(Subspace);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    JS_EXPORT_PRIVATE Subspace(CString name, Heap&amp;, AllocatorAttributes);
+    JS_EXPORT_PRIVATE virtual ~Subspace();
+    
+    const char *name() const { return m_name.data(); }
+    MarkedSpace&amp; space() const { return m_space; }
+    
+    const AllocatorAttributes&amp; attributes() const { return m_attributes; }
+    
+    // The purpose of overriding this is to specialize the sweep for your destructors. This won't
+    // be called for no-destructor blocks. This must call MarkedBlock::finishSweepKnowingSubspace.
+    virtual FreeList finishSweep(MarkedBlock::Handle&amp;, MarkedBlock::Handle::SweepMode);
+    
+    // These get called for large objects.
+    virtual void destroy(VM&amp;, JSCell*);
+    
+    MarkedAllocator* tryAllocatorFor(size_t);
+    MarkedAllocator* allocatorFor(size_t);
+    
+    JS_EXPORT_PRIVATE void* allocate(size_t);
+    JS_EXPORT_PRIVATE void* allocate(GCDeferralContext*, size_t);
+    
+    JS_EXPORT_PRIVATE void* tryAllocate(size_t);
+    JS_EXPORT_PRIVATE void* tryAllocate(GCDeferralContext*, size_t);
+    
+    template&lt;typename Func&gt;
+    void forEachMarkedBlock(const Func&amp;);
+    
+    template&lt;typename Func&gt;
+    void forEachNotEmptyMarkedBlock(const Func&amp;);
+    
+    template&lt;typename Func&gt;
+    void forEachLargeAllocation(const Func&amp;);
+    
+    template&lt;typename Func&gt;
+    void forEachMarkedCell(const Func&amp;);
+    
+    static ptrdiff_t offsetOfAllocatorForSizeStep() { return OBJECT_OFFSETOF(Subspace, m_allocatorForSizeStep); }
+    
+    MarkedAllocator** allocatorForSizeStep() { return &amp;m_allocatorForSizeStep[0]; }
+
+private:
+    MarkedAllocator* allocatorForSlow(size_t);
+    
+    // These slow paths are concerned with large allocations and allocator creation.
+    void* allocateSlow(GCDeferralContext*, size_t);
+    void* tryAllocateSlow(GCDeferralContext*, size_t);
+    
+    MarkedSpace&amp; m_space;
+    
+    CString m_name;
+    AllocatorAttributes m_attributes;
+    
+    std::array&lt;MarkedAllocator*, MarkedSpace::numSizeClasses&gt; m_allocatorForSizeStep;
+    MarkedAllocator* m_firstAllocator { nullptr };
+    SentinelLinkedList&lt;LargeAllocation, BasicRawSentinelNode&lt;LargeAllocation&gt;&gt; m_largeAllocations;
+};
+
+ALWAYS_INLINE MarkedAllocator* Subspace::tryAllocatorFor(size_t size)
+{
+    if (size &lt;= MarkedSpace::largeCutoff)
+        return m_allocatorForSizeStep[MarkedSpace::sizeClassToIndex(size)];
+    return nullptr;
+}
+
+ALWAYS_INLINE MarkedAllocator* Subspace::allocatorFor(size_t size)
+{
+    if (size &lt;= MarkedSpace::largeCutoff) {
+        if (MarkedAllocator* result = m_allocatorForSizeStep[MarkedSpace::sizeClassToIndex(size)])
+            return result;
+        return allocatorForSlow(size);
+    }
+    return nullptr;
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapSubspaceInlinesh"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/JavaScriptCore/heap/SubspaceInlines.h (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/SubspaceInlines.h                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/SubspaceInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,76 @@
</span><ins>+/*
+ * Copyright (C) 2017 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. 
+ */
+
+#pragma once
+
+#include &quot;JSCell.h&quot;
+#include &quot;MarkedAllocator.h&quot;
+#include &quot;MarkedBlock.h&quot;
+#include &quot;MarkedSpace.h&quot;
+#include &quot;Subspace.h&quot;
+
+namespace JSC {
+
+template&lt;typename Func&gt;
+void Subspace::forEachMarkedBlock(const Func&amp; func)
+{
+    for (MarkedAllocator* allocator = m_firstAllocator; allocator; allocator = allocator-&gt;nextAllocatorInSubspace())
+        allocator-&gt;forEachBlock(func);
+}
+
+template&lt;typename Func&gt;
+void Subspace::forEachNotEmptyMarkedBlock(const Func&amp; func)
+{
+    for (MarkedAllocator* allocator = m_firstAllocator; allocator; allocator = allocator-&gt;nextAllocatorInSubspace())
+        allocator-&gt;forEachNotEmptyBlock(func);
+}
+
+template&lt;typename Func&gt;
+void Subspace::forEachLargeAllocation(const Func&amp; func)
+{
+    for (LargeAllocation* allocation = m_largeAllocations.begin(); allocation != m_largeAllocations.end(); allocation = allocation-&gt;next())
+        func(allocation);
+}
+
+template&lt;typename Func&gt;
+void Subspace::forEachMarkedCell(const Func&amp; func)
+{
+    forEachNotEmptyMarkedBlock(
+        [&amp;] (MarkedBlock::Handle* handle) {
+            handle-&gt;forEachMarkedCell(
+                [&amp;] (HeapCell* cell, HeapCell::Kind kind) -&gt; IterationStatus { 
+                    func(cell, kind);
+                    return IterationStatus::Continue;
+                });
+        });
+    forEachLargeAllocation(
+        [&amp;] (LargeAllocation* allocation) {
+            if (allocation-&gt;isMarked())
+                func(allocation-&gt;cell(), m_attributes.cellKind);
+        });
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapWeakBlockcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/WeakBlock.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/WeakBlock.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/WeakBlock.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -100,7 +100,8 @@
</span><span class="cx"> {
</span><span class="cx">     HeapVersion markingVersion = visitor.markingVersion();
</span><span class="cx"> 
</span><del>-    for (size_t i = 0; i &lt; weakImplCount(); ++i) {
</del><ins>+    size_t count = weakImplCount();
+    for (size_t i = 0; i &lt; count; ++i) {
</ins><span class="cx">         WeakImpl* weakImpl = &amp;weakImpls()[i];
</span><span class="cx">         if (weakImpl-&gt;state() != WeakImpl::Live)
</span><span class="cx">             continue;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapWeakBlockh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/WeakBlock.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/WeakBlock.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/WeakBlock.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -64,6 +64,7 @@
</span><span class="cx">     SweepResult takeSweepResult();
</span><span class="cx"> 
</span><span class="cx">     void visit(SlotVisitor&amp;);
</span><ins>+
</ins><span class="cx">     void reap();
</span><span class="cx"> 
</span><span class="cx">     void lastChanceToFinalize();
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreheapWeakSeth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/heap/WeakSet.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/heap/WeakSet.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/heap/WeakSet.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -53,7 +53,8 @@
</span><span class="cx"> 
</span><span class="cx">     bool isEmpty() const;
</span><span class="cx"> 
</span><del>-    unsigned visit(SlotVisitor&amp;);
</del><ins>+    void visit(SlotVisitor&amp;);
+
</ins><span class="cx">     void reap();
</span><span class="cx">     void sweep();
</span><span class="cx">     void shrink();
</span><span class="lines">@@ -106,14 +107,10 @@
</span><span class="cx">         block-&gt;lastChanceToFinalize();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline unsigned WeakSet::visit(SlotVisitor&amp; visitor)
</del><ins>+inline void WeakSet::visit(SlotVisitor&amp; visitor)
</ins><span class="cx"> {
</span><del>-    unsigned count = 0;
-    for (WeakBlock* block = m_blocks.head(); block; block = block-&gt;next()) {
-        count++;
</del><ins>+    for (WeakBlock* block = m_blocks.head(); block; block = block-&gt;next())
</ins><span class="cx">         block-&gt;visit(visitor);
</span><del>-    }
-    return count;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline void WeakSet::reap()
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/jit/AssemblyHelpers.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/jit/AssemblyHelpers.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/jit/AssemblyHelpers.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -1579,7 +1579,7 @@
</span><span class="cx">         GPRReg resultGPR, StructureType structure, StorageType storage, GPRReg scratchGPR1,
</span><span class="cx">         GPRReg scratchGPR2, JumpList&amp; slowPath, size_t size)
</span><span class="cx">     {
</span><del>-        MarkedAllocator* allocator = vm()-&gt;heap.allocatorForObjectOfType&lt;ClassType&gt;(size);
</del><ins>+        MarkedAllocator* allocator = subspaceFor&lt;ClassType&gt;(*vm())-&gt;allocatorFor(size);
</ins><span class="cx">         if (!allocator) {
</span><span class="cx">             slowPath.append(jump());
</span><span class="cx">             return;
</span><span class="lines">@@ -1596,7 +1596,7 @@
</span><span class="cx">     
</span><span class="cx">     // allocationSize can be aliased with any of the other input GPRs. If it's not aliased then it
</span><span class="cx">     // won't be clobbered.
</span><del>-    void emitAllocateVariableSized(GPRReg resultGPR, MarkedSpace::Subspace&amp; subspace, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList&amp; slowPath)
</del><ins>+    void emitAllocateVariableSized(GPRReg resultGPR, Subspace&amp; subspace, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList&amp; slowPath)
</ins><span class="cx">     {
</span><span class="cx">         static_assert(!(MarkedSpace::sizeStep &amp; (MarkedSpace::sizeStep - 1)), &quot;MarkedSpace::sizeStep must be a power of two.&quot;);
</span><span class="cx">         
</span><span class="lines">@@ -1605,7 +1605,7 @@
</span><span class="cx">         add32(TrustedImm32(MarkedSpace::sizeStep - 1), allocationSize, scratchGPR1);
</span><span class="cx">         urshift32(TrustedImm32(stepShift), scratchGPR1);
</span><span class="cx">         slowPath.append(branch32(Above, scratchGPR1, TrustedImm32(MarkedSpace::largeCutoff &gt;&gt; stepShift)));
</span><del>-        move(TrustedImmPtr(&amp;subspace.allocatorForSizeStep[0] - 1), scratchGPR2);
</del><ins>+        move(TrustedImmPtr(subspace.allocatorForSizeStep() - 1), scratchGPR2);
</ins><span class="cx">         loadPtr(BaseIndex(scratchGPR2, scratchGPR1, timesPtr()), scratchGPR1);
</span><span class="cx">         
</span><span class="cx">         emitAllocate(resultGPR, nullptr, scratchGPR1, scratchGPR2, slowPath);
</span><span class="lines">@@ -1614,7 +1614,7 @@
</span><span class="cx">     template&lt;typename ClassType, typename StructureType&gt;
</span><span class="cx">     void emitAllocateVariableSizedCell(GPRReg resultGPR, StructureType structure, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList&amp; slowPath)
</span><span class="cx">     {
</span><del>-        MarkedSpace::Subspace&amp; subspace = vm()-&gt;heap.template subspaceForObjectOfType&lt;ClassType&gt;();
</del><ins>+        Subspace&amp; subspace = *subspaceFor&lt;ClassType&gt;(*vm());
</ins><span class="cx">         emitAllocateVariableSized(resultGPR, subspace, allocationSize, scratchGPR1, scratchGPR2, slowPath);
</span><span class="cx">         emitStoreStructureWithTypeInfo(structure, resultGPR, scratchGPR2);
</span><span class="cx">     }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/jit/JITOpcodes.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/jit/JITOpcodes.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/jit/JITOpcodes.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -83,7 +83,7 @@
</span><span class="cx"> {
</span><span class="cx">     Structure* structure = currentInstruction[3].u.objectAllocationProfile-&gt;structure();
</span><span class="cx">     size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
</span><del>-    MarkedAllocator* allocator = m_vm-&gt;heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+    MarkedAllocator* allocator = subspaceFor&lt;JSFinalObject&gt;(*m_vm)-&gt;allocatorFor(allocationSize);
</ins><span class="cx"> 
</span><span class="cx">     RegisterID resultReg = regT0;
</span><span class="cx">     RegisterID allocatorReg = regT1;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -164,7 +164,7 @@
</span><span class="cx"> {
</span><span class="cx">     Structure* structure = currentInstruction[3].u.objectAllocationProfile-&gt;structure();
</span><span class="cx">     size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
</span><del>-    MarkedAllocator* allocator = m_vm-&gt;heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+    MarkedAllocator* allocator = subspaceFor&lt;JSFinalObject&gt;(*m_vm)-&gt;allocatorFor(allocationSize);
</ins><span class="cx"> 
</span><span class="cx">     RegisterID resultReg = returnValueGPR;
</span><span class="cx">     RegisterID allocatorReg = regT1;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/jsc.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/jsc.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/jsc.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><del>- *  Copyright (C) 2004-2008, 2012-2013, 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2004-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com)
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -163,7 +163,6 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     typedef JSNonFinalObject Base;
</span><del>-    static const bool needsDestruction = false;
</del><span class="cx"> 
</span><span class="cx">     Root* root() const { return m_root.get(); }
</span><span class="cx">     void setRoot(VM&amp; vm, Root* root) { m_root.set(vm, this, root); }
</span><span class="lines">@@ -264,7 +263,6 @@
</span><span class="cx">     typedef JSDestructibleObject Base;
</span><span class="cx"> 
</span><span class="cx">     DECLARE_INFO;
</span><del>-    static const bool needsDestruction = true;
</del><span class="cx"> 
</span><span class="cx">     static Structure* createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
</span><span class="cx">     {
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeButterflyInlinesh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/ButterflyInlines.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/ButterflyInlines.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/ButterflyInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -59,10 +59,10 @@
</span><span class="cx">     return optimalContiguousVectorLength(structure ? structure-&gt;outOfLineCapacity() : 0, vectorLength);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline Butterfly* Butterfly::createUninitialized(VM&amp; vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
</del><ins>+inline Butterfly* Butterfly::createUninitialized(VM&amp; vm, JSCell*, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
</ins><span class="cx"> {
</span><span class="cx">     size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
</span><del>-    void* base = vm.heap.allocateAuxiliary(intendedOwner, size);
</del><ins>+    void* base = vm.auxiliarySpace.allocate(size);
</ins><span class="cx">     Butterfly* result = fromBase(base, preCapacity, propertyCapacity);
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -134,14 +134,16 @@
</span><span class="cx">     size_t newIndexingPayloadSizeInBytes)
</span><span class="cx"> {
</span><span class="cx">     ASSERT_UNUSED(oldStructure, !indexingHeader()-&gt;preCapacity(oldStructure));
</span><del>-    ASSERT_UNUSED(oldStructure, hadIndexingHeader == oldStructure-&gt;hasIndexingHeader(intendedOwner));
</del><ins>+    ASSERT_UNUSED(intendedOwner, hadIndexingHeader == oldStructure-&gt;hasIndexingHeader(intendedOwner));
</ins><span class="cx">     void* theBase = base(0, propertyCapacity);
</span><span class="cx">     size_t oldSize = totalSize(0, propertyCapacity, hadIndexingHeader, oldIndexingPayloadSizeInBytes);
</span><span class="cx">     size_t newSize = totalSize(0, propertyCapacity, true, newIndexingPayloadSizeInBytes);
</span><del>-    theBase = vm.heap.tryReallocateAuxiliary(intendedOwner, theBase, oldSize, newSize);
-    if (!theBase)
-        return 0;
-    return fromBase(theBase, 0, propertyCapacity);
</del><ins>+    void* newBase = vm.auxiliarySpace.tryAllocate(newSize);
+    if (!newBase)
+        return nullptr;
+    // FIXME: This probably shouldn't be a memcpy.
+    memcpy(newBase, theBase, oldSize);
+    return fromBase(newBase, 0, propertyCapacity);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline Butterfly* Butterfly::growArrayRight(
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeClassInfoh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/ClassInfo.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/ClassInfo.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/ClassInfo.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx"> 
</span><span class="cx">     typedef void (*VisitChildrenFunctionPtr)(JSCell*, SlotVisitor&amp;);
</span><span class="cx">     VisitChildrenFunctionPtr visitChildren;
</span><del>-
</del><ins>+    
</ins><span class="cx">     typedef CallType (*GetCallDataFunctionPtr)(JSCell*, CallData&amp;);
</span><span class="cx">     GetCallDataFunctionPtr getCallData;
</span><span class="cx"> 
</span><span class="lines">@@ -122,6 +122,9 @@
</span><span class="cx"> 
</span><span class="cx">     typedef size_t (*EstimatedSizeFunctionPtr)(JSCell*);
</span><span class="cx">     EstimatedSizeFunctionPtr estimatedSize;
</span><ins>+    
+    typedef void (*VisitOutputConstraintsPtr)(JSCell*, SlotVisitor&amp;);
+    VisitOutputConstraintsPtr visitOutputConstraints;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> #define CREATE_MEMBER_CHECKER(member) \
</span><span class="lines">@@ -174,7 +177,8 @@
</span><span class="cx">         &amp;ClassName::getPrototype, \
</span><span class="cx">         &amp;ClassName::dumpToStream, \
</span><span class="cx">         &amp;ClassName::heapSnapshot, \
</span><del>-        &amp;ClassName::estimatedSize \
</del><ins>+        &amp;ClassName::estimatedSize, \
+        &amp;ClassName::visitOutputConstraints \
</ins><span class="cx">     }, \
</span><span class="cx">     ClassName::TypedArrayStorageType
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeClonedArgumentscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/ClonedArguments.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/ClonedArguments.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/ClonedArguments.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx">         butterfly-&gt;arrayStorage()-&gt;m_numValuesInVector = vectorLength;
</span><span class="cx"> 
</span><span class="cx">     } else {
</span><del>-        void* temp = vm.heap.tryAllocateAuxiliary(nullptr, Butterfly::totalSize(0, structure-&gt;outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)));
</del><ins>+        void* temp = vm.auxiliarySpace.tryAllocate(Butterfly::totalSize(0, structure-&gt;outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)));
</ins><span class="cx">         if (!temp)
</span><span class="cx">             return 0;
</span><span class="cx">         butterfly = Butterfly::fromBase(temp, 0, structure-&gt;outOfLineCapacity());
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeDirectArgumentscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/DirectArguments.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/DirectArguments.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/DirectArguments.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -116,7 +116,7 @@
</span><span class="cx">     putDirect(vm, vm.propertyNames-&gt;callee, m_callee.get(), DontEnum);
</span><span class="cx">     putDirect(vm, vm.propertyNames-&gt;iteratorSymbol, globalObject()-&gt;arrayProtoValuesFunction(), DontEnum);
</span><span class="cx">     
</span><del>-    void* backingStore = vm.heap.tryAllocateAuxiliary(this, overridesSize());
</del><ins>+    void* backingStore = vm.auxiliarySpace.tryAllocate(overridesSize());
</ins><span class="cx">     RELEASE_ASSERT(backingStore);
</span><span class="cx">     bool* overrides = static_cast&lt;bool*&gt;(backingStore);
</span><span class="cx">     m_overrides.set(vm, this, overrides);
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeGenericArgumentsInlinesh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeHashMapImplh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/HashMapImpl.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/HashMapImpl.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/HashMapImpl.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -171,11 +171,11 @@
</span><span class="cx">         return bitwise_cast&lt;BucketType**&gt;(this);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static HashMapBuffer* create(ExecState* exec, VM&amp; vm, JSCell* owner, uint32_t capacity)
</del><ins>+    static HashMapBuffer* create(ExecState* exec, VM&amp; vm, JSCell*, uint32_t capacity)
</ins><span class="cx">     {
</span><span class="cx">         auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx">         size_t allocationSize = HashMapBuffer::allocationSize(capacity);
</span><del>-        void* data = vm.heap.tryAllocateAuxiliary(owner, allocationSize);
</del><ins>+        void* data = vm.auxiliarySpace.tryAllocate(allocationSize);
</ins><span class="cx">         if (!data) {
</span><span class="cx">             throwOutOfMemoryError(exec, scope);
</span><span class="cx">             return nullptr;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSArraycpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSArray.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSArray.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSArray.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -75,7 +75,7 @@
</span><span class="cx">             || hasContiguous(indexingType));
</span><span class="cx"> 
</span><span class="cx">         unsigned vectorLength = Butterfly::optimalContiguousVectorLength(structure, initialLength);
</span><del>-        void* temp = vm.heap.tryAllocateAuxiliary(deferralContext, nullptr, Butterfly::totalSize(0, outOfLineStorage, true, vectorLength * sizeof(EncodedJSValue)));
</del><ins>+        void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(0, outOfLineStorage, true, vectorLength * sizeof(EncodedJSValue)));
</ins><span class="cx">         if (!temp)
</span><span class="cx">             return nullptr;
</span><span class="cx">         butterfly = Butterfly::fromBase(temp, 0, outOfLineStorage);
</span><span class="lines">@@ -90,7 +90,7 @@
</span><span class="cx">         }
</span><span class="cx">     } else {
</span><span class="cx">         unsigned vectorLength = ArrayStorage::optimalVectorLength(0, structure, initialLength);
</span><del>-        void* temp = vm.heap.tryAllocateAuxiliary(nullptr, Butterfly::totalSize(0, outOfLineStorage, true, ArrayStorage::sizeFor(vectorLength)));
</del><ins>+        void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(0, outOfLineStorage, true, ArrayStorage::sizeFor(vectorLength)));
</ins><span class="cx">         if (!temp)
</span><span class="cx">             return nullptr;
</span><span class="cx">         butterfly = Butterfly::fromBase(temp, 0, outOfLineStorage);
</span><span class="lines">@@ -347,7 +347,7 @@
</span><span class="cx">         allocatedNewStorage = false;
</span><span class="cx">     } else {
</span><span class="cx">         size_t newSize = Butterfly::totalSize(0, propertyCapacity, true, ArrayStorage::sizeFor(desiredCapacity));
</span><del>-        newAllocBase = vm.heap.tryAllocateAuxiliary(this, newSize);
</del><ins>+        newAllocBase = vm.auxiliarySpace.tryAllocate(newSize);
</ins><span class="cx">         if (!newAllocBase)
</span><span class="cx">             return false;
</span><span class="cx">         newStorageCapacity = desiredCapacity;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSArrayBufferViewcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -65,7 +65,7 @@
</span><span class="cx">         void* temp;
</span><span class="cx">         size_t size = sizeOf(length, elementSize);
</span><span class="cx">         if (size) {
</span><del>-            temp = vm.heap.tryAllocateAuxiliary(nullptr, size);
</del><ins>+            temp = vm.auxiliarySpace.tryAllocate(nullptr, size);
</ins><span class="cx">             if (!temp)
</span><span class="cx">                 return;
</span><span class="cx">         } else
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSCellh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSCell.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSCell.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSCell.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2015 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -81,6 +81,12 @@
</span><span class="cx"> 
</span><span class="cx">     static const bool needsDestruction = false;
</span><span class="cx"> 
</span><ins>+    // Don't call this directly. Call JSC::subspaceFor&lt;Type&gt;(vm) instead.
+    // FIXME: Refer to Subspace by reference.
+    // https://bugs.webkit.org/show_bug.cgi?id=166988
+    template&lt;typename CellType&gt;
+    static Subspace* subspaceFor(VM&amp;);
+
</ins><span class="cx">     static JSCell* seenMultipleCalleeObjects() { return bitwise_cast&lt;JSCell*&gt;(static_cast&lt;uintptr_t&gt;(1)); }
</span><span class="cx"> 
</span><span class="cx">     enum CreatingEarlyCellTag { CreatingEarlyCell };
</span><span class="lines">@@ -154,6 +160,7 @@
</span><span class="cx">     JS_EXPORT_PRIVATE static size_t estimatedSize(JSCell*);
</span><span class="cx"> 
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><ins>+    static void visitOutputConstraints(JSCell*, SlotVisitor&amp;);
</ins><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE static void heapSnapshot(JSCell*, HeapSnapshotBuilder&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -290,4 +297,12 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// FIXME: Refer to Subspace by reference.
+// https://bugs.webkit.org/show_bug.cgi?id=166988
+template&lt;typename Type&gt;
+inline Subspace* subspaceFor(VM&amp; vm)
+{
+    return Type::template subspaceFor&lt;Type&gt;(vm);
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSCellInlinesh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSCellInlines.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSCellInlines.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSCellInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -120,6 +120,10 @@
</span><span class="cx">     visitor.appendUnbarriered(cell-&gt;structure(visitor.vm()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void JSCell::visitOutputConstraints(JSCell*, SlotVisitor&amp;)
+{
+}
+
</ins><span class="cx"> ALWAYS_INLINE VM&amp; ExecState::vm() const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(callee());
</span><span class="lines">@@ -129,12 +133,20 @@
</span><span class="cx">     return *callee()-&gt;markedBlock().vm();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template&lt;typename CellType&gt;
+Subspace* JSCell::subspaceFor(VM&amp; vm)
+{
+    if (CellType::needsDestruction)
+        return &amp;vm.destructibleCellSpace;
+    return &amp;vm.cellSpace;
+}
+
</ins><span class="cx"> template&lt;typename T&gt;
</span><span class="cx"> void* allocateCell(Heap&amp; heap, size_t size)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
</span><span class="cx">     ASSERT(size &gt;= sizeof(T));
</span><del>-    JSCell* result = static_cast&lt;JSCell*&gt;(heap.allocateObjectOfType&lt;T&gt;(size));
</del><ins>+    JSCell* result = static_cast&lt;JSCell*&gt;(subspaceFor&lt;T&gt;(*heap.vm())-&gt;allocate(size));
</ins><span class="cx"> #if ENABLE(GC_VALIDATION)
</span><span class="cx">     ASSERT(!heap.vm()-&gt;isInitializingObject());
</span><span class="cx">     heap.vm()-&gt;setInitializingObjectClass(T::info());
</span><span class="lines">@@ -153,7 +165,7 @@
</span><span class="cx"> void* allocateCell(Heap&amp; heap, GCDeferralContext* deferralContext, size_t size)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(size &gt;= sizeof(T));
</span><del>-    JSCell* result = static_cast&lt;JSCell*&gt;(heap.allocateObjectOfType&lt;T&gt;(deferralContext, size));
</del><ins>+    JSCell* result = static_cast&lt;JSCell*&gt;(subspaceFor&lt;T&gt;(*heap.vm())-&gt;allocate(deferralContext, size));
</ins><span class="cx"> #if ENABLE(GC_VALIDATION)
</span><span class="cx">     ASSERT(!heap.vm()-&gt;isInitializingObject());
</span><span class="cx">     heap.vm()-&gt;setInitializingObjectClass(T::info());
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSDestructibleObjecth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObject.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObject.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObject.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -36,6 +36,12 @@
</span><span class="cx">     typedef JSNonFinalObject Base;
</span><span class="cx"> 
</span><span class="cx">     static const bool needsDestruction = true;
</span><ins>+    
+    template&lt;typename CellType&gt;
+    static Subspace* subspaceFor(VM&amp; vm)
+    {
+        return &amp;vm.destructibleObjectSpace;
+    }
</ins><span class="cx"> 
</span><span class="cx">     const ClassInfo* classInfo() const { return m_classInfo; }
</span><span class="cx">     
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSDestructibleObjectSubspacecppfromrev210867branchessafari603branchSourceJavaScriptCoreheapAllocatorAttributesh"></a>
<div class="copfile"><h4>Copied: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObjectSubspace.cpp (from rev 210867, branches/safari-603-branch/Source/JavaScriptCore/heap/AllocatorAttributes.h) (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObjectSubspace.cpp                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObjectSubspace.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+/*
+ * Copyright (C) 2017 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;JSDestructibleObjectSubspace.h&quot;
+
+#include &quot;MarkedBlockInlines.h&quot;
+#include &quot;JSCInlines.h&quot;
+#include &quot;SubspaceInlines.h&quot;
+
+namespace JSC {
+
+namespace {
+
+struct DestroyFunc {
+    ALWAYS_INLINE void operator()(VM&amp;, JSCell* cell) const
+    {
+        static_cast&lt;JSDestructibleObject*&gt;(cell)-&gt;classInfo()-&gt;methodTable.destroy(cell);
+    }
+};
+
+} // anonymous namespace
+
+JSDestructibleObjectSubspace::JSDestructibleObjectSubspace(CString name, Heap&amp; heap)
+    : Subspace(name, heap, AllocatorAttributes(NeedsDestruction, HeapCell::JSCell))
+{
+}
+
+JSDestructibleObjectSubspace::~JSDestructibleObjectSubspace()
+{
+}
+
+FreeList JSDestructibleObjectSubspace::finishSweep(MarkedBlock::Handle&amp; handle, MarkedBlock::Handle::SweepMode sweepMode)
+{
+    return handle.finishSweepKnowingSubspace(sweepMode, DestroyFunc());
+}
+
+void JSDestructibleObjectSubspace::destroy(VM&amp; vm, JSCell* cell)
+{
+    DestroyFunc()(vm, cell);
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSDestructibleObjectSubspacehfromrev210867branchessafari603branchSourceJavaScriptCoreheapAllocatorAttributesh"></a>
<div class="copfile"><h4>Copied: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObjectSubspace.h (from rev 210867, branches/safari-603-branch/Source/JavaScriptCore/heap/AllocatorAttributes.h) (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObjectSubspace.h                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSDestructibleObjectSubspace.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+/*
+ * Copyright (C) 2017 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. 
+ */
+
+#pragma once
+
+#include &quot;Subspace.h&quot;
+
+namespace JSC {
+
+class JSDestructibleObjectSubspace : public Subspace {
+public:
+    JS_EXPORT_PRIVATE JSDestructibleObjectSubspace(CString name, Heap&amp;);
+    JS_EXPORT_PRIVATE virtual ~JSDestructibleObjectSubspace();
+    
+    FreeList finishSweep(MarkedBlock::Handle&amp;, MarkedBlock::Handle::SweepMode) override;
+    void destroy(VM&amp;, JSCell*) override;
+};
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSObjecth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSObject.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSObject.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSObject.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003-2009, 2012-2016 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -1280,7 +1280,6 @@
</span><span class="cx">     : JSCell(vm, structure)
</span><span class="cx">     , m_butterfly(vm, this, butterfly)
</span><span class="cx"> {
</span><del>-    vm.heap.ascribeOwner(this, butterfly);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline JSValue JSObject::getPrototypeDirect() const
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSObjectInlinesh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSObjectInlines.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSObjectInlines.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSObjectInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003-2006, 2008, 2009, 2012-2016 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSSegmentedVariableObjecth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx">     
</span><span class="cx">     JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx">     JS_EXPORT_PRIVATE static void heapSnapshot(JSCell*, HeapSnapshotBuilder&amp;);
</span><del>-
</del><ins>+    
</ins><span class="cx"> protected:
</span><span class="cx">     JSSegmentedVariableObject(VM&amp; vm, Structure* structure, JSScope* scope)
</span><span class="cx">         : JSSymbolTableObject(vm, structure, scope)
</span><span class="lines">@@ -99,6 +99,8 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> private:
</span><ins>+    // FIXME: This needs a destructor, which can only be added using custom subspace.
+    
</ins><span class="cx">     SegmentedVector&lt;WriteBarrier&lt;Unknown&gt;, 16&gt; m_variables;
</span><span class="cx">     ConcurrentJSLock m_lock;
</span><span class="cx"> };
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSStringh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSString.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSString.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSString.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2014, 2016 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -85,9 +85,17 @@
</span><span class="cx"> 
</span><span class="cx">     static const bool needsDestruction = true;
</span><span class="cx">     static void destroy(JSCell*);
</span><del>-
</del><ins>+    
+    // We specialize the string subspace to get the fastest possible sweep. This wouldn't be
+    // necessary if JSString didn't have a destructor.
+    template&lt;typename&gt;
+    static Subspace* subspaceFor(VM&amp; vm)
+    {
+        return &amp;vm.stringSpace;
+    }
+    
</ins><span class="cx">     static const unsigned MaxLength = std::numeric_limits&lt;int32_t&gt;::max();
</span><del>-
</del><ins>+    
</ins><span class="cx"> private:
</span><span class="cx">     JSString(VM&amp; vm, PassRefPtr&lt;StringImpl&gt; value)
</span><span class="cx">         : JSCell(vm, vm.stringStructure.get())
</span><span class="lines">@@ -234,6 +242,8 @@
</span><span class="cx">     friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length);
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+// NOTE: This class cannot override JSString's destructor. JSString's destructor is called directly
+// from JSStringSubspace::
</ins><span class="cx"> class JSRopeString final : public JSString {
</span><span class="cx">     friend class JSString;
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSStringSubspacecppfromrev210867branchessafari603branchSourceJavaScriptCoreheapAllocatorAttributesh"></a>
<div class="copfile"><h4>Copied: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSStringSubspace.cpp (from rev 210867, branches/safari-603-branch/Source/JavaScriptCore/heap/AllocatorAttributes.h) (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSStringSubspace.cpp                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSStringSubspace.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+/*
+ * Copyright (C) 2017 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;JSStringSubspace.h&quot;
+
+#include &quot;MarkedBlockInlines.h&quot;
+#include &quot;JSCInlines.h&quot;
+#include &quot;SubspaceInlines.h&quot;
+
+namespace JSC {
+
+namespace {
+
+struct DestroyFunc {
+    ALWAYS_INLINE void operator()(VM&amp;, JSCell* cell) const
+    {
+        static_cast&lt;JSString*&gt;(cell)-&gt;JSString::~JSString();
+    }
+};
+
+} // anonymous namespace
+
+JSStringSubspace::JSStringSubspace(CString name, Heap&amp; heap)
+    : Subspace(name, heap, AllocatorAttributes(NeedsDestruction, HeapCell::JSCell))
+{
+}
+
+JSStringSubspace::~JSStringSubspace()
+{
+}
+
+FreeList JSStringSubspace::finishSweep(MarkedBlock::Handle&amp; handle, MarkedBlock::Handle::SweepMode sweepMode)
+{
+    return handle.finishSweepKnowingSubspace(sweepMode, DestroyFunc());
+}
+
+void JSStringSubspace::destroy(VM&amp; vm, JSCell* cell)
+{
+    DestroyFunc()(vm, cell);
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSStringSubspacehfromrev210867branchessafari603branchSourceJavaScriptCoreheapAllocatorAttributesh"></a>
<div class="copfile"><h4>Copied: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSStringSubspace.h (from rev 210867, branches/safari-603-branch/Source/JavaScriptCore/heap/AllocatorAttributes.h) (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSStringSubspace.h                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSStringSubspace.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+/*
+ * Copyright (C) 2017 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. 
+ */
+
+#pragma once
+
+#include &quot;Subspace.h&quot;
+
+namespace JSC {
+
+class JSStringSubspace : public Subspace {
+public:
+    JS_EXPORT_PRIVATE JSStringSubspace(CString name, Heap&amp;);
+    JS_EXPORT_PRIVATE virtual ~JSStringSubspace();
+    
+    FreeList finishSweep(MarkedBlock::Handle&amp;, MarkedBlock::Handle::SweepMode) override;
+    void destroy(VM&amp;, JSCell*) override;
+};
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeRegExpMatchesArrayh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/RegExpMatchesArray.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/RegExpMatchesArray.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/RegExpMatchesArray.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- *  Copyright (C) 2008, 2016 Apple Inc. All Rights Reserved.
</del><ins>+ *  Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx">     if (vectorLength &gt; MAX_STORAGE_VECTOR_LENGTH)
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><del>-    void* temp = vm.heap.tryAllocateAuxiliary(deferralContext, nullptr, Butterfly::totalSize(0, structure-&gt;outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)));
</del><ins>+    void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(0, structure-&gt;outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)));
</ins><span class="cx">     if (!temp)
</span><span class="cx">         return nullptr;
</span><span class="cx">     Butterfly* butterfly = Butterfly::fromBase(temp, 0, structure-&gt;outOfLineCapacity());
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2011, 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -164,6 +164,11 @@
</span><span class="cx">     , executableAllocator(*this)
</span><span class="cx"> #endif
</span><span class="cx">     , heap(this, heapType)
</span><ins>+    , auxiliarySpace(&quot;Auxiliary&quot;, heap, AllocatorAttributes(DoesNotNeedDestruction, HeapCell::Auxiliary))
+    , cellSpace(&quot;JSCell&quot;, heap, AllocatorAttributes(DoesNotNeedDestruction, HeapCell::JSCell))
+    , destructibleCellSpace(&quot;Destructible JSCell&quot;, heap, AllocatorAttributes(NeedsDestruction, HeapCell::JSCell))
+    , stringSpace(&quot;JSString&quot;, heap)
+    , destructibleObjectSpace(&quot;JSDestructibleObject&quot;, heap)
</ins><span class="cx">     , vmType(vmType)
</span><span class="cx">     , clientData(0)
</span><span class="cx">     , topVMEntryFrame(nullptr)
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2009, 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -40,7 +40,9 @@
</span><span class="cx"> #include &quot;Intrinsic.h&quot;
</span><span class="cx"> #include &quot;JITThunks.h&quot;
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><ins>+#include &quot;JSDestructibleObjectSubspace.h&quot;
</ins><span class="cx"> #include &quot;JSLock.h&quot;
</span><ins>+#include &quot;JSStringSubspace.h&quot;
</ins><span class="cx"> #include &quot;MacroAssemblerCodeRef.h&quot;
</span><span class="cx"> #include &quot;Microtask.h&quot;
</span><span class="cx"> #include &quot;NumericStrings.h&quot;
</span><span class="lines">@@ -49,6 +51,7 @@
</span><span class="cx"> #include &quot;SmallStrings.h&quot;
</span><span class="cx"> #include &quot;SourceCode.h&quot;
</span><span class="cx"> #include &quot;Strong.h&quot;
</span><ins>+#include &quot;Subspace.h&quot;
</ins><span class="cx"> #include &quot;TemplateRegistryKeyTable.h&quot;
</span><span class="cx"> #include &quot;ThunkGenerators.h&quot;
</span><span class="cx"> #include &quot;VMEntryRecord.h&quot;
</span><span class="lines">@@ -282,6 +285,14 @@
</span><span class="cx">     // The heap should be just after executableAllocator and before other members to ensure that it's
</span><span class="cx">     // destructed after all the objects that reference it.
</span><span class="cx">     Heap heap;
</span><ins>+    
+    Subspace auxiliarySpace;
+    
+    // Whenever possible, use subspaceFor&lt;CellType&gt;(vm) to get one of these subspaces.
+    Subspace cellSpace;
+    Subspace destructibleCellSpace;
+    JSStringSubspace stringSpace;
+    JSDestructibleObjectSubspace destructibleObjectSpace;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx">     std::unique_ptr&lt;DFG::LongLivedState&gt; dfgState;
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/CMakeLists.txt (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/CMakeLists.txt        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/CMakeLists.txt        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1218,6 +1218,7 @@
</span><span class="cx">     bindings/js/ScriptState.cpp
</span><span class="cx">     bindings/js/StructuredClone.cpp
</span><span class="cx">     bindings/js/SerializedScriptValue.cpp
</span><ins>+    bindings/js/WebCoreJSClientData.cpp
</ins><span class="cx">     bindings/js/WebCoreTypedArrayController.cpp
</span><span class="cx">     bindings/js/WorkerScriptController.cpp
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/ChangeLog        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,5 +1,64 @@
</span><span class="cx"> 2017-01-18  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r210844. rdar://problem/29993906
+
+    2017-01-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+            Make opaque root scanning truly constraint-based
+            https://bugs.webkit.org/show_bug.cgi?id=165760
+
+            Reviewed by Geoffrey Garen.
+
+            No new tests yet. I think that writing tests for this is a big investigation:
+            https://bugs.webkit.org/show_bug.cgi?id=165808
+
+            Remove the previous advancing wavefront DOM write barrier. I don't think this will scale
+            very well. It's super confusing.
+
+            This change makes it so that visitAdditionalChildren can become a GC constraint that
+            executes as part of the fixpoint. This changes all WebCore visitAdditionalChildren into
+            output constraints by using new JSC API for Subspaces and MarkingConstraints.
+
+            * ForwardingHeaders/heap/MarkedAllocatorInlines.h: Added.
+            * ForwardingHeaders/heap/MarkedBlockInlines.h: Added.
+            * ForwardingHeaders/heap/MarkingConstraint.h: Added.
+            * ForwardingHeaders/heap/SubspaceInlines.h: Added.
+            * ForwardingHeaders/heap/VisitingTimeout.h: Added.
+            * WebCore.xcodeproj/project.pbxproj:
+            * bindings/js/CommonVM.cpp:
+            (WebCore::commonVMSlow):
+            (WebCore::writeBarrierOpaqueRootSlow): Deleted.
+            * bindings/js/CommonVM.h:
+            (WebCore::writeBarrierOpaqueRoot): Deleted.
+            * bindings/js/JSDOMGlobalObject.cpp:
+            (WebCore::JSDOMGlobalObject::finishCreation):
+            (WebCore::JSDOMGlobalObject::scriptExecutionContext):
+            * bindings/js/JSDOMWrapper.cpp:
+            (WebCore::outputConstraintSubspaceFor):
+            (WebCore::globalObjectOutputConstraintSubspaceFor):
+            * bindings/js/JSDOMWrapper.h:
+            * bindings/js/WebCoreJSClientData.cpp: Added.
+            (WebCore::JSVMClientData::JSVMClientData):
+            (WebCore::JSVMClientData::~JSVMClientData):
+            (WebCore::JSVMClientData::getAllWorlds):
+            (WebCore::initNormalWorldClientData):
+            * bindings/js/WebCoreJSClientData.h:
+            (WebCore::JSVMClientData::outputConstraintSpace):
+            (WebCore::JSVMClientData::globalObjectOutputConstraintSpace):
+            (WebCore::JSVMClientData::forEachOutputConstraintSpace):
+            (WebCore::JSVMClientData::JSVMClientData): Deleted.
+            (WebCore::JSVMClientData::~JSVMClientData): Deleted.
+            (WebCore::JSVMClientData::getAllWorlds): Deleted.
+            (WebCore::initNormalWorldClientData): Deleted.
+            * bindings/scripts/CodeGeneratorJS.pm:
+            (GenerateHeader):
+            (GenerateImplementation):
+            * dom/ContainerNodeAlgorithms.cpp:
+            (WebCore::notifyChildNodeInserted):
+            (WebCore::notifyChildNodeRemoved):
+
+2017-01-18  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r210829. rdar://problem/30044439
</span><span class="cx"> 
</span><span class="cx">     2017-01-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoreForwardingHeadersheapMarkedAllocatorInlinesh"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkedAllocatorInlines.h (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkedAllocatorInlines.h                                (rev 0)
+++ branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkedAllocatorInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+#pragma once
+#include &lt;JavaScriptCore/MarkedAllocatorInlines.h&gt;
</ins></span></pre></div>
<a id="branchessafari603branchSourceWebCoreForwardingHeadersheapMarkedBlockInlinesh"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkedBlockInlines.h (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkedBlockInlines.h                                (rev 0)
+++ branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkedBlockInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+#pragma once
+#include &lt;JavaScriptCore/MarkedBlockInlines.h&gt;
</ins></span></pre></div>
<a id="branchessafari603branchSourceWebCoreForwardingHeadersheapMarkingConstrainth"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkingConstraint.h (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkingConstraint.h                                (rev 0)
+++ branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/MarkingConstraint.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+#pragma once
+#include &lt;JavaScriptCore/MarkingConstraint.h&gt;
</ins></span></pre></div>
<a id="branchessafari603branchSourceWebCoreForwardingHeadersheapSubspaceInlinesh"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/SubspaceInlines.h (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/SubspaceInlines.h                                (rev 0)
+++ branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/SubspaceInlines.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+#pragma once
+#include &lt;JavaScriptCore/SubspaceInlines.h&gt;
</ins></span></pre></div>
<a id="branchessafari603branchSourceWebCoreForwardingHeadersheapVisitingTimeouth"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/VisitingTimeout.h (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/VisitingTimeout.h                                (rev 0)
+++ branches/safari-603-branch/Source/WebCore/ForwardingHeaders/heap/VisitingTimeout.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+#pragma once
+#include &lt;JavaScriptCore/VisitingTimeout.h&gt;
</ins></span></pre></div>
<a id="branchessafari603branchSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -490,6 +490,7 @@
</span><span class="cx">                 0F6A12BD1A00923700C6DE72 /* DebugPageOverlays.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6A12BB1A00923700C6DE72 /* DebugPageOverlays.cpp */; };
</span><span class="cx">                 0F6A12BE1A00923700C6DE72 /* DebugPageOverlays.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6A12BC1A00923700C6DE72 /* DebugPageOverlays.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F7D07331884C56C00B4AF86 /* PlatformTextTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = 072847E216EBC5B00043CFA4 /* PlatformTextTrack.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F7DF1481E2BF1B10095951B /* WebCoreJSClientData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7DF1471E2BF1A60095951B /* WebCoreJSClientData.cpp */; };
</ins><span class="cx">                 0F87166F1C869D83004FF0DE /* LengthPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F87166D1C869D83004FF0DE /* LengthPoint.cpp */; };
</span><span class="cx">                 0F8716701C869D83004FF0DE /* LengthPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F87166E1C869D83004FF0DE /* LengthPoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F8B45721DC3FBA300443C3F /* IntersectionObserverCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8B45711DC3FBA300443C3F /* IntersectionObserverCallback.h */; };
</span><span class="lines">@@ -7505,6 +7506,7 @@
</span><span class="cx">                 0F6383DC18615B29003E5DB5 /* ThreadedScrollingTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadedScrollingTree.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6A12BB1A00923700C6DE72 /* DebugPageOverlays.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebugPageOverlays.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6A12BC1A00923700C6DE72 /* DebugPageOverlays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugPageOverlays.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F7DF1471E2BF1A60095951B /* WebCoreJSClientData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebCoreJSClientData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F87166D1C869D83004FF0DE /* LengthPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LengthPoint.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F87166E1C869D83004FF0DE /* LengthPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LengthPoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F8B456F1DC3FB1000443C3F /* IntersectionObserverCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = IntersectionObserverCallback.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -22083,6 +22085,7 @@
</span><span class="cx">                                 414B82031D6DF0D90077EBE3 /* StructuredClone.h */,
</span><span class="cx">                                 419BE7521BC7F3DB00E1C85B /* WebCoreBuiltinNames.h */,
</span><span class="cx">                                 BC53D910114310CC000D817E /* WebCoreJSClientData.h */,
</span><ins>+                                0F7DF1471E2BF1A60095951B /* WebCoreJSClientData.cpp */,
</ins><span class="cx">                                 0F099D0617B968A100FF84B9 /* WebCoreTypedArrayController.cpp */,
</span><span class="cx">                                 0F099D0717B968A100FF84B9 /* WebCoreTypedArrayController.h */,
</span><span class="cx">                                 E1A643FC0EC097A000779668 /* WorkerScriptController.cpp */,
</span><span class="lines">@@ -30238,6 +30241,7 @@
</span><span class="cx">                                 598365E61355F60D001B185D /* JSPositionErrorCallback.cpp in Sources */,
</span><span class="cx">                                 7C330A071DF9F95100D3395C /* JSPositionOptions.cpp in Sources */,
</span><span class="cx">                                 65DF31FF09D1CC60000BE325 /* JSProcessingInstruction.cpp in Sources */,
</span><ins>+                                0F7DF1481E2BF1B10095951B /* WebCoreJSClientData.cpp in Sources */,
</ins><span class="cx">                                 E44613ED0CD681BA00FADA75 /* JSProgressEvent.cpp in Sources */,
</span><span class="cx">                                 077664FC183E6B5C00133B92 /* JSQuickTimePluginReplacement.cpp in Sources */,
</span><span class="cx">                                 B658FFA11522EF3A00DD5595 /* JSRadioNodeList.cpp in Sources */,
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorebindingsjsCommonVMcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/bindings/js/CommonVM.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/bindings/js/CommonVM.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/bindings/js/CommonVM.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -38,7 +38,6 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> VM* g_commonVMOrNull;
</span><del>-bool g_opaqueRootWriteBarrierEnabled;
</del><span class="cx"> 
</span><span class="cx"> VM&amp; commonVMSlow()
</span><span class="cx"> {
</span><span class="lines">@@ -60,18 +59,11 @@
</span><span class="cx"> #endif
</span><span class="cx">     
</span><span class="cx">     g_commonVMOrNull-&gt;setGlobalConstRedeclarationShouldThrow(Settings::globalConstRedeclarationShouldThrow());
</span><del>-    g_commonVMOrNull-&gt;heap.addMutatorShouldBeFencedCache(g_opaqueRootWriteBarrierEnabled);
</del><span class="cx">     
</span><del>-    initNormalWorldClientData(g_commonVMOrNull);
</del><ins>+    JSVMClientData::initNormalWorld(g_commonVMOrNull);
</ins><span class="cx">     
</span><span class="cx">     return *g_commonVMOrNull;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void writeBarrierOpaqueRootSlow(void* root)
-{
-    if (VM* vm = g_commonVMOrNull)
-        vm-&gt;heap.writeBarrierOpaqueRoot(root);
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorebindingsjsCommonVMh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/bindings/js/CommonVM.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/bindings/js/CommonVM.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/bindings/js/CommonVM.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -32,10 +32,8 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> WEBCORE_EXPORT extern JSC::VM* g_commonVMOrNull;
</span><del>-WEBCORE_EXPORT extern bool g_opaqueRootWriteBarrierEnabled;
</del><span class="cx"> 
</span><span class="cx"> WEBCORE_EXPORT JSC::VM&amp; commonVMSlow();
</span><del>-WEBCORE_EXPORT void writeBarrierOpaqueRootSlow(void*);
</del><span class="cx"> 
</span><span class="cx"> inline JSC::VM&amp; commonVM()
</span><span class="cx"> {
</span><span class="lines">@@ -44,12 +42,5 @@
</span><span class="cx">     return commonVMSlow();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename Func&gt;
-void writeBarrierOpaqueRoot(const Func&amp; rootThunk)
-{
-    if (g_opaqueRootWriteBarrierEnabled)
-        writeBarrierOpaqueRootSlow(rootThunk());
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorebindingsjsJSDOMGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -161,6 +161,8 @@
</span><span class="cx">     ASSERT(inherits(info()));
</span><span class="cx"> 
</span><span class="cx">     addBuiltinGlobals(vm);
</span><ins>+    
+    RELEASE_ASSERT(classInfo());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSDOMGlobalObject::finishCreation(VM&amp; vm, JSObject* thisValue)
</span><span class="lines">@@ -169,6 +171,8 @@
</span><span class="cx">     ASSERT(inherits(info()));
</span><span class="cx"> 
</span><span class="cx">     addBuiltinGlobals(vm);
</span><ins>+    
+    RELEASE_ASSERT(classInfo());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ScriptExecutionContext* JSDOMGlobalObject::scriptExecutionContext() const
</span><span class="lines">@@ -177,7 +181,8 @@
</span><span class="cx">         return jsCast&lt;const JSDOMWindowBase*&gt;(this)-&gt;scriptExecutionContext();
</span><span class="cx">     if (inherits(JSWorkerGlobalScopeBase::info()))
</span><span class="cx">         return jsCast&lt;const JSWorkerGlobalScopeBase*&gt;(this)-&gt;scriptExecutionContext();
</span><del>-    ASSERT_NOT_REACHED();
</del><ins>+    dataLog(&quot;Unexpected global object: &quot;, JSValue(this), &quot;\n&quot;);
+    RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorebindingsjsJSDOMWrappercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMWrapper.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMWrapper.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMWrapper.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DOMWrapperWorld.h&quot;
</span><span class="cx"> #include &quot;JSDOMWindow.h&quot;
</span><ins>+#include &quot;WebCoreJSClientData.h&quot;
</ins><span class="cx"> #include &lt;runtime/Error.h&gt;
</span><span class="cx"> 
</span><span class="cx"> using namespace JSC;
</span><span class="lines">@@ -43,4 +44,14 @@
</span><span class="cx">     return *domWindow;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Subspace* outputConstraintSubspaceFor(VM&amp; vm)
+{
+    return &amp;static_cast&lt;JSVMClientData*&gt;(vm.clientData)-&gt;outputConstraintSpace();
+}
+
+Subspace* globalObjectOutputConstraintSubspaceFor(VM&amp; vm)
+{
+    return &amp;static_cast&lt;JSVMClientData*&gt;(vm.clientData)-&gt;globalObjectOutputConstraintSpace();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorebindingsjsJSDOMWrapperh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMWrapper.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMWrapper.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/bindings/js/JSDOMWrapper.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -73,6 +73,9 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+WEBCORE_EXPORT JSC::Subspace* outputConstraintSubspaceFor(JSC::VM&amp;);
+WEBCORE_EXPORT JSC::Subspace* globalObjectOutputConstraintSubspaceFor(JSC::VM&amp;);
+
</ins><span class="cx"> template&lt;typename ImplementationClass&gt; class JSDOMWrapper : public JSDOMObject {
</span><span class="cx"> public:
</span><span class="cx">     typedef JSDOMObject Base;
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorebindingsjsWebCoreJSClientDatacpp"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/WebCore/bindings/js/WebCoreJSClientData.cpp (0 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/bindings/js/WebCoreJSClientData.cpp                                (rev 0)
+++ branches/safari-603-branch/Source/WebCore/bindings/js/WebCoreJSClientData.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -0,0 +1,117 @@
</span><ins>+/*
+ * Copyright (C) 2017 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;WebCoreJSClientData.h&quot;
+
+#include &quot;JSDOMBinding.h&quot;
+#include &lt;heap/HeapInlines.h&gt;
+#include &lt;heap/MarkingConstraint.h&gt;
+#include &lt;heap/MarkedAllocatorInlines.h&gt;
+#include &lt;heap/MarkedBlockInlines.h&gt;
+#include &lt;heap/SubspaceInlines.h&gt;
+#include &lt;heap/VisitingTimeout.h&gt;
+#include &lt;runtime/VM.h&gt;
+#include &lt;wtf/MainThread.h&gt;
+
+using namespace JSC;
+
+namespace WebCore {
+
+JSVMClientData::JSVMClientData(VM&amp; vm)
+    : m_builtinFunctions(vm)
+    , m_builtinNames(&amp;vm)
+    , m_outputConstraintSpace(&quot;WebCore Wrapper w/ Output Constraint&quot;, vm.heap)
+    , m_globalObjectOutputConstraintSpace(&quot;WebCore Global Object w/ Output Constraint&quot;, vm.heap, AllocatorAttributes(DoesNotNeedDestruction, HeapCell::JSCell))
+{
+}
+
+JSVMClientData::~JSVMClientData()
+{
+    ASSERT(m_worldSet.contains(m_normalWorld.get()));
+    ASSERT(m_worldSet.size() == 1);
+    ASSERT(m_normalWorld-&gt;hasOneRef());
+    m_normalWorld = nullptr;
+    ASSERT(m_worldSet.isEmpty());
+}
+
+void JSVMClientData::getAllWorlds(Vector&lt;Ref&lt;DOMWrapperWorld&gt;&gt;&amp; worlds)
+{
+    ASSERT(worlds.isEmpty());
+    
+    worlds.reserveInitialCapacity(m_worldSet.size());
+    for (auto it = m_worldSet.begin(), end = m_worldSet.end(); it != end; ++it)
+        worlds.uncheckedAppend(*(*it));
+}
+
+void JSVMClientData::initNormalWorld(VM* vm)
+{
+    JSVMClientData* clientData = new JSVMClientData(*vm);
+    vm-&gt;clientData = clientData; // ~VM deletes this pointer.
+    
+    auto constraint = std::make_unique&lt;MarkingConstraint&gt;(
+        &quot;Wcoc&quot;, &quot;WebCore Output Constraints&quot;,
+        [vm, clientData, lastExecutionVersion = vm-&gt;heap.mutatorExecutionVersion()]
+        (SlotVisitor&amp; slotVisitor, const VisitingTimeout&amp;) mutable {
+            Heap&amp; heap = vm-&gt;heap;
+            
+            if (heap.mutatorExecutionVersion() == lastExecutionVersion)
+                return;
+            
+            lastExecutionVersion = heap.mutatorExecutionVersion();
+
+            // We have to manage the visit count here ourselves. We need to know that if this adds
+            // opaque roots then we cannot declare termination yet. The way we signal this to the
+            // constraint solver is by adding to the visit count.
+            
+            size_t numOpaqueRootsBefore = heap.numOpaqueRoots();
+
+            // FIXME: Make this parallel!
+            unsigned numRevisited = 0;
+            clientData-&gt;forEachOutputConstraintSpace(
+                [&amp;] (Subspace&amp; subspace) {
+                    subspace.forEachMarkedCell(
+                        [&amp;] (HeapCell* heapCell, HeapCell::Kind) {
+                            JSCell* cell = static_cast&lt;JSCell*&gt;(heapCell);
+                            cell-&gt;methodTable(*vm)-&gt;visitOutputConstraints(cell, slotVisitor);
+                            numRevisited++;
+                        });
+                });
+            if (Options::logGC())
+                dataLog(&quot;(&quot;, numRevisited, &quot;)&quot;);
+            
+            slotVisitor.mergeIfNecessary();
+            
+            slotVisitor.addToVisitCount(heap.numOpaqueRoots() - numOpaqueRootsBefore);
+        },
+        ConstraintVolatility::SeldomGreyed);
+    vm-&gt;heap.addMarkingConstraint(WTFMove(constraint));
+        
+    clientData-&gt;m_normalWorld = DOMWrapperWorld::create(*vm, true);
+    vm-&gt;m_typedArrayController = adoptRef(new WebCoreTypedArrayController());
+}
+
+} // namespace WebCore
+
</ins></span></pre></div>
<a id="branchessafari603branchSourceWebCorebindingsjsWebCoreJSClientDatah"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/bindings/js/WebCoreJSClientData.h (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/bindings/js/WebCoreJSClientData.h        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/bindings/js/WebCoreJSClientData.h        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2007 Samuel Weinig &lt;sam@webkit.org&gt;
</span><span class="cx">  *  Copyright (C) 2009 Google, Inc. All rights reserved.
</span><span class="cx">  *
</span><span class="lines">@@ -33,35 +33,18 @@
</span><span class="cx"> class JSVMClientData : public JSC::VM::ClientData {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(JSVMClientData); WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx">     friend class VMWorldIterator;
</span><del>-    friend void initNormalWorldClientData(JSC::VM*);
</del><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    explicit JSVMClientData(JSC::VM&amp; vm)
-        : m_builtinFunctions(vm)
-        , m_builtinNames(&amp;vm)
-    {
-    }
</del><ins>+    explicit JSVMClientData(JSC::VM&amp;);
</ins><span class="cx"> 
</span><del>-    virtual ~JSVMClientData()
-    {
-        ASSERT(m_worldSet.contains(m_normalWorld.get()));
-        ASSERT(m_worldSet.size() == 1);
-        ASSERT(m_normalWorld-&gt;hasOneRef());
-        m_normalWorld = nullptr;
-        ASSERT(m_worldSet.isEmpty());
-    }
</del><ins>+    virtual ~JSVMClientData();
+    
+    WEBCORE_EXPORT static void initNormalWorld(JSC::VM*);
</ins><span class="cx"> 
</span><span class="cx">     DOMWrapperWorld&amp; normalWorld() { return *m_normalWorld; }
</span><span class="cx"> 
</span><del>-    void getAllWorlds(Vector&lt;Ref&lt;DOMWrapperWorld&gt;&gt;&amp; worlds)
-    {
-        ASSERT(worlds.isEmpty());
</del><ins>+    void getAllWorlds(Vector&lt;Ref&lt;DOMWrapperWorld&gt;&gt;&amp;);
</ins><span class="cx"> 
</span><del>-        worlds.reserveInitialCapacity(m_worldSet.size());
-        for (auto it = m_worldSet.begin(), end = m_worldSet.end(); it != end; ++it)
-            worlds.uncheckedAppend(*(*it));
-    }
-
</del><span class="cx">     void rememberWorld(DOMWrapperWorld&amp; world)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(!m_worldSet.contains(&amp;world));
</span><span class="lines">@@ -76,6 +59,16 @@
</span><span class="cx"> 
</span><span class="cx">     WebCoreBuiltinNames&amp; builtinNames() { return m_builtinNames; }
</span><span class="cx">     JSBuiltinFunctions&amp; builtinFunctions() { return m_builtinFunctions; }
</span><ins>+    
+    JSC::Subspace&amp; outputConstraintSpace() { return m_outputConstraintSpace; }
+    JSC::Subspace&amp; globalObjectOutputConstraintSpace() { return m_globalObjectOutputConstraintSpace; }
+    
+    template&lt;typename Func&gt;
+    void forEachOutputConstraintSpace(const Func&amp; func)
+    {
+        func(m_outputConstraintSpace);
+        func(m_globalObjectOutputConstraintSpace);
+    }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     HashSet&lt;DOMWrapperWorld*&gt; m_worldSet;
</span><span class="lines">@@ -83,14 +76,9 @@
</span><span class="cx"> 
</span><span class="cx">     JSBuiltinFunctions m_builtinFunctions;
</span><span class="cx">     WebCoreBuiltinNames m_builtinNames;
</span><ins>+    
+    JSC::JSDestructibleObjectSubspace m_outputConstraintSpace;
+    JSC::Subspace m_globalObjectOutputConstraintSpace;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline void initNormalWorldClientData(JSC::VM* vm)
-{
-    JSVMClientData* clientData = new JSVMClientData(*vm);
-    vm-&gt;clientData = clientData; // ~VM deletes this pointer.
-    clientData-&gt;m_normalWorld = DOMWrapperWorld::create(*vm, true);
-    vm-&gt;m_typedArrayController = adoptRef(new WebCoreTypedArrayController());
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorebindingsjsWorkerScriptControllercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/bindings/js/WorkerScriptController.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/bindings/js/WorkerScriptController.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/bindings/js/WorkerScriptController.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -53,7 +53,7 @@
</span><span class="cx"> {
</span><span class="cx">     m_vm-&gt;heap.acquireAccess(); // It's not clear that we have good discipline for heap access, so turn it on permanently.
</span><span class="cx">     m_vm-&gt;ensureWatchdog();
</span><del>-    initNormalWorldClientData(m_vm.get());
</del><ins>+    JSVMClientData::initNormalWorld(m_vm.get());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WorkerScriptController::~WorkerScriptController()
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -1705,6 +1705,23 @@
</span><span class="cx">         push(@headerContent, &quot;    static void visitChildren(JSCell*, JSC::SlotVisitor&amp;);\n&quot;);
</span><span class="cx">         push(@headerContent, &quot;    void visitAdditionalChildren(JSC::SlotVisitor&amp;);\n&quot;) if $interface-&gt;extendedAttributes-&gt;{JSCustomMarkFunction};
</span><span class="cx">         push(@headerContent, &quot;\n&quot;);
</span><ins>+
+        if ($interface-&gt;extendedAttributes-&gt;{JSCustomMarkFunction}) {
+            # We assume that the logic in visitAdditionalChildren is highly volatile, and during a
+            # concurrent GC or in between eden GCs something may happen that would lead to this
+            # logic behaving differently. Since this could mark objects or add opaque roots, this
+            # means that after any increment of mutator resumption in a concurrent GC and at least
+            # once during any eden GC we need to re-execute visitAdditionalChildren on any objects
+            # that we had executed it on before. We do this using the DOM's own MarkingConstraint,
+            # which will call visitOutputConstraints on all objects in the DOM's own
+            # outputConstraintSubspace. visitOutputConstraints is the name JSC uses for the method
+            # that the GC calls to ask an object is it would like to mark anything else after the
+            # program resumed since the last call to visitChildren or visitOutputConstraints. Since
+            # this just calls visitAdditionalChildren, you usually don't have to worry about this.
+            push(@headerContent, &quot;    static void visitOutputConstraints(JSCell*, JSC::SlotVisitor&amp;);\n&quot;);
+            my $subspaceFunc = IsDOMGlobalObject($interface) ? &quot;globalObjectOutputConstraintSubspaceFor&quot; : &quot;outputConstraintSubspaceFor&quot;;
+            push(@headerContent, &quot;    template&lt;typename&gt; static JSC::Subspace* subspaceFor(JSC::VM&amp; vm) { return $subspaceFunc(vm); }\n&quot;);
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (InstanceNeedsEstimatedSize($interface)) {
</span><span class="lines">@@ -3986,6 +4003,15 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         push(@implContent, &quot;}\n\n&quot;);
</span><ins>+        if ($interface-&gt;extendedAttributes-&gt;{JSCustomMarkFunction}) {
+            push(@implContent, &quot;void ${className}::visitOutputConstraints(JSCell* cell, SlotVisitor&amp; visitor)\n&quot;);
+            push(@implContent, &quot;{\n&quot;);
+            push(@implContent, &quot;    auto* thisObject = jsCast&lt;${className}*&gt;(cell);\n&quot;);
+            push(@implContent, &quot;    ASSERT_GC_OBJECT_INHERITS(thisObject, info());\n&quot;);
+            push(@implContent, &quot;    Base::visitOutputConstraints(thisObject, visitor);\n&quot;);
+            push(@implContent, &quot;    thisObject-&gt;visitAdditionalChildren(visitor);\n&quot;);
+            push(@implContent, &quot;}\n\n&quot;);
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (InstanceNeedsEstimatedSize($interface)) {
</span></span></pre></div>
<a id="branchessafari603branchSourceWebCoredomContainerNodeAlgorithmscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/WebCore/dom/ContainerNodeAlgorithms.cpp (210867 => 210868)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/WebCore/dom/ContainerNodeAlgorithms.cpp        2017-01-18 20:42:40 UTC (rev 210867)
+++ branches/safari-603-branch/Source/WebCore/dom/ContainerNodeAlgorithms.cpp        2017-01-18 20:43:04 UTC (rev 210868)
</span><span class="lines">@@ -26,7 +26,6 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;ContainerNodeAlgorithms.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;CommonVM.h&quot;
</del><span class="cx"> #include &quot;HTMLFrameOwnerElement.h&quot;
</span><span class="cx"> #include &quot;InspectorInstrumentation.h&quot;
</span><span class="cx"> #include &quot;NoEventDispatchAssertion.h&quot;
</span><span class="lines">@@ -102,8 +101,6 @@
</span><span class="cx">         notifyNodeInsertedIntoDocument(insertionPoint, node, postInsertionNotificationTargets);
</span><span class="cx">     else if (is&lt;ContainerNode&gt;(node))
</span><span class="cx">         notifyNodeInsertedIntoTree(insertionPoint, downcast&lt;ContainerNode&gt;(node), postInsertionNotificationTargets);
</span><del>-
-    writeBarrierOpaqueRoot([&amp;insertionPoint] () -&gt; void* { return insertionPoint.opaqueRoot(); });
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void notifyNodeRemovedFromDocument(ContainerNode&amp; insertionPoint, Node&amp; node)
</span><span class="lines">@@ -155,8 +152,6 @@
</span><span class="cx"> 
</span><span class="cx"> void notifyChildNodeRemoved(ContainerNode&amp; insertionPoint, Node&amp; child)
</span><span class="cx"> {
</span><del>-    writeBarrierOpaqueRoot([&amp;child] () -&gt; void* { return &amp;child; });
-
</del><span class="cx">     if (!child.inDocument()) {
</span><span class="cx">         if (is&lt;ContainerNode&gt;(child))
</span><span class="cx">             notifyNodeRemovedFromTree(insertionPoint, downcast&lt;ContainerNode&gt;(child));
</span></span></pre>
</div>
</div>

</body>
</html>