<!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 <matthew_hanson@apple.com>
</span><span class="cx">
</span><ins>+ Merge r210844. rdar://problem/29993906
+
+ 2017-01-16 Filip Pizlo <fpizlo@apple.com>
+
+ 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 <matthew_hanson@apple.com>
+
</ins><span class="cx"> Merge r210695. rdar://problem/29913445
</span><span class="cx">
</span><span class="cx"> 2017-01-12 Saam Barati <sbarati@apple.com>
</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 = ["a", "b"];
+for (var i = 0; i < 10000000; ++i)
+ global = array[i & 1] + "c";
</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 <matthew_hanson@apple.com>
</span><span class="cx">
</span><ins>+ Merge r210844. rdar://problem/29993906
+
+ 2017-01-16 Filip Pizlo <fpizlo@apple.com>
+
+ 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->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<> 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<Type>(vm). This calls
+ Type::subspaceFor<Type>(vm). This allows cell classes to override subspaceFor<> and it
+ allows any subspaceFor<> implementation to query static flags in the type. This is how
+ JSCell::subspaceFor<> 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<Type>::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 <matthew_hanson@apple.com>
+
</ins><span class="cx"> Merge r210829. rdar://problem/30044439
</span><span class="cx">
</span><span class="cx"> 2017-01-16 Filip Pizlo <fpizlo@apple.com>
</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 = "<group>"; };
</span><span class="cx">                 0F7C39FE1C90C55B00480151 /* DFGOpInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOpInfo.h; path = dfg/DFGOpInfo.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F7C5FB71D888A010044F5E2 /* MarkedBlockInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedBlockInlines.h; sourceTree = "<group>"; };
</span><del>-                0F7C5FB91D8895050044F5E2 /* MarkedSpaceInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpaceInlines.h; sourceTree = "<group>"; };
</del><span class="cx">                 0F7CF94E1DBEEE860098CC12 /* ReleaseHeapAccessScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReleaseHeapAccessScope.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F7CF9501DC027D70098CC12 /* StopIfNecessaryTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StopIfNecessaryTimer.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F7CF9511DC027D70098CC12 /* StopIfNecessaryTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StopIfNecessaryTimer.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F7CF9541DC1258B0098CC12 /* AtomicsObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AtomicsObject.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F7CF9551DC1258B0098CC12 /* AtomicsObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicsObject.h; sourceTree = "<group>"; };
</span><ins>+                0F7DF12F1E2970D50095951B /* ConstraintVolatility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstraintVolatility.h; sourceTree = "<group>"; };
+                0F7DF1301E2970D50095951B /* MarkedSpaceInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpaceInlines.h; sourceTree = "<group>"; };
+                0F7DF1311E2970D50095951B /* Subspace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Subspace.cpp; sourceTree = "<group>"; };
+                0F7DF1321E2970D50095951B /* Subspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Subspace.h; sourceTree = "<group>"; };
+                0F7DF1331E2970D50095951B /* SubspaceInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubspaceInlines.h; sourceTree = "<group>"; };
+                0F7DF1391E29710E0095951B /* JSDestructibleObjectSubspace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDestructibleObjectSubspace.cpp; sourceTree = "<group>"; };
+                0F7DF13A1E29710E0095951B /* JSDestructibleObjectSubspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDestructibleObjectSubspace.h; sourceTree = "<group>"; };
+                0F7DF13D1E2AFC4B0095951B /* JSStringSubspace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringSubspace.cpp; sourceTree = "<group>"; };
+                0F7DF13E1E2AFC4B0095951B /* JSStringSubspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringSubspace.h; sourceTree = "<group>"; };
+                0F7DF1451E2BEF680095951B /* MarkedAllocatorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedAllocatorInlines.h; sourceTree = "<group>"; };
</ins><span class="cx">                 0F7F98891D9596C300F4F12E /* DFGStoreBarrierClusteringPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStoreBarrierClusteringPhase.cpp; path = dfg/DFGStoreBarrierClusteringPhase.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F7F988A1D9596C300F4F12E /* DFGStoreBarrierClusteringPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStoreBarrierClusteringPhase.h; path = dfg/DFGStoreBarrierClusteringPhase.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F8023E91613832300A0BA45 /* ByValInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByValInfo.h; sourceTree = "<group>"; };
</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 <= 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()->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()->heap.allocatorForAuxiliaryData(size)) {
</del><ins>+ if (MarkedAllocator* allocator = m_jit.vm()->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()->heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+ MarkedAllocator* allocatorPtr = subspaceFor<JSFinalObject>(*m_jit.vm())->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()->heap.allocatorForObjectWithDestructor(sizeof(JSRopeString));
</del><ins>+ MarkedAllocator* markedAllocator = subspaceFor<JSString>(*m_jit.vm())->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()->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()->heap.allocatorForAuxiliaryData(size);
</del><ins>+ MarkedAllocator* allocator = m_jit.vm()->auxiliarySpace.allocatorFor(size);
</ins><span class="cx">
</span><span class="cx"> if (!allocator || node->transition()->previous->couldHaveIndexingHeader()) {
</span><span class="cx"> SpeculateCellOperand base(this, node->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->transition()->next->outOfLineCapacity() * sizeof(JSValue));
</span><span class="cx">
</span><del>- MarkedAllocator* allocator = m_jit.vm()->heap.allocatorForAuxiliaryData(newSize);
</del><ins>+ MarkedAllocator* allocator = m_jit.vm()->auxiliarySpace.allocatorFor(newSize);
</ins><span class="cx">
</span><span class="cx"> if (!allocator || node->transition()->previous->couldHaveIndexingHeader()) {
</span><span class="cx"> SpeculateCellOperand base(this, node->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()->heap.subspaceForAuxiliaryData(), scratchGPR, scratchGPR,
</del><ins>+ storageGPR, m_jit.vm()->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()->heap.subspaceForAuxiliaryData(), scratch2, scratch1, scratch3, slowCases);
</del><ins>+ storageResultGPR, m_jit.vm()->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->structure();
</span><span class="cx"> size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
</span><del>- MarkedAllocator* allocatorPtr = m_jit.vm()->heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+ MarkedAllocator* allocatorPtr = subspaceFor<JSFinalObject>(*m_jit.vm())->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->structure();
</span><span class="cx"> size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
</span><del>- MarkedAllocator* allocatorPtr = m_jit.vm()->heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+ MarkedAllocator* allocatorPtr = subspaceFor<JSFinalObject>(*m_jit.vm())->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<JSString>)) \
</span><span class="cx"> macro(JSRopeString_fibers, JSRopeString::offsetOfFibers(), sizeof(WriteBarrier<JSString>)) \
</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<intptr_t>(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<JSRopeString>(vm())->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->outOfLineCapacity() || hasIndexedProperties(structure->indexingType())) {
</span><span class="cx"> size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
</span><del>- MarkedAllocator* cellAllocator = vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+ MarkedAllocator* cellAllocator = subspaceFor<JSFinalObject>(vm())->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->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<ClassType>(size);
</del><ins>+ MarkedAllocator* allocator = subspaceFor<ClassType>(vm())->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->hasIntPtr() && size->hasIntPtr()) {
</span><del>- MarkedSpace::Subspace* actualSubspace = bitwise_cast<MarkedSpace::Subspace*>(subspace->asIntPtr());
</del><ins>+ Subspace* actualSubspace = bitwise_cast<Subspace*>(subspace->asIntPtr());
</ins><span class="cx"> size_t actualSize = size->asIntPtr();
</span><span class="cx">
</span><del>- MarkedAllocator* actualAllocator = MarkedSpace::allocatorFor(*actualSubspace, actualSize);
</del><ins>+ MarkedAllocator* actualAllocator = actualSubspace->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& subspace, LValue size, LBasicBlock slowPath)
</del><ins>+ LValue allocatorForSize(Subspace& subspace, LValue size, LBasicBlock slowPath)
</ins><span class="cx"> {
</span><span class="cx"> return allocatorForSize(m_out.constIntPtr(&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<ClassType>(), size, slowPath);
</del><ins>+ *subspaceFor<ClassType>(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<ClassType>(), size, slowPath);
</del><ins>+ *subspaceFor<ClassType>(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->inlineCapacity());
</span><del>- MarkedAllocator* allocator = vm().heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+ MarkedAllocator* allocator = subspaceFor<JSFinalObject>(vm())->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 "ConstraintVolatility.h"
</ins><span class="cx"> #include "DestructionMode.h"
</span><span class="cx"> #include "HeapCell.h"
</span><span class="cx"> #include <wtf/PrintStream.h>
</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& 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 <wtf/PrintStream.h>
+
+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 "root" 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& out, JSC::ConstraintVolatility volatility)
+{
+ switch (volatility) {
+ case JSC::ConstraintVolatility::SeldomGreyed:
+ out.print("SeldomGreyed");
+ return;
+ case JSC::ConstraintVolatility::GreyedByExecution:
+ out.print("GreyedByExecuction");
+ return;
+ case JSC::ConstraintVolatility::GreyedByMarking:
+ out.print("GreyedByMarking");
+ 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 "config.h"
</span><span class="cx"> #include "GCActivityCallback.h"
</span><span class="cx">
</span><del>-#include "Heap.h"
</del><ins>+#include "HeapInlines.h"
</ins><span class="cx"> #include "JSLock.h"
</span><span class="cx"> #include "JSObject.h"
</span><span class="cx"> #include "VM.h"
</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& stats = timingStats(m_name, *m_scope);
</span><span class="cx"> stats.add(timing);
</span><del>- dataLog("[GC:", *m_scope, "] ", m_name, " took: ", timing, " ms (average ", stats.mean(), " ms).\n");
</del><ins>+ dataLog("[GC:", *m_scope, "] ", m_name, " took: ", timing, "ms (average ", stats.mean(), "ms).\n");
</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<SlotVisitor>(*this))
</span><span class="cx"> , m_mutatorMarkStack(std::make_unique<MarkStackArray>())
</span><span class="cx"> , m_raceMarkStack(std::make_unique<MarkStackArray>())
</span><ins>+ , m_constraintSet(std::make_unique<MarkingConstraintSet>())
</ins><span class="cx"> , m_handleSet(vm)
</span><span class="cx"> , m_codeBlocks(std::make_unique<CodeBlockSet>())
</span><span class="cx"> , m_jitStubRoutines(std::make_unique<JITStubRoutineSet>())
</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->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("i#", iteration, " b=", m_barriersExecuted, " ");
</del><ins>+ dataLog("v=", bytesVisited() / 1024, "kb o=", m_opaqueRoots.size(), " b=", m_barriersExecuted, " ");
</ins><span class="cx">
</span><span class="cx"> if (slotVisitor.didReachTermination()) {
</span><ins>+ if (Options::logGC())
+ dataLog("i#", iteration, " ");
+
</ins><span class="cx"> assertSharedMarkStacksEmpty();
</span><span class="cx">
</span><ins>+ slotVisitor.mergeIfNecessary();
+ for (auto& parallelVisitor : m_parallelSlotVisitors)
+ parallelVisitor->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->executeConvergence(slotVisitor, MonotonicTime::infinity());
</span><del>- if (executedEverything && slotVisitor.isEmpty()) {
</del><ins>+ if (converged && 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->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("p=", thisPauseMS, " ms (max ", maxPauseMS(thisPauseMS), ")...]\n");
</del><ins>+ dataLog("p=", thisPauseMS, "ms (max ", maxPauseMS(thisPauseMS), ")...]\n");
</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->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("[Full sweep: ", capacity() / 1024, " kb ");
</del><ins>+ dataLog("[Full sweep: ", capacity() / 1024, "kb ");
</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("=> ", capacity() / 1024, " kb, ", after - before, " ms]\n");
</del><ins>+ dataLog("=> ", capacity() / 1024, "kb, ", after - before, "ms]\n");
</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("[GC: START ", capacity() / 1024, " kb ");
</del><ins>+ dataLog("[GC: START ", capacity() / 1024, "kb ");
</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("p=", thisPauseMS, " ms (max ", maxPauseMS(thisPauseMS), "), cycle ", (after - before).milliseconds(), " ms END]\n");
</del><ins>+ dataLog("p=", thisPauseMS, "ms (max ", maxPauseMS(thisPauseMS), "), cycle ", (after - before).milliseconds(), "ms END]\n");
</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("=> ", currentHeapSize / 1024, " kb, ");
</del><ins>+ dataLog("=> ", currentHeapSize / 1024, "kb, ");
</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->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<MarkingConstraintSet>();
-
</del><span class="cx"> m_constraintSet->add(
</span><span class="cx"> "Cs", "Conservative Scan",
</span><span class="cx"> [this] (SlotVisitor& slotVisitor, const VisitingTimeout&) {
</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->add(
</span><span class="cx"> "Msr", "Misc Small Roots",
</span><span class="lines">@@ -2162,7 +2180,7 @@
</span><span class="cx"> slotVisitor.appendUnbarriered(m_vm->exception());
</span><span class="cx"> slotVisitor.appendUnbarriered(m_vm->lastException());
</span><span class="cx"> },
</span><del>- MarkingConstraint::GreyedByExecution);
</del><ins>+ ConstraintVolatility::GreyedByExecution);
</ins><span class="cx">
</span><span class="cx"> m_constraintSet->add(
</span><span class="cx"> "Sh", "Strong Handles",
</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->add(
</span><span class="cx"> "D", "Debugger",
</span><span class="lines">@@ -2190,7 +2208,7 @@
</span><span class="cx">
</span><span class="cx"> m_vm->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->add(
</span><span class="cx"> "Jsr", "JIT Stub Routines",
</span><span class="lines">@@ -2197,18 +2215,14 @@
</span><span class="cx"> [this] (SlotVisitor& slotVisitor, const VisitingTimeout&) {
</span><span class="cx"> m_jitStubRoutines->traceMarkedStubRoutines(slotVisitor);
</span><span class="cx"> },
</span><del>- MarkingConstraint::GreyedByExecution);
</del><ins>+ ConstraintVolatility::GreyedByExecution);
</ins><span class="cx">
</span><span class="cx"> m_constraintSet->add(
</span><span class="cx"> "Ws", "Weak Sets",
</span><span class="cx"> [this] (SlotVisitor& slotVisitor, const VisitingTimeout&) {
</span><del>- slotVisitor.mergeOpaqueRootsIfNecessary();
- for (auto& parallelVisitor : m_parallelSlotVisitors)
- parallelVisitor->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->add(
</span><span class="cx"> "Wrh", "Weak Reference Harvesters",
</span><span class="lines">@@ -2216,7 +2230,7 @@
</span><span class="cx"> for (WeakReferenceHarvester* current = m_weakReferenceHarvesters.head(); current; current = current->next())
</span><span class="cx"> current->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->add(
</span><span class="lines">@@ -2236,7 +2250,7 @@
</span><span class="cx"> if (Options::logGC() == GCLogging::Verbose)
</span><span class="cx"> dataLog("DFG Worklists:\n", 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->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->add(
</span><span class="cx"> "Mrms", "Mutator+Race Mark Stack",
</span><span class="lines">@@ -2268,12 +2282,18 @@
</span><span class="cx"> [this] (SlotVisitor&) -> double {
</span><span class="cx"> return m_mutatorMarkStack->size() + m_raceMarkStack->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<MarkingConstraint> constraint)
+{
+ PreventCollectionScope preventCollectionScope(*this);
+ m_constraintSet->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& cache)
-{
- ASSERT(hasHeapAccess());
- cache = m_mutatorShouldBeFenced;
- m_mutatorShouldBeFencedCaches.append(&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 "HeapObserver.h"
</span><span class="cx"> #include "ListableHandler.h"
</span><span class="cx"> #include "MachineStackMarker.h"
</span><del>-#include "MarkedAllocator.h"
</del><span class="cx"> #include "MarkedBlock.h"
</span><span class="cx"> #include "MarkedBlockSet.h"
</span><span class="cx"> #include "MarkedSpace.h"
</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->cellState() < 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& objectSpace() { return m_objectSpace; }
</span><span class="cx"> MachineThreads& 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& subspaceForObjectWithoutDestructor() { return m_objectSpace.subspaceForObjectsWithoutDestructor(); }
- MarkedSpace::Subspace& subspaceForObjectDestructor() { return m_objectSpace.subspaceForObjectsWithDestructor(); }
- MarkedSpace::Subspace& subspaceForAuxiliaryData() { return m_objectSpace.subspaceForAuxiliaryData(); }
- template<typename ClassType> MarkedSpace::Subspace& subspaceForObjectOfType();
- MarkedAllocator* allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); }
- MarkedAllocator* allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); }
- template<typename ClassType> 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&);
</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<MarkingConstraint>);
+
+ 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<typename T> friend void* allocateCell(Heap&);
- template<typename T> friend void* allocateCell(Heap&, size_t);
- template<typename T> friend void* allocateCell(Heap&, GCDeferralContext*);
- template<typename T> friend void* allocateCell(Heap&, 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<typename ClassType> void* allocateObjectOfType(size_t); // Chooses one of the methods above based on type.
- template<typename ClassType> 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<bool(CodeBlock*)>&);
</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<typename Func>
</span><span class="cx"> void iterateExecutingAndCompilingCodeBlocks(const Func&);
</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<bool*> 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<void*> m_opaqueRoots;
</del><ins>+ HashSet<const void*> 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<Lock> m_threadLock;
</span><span class="cx"> RefPtr<AutomaticThreadCondition> m_threadCondition; // The mutator must not wait on this. It would cause a deadlock.
</span><span class="cx"> RefPtr<AutomaticThread> 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<VM*>(bitwise_cast<uintptr_t>(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->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("JSC GC allocating %lu bytes with normal destructor.\n", bytes);
-#endif
- ASSERT(isValidAllocation(bytes));
- return m_objectSpace.allocateWithDestructor(bytes);
-}
-
-inline void* Heap::allocateWithoutDestructor(size_t bytes)
-{
-#if ENABLE(ALLOCATION_LOGGING)
- dataLogF("JSC GC allocating %lu bytes without destructor.\n", 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<typename ClassType>
-inline void* Heap::allocateObjectOfType(size_t bytes)
-{
- // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
- ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value));
-
- if (ClassType::needsDestruction)
- return allocateWithDestructor(bytes);
- return allocateWithoutDestructor(bytes);
-}
-
-template<typename ClassType>
-inline void* Heap::allocateObjectOfType(GCDeferralContext* deferralContext, size_t bytes)
-{
- ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value));
-
- if (ClassType::needsDestruction)
- return allocateWithDestructor(deferralContext, bytes);
- return allocateWithoutDestructor(deferralContext, bytes);
-}
-
-template<typename ClassType>
-inline MarkedSpace::Subspace& Heap::subspaceForObjectOfType()
-{
- // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
- ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value));
-
- if (ClassType::needsDestruction)
- return subspaceForObjectDestructor();
- return subspaceForObjectWithoutDestructor();
-}
-
-template<typename ClassType>
-inline MarkedAllocator* Heap::allocatorForObjectOfType(size_t bytes)
-{
- // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject.
- ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value));
-
- MarkedAllocator* result;
- if (ClassType::needsDestruction)
- result = allocatorForObjectWithDestructor(bytes);
- else
- result = allocatorForObjectWithoutDestructor(bytes);
-
- ASSERT(result || !ClassType::info()->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("JSC GC allocating %lu bytes of auxiliary for %p: %p.\n", 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("JSC GC allocating %lu bytes of auxiliary for %p: %p.\n", 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("JSC GC allocating %lu bytes of auxiliary for %p: %p.\n", 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("JSC GC ascribing %p as owner of storage %p.\n", intendedOwner, storage);
-#else
- UNUSED_PARAM(intendedOwner);
- UNUSED_PARAM(storage);
-#endif
-}
-
</del><span class="cx"> #if USE(FOUNDATION)
</span><span class="cx"> template <typename T>
</span><span class="cx"> inline void Heap::releaseSoon(RetainPtr<T>&& 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& heap, size_t size, const AllocatorAttributes& attributes)
</del><ins>+LargeAllocation* LargeAllocation::tryCreate(Heap& 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& heap, size_t size, const AllocatorAttributes& attributes)
</del><ins>+LargeAllocation::LargeAllocation(Heap& 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->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 && !isLive()) {
</span><span class="cx"> if (m_attributes.destruction == NeedsDestruction)
</span><del>- static_cast<JSCell*>(cell())->callDestructor(*vm());
</del><ins>+ m_subspace->destroy(*vm(), static_cast<JSCell*>(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<LargeAllocation> {
</ins><span class="cx"> public:
</span><del>- static LargeAllocation* tryCreate(Heap&, size_t, const AllocatorAttributes&);
</del><ins>+ static LargeAllocation* tryCreate(Heap&, 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<LargeAllocation*>(bitwise_cast<char*>(cell) - headerSize());
</span><span class="lines">@@ -136,7 +138,7 @@
</span><span class="cx"> void dump(PrintStream&) const;
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- LargeAllocation(Heap&, size_t, const AllocatorAttributes&);
</del><ins>+ LargeAllocation(Heap&, 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<bool> 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 "Heap.h"
</span><span class="cx"> #include "IncrementalSweeper.h"
</span><span class="cx"> #include "JSCInlines.h"
</span><ins>+#include "MarkedAllocatorInlines.h"
</ins><span class="cx"> #include "MarkedBlockInlines.h"
</span><span class="cx"> #include "SuperSampler.h"
</span><span class="cx"> #include "VM.h"
</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& 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<unsigned>(cellSize))
</span><del>- , m_attributes(attributes)
</del><ins>+ , m_attributes(subspace->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"> && shouldStealEmptyBlocksFromOtherAllocators()) {
</span><del>- if (MarkedBlock::Handle* block = m_markedSpace->findEmptyBlockToSteal()) {
</del><ins>+ if (MarkedBlock::Handle* block = markedSpace().findEmptyBlockToSteal()) {
</ins><span class="cx"> block->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->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->vm()->currentThreadIsHoldingAPILock());
</span><span class="cx"> doTestCollectionsIfNeeded(deferralContext);
</span><span class="cx">
</span><del>- ASSERT(!m_markedSpace->isIterating());
</del><ins>+ ASSERT(!markedSpace().isIterating());
</ins><span class="cx"> m_heap->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->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"> [&] (size_t index) {
</span><del>- m_markedSpace->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& MarkedAllocator::markedSpace() const
+{
+ return m_subspace->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&);
</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<typename Functor> void forEachBlock(const Functor&);
</span><ins>+ template<typename Functor> void forEachNotEmptyBlock(const Functor&);
</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& markedSpace() const;
+
</ins><span class="cx"> void dump(PrintStream&) const;
</span><span class="cx"> void dumpBits(PrintStream& = 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->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->next;
- return head;
-}
-
-template <typename Functor> inline void MarkedAllocator::forEachBlock(const Functor& functor)
-{
- m_live.forEachSetBit(
- [&] (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 "MarkedAllocator.h"
+
+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->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->next;
+ return head;
+}
+
+template <typename Functor> inline void MarkedAllocator::forEachBlock(const Functor& functor)
+{
+ m_live.forEachSetBit(
+ [&] (size_t index) {
+ functor(m_blocks[index]);
+ });
+}
+
+template <typename Functor> inline void MarkedAllocator::forEachNotEmptyBlock(const Functor& functor)
+{
+ m_markingNotEmpty.forEachSetBit(
+ [&] (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), ": Allocated.\n");
</span><span class="cx"> }
</span><span class="cx">
</span><del>-template<MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepMode sweepMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode, MarkedBlock::Handle::NewlyAllocatedMode newlyAllocatedMode, MarkedBlock::Handle::MarksMode marksMode>
-FreeList MarkedBlock::Handle::specializedSweep()
-{
- RELEASE_ASSERT(!(destructionMode == BlockHasNoDestructors && sweepMode == SweepOnly));
-
- SuperSamplerScope superSamplerScope(false);
-
- MarkedBlock& block = this->block();
-
- if (false)
- dataLog(RawPointer(this), "/", RawPointer(&block), ": MarkedBlock::Handle::specializedSweep!\n");
-
- if (Options::useBumpAllocator()
- && emptyMode == IsEmpty
- && newlyAllocatedMode == DoesNotHaveNewlyAllocated) {
-
- // This is an incredibly powerful assertion that checks the sanity of our block bits.
- if (marksMode == MarksNotStale && !block.m_marks.isEmpty()) {
- WTF::dataFile().atomically(
- [&] (PrintStream& out) {
- out.print("Block ", RawPointer(&block), ": marks not empty!\n");
- out.print("Block lock is held: ", block.m_lock.isHeld(), "\n");
- out.print("Marking version of block: ", block.m_markingVersion, "\n");
- out.print("Marking version of heap: ", space()->markingVersion(), "\n");
- UNREACHABLE_FOR_PLATFORM();
- });
- }
-
- char* startOfLastCell = static_cast<char*>(cellAlign(block.atoms() + m_endAtom - 1));
- char* payloadEnd = startOfLastCell + cellSize();
- RELEASE_ASSERT(payloadEnd - MarkedBlock::blockSize <= bitwise_cast<char*>(&block));
- char* payloadBegin = bitwise_cast<char*>(block.atoms() + firstAtom());
- if (scribbleMode == Scribble)
- scribble(payloadBegin, payloadEnd - payloadBegin);
- if (sweepMode == SweepToFreeList)
- setIsFreeListed();
- else
- m_allocator->setIsEmpty(NoLockingNecessary, this, true);
- if (space()->isMarking())
- block.m_lock.unlock();
- FreeList result = FreeList::bump(payloadEnd, payloadEnd - payloadBegin);
- if (false)
- dataLog("Quickly swept block ", RawPointer(this), " with cell size ", cellSize(), " and attributes ", m_attributes, ": ", result, "\n");
- 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<size_t> deadCells;
- auto handleDeadCell = [&] (size_t i) {
- HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&block.atoms()[i]);
-
- if (destructionMode != BlockHasNoDestructors && emptyMode == NotEmpty)
- static_cast<JSCell*>(cell)->callDestructor(*vm());
-
- if (sweepMode == SweepToFreeList) {
- FreeCell* freeCell = reinterpret_cast_ptr<FreeCell*>(cell);
- if (scribbleMode == Scribble)
- scribble(freeCell, cellSize());
- freeCell->next = head;
- head = freeCell;
- ++count;
- }
- };
- for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
- if (emptyMode == NotEmpty
- && ((marksMode == MarksNotStale && block.m_marks.get(i))
- || (newlyAllocatedMode == HasNewlyAllocated && 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 && newlyAllocatedMode == HasNewlyAllocated)
- m_newlyAllocatedVersion = MarkedSpace::nullVersion;
-
- if (space()->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->setIsEmpty(NoLockingNecessary, this, true);
- if (false)
- dataLog("Slowly swept block ", RawPointer(&block), " with cell size ", cellSize(), " and attributes ", m_attributes, ": ", result, "\n");
- return result;
-}
-
-FreeList MarkedBlock::Handle::sweep(SweepMode sweepMode)
-{
- // FIXME: Maybe HelpingGCScope should just be called SweepScope?
- HelpingGCScope helpingGCScope(*heap());
-
- m_allocator->setIsUnswept(NoLockingNecessary, this, false);
-
- m_weakSet.sweep();
-
- if (sweepMode == SweepOnly && m_attributes.destruction == DoesNotNeedDestruction)
- return FreeList();
-
- if (UNLIKELY(m_isFreeListed)) {
- RELEASE_ASSERT(sweepMode == SweepToFreeList);
- return FreeList();
- }
-
- ASSERT(!m_allocator->isAllocated(NoLockingNecessary, this));
-
- if (space()->isMarking())
- block().m_lock.lock();
-
- if (m_attributes.destruction == NeedsDestruction) {
- if (space()->isMarking())
- return sweepHelperSelectScribbleMode<BlockHasDestructorsAndCollectorIsRunning>(sweepMode);
- return sweepHelperSelectScribbleMode<BlockHasDestructors>(sweepMode);
- }
- return sweepHelperSelectScribbleMode<BlockHasNoDestructors>(sweepMode);
-}
-
-template<MarkedBlock::Handle::SweepDestructionMode destructionMode>
-FreeList MarkedBlock::Handle::sweepHelperSelectScribbleMode(SweepMode sweepMode)
-{
- if (scribbleFreeCells())
- return sweepHelperSelectEmptyMode<destructionMode, Scribble>(sweepMode);
- return sweepHelperSelectEmptyMode<destructionMode, DontScribble>(sweepMode);
-}
-
-template<MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode>
-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->isEmpty(NoLockingNecessary, this))
- return sweepHelperSelectHasNewlyAllocated<IsEmpty, destructionMode, scribbleMode>(sweepMode);
- return sweepHelperSelectHasNewlyAllocated<NotEmpty, destructionMode, scribbleMode>(sweepMode);
-}
-
-template<MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode>
-FreeList MarkedBlock::Handle::sweepHelperSelectHasNewlyAllocated(SweepMode sweepMode)
-{
- if (hasAnyNewlyAllocated())
- return sweepHelperSelectSweepMode<emptyMode, destructionMode, scribbleMode, HasNewlyAllocated>(sweepMode);
- return sweepHelperSelectSweepMode<emptyMode, destructionMode, scribbleMode, DoesNotHaveNewlyAllocated>(sweepMode);
-}
-
-template<MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode, MarkedBlock::Handle::NewlyAllocatedMode newlyAllocatedMode>
-FreeList MarkedBlock::Handle::sweepHelperSelectSweepMode(SweepMode sweepMode)
-{
- if (sweepMode == SweepToFreeList)
- return sweepHelperSelectMarksMode<emptyMode, SweepToFreeList, destructionMode, scribbleMode, newlyAllocatedMode>();
- return sweepHelperSelectMarksMode<emptyMode, SweepOnly, destructionMode, scribbleMode, newlyAllocatedMode>();
-}
-
-template<MarkedBlock::Handle::EmptyMode emptyMode, MarkedBlock::Handle::SweepMode sweepMode, MarkedBlock::Handle::SweepDestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode, MarkedBlock::Handle::NewlyAllocatedMode newlyAllocatedMode>
-FreeList MarkedBlock::Handle::sweepHelperSelectMarksMode()
-{
- HeapVersion markingVersion = space()->markingVersion();
- bool marksAreUseful = !block().areMarksStale(markingVersion);
-
- if (space()->isMarking())
- marksAreUseful |= block().marksConveyLivenessDuringMarking(markingVersion);
-
- if (!marksAreUseful)
- return specializedSweep<emptyMode, sweepMode, destructionMode, scribbleMode, newlyAllocatedMode, MarksStale>();
- return specializedSweep<emptyMode, sweepMode, destructionMode, scribbleMode, newlyAllocatedMode, MarksNotStale>();
-}
-
</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()->subspace();
+}
+
+FreeList MarkedBlock::Handle::sweep(SweepMode sweepMode)
+{
+ // FIXME: Maybe HelpingGCScope should just be called SweepScope?
+ HelpingGCScope helpingGCScope(*heap());
+
+ m_allocator->setIsUnswept(NoLockingNecessary, this, false);
+
+ m_weakSet.sweep();
+
+ if (sweepMode == SweepOnly && m_attributes.destruction == DoesNotNeedDestruction)
+ return FreeList();
+
+ if (UNLIKELY(m_isFreeListed)) {
+ RELEASE_ASSERT(sweepMode == SweepToFreeList);
+ return FreeList();
+ }
+
+ ASSERT(!m_allocator->isAllocated(NoLockingNecessary, this));
+
+ if (space()->isMarking())
+ block().m_lock.lock();
+
+ if (m_attributes.destruction == NeedsDestruction)
+ return subspace()->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->emptyMode();
+ ScribbleMode scribbleMode = this->scribbleMode();
+ NewlyAllocatedMode newlyAllocatedMode = this->newlyAllocatedMode();
+ MarksMode marksMode = this->marksMode();
+
+ FreeList result;
+ auto trySpecialized = [&] () -> 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<true, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, [] (VM&, JSCell*) { });
+ return true;
+ case MarksStale:
+ result = specializedSweep<true, IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, [] (VM&, JSCell*) { });
+ return true;
+ }
+ break;
+ case NotEmpty:
+ switch (marksMode) {
+ case MarksNotStale:
+ result = specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, [] (VM&, JSCell*) { });
+ return true;
+ case MarksStale:
+ result = specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(IsEmpty, SweepToFreeList, BlockHasNoDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale, [] (VM&, JSCell*) { });
+ return true;
+ }
+ break;
+ }
+
+ return false;
+ };
+
+ if (trySpecialized())
+ return result;
+
+ // The template arguments don't matter because the first one is false.
+ return specializedSweep<false, IsEmpty, SweepOnly, BlockHasNoDestructors, DontScribble, HasNewlyAllocated, MarksStale>(emptyMode, sweepMode, BlockHasNoDestructors, scribbleMode, newlyAllocatedMode, marksMode, [] (VM&, 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<typename DestroyFunc>
+ FreeList finishSweepKnowingSubspace(SweepMode, const DestroyFunc&);
+
</ins><span class="cx"> void unsweepWithNoNewlyAllocated();
</span><span class="cx">
</span><span class="cx"> void zap(const FreeList&);
</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&);
</del><ins>+ void visitWeakSet(SlotVisitor&);
</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 <typename Functor> IterationStatus forEachCell(const Functor&);
</span><span class="cx"> template <typename Functor> inline IterationStatus forEachLiveCell(const Functor&);
</span><span class="cx"> template <typename Functor> inline IterationStatus forEachDeadCell(const Functor&);
</span><ins>+ template <typename Functor> inline IterationStatus forEachMarkedCell(const Functor&);
</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&, void*);
</span><span class="cx">
</span><span class="cx"> enum SweepDestructionMode { BlockHasNoDestructors, BlockHasDestructors, BlockHasDestructorsAndCollectorIsRunning };
</span><del>-
- template<SweepDestructionMode>
- FreeList sweepHelperSelectScribbleMode(SweepMode = SweepOnly);
-
</del><span class="cx"> enum ScribbleMode { DontScribble, Scribble };
</span><del>-
- template<SweepDestructionMode, ScribbleMode>
- FreeList sweepHelperSelectEmptyMode(SweepMode = SweepOnly);
-
</del><span class="cx"> enum EmptyMode { IsEmpty, NotEmpty };
</span><del>-
- template<EmptyMode, SweepDestructionMode, ScribbleMode>
- 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<EmptyMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode>
- FreeList sweepHelperSelectSweepMode(SweepMode = SweepOnly);
</del><ins>+ SweepDestructionMode sweepDestructionMode();
+ EmptyMode emptyMode();
+ ScribbleMode scribbleMode();
+ NewlyAllocatedMode newlyAllocatedMode();
+ MarksMode marksMode();
</ins><span class="cx">
</span><del>- template<EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode>
- FreeList sweepHelperSelectMarksMode();
</del><ins>+ template<bool, EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode, MarksMode, typename DestroyFunc>
+ FreeList specializedSweep(EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode, MarksMode, const DestroyFunc&);
</ins><span class="cx">
</span><del>- enum MarksMode { MarksStale, MarksNotStale };
-
- template<EmptyMode, SweepMode, SweepDestructionMode, ScribbleMode, NewlyAllocatedMode, MarksMode>
- FreeList specializedSweep();
-
</del><span class="cx"> template<typename Func>
</span><span class="cx"> void forEachFreeCell(const FreeList&, const Func&);
</span><span class="cx">
</span><span class="lines">@@ -282,7 +276,7 @@
</span><span class="cx">
</span><span class="cx"> WeakSet& 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& visitor)
</del><ins>+inline void MarkedBlock::Handle::visitWeakSet(SlotVisitor& 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 "JSCell.h"
</ins><span class="cx"> #include "MarkedAllocator.h"
</span><span class="cx"> #include "MarkedBlock.h"
</span><span class="cx"> #include "MarkedSpace.h"
</span><ins>+#include "Operations.h"
+#include "SuperSampler.h"
</ins><span class="cx"> #include "VM.h"
</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()->newlyAllocatedVersion();
+}
+
+inline bool MarkedBlock::Handle::hasAnyNewlyAllocated()
+{
+ return !isNewlyAllocatedStale();
+}
+
+inline Heap* MarkedBlock::heap() const
+{
+ return &vm()->heap;
+}
+
+inline MarkedSpace* MarkedBlock::space() const
+{
+ return &heap()->objectSpace();
+}
+
+inline MarkedSpace* MarkedBlock::Handle::space() const
+{
+ return &heap()->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<const HeapCell*>(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<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>
+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& destroyFunc)
</ins><span class="cx"> {
</span><del>- return m_newlyAllocatedVersion != space()->newlyAllocatedVersion();
</del><ins>+ if (specialize) {
+ emptyMode = specializedEmptyMode;
+ sweepMode = specializedSweepMode;
+ destructionMode = specializedDestructionMode;
+ scribbleMode = specializedScribbleMode;
+ newlyAllocatedMode = specializedNewlyAllocatedMode;
+ marksMode = specializedMarksMode;
+ }
+
+ RELEASE_ASSERT(!(destructionMode == BlockHasNoDestructors && sweepMode == SweepOnly));
+
+ SuperSamplerScope superSamplerScope(false);
+
+ MarkedBlock& block = this->block();
+
+ if (false)
+ dataLog(RawPointer(this), "/", RawPointer(&block), ": MarkedBlock::Handle::specializedSweep!\n");
+
+ if (Options::useBumpAllocator()
+ && emptyMode == IsEmpty
+ && newlyAllocatedMode == DoesNotHaveNewlyAllocated) {
+
+ // This is an incredibly powerful assertion that checks the sanity of our block bits.
+ if (marksMode == MarksNotStale && !block.m_marks.isEmpty()) {
+ WTF::dataFile().atomically(
+ [&] (PrintStream& out) {
+ out.print("Block ", RawPointer(&block), ": marks not empty!\n");
+ out.print("Block lock is held: ", block.m_lock.isHeld(), "\n");
+ out.print("Marking version of block: ", block.m_markingVersion, "\n");
+ out.print("Marking version of heap: ", space()->markingVersion(), "\n");
+ UNREACHABLE_FOR_PLATFORM();
+ });
+ }
+
+ char* startOfLastCell = static_cast<char*>(cellAlign(block.atoms() + m_endAtom - 1));
+ char* payloadEnd = startOfLastCell + cellSize();
+ RELEASE_ASSERT(payloadEnd - MarkedBlock::blockSize <= bitwise_cast<char*>(&block));
+ char* payloadBegin = bitwise_cast<char*>(block.atoms() + firstAtom());
+ if (scribbleMode == Scribble)
+ scribble(payloadBegin, payloadEnd - payloadBegin);
+ if (sweepMode == SweepToFreeList)
+ setIsFreeListed();
+ else
+ m_allocator->setIsEmpty(NoLockingNecessary, this, true);
+ if (space()->isMarking())
+ block.m_lock.unlock();
+ FreeList result = FreeList::bump(payloadEnd, payloadEnd - payloadBegin);
+ if (false)
+ dataLog("Quickly swept block ", RawPointer(this), " with cell size ", cellSize(), " and attributes ", m_attributes, ": ", result, "\n");
+ 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<size_t> deadCells;
+ VM& vm = *this->vm();
+ auto handleDeadCell = [&] (size_t i) {
+ HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&block.atoms()[i]);
+
+ if (destructionMode != BlockHasNoDestructors && emptyMode == NotEmpty) {
+ JSCell* jsCell = static_cast<JSCell*>(cell);
+ if (!jsCell->isZapped()) {
+ destroyFunc(vm, jsCell);
+ jsCell->zap();
+ }
+ }
+
+ if (sweepMode == SweepToFreeList) {
+ FreeCell* freeCell = reinterpret_cast_ptr<FreeCell*>(cell);
+ if (scribbleMode == Scribble)
+ scribble(freeCell, cellSize());
+ freeCell->next = head;
+ head = freeCell;
+ ++count;
+ }
+ };
+ for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
+ if (emptyMode == NotEmpty
+ && ((marksMode == MarksNotStale && block.m_marks.get(i))
+ || (newlyAllocatedMode == HasNewlyAllocated && 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 && newlyAllocatedMode == HasNewlyAllocated)
+ m_newlyAllocatedVersion = MarkedSpace::nullVersion;
+
+ if (space()->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->setIsEmpty(NoLockingNecessary, this, true);
+ if (false)
+ dataLog("Slowly swept block ", RawPointer(&block), " with cell size ", cellSize(), " and attributes ", m_attributes, ": ", result, "\n");
+ return result;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-inline bool MarkedBlock::Handle::hasAnyNewlyAllocated()
</del><ins>+template<typename DestroyFunc>
+FreeList MarkedBlock::Handle::finishSweepKnowingSubspace(SweepMode sweepMode, const DestroyFunc& destroyFunc)
</ins><span class="cx"> {
</span><del>- return !isNewlyAllocatedStale();
</del><ins>+ SweepDestructionMode destructionMode = this->sweepDestructionMode();
+ EmptyMode emptyMode = this->emptyMode();
+ ScribbleMode scribbleMode = this->scribbleMode();
+ NewlyAllocatedMode newlyAllocatedMode = this->newlyAllocatedMode();
+ MarksMode marksMode = this->marksMode();
+
+ FreeList result;
+ auto trySpecialized = [&] () -> 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<true, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale>(IsEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksNotStale, destroyFunc);
+ return true;
+ case MarksStale:
+ result = specializedSweep<true, NotEmpty, SweepToFreeList, BlockHasDestructors, DontScribble, DoesNotHaveNewlyAllocated, MarksStale>(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<false, IsEmpty, SweepOnly, BlockHasNoDestructors, DontScribble, HasNewlyAllocated, MarksStale>(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()->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->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()->markingVersion();
+ bool marksAreUseful = !block().areMarksStale(markingVersion);
+ if (space()->isMarking())
+ marksAreUseful |= block().marksConveyLivenessDuringMarking(markingVersion);
+ return marksAreUseful ? MarksNotStale : MarksStale;
+}
+
</ins><span class="cx"> template <typename Functor>
</span><span class="cx"> inline IterationStatus MarkedBlock::Handle::forEachLiveCell(const Functor& 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 <typename Functor>
+inline IterationStatus MarkedBlock::Handle::forEachMarkedCell(const Functor& functor)
</ins><span class="cx"> {
</span><del>- return &vm()->heap;
-}
</del><ins>+ HeapCell::Kind kind = m_attributes.cellKind;
+ MarkedBlock& block = this->block();
+ bool areMarksStale = block.areMarksStale();
+ WTF::loadLoadFence();
+ if (areMarksStale)
+ return IterationStatus::Continue;
+ for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
+ HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&m_block->atoms()[i]);
+ if (!block.isMarkedRaw(cell))
+ continue;
</ins><span class="cx">
</span><del>-inline MarkedSpace* MarkedBlock::space() const
-{
- return &heap()->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 &heap()->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 <eric@webkit.org>
</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 "IncrementalSweeper.h"
</span><span class="cx"> #include "JSObject.h"
</span><span class="cx"> #include "JSCInlines.h"
</span><ins>+#include "MarkedAllocatorInlines.h"
</ins><span class="cx"> #include "MarkedBlockInlines.h"
</span><span class="cx"> #include <wtf/ListDump.h>
</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,
- [&] (size_t sizeClass) -> size_t {
- return sizeClass;
- },
- [&] (size_t sizeClass) -> size_t {
- return sizeClass;
</del><ins>+ static std::once_flag flag;
+ std::call_once(
+ flag,
+ [] {
+ buildSizeClassTable(
+ s_sizeClassForSizeStep,
+ [&] (size_t sizeClass) -> size_t {
+ return sizeClass;
+ },
+ [&] (size_t sizeClass) -> 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(
- [&] (Subspace& subspace, AllocatorAttributes attributes) -> IterationStatus {
- subspace.attributes = attributes;
-
- buildSizeClassTable(
- subspace.allocatorForSizeStep,
- [&] (size_t sizeClass) -> MarkedAllocator* {
- return subspace.bagOfAllocators.add(heap, this, sizeClass, attributes);
- },
- [&] (size_t) -> MarkedAllocator* {
- return nullptr;
- });
-
- return IterationStatus::Continue;
- });
-
- MarkedAllocator* previous = nullptr;
- forEachSubspace(
- [&] (Subspace& subspace, AllocatorAttributes) -> IterationStatus {
- for (MarkedAllocator* allocator : subspace.bagOfAllocators) {
- allocator->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"> [&] (MarkedAllocator& allocator) -> IterationStatus {
</span><span class="cx"> allocator.lastChanceToFinalize();
</span><span class="lines">@@ -245,72 +218,6 @@
</span><span class="cx"> allocation->lastChanceToFinalize();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void* MarkedSpace::allocate(Subspace& subspace, size_t bytes)
-{
- if (false)
- dataLog("Allocating ", bytes, " bytes in ", subspace.attributes, ".\n");
- if (MarkedAllocator* allocator = allocatorFor(subspace, bytes)) {
- void* result = allocator->allocate();
- return result;
- }
- return allocateLarge(subspace, nullptr, bytes);
-}
-
-void* MarkedSpace::allocate(Subspace& subspace, GCDeferralContext* deferralContext, size_t bytes)
-{
- if (false)
- dataLog("Allocating ", bytes, " deferred bytes in ", subspace.attributes, ".\n");
- if (MarkedAllocator* allocator = allocatorFor(subspace, bytes)) {
- void* result = allocator->allocate(deferralContext);
- return result;
- }
- return allocateLarge(subspace, deferralContext, bytes);
-}
-
-void* MarkedSpace::tryAllocate(Subspace& subspace, size_t bytes)
-{
- if (false)
- dataLog("Try-allocating ", bytes, " bytes in ", subspace.attributes, ".\n");
- if (MarkedAllocator* allocator = allocatorFor(subspace, bytes)) {
- void* result = allocator->tryAllocate();
- return result;
- }
- return tryAllocateLarge(subspace, nullptr, bytes);
-}
-
-void* MarkedSpace::tryAllocate(Subspace& subspace, GCDeferralContext* deferralContext, size_t bytes)
-{
- if (false)
- dataLog("Try-allocating ", bytes, " deferred bytes in ", subspace.attributes, ".\n");
- if (MarkedAllocator* allocator = allocatorFor(subspace, bytes)) {
- void* result = allocator->tryAllocate(deferralContext);
- return result;
- }
- return tryAllocateLarge(subspace, deferralContext, bytes);
-}
-
-void* MarkedSpace::allocateLarge(Subspace& subspace, GCDeferralContext* deferralContext, size_t size)
-{
- void* result = tryAllocateLarge(subspace, deferralContext, size);
- RELEASE_ASSERT(result);
- return result;
-}
-
-void* MarkedSpace::tryAllocateLarge(Subspace& subspace, GCDeferralContext* deferralContext, size_t size)
-{
- m_heap->collectIfNecessaryOrDefer(deferralContext);
-
- size = WTF::roundUpToMultipleOf<sizeStep>(size);
- LargeAllocation* allocation = LargeAllocation::tryCreate(*m_heap, size, subspace.attributes);
- if (!allocation)
- return nullptr;
-
- m_largeAllocations.append(allocation);
- m_heap->didAllocate(size);
- m_capacity += size;
- return allocation->cell();
-}
-
</del><span class="cx"> void MarkedSpace::sweep()
</span><span class="cx"> {
</span><span class="cx"> m_heap->sweeper()->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&, Subspace* subspace, size_t sizeClass)
+{
+ MarkedAllocator* allocator = m_bagOfAllocators.add(heap(), subspace, sizeClass);
+ allocator->setNextAllocator(nullptr);
+
+ WTF::storeStoreFence();
+
+ if (!m_firstAllocator) {
+ m_firstAllocator = allocator;
+ m_lastAllocator = allocator;
+ m_allocatorForEmptyAllocation = allocator;
+ } else {
+ m_lastAllocator->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 "class" 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<MarkedAllocator*, numSizeClasses> allocatorForSizeStep;
-
- // Each MarkedAllocator is a size class.
- Bag<MarkedAllocator> 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&, size_t);
-
- MarkedAllocator* allocatorFor(size_t);
- MarkedAllocator* destructorAllocatorFor(size_t);
- MarkedAllocator* auxiliaryAllocatorFor(size_t);
-
- JS_EXPORT_PRIVATE void* allocate(Subspace&, size_t);
- JS_EXPORT_PRIVATE void* allocate(Subspace&, GCDeferralContext*, size_t);
- JS_EXPORT_PRIVATE void* tryAllocate(Subspace&, size_t);
- JS_EXPORT_PRIVATE void* tryAllocate(Subspace&, 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& subspaceForObjectsWithDestructor() { return m_destructorSpace; }
- Subspace& subspaceForObjectsWithoutDestructor() { return m_normalSpace; }
- Subspace& subspaceForAuxiliaryData() { return m_auxiliarySpace; }
-
</del><span class="cx"> void prepareForAllocation();
</span><span class="cx">
</span><span class="cx"> void visitWeakSets(SlotVisitor&);
</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& allocatorLock() { return m_allocatorLock; }
+ MarkedAllocator* addMarkedAllocator(const AbstractLocker&, 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& = WTF::dataFile());
</span><span class="cx">
</span><ins>+ JS_EXPORT_PRIVATE static std::array<size_t, numSizeClasses> 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<size_t, numSizeClasses> s_sizeClassForSizeStep;
-
- void* allocateLarge(Subspace&, GCDeferralContext*, size_t);
- void* tryAllocateLarge(Subspace&, GCDeferralContext*, size_t);
</del><ins>+ void* allocateSlow(Subspace&, GCDeferralContext*, size_t);
+ void* tryAllocateSlow(Subspace&, 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&);
</span><span class="cx">
</span><span class="cx"> template<typename Functor> inline void forEachAllocator(const Functor&);
</span><del>- template<typename Functor> inline void forEachSubspace(const Functor&);
</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<Subspace*> m_subspaces;
</ins><span class="cx">
</span><ins>+ Vector<LargeAllocation*> 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<LargeAllocation*> 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<WeakSet, BasicRawSentinelNode<WeakSet>> m_activeWeakSets;
</span><span class="cx"> SentinelLinkedList<WeakSet, BasicRawSentinelNode<WeakSet>> m_newActiveWeakSets;
</span><del>-
</del><ins>+
+ Lock m_allocatorLock;
+ Bag<MarkedAllocator> 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& space, size_t bytes)
-{
- ASSERT(bytes);
- if (bytes <= 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 <typename Functor> inline void MarkedSpace::forEachBlock(const Functor& 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<typename Functor>
-inline void MarkedSpace::forEachSubspace(const Functor& 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<void(SlotVisitor&, const VisitingTimeout&)> 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<void(SlotVisitor&, const VisitingTimeout&)> executeFunction,
</span><span class="cx"> ::Function<double(SlotVisitor&)> 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 "ConstraintVolatility.h"
</ins><span class="cx"> #include "VisitingTimeout.h"
</span><span class="cx"> #include <wtf/FastMalloc.h>
</span><span class="cx"> #include <wtf/Function.h>
</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 "root" 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<void(SlotVisitor&, const VisitingTimeout&)>,
</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<void(SlotVisitor&, const VisitingTimeout&)>,
</span><span class="cx"> ::Function<double(SlotVisitor&)>,
</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<void(SlotVisitor&, const VisitingTimeout& timeout)> m_executeFunction;
</span><span class="cx"> ::Function<double(SlotVisitor&)> 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& constraint : m_set) {
</span><span class="cx"> constraint->resetStats();
</span><span class="cx"> switch (constraint->volatility()) {
</span><del>- case MarkingConstraint::GreyedByExecution:
</del><ins>+ case ConstraintVolatility::GreyedByExecution:
</ins><span class="cx"> m_unexecutedRoots.set(constraint->index());
</span><span class="cx"> break;
</span><del>- case MarkingConstraint::GreyedByMarking:
</del><ins>+ case ConstraintVolatility::GreyedByMarking:
</ins><span class="cx"> m_unexecutedOutgrowths.set(constraint->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<void(SlotVisitor&, const VisitingTimeout&)> function, MarkingConstraint::Volatility volatility)
</del><ins>+void MarkingConstraintSet::add(CString abbreviatedName, CString name, Function<void(SlotVisitor&, const VisitingTimeout&)> function, ConstraintVolatility volatility)
</ins><span class="cx"> {
</span><span class="cx"> add(std::make_unique<MarkingConstraint>(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<void(SlotVisitor&, const VisitingTimeout&)> executeFunction,
</span><span class="cx"> Function<double(SlotVisitor&)> quickWorkEstimateFunction,
</span><del>- MarkingConstraint::Volatility volatility)
</del><ins>+ ConstraintVolatility volatility)
</ins><span class="cx"> {
</span><span class="cx"> add(std::make_unique<MarkingConstraint>(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->m_index = m_set.size();
</span><span class="cx"> m_ordered.append(constraint.get());
</span><del>- if (constraint->volatility() == MarkingConstraint::GreyedByMarking)
</del><ins>+ if (constraint->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"> [&] (MarkingConstraint* a, MarkingConstraint* b) -> bool {
</span><span class="cx"> // Remember: return true if a should come before b.
</span><del>- if (a->volatility() != b->volatility()) {
</del><ins>+
+ auto volatilityScore = [] (MarkingConstraint* constraint) -> unsigned {
+ return constraint->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->volatility() > b->volatility(); // GreyedByMarking should come before GreyedByExecution.
</del><ins>+ return aVolatilityScore > bVolatilityScore;
</ins><span class="cx"> else
</span><del>- return a->volatility() < b->volatility(); // GreyedByExecution should come before GreyedByMarking.
</del><ins>+ return aVolatilityScore < bVolatilityScore;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- return a->workEstimate(visitor) > b->workEstimate(visitor);
</del><ins>+ double aWorkEstimate = a->workEstimate(visitor);
+ double bWorkEstimate = b->workEstimate(visitor);
+
+ if (aWorkEstimate != bWorkEstimate)
+ return aWorkEstimate > bWorkEstimate;
+
+ // This causes us to use SeldomGreyed vs GreyedByExecution as a final tie-breaker.
+ return a->volatility() > b->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<void(SlotVisitor&, const VisitingTimeout&)>,
</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<void(SlotVisitor&, const VisitingTimeout&)>,
</span><span class="cx"> ::Function<double(SlotVisitor&)>,
</span><del>- MarkingConstraint::Volatility);
</del><ins>+ ConstraintVolatility);
</ins><span class="cx">
</span><span class="cx"> void add(std::unique_ptr<MarkingConstraint>);
</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&, 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&,
</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& 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("Visiting ", RawPointer(cell));
</span><del>- if (m_isVisitingMutatorStack)
- dataLog(" (mutator)");
</del><ins>+ if (!m_isFirstVisit)
+ dataLog(" (subsequent)");
</ins><span class="cx"> dataLog("\n");
</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->appendNode(const_cast<JSCell*>(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& from, MarkStackArray& 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() && 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() && 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<unsigned>(m_opaqueRoots.size()) < 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<T>& 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& 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()->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()->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 "config.h"
+#include "Subspace.h"
+
+#include "JSCInlines.h"
+#include "MarkedAllocatorInlines.h"
+#include "MarkedBlockInlines.h"
+#include "PreventCollectionScope.h"
+#include "SubspaceInlines.h"
+
+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& vm, JSCell* cell) const
+ {
+ ASSERT(cell->structureID());
+ ASSERT(cell->inlineTypeFlags() & StructureIsImmortal);
+ Structure* structure = cell->structure(vm);
+ const ClassInfo* classInfo = structure->classInfo();
+ MethodTable::DestroyFunctionPtr destroy = classInfo->methodTable.destroy;
+ destroy(cell);
+ }
+};
+
+} // anonymous namespace
+
+Subspace::Subspace(CString name, Heap& 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& block, MarkedBlock::Handle::SweepMode sweepMode)
+{
+ return block.finishSweepKnowingSubspace(sweepMode, DestroyFunc());
+}
+
+void Subspace::destroy(VM& 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->allocate();
+ return allocateSlow(nullptr, size);
+}
+
+void* Subspace::allocate(GCDeferralContext* deferralContext, size_t size)
+{
+ if (MarkedAllocator* allocator = tryAllocatorFor(size))
+ return allocator->allocate(deferralContext);
+ return allocateSlow(deferralContext, size);
+}
+
+void* Subspace::tryAllocate(size_t size)
+{
+ if (MarkedAllocator* allocator = tryAllocatorFor(size))
+ return allocator->tryAllocate();
+ return tryAllocateSlow(nullptr, size);
+}
+
+void* Subspace::tryAllocate(GCDeferralContext* deferralContext, size_t size)
+{
+ if (MarkedAllocator* allocator = tryAllocatorFor(size))
+ return allocator->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 "please always take the slow path". 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 "forEachAllocator" 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("Creating marked allocator for ", m_name, ", ", m_attributes, ", ", sizeClass, ".\n");
+ 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->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->tryAllocate(deferralContext);
+
+ if (size <= Options::largeAllocationCutoff()
+ && size <= MarkedSpace::largeCutoff) {
+ dataLog("FATAL: attampting to allocate small object using large allocation.\n");
+ dataLog("Requested allocation size: ", size, "\n");
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ m_space.heap()->collectIfNecessaryOrDefer(deferralContext);
+
+ size = WTF::roundUpToMultipleOf<MarkedSpace::sizeStep>(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->didAllocate(size);
+ m_space.m_capacity += size;
+
+ m_largeAllocations.append(allocation);
+
+ return allocation->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 "MarkedBlock.h"
+#include "MarkedSpace.h"
+#include <wtf/text/CString.h>
+
+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&, AllocatorAttributes);
+ JS_EXPORT_PRIVATE virtual ~Subspace();
+
+ const char *name() const { return m_name.data(); }
+ MarkedSpace& space() const { return m_space; }
+
+ const AllocatorAttributes& 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&, MarkedBlock::Handle::SweepMode);
+
+ // These get called for large objects.
+ virtual void destroy(VM&, 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<typename Func>
+ void forEachMarkedBlock(const Func&);
+
+ template<typename Func>
+ void forEachNotEmptyMarkedBlock(const Func&);
+
+ template<typename Func>
+ void forEachLargeAllocation(const Func&);
+
+ template<typename Func>
+ void forEachMarkedCell(const Func&);
+
+ static ptrdiff_t offsetOfAllocatorForSizeStep() { return OBJECT_OFFSETOF(Subspace, m_allocatorForSizeStep); }
+
+ MarkedAllocator** allocatorForSizeStep() { return &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& m_space;
+
+ CString m_name;
+ AllocatorAttributes m_attributes;
+
+ std::array<MarkedAllocator*, MarkedSpace::numSizeClasses> m_allocatorForSizeStep;
+ MarkedAllocator* m_firstAllocator { nullptr };
+ SentinelLinkedList<LargeAllocation, BasicRawSentinelNode<LargeAllocation>> m_largeAllocations;
+};
+
+ALWAYS_INLINE MarkedAllocator* Subspace::tryAllocatorFor(size_t size)
+{
+ if (size <= MarkedSpace::largeCutoff)
+ return m_allocatorForSizeStep[MarkedSpace::sizeClassToIndex(size)];
+ return nullptr;
+}
+
+ALWAYS_INLINE MarkedAllocator* Subspace::allocatorFor(size_t size)
+{
+ if (size <= 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 "JSCell.h"
+#include "MarkedAllocator.h"
+#include "MarkedBlock.h"
+#include "MarkedSpace.h"
+#include "Subspace.h"
+
+namespace JSC {
+
+template<typename Func>
+void Subspace::forEachMarkedBlock(const Func& func)
+{
+ for (MarkedAllocator* allocator = m_firstAllocator; allocator; allocator = allocator->nextAllocatorInSubspace())
+ allocator->forEachBlock(func);
+}
+
+template<typename Func>
+void Subspace::forEachNotEmptyMarkedBlock(const Func& func)
+{
+ for (MarkedAllocator* allocator = m_firstAllocator; allocator; allocator = allocator->nextAllocatorInSubspace())
+ allocator->forEachNotEmptyBlock(func);
+}
+
+template<typename Func>
+void Subspace::forEachLargeAllocation(const Func& func)
+{
+ for (LargeAllocation* allocation = m_largeAllocations.begin(); allocation != m_largeAllocations.end(); allocation = allocation->next())
+ func(allocation);
+}
+
+template<typename Func>
+void Subspace::forEachMarkedCell(const Func& func)
+{
+ forEachNotEmptyMarkedBlock(
+ [&] (MarkedBlock::Handle* handle) {
+ handle->forEachMarkedCell(
+ [&] (HeapCell* cell, HeapCell::Kind kind) -> IterationStatus {
+ func(cell, kind);
+ return IterationStatus::Continue;
+ });
+ });
+ forEachLargeAllocation(
+ [&] (LargeAllocation* allocation) {
+ if (allocation->isMarked())
+ func(allocation->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 < weakImplCount(); ++i) {
</del><ins>+ size_t count = weakImplCount();
+ for (size_t i = 0; i < count; ++i) {
</ins><span class="cx"> WeakImpl* weakImpl = &weakImpls()[i];
</span><span class="cx"> if (weakImpl->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&);
</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&);
</del><ins>+ void visit(SlotVisitor&);
+
</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->lastChanceToFinalize();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline unsigned WeakSet::visit(SlotVisitor& visitor)
</del><ins>+inline void WeakSet::visit(SlotVisitor& visitor)
</ins><span class="cx"> {
</span><del>- unsigned count = 0;
- for (WeakBlock* block = m_blocks.head(); block; block = block->next()) {
- count++;
</del><ins>+ for (WeakBlock* block = m_blocks.head(); block; block = block->next())
</ins><span class="cx"> block->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& slowPath, size_t size)
</span><span class="cx"> {
</span><del>- MarkedAllocator* allocator = vm()->heap.allocatorForObjectOfType<ClassType>(size);
</del><ins>+ MarkedAllocator* allocator = subspaceFor<ClassType>(*vm())->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& subspace, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList& slowPath)
</del><ins>+ void emitAllocateVariableSized(GPRReg resultGPR, Subspace& subspace, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList& slowPath)
</ins><span class="cx"> {
</span><span class="cx"> static_assert(!(MarkedSpace::sizeStep & (MarkedSpace::sizeStep - 1)), "MarkedSpace::sizeStep must be a power of two.");
</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 >> stepShift)));
</span><del>- move(TrustedImmPtr(&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<typename ClassType, typename StructureType>
</span><span class="cx"> void emitAllocateVariableSizedCell(GPRReg resultGPR, StructureType structure, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList& slowPath)
</span><span class="cx"> {
</span><del>- MarkedSpace::Subspace& subspace = vm()->heap.template subspaceForObjectOfType<ClassType>();
</del><ins>+ Subspace& subspace = *subspaceFor<ClassType>(*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->structure();
</span><span class="cx"> size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
</span><del>- MarkedAllocator* allocator = m_vm->heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+ MarkedAllocator* allocator = subspaceFor<JSFinalObject>(*m_vm)->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->structure();
</span><span class="cx"> size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
</span><del>- MarkedAllocator* allocator = m_vm->heap.allocatorForObjectWithoutDestructor(allocationSize);
</del><ins>+ MarkedAllocator* allocator = subspaceFor<JSFinalObject>(*m_vm)->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& 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& 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->outOfLineCapacity() : 0, vectorLength);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline Butterfly* Butterfly::createUninitialized(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
</del><ins>+inline Butterfly* Butterfly::createUninitialized(VM& 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()->preCapacity(oldStructure));
</span><del>- ASSERT_UNUSED(oldStructure, hadIndexingHeader == oldStructure->hasIndexingHeader(intendedOwner));
</del><ins>+ ASSERT_UNUSED(intendedOwner, hadIndexingHeader == oldStructure->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&);
</span><span class="cx"> VisitChildrenFunctionPtr visitChildren;
</span><del>-
</del><ins>+
</ins><span class="cx"> typedef CallType (*GetCallDataFunctionPtr)(JSCell*, CallData&);
</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&);
+ 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"> &ClassName::getPrototype, \
</span><span class="cx"> &ClassName::dumpToStream, \
</span><span class="cx"> &ClassName::heapSnapshot, \
</span><del>- &ClassName::estimatedSize \
</del><ins>+ &ClassName::estimatedSize, \
+ &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->arrayStorage()->m_numValuesInVector = vectorLength;
</span><span class="cx">
</span><span class="cx"> } else {
</span><del>- void* temp = vm.heap.tryAllocateAuxiliary(nullptr, Butterfly::totalSize(0, structure->outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)));
</del><ins>+ void* temp = vm.auxiliarySpace.tryAllocate(Butterfly::totalSize(0, structure->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->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->callee, m_callee.get(), DontEnum);
</span><span class="cx"> putDirect(vm, vm.propertyNames->iteratorSymbol, globalObject()->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<bool*>(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<BucketType**>(this);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- static HashMapBuffer* create(ExecState* exec, VM& vm, JSCell* owner, uint32_t capacity)
</del><ins>+ static HashMapBuffer* create(ExecState* exec, VM& 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<Type>(vm) instead.
+ // FIXME: Refer to Subspace by reference.
+ // https://bugs.webkit.org/show_bug.cgi?id=166988
+ template<typename CellType>
+ static Subspace* subspaceFor(VM&);
+
</ins><span class="cx"> static JSCell* seenMultipleCalleeObjects() { return bitwise_cast<JSCell*>(static_cast<uintptr_t>(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&);
</span><ins>+ static void visitOutputConstraints(JSCell*, SlotVisitor&);
</ins><span class="cx">
</span><span class="cx"> JS_EXPORT_PRIVATE static void heapSnapshot(JSCell*, HeapSnapshotBuilder&);
</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<typename Type>
+inline Subspace* subspaceFor(VM& vm)
+{
+ return Type::template subspaceFor<Type>(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->structure(visitor.vm()));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+inline void JSCell::visitOutputConstraints(JSCell*, SlotVisitor&)
+{
+}
+
</ins><span class="cx"> ALWAYS_INLINE VM& 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()->markedBlock().vm();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+template<typename CellType>
+Subspace* JSCell::subspaceFor(VM& vm)
+{
+ if (CellType::needsDestruction)
+ return &vm.destructibleCellSpace;
+ return &vm.cellSpace;
+}
+
</ins><span class="cx"> template<typename T>
</span><span class="cx"> void* allocateCell(Heap& heap, size_t size)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
</span><span class="cx"> ASSERT(size >= sizeof(T));
</span><del>- JSCell* result = static_cast<JSCell*>(heap.allocateObjectOfType<T>(size));
</del><ins>+ JSCell* result = static_cast<JSCell*>(subspaceFor<T>(*heap.vm())->allocate(size));
</ins><span class="cx"> #if ENABLE(GC_VALIDATION)
</span><span class="cx"> ASSERT(!heap.vm()->isInitializingObject());
</span><span class="cx"> heap.vm()->setInitializingObjectClass(T::info());
</span><span class="lines">@@ -153,7 +165,7 @@
</span><span class="cx"> void* allocateCell(Heap& heap, GCDeferralContext* deferralContext, size_t size)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(size >= sizeof(T));
</span><del>- JSCell* result = static_cast<JSCell*>(heap.allocateObjectOfType<T>(deferralContext, size));
</del><ins>+ JSCell* result = static_cast<JSCell*>(subspaceFor<T>(*heap.vm())->allocate(deferralContext, size));
</ins><span class="cx"> #if ENABLE(GC_VALIDATION)
</span><span class="cx"> ASSERT(!heap.vm()->isInitializingObject());
</span><span class="cx"> heap.vm()->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<typename CellType>
+ static Subspace* subspaceFor(VM& vm)
+ {
+ return &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 "config.h"
+#include "JSDestructibleObjectSubspace.h"
+
+#include "MarkedBlockInlines.h"
+#include "JSCInlines.h"
+#include "SubspaceInlines.h"
+
+namespace JSC {
+
+namespace {
+
+struct DestroyFunc {
+ ALWAYS_INLINE void operator()(VM&, JSCell* cell) const
+ {
+ static_cast<JSDestructibleObject*>(cell)->classInfo()->methodTable.destroy(cell);
+ }
+};
+
+} // anonymous namespace
+
+JSDestructibleObjectSubspace::JSDestructibleObjectSubspace(CString name, Heap& heap)
+ : Subspace(name, heap, AllocatorAttributes(NeedsDestruction, HeapCell::JSCell))
+{
+}
+
+JSDestructibleObjectSubspace::~JSDestructibleObjectSubspace()
+{
+}
+
+FreeList JSDestructibleObjectSubspace::finishSweep(MarkedBlock::Handle& handle, MarkedBlock::Handle::SweepMode sweepMode)
+{
+ return handle.finishSweepKnowingSubspace(sweepMode, DestroyFunc());
+}
+
+void JSDestructibleObjectSubspace::destroy(VM& 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 "Subspace.h"
+
+namespace JSC {
+
+class JSDestructibleObjectSubspace : public Subspace {
+public:
+ JS_EXPORT_PRIVATE JSDestructibleObjectSubspace(CString name, Heap&);
+ JS_EXPORT_PRIVATE virtual ~JSDestructibleObjectSubspace();
+
+ FreeList finishSweep(MarkedBlock::Handle&, MarkedBlock::Handle::SweepMode) override;
+ void destroy(VM&, 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&);
</span><span class="cx"> JS_EXPORT_PRIVATE static void heapSnapshot(JSCell*, HeapSnapshotBuilder&);
</span><del>-
</del><ins>+
</ins><span class="cx"> protected:
</span><span class="cx"> JSSegmentedVariableObject(VM& 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<WriteBarrier<Unknown>, 16> 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<typename>
+ static Subspace* subspaceFor(VM& vm)
+ {
+ return &vm.stringSpace;
+ }
+
</ins><span class="cx"> static const unsigned MaxLength = std::numeric_limits<int32_t>::max();
</span><del>-
</del><ins>+
</ins><span class="cx"> private:
</span><span class="cx"> JSString(VM& vm, PassRefPtr<StringImpl> 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 "config.h"
+#include "JSStringSubspace.h"
+
+#include "MarkedBlockInlines.h"
+#include "JSCInlines.h"
+#include "SubspaceInlines.h"
+
+namespace JSC {
+
+namespace {
+
+struct DestroyFunc {
+ ALWAYS_INLINE void operator()(VM&, JSCell* cell) const
+ {
+ static_cast<JSString*>(cell)->JSString::~JSString();
+ }
+};
+
+} // anonymous namespace
+
+JSStringSubspace::JSStringSubspace(CString name, Heap& heap)
+ : Subspace(name, heap, AllocatorAttributes(NeedsDestruction, HeapCell::JSCell))
+{
+}
+
+JSStringSubspace::~JSStringSubspace()
+{
+}
+
+FreeList JSStringSubspace::finishSweep(MarkedBlock::Handle& handle, MarkedBlock::Handle::SweepMode sweepMode)
+{
+ return handle.finishSweepKnowingSubspace(sweepMode, DestroyFunc());
+}
+
+void JSStringSubspace::destroy(VM& 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 "Subspace.h"
+
+namespace JSC {
+
+class JSStringSubspace : public Subspace {
+public:
+ JS_EXPORT_PRIVATE JSStringSubspace(CString name, Heap&);
+ JS_EXPORT_PRIVATE virtual ~JSStringSubspace();
+
+ FreeList finishSweep(MarkedBlock::Handle&, MarkedBlock::Handle::SweepMode) override;
+ void destroy(VM&, 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 > 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->outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)));
</del><ins>+ void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(0, structure->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->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("Auxiliary", heap, AllocatorAttributes(DoesNotNeedDestruction, HeapCell::Auxiliary))
+ , cellSpace("JSCell", heap, AllocatorAttributes(DoesNotNeedDestruction, HeapCell::JSCell))
+ , destructibleCellSpace("Destructible JSCell", heap, AllocatorAttributes(NeedsDestruction, HeapCell::JSCell))
+ , stringSpace("JSString", heap)
+ , destructibleObjectSpace("JSDestructibleObject", 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 "Intrinsic.h"
</span><span class="cx"> #include "JITThunks.h"
</span><span class="cx"> #include "JSCJSValue.h"
</span><ins>+#include "JSDestructibleObjectSubspace.h"
</ins><span class="cx"> #include "JSLock.h"
</span><ins>+#include "JSStringSubspace.h"
</ins><span class="cx"> #include "MacroAssemblerCodeRef.h"
</span><span class="cx"> #include "Microtask.h"
</span><span class="cx"> #include "NumericStrings.h"
</span><span class="lines">@@ -49,6 +51,7 @@
</span><span class="cx"> #include "SmallStrings.h"
</span><span class="cx"> #include "SourceCode.h"
</span><span class="cx"> #include "Strong.h"
</span><ins>+#include "Subspace.h"
</ins><span class="cx"> #include "TemplateRegistryKeyTable.h"
</span><span class="cx"> #include "ThunkGenerators.h"
</span><span class="cx"> #include "VMEntryRecord.h"
</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<CellType>(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<DFG::LongLivedState> 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 <matthew_hanson@apple.com>
</span><span class="cx">
</span><ins>+ Merge r210844. rdar://problem/29993906
+
+ 2017-01-16 Filip Pizlo <fpizlo@apple.com>
+
+ 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 <matthew_hanson@apple.com>
+
</ins><span class="cx"> Merge r210829. rdar://problem/30044439
</span><span class="cx">
</span><span class="cx"> 2017-01-16 Filip Pizlo <fpizlo@apple.com>
</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 <JavaScriptCore/MarkedAllocatorInlines.h>
</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 <JavaScriptCore/MarkedBlockInlines.h>
</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 <JavaScriptCore/MarkingConstraint.h>
</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 <JavaScriptCore/SubspaceInlines.h>
</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 <JavaScriptCore/VisitingTimeout.h>
</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 = "<group>"; };
</span><span class="cx">                 0F6A12BB1A00923700C6DE72 /* DebugPageOverlays.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebugPageOverlays.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F6A12BC1A00923700C6DE72 /* DebugPageOverlays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugPageOverlays.h; sourceTree = "<group>"; };
</span><ins>+                0F7DF1471E2BF1A60095951B /* WebCoreJSClientData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebCoreJSClientData.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 0F87166D1C869D83004FF0DE /* LengthPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LengthPoint.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F87166E1C869D83004FF0DE /* LengthPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LengthPoint.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F8B456F1DC3FB1000443C3F /* IntersectionObserverCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = IntersectionObserverCallback.idl; sourceTree = "<group>"; };
</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& 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->setGlobalConstRedeclarationShouldThrow(Settings::globalConstRedeclarationShouldThrow());
</span><del>- g_commonVMOrNull->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->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& commonVMSlow();
</span><del>-WEBCORE_EXPORT void writeBarrierOpaqueRootSlow(void*);
</del><span class="cx">
</span><span class="cx"> inline JSC::VM& 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<typename Func>
-void writeBarrierOpaqueRoot(const Func& 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& 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<const JSDOMWindowBase*>(this)->scriptExecutionContext();
</span><span class="cx"> if (inherits(JSWorkerGlobalScopeBase::info()))
</span><span class="cx"> return jsCast<const JSWorkerGlobalScopeBase*>(this)->scriptExecutionContext();
</span><del>- ASSERT_NOT_REACHED();
</del><ins>+ dataLog("Unexpected global object: ", JSValue(this), "\n");
+ 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 "DOMWrapperWorld.h"
</span><span class="cx"> #include "JSDOMWindow.h"
</span><ins>+#include "WebCoreJSClientData.h"
</ins><span class="cx"> #include <runtime/Error.h>
</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& vm)
+{
+ return &static_cast<JSVMClientData*>(vm.clientData)->outputConstraintSpace();
+}
+
+Subspace* globalObjectOutputConstraintSubspaceFor(VM& vm)
+{
+ return &static_cast<JSVMClientData*>(vm.clientData)->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&);
+WEBCORE_EXPORT JSC::Subspace* globalObjectOutputConstraintSubspaceFor(JSC::VM&);
+
</ins><span class="cx"> template<typename ImplementationClass> 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 "config.h"
+#include "WebCoreJSClientData.h"
+
+#include "JSDOMBinding.h"
+#include <heap/HeapInlines.h>
+#include <heap/MarkingConstraint.h>
+#include <heap/MarkedAllocatorInlines.h>
+#include <heap/MarkedBlockInlines.h>
+#include <heap/SubspaceInlines.h>
+#include <heap/VisitingTimeout.h>
+#include <runtime/VM.h>
+#include <wtf/MainThread.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+JSVMClientData::JSVMClientData(VM& vm)
+ : m_builtinFunctions(vm)
+ , m_builtinNames(&vm)
+ , m_outputConstraintSpace("WebCore Wrapper w/ Output Constraint", vm.heap)
+ , m_globalObjectOutputConstraintSpace("WebCore Global Object w/ Output Constraint", vm.heap, AllocatorAttributes(DoesNotNeedDestruction, HeapCell::JSCell))
+{
+}
+
+JSVMClientData::~JSVMClientData()
+{
+ ASSERT(m_worldSet.contains(m_normalWorld.get()));
+ ASSERT(m_worldSet.size() == 1);
+ ASSERT(m_normalWorld->hasOneRef());
+ m_normalWorld = nullptr;
+ ASSERT(m_worldSet.isEmpty());
+}
+
+void JSVMClientData::getAllWorlds(Vector<Ref<DOMWrapperWorld>>& 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->clientData = clientData; // ~VM deletes this pointer.
+
+ auto constraint = std::make_unique<MarkingConstraint>(
+ "Wcoc", "WebCore Output Constraints",
+ [vm, clientData, lastExecutionVersion = vm->heap.mutatorExecutionVersion()]
+ (SlotVisitor& slotVisitor, const VisitingTimeout&) mutable {
+ Heap& heap = vm->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->forEachOutputConstraintSpace(
+ [&] (Subspace& subspace) {
+ subspace.forEachMarkedCell(
+ [&] (HeapCell* heapCell, HeapCell::Kind) {
+ JSCell* cell = static_cast<JSCell*>(heapCell);
+ cell->methodTable(*vm)->visitOutputConstraints(cell, slotVisitor);
+ numRevisited++;
+ });
+ });
+ if (Options::logGC())
+ dataLog("(", numRevisited, ")");
+
+ slotVisitor.mergeIfNecessary();
+
+ slotVisitor.addToVisitCount(heap.numOpaqueRoots() - numOpaqueRootsBefore);
+ },
+ ConstraintVolatility::SeldomGreyed);
+ vm->heap.addMarkingConstraint(WTFMove(constraint));
+
+ clientData->m_normalWorld = DOMWrapperWorld::create(*vm, true);
+ vm->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 <sam@webkit.org>
</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& vm)
- : m_builtinFunctions(vm)
- , m_builtinNames(&vm)
- {
- }
</del><ins>+ explicit JSVMClientData(JSC::VM&);
</ins><span class="cx">
</span><del>- virtual ~JSVMClientData()
- {
- ASSERT(m_worldSet.contains(m_normalWorld.get()));
- ASSERT(m_worldSet.size() == 1);
- ASSERT(m_normalWorld->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& normalWorld() { return *m_normalWorld; }
</span><span class="cx">
</span><del>- void getAllWorlds(Vector<Ref<DOMWrapperWorld>>& worlds)
- {
- ASSERT(worlds.isEmpty());
</del><ins>+ void getAllWorlds(Vector<Ref<DOMWrapperWorld>>&);
</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& world)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!m_worldSet.contains(&world));
</span><span class="lines">@@ -76,6 +59,16 @@
</span><span class="cx">
</span><span class="cx"> WebCoreBuiltinNames& builtinNames() { return m_builtinNames; }
</span><span class="cx"> JSBuiltinFunctions& builtinFunctions() { return m_builtinFunctions; }
</span><ins>+
+ JSC::Subspace& outputConstraintSpace() { return m_outputConstraintSpace; }
+ JSC::Subspace& globalObjectOutputConstraintSpace() { return m_globalObjectOutputConstraintSpace; }
+
+ template<typename Func>
+ void forEachOutputConstraintSpace(const Func& func)
+ {
+ func(m_outputConstraintSpace);
+ func(m_globalObjectOutputConstraintSpace);
+ }
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> HashSet<DOMWrapperWorld*> 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->clientData = clientData; // ~VM deletes this pointer.
- clientData->m_normalWorld = DOMWrapperWorld::create(*vm, true);
- vm->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->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->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, " static void visitChildren(JSCell*, JSC::SlotVisitor&);\n");
</span><span class="cx"> push(@headerContent, " void visitAdditionalChildren(JSC::SlotVisitor&);\n") if $interface->extendedAttributes->{JSCustomMarkFunction};
</span><span class="cx"> push(@headerContent, "\n");
</span><ins>+
+ if ($interface->extendedAttributes->{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, " static void visitOutputConstraints(JSCell*, JSC::SlotVisitor&);\n");
+ my $subspaceFunc = IsDOMGlobalObject($interface) ? "globalObjectOutputConstraintSubspaceFor" : "outputConstraintSubspaceFor";
+ push(@headerContent, " template<typename> static JSC::Subspace* subspaceFor(JSC::VM& vm) { return $subspaceFunc(vm); }\n");
+ }
</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, "}\n\n");
</span><ins>+ if ($interface->extendedAttributes->{JSCustomMarkFunction}) {
+ push(@implContent, "void ${className}::visitOutputConstraints(JSCell* cell, SlotVisitor& visitor)\n");
+ push(@implContent, "{\n");
+ push(@implContent, " auto* thisObject = jsCast<${className}*>(cell);\n");
+ push(@implContent, " ASSERT_GC_OBJECT_INHERITS(thisObject, info());\n");
+ push(@implContent, " Base::visitOutputConstraints(thisObject, visitor);\n");
+ push(@implContent, " thisObject->visitAdditionalChildren(visitor);\n");
+ push(@implContent, "}\n\n");
+ }
</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 "config.h"
</span><span class="cx"> #include "ContainerNodeAlgorithms.h"
</span><span class="cx">
</span><del>-#include "CommonVM.h"
</del><span class="cx"> #include "HTMLFrameOwnerElement.h"
</span><span class="cx"> #include "InspectorInstrumentation.h"
</span><span class="cx"> #include "NoEventDispatchAssertion.h"
</span><span class="lines">@@ -102,8 +101,6 @@
</span><span class="cx"> notifyNodeInsertedIntoDocument(insertionPoint, node, postInsertionNotificationTargets);
</span><span class="cx"> else if (is<ContainerNode>(node))
</span><span class="cx"> notifyNodeInsertedIntoTree(insertionPoint, downcast<ContainerNode>(node), postInsertionNotificationTargets);
</span><del>-
- writeBarrierOpaqueRoot([&insertionPoint] () -> void* { return insertionPoint.opaqueRoot(); });
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void notifyNodeRemovedFromDocument(ContainerNode& insertionPoint, Node& node)
</span><span class="lines">@@ -155,8 +152,6 @@
</span><span class="cx">
</span><span class="cx"> void notifyChildNodeRemoved(ContainerNode& insertionPoint, Node& child)
</span><span class="cx"> {
</span><del>- writeBarrierOpaqueRoot([&child] () -> void* { return &child; });
-
</del><span class="cx"> if (!child.inDocument()) {
</span><span class="cx"> if (is<ContainerNode>(child))
</span><span class="cx"> notifyNodeRemovedFromTree(insertionPoint, downcast<ContainerNode>(child));
</span></span></pre>
</div>
</div>
</body>
</html>