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

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

<h3>Log Message</h3>
<pre>The tracking of the coarse-grain Heap state (allocating or not, collector or not, eden vs full) should respect the orthogonality between allocating and collecting
https://bugs.webkit.org/show_bug.cgi?id=163738

Reviewed by Geoffrey Garen.
Source/JavaScriptCore:

        
We need to know if we're currently in an allocation slow path, so that code can assert that
it's not being used from inside a destructor that runs during a sweep. We need to know if
we're currently collecting, because some code behaves differently during collection, and
other code wants to assert that it's not being used from inside a visitChildren method that
runs during marking. If we are collecting, we need to know if it's an eden collection or a
full collection. If we are requesting a collection, we need to know if we're requesting an
eden collection, a full collection, or any kind of collection.
        
Prior to this change, you would reason about all of these things using the HeapOperation. It
had the following states: NoOperation, Allocation, FullCollection, EdenCollection, and
AnyCollection. NoOperation versus Allocation was primarily for asserting that sweep didn't
call arbitrary JS. FullCollection versus EdenCollection was about describing generations. We
would even use HeapOperation in places where we knew that it could only be either Full or
Eden, because we just needed a variable to tell us which generation we were talking about.
It was all very confusing.
        
Where it completely breaks down is the fact that a concurrent GC has two logical threads, the
mutator and the collector, which can change state independently. The mutator can be
allocating. It can also be doing some work to help the GC. That's three states: running,
allocating, or helping GC. At the same time, the GC thread could either be running or not,
and if it's running, it could be a full collection or an eden collection. Because the mutator
and collector can run at the same time, it means that if we used one enum, we would need nine
states: every combination of mutator running, allocating, or helping GC, crossed with
collector not running, running eden, or running full. So, this change decouples mutator state
from collector state and uses two separate fields with two different types.
        
Mutator state is described using MutatorState, which can be either MutatorState::Running,
MutatorState::Allocating, or MutatorState::HelpingGC.
        
Collector state is described using Optional&lt;CollectionScope&gt;. CollectionScope describes how
big the scope of the collection is, and it can be either CollectionScope::Eden or
CollectionScope::Full. If the Optional is Nullopt, it means that we are not collecting. This
way, you can treat collectionScope as a boolean (an Optional is true iff it's engaged). You
can pass around just a CollectionScope if you know that you must be collecting and you just
want to know about the generation. Also, we can use Nullopt in methods that request
collection, which those methods take to mean that they can run any kind of collection (the
old AnyCollection).
        
Another use of HeapOperation was to answer questions about whether the caller is running as
part of the GC or as part of the mutator. Optional&lt;CollectionScope&gt; does not answer this,
since code that runs in the mutator while the mutator is not HelpingGC at the same time as
the collector is running should run as if it was part of the mutator not as if it was part of
the GC. MutatorState is needed to answer this question, but it doesn't tell the whole story
since code that runs in the collector thread at the same time as the mutator is running
should run as if it was part of the GC not as if it was part of the mutator. So, we need to
know if we're on the collector thread or the mutator thread. We already have a WTF facility
for this, which answers if a thread is a GC thread. But we already use this to answer a
stronger question: are we part of the parallel GC helpers? Some functions in the GC, like
mark bit queries, will work fine in a concurrent collector thread so long as there is no
parallel marking. So, this change also changes WTF's mayBeGCThread to tell what kind of GC
thread we may be: either GCThreadType::Main or GCThreadType::Helper. The parallel GC safety
checks look for GCThreadType::Helper. The &quot;should I run as mutator&quot; query can now be answered
by checking with mayBeGCThread, which returns Optional&lt;GCThreadType&gt;; if engaged, then run as
GC, else run as GC if MutatorState is HelpingGC, else run as mutator.
        
This doesn't change the way that the GC behaves, but it does change how the GC represents a
fundamental piece of state. So, it's a big change. It should be perf-neutral (still testing).

* API/JSBase.cpp:
(JSSynchronousEdenCollectForDebugging):
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::jettison):
* dfg/DFGWorklist.cpp:
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* heap/AllocatingScope.h: Added.
(JSC::AllocatingScope::AllocatingScope):
(JSC::AllocatingScope::~AllocatingScope):
* heap/AllocationScope.h: Removed.
* heap/CodeBlockSet.cpp:
(JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced):
* heap/CodeBlockSet.h:
* heap/CollectionScope.cpp: Added.
(JSC::collectionScopeName):
(WTF::printInternal):
* heap/CollectionScope.h: Added.
* heap/EdenGCActivityCallback.cpp:
(JSC::EdenGCActivityCallback::doCollection):
* heap/FullGCActivityCallback.cpp:
(JSC::FullGCActivityCallback::doCollection):
* heap/GCTypeMap.h:
(JSC::GCTypeMap::operator[]):
* heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::lastChanceToFinalize):
(JSC::Heap::markRoots):
(JSC::Heap::beginMarking):
(JSC::Heap::visitSmallStrings):
(JSC::Heap::updateObjectCounts):
(JSC::Heap::deleteAllCodeBlocks):
(JSC::Heap::deleteUnmarkedCompiledCode):
(JSC::Heap::collectAllGarbage):
(JSC::Heap::collect):
(JSC::Heap::collectWithoutAnySweep):
(JSC::Heap::collectImpl):
(JSC::Heap::willStartCollection):
(JSC::Heap::flushWriteBarrierBuffer):
(JSC::Heap::pruneStaleEntriesFromWeakGCMaps):
(JSC::Heap::notifyIncrementalSweeper):
(JSC::Heap::updateAllocationLimits):
(JSC::Heap::didFinishCollection):
(JSC::Heap::isValidAllocation):
(JSC::Heap::shouldDoFullCollection):
* heap/Heap.h:
(JSC::Heap::mutatorState):
(JSC::Heap::collectionScope):
(JSC::Heap::operationInProgress): Deleted.
* heap/HeapInlines.h:
(JSC::Heap::shouldCollect):
(JSC::Heap::isCurrentThreadBusy):
(JSC::Heap::isMarked):
(JSC::Heap::reportExtraMemoryVisited):
(JSC::Heap::reportExternalMemoryVisited):
(JSC::Heap::collectAccordingToDeferGCProbability):
(JSC::Heap::isBusy): Deleted.
(JSC::Heap::isCollecting): Deleted.
* heap/HeapObserver.h:
* heap/HeapOperation.cpp: Removed.
* heap/HeapOperation.h: Removed.
* heap/HeapVerifier.cpp:
(JSC::HeapVerifier::initializeGCCycle):
(JSC::HeapVerifier::reportObject):
(JSC::HeapVerifier::collectionTypeName): Deleted.
* heap/HeapVerifier.h:
(JSC::HeapVerifier::GCCycle::collectionTypeName): Deleted.
* heap/HelpingGCScope.h: Added.
(JSC::HelpingGCScope::HelpingGCScope):
(JSC::HelpingGCScope::~HelpingGCScope):
* heap/LargeAllocation.cpp:
(JSC::LargeAllocation::flip):
* heap/MarkedAllocator.cpp:
(JSC::MarkedAllocator::doTestCollectionsIfNeeded):
(JSC::MarkedAllocator::allocateSlowCaseImpl):
* heap/MarkedBlock.h:
* heap/MarkedSpace.cpp:
(JSC::MarkedSpace::prepareForAllocation):
(JSC::MarkedSpace::visitWeakSets):
(JSC::MarkedSpace::reapWeakSets):
(JSC::MarkedSpace::prepareForMarking):
(JSC::MarkedSpace::beginMarking):
(JSC::MarkedSpace::snapshotUnswept):
* heap/MutatorState.cpp: Added.
(WTF::printInternal):
* heap/MutatorState.h: Added.
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::didStartMarking):
* inspector/agents/InspectorHeapAgent.cpp:
(Inspector::protocolTypeForHeapOperation):
(Inspector::InspectorHeapAgent::didGarbageCollect):
* inspector/agents/InspectorHeapAgent.h:
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
* jsc.cpp:
(functionFullGC):
(functionEdenGC):
* runtime/Completion.cpp:
(JSC::evaluate):
(JSC::loadAndEvaluateModule):
(JSC::loadModule):
(JSC::linkAndEvaluateModule):
* runtime/JSLock.cpp:
(JSC::JSLock::DropAllLocks::DropAllLocks):
* runtime/SmallStrings.h:
(JSC::SmallStrings::needsToBeVisited):
* runtime/VM.h:
(JSC::VM::isCollectorBusyOnCurrentThread):
(JSC::VM::isCollectorBusy): Deleted.
* tools/JSDollarVMPrototype.cpp:
(JSC::JSDollarVMPrototype::edenGC):

Source/WebCore:


No new tests because no change in behavior.

* bindings/js/GCController.cpp:
(WebCore::GCController::garbageCollectNow):

Source/WTF:

        
There will soon be different kinds of GC threads, and WTF's &quot;are you a GC thread&quot; thing
should know about this.

* wtf/MainThread.cpp:
(WTF::initializeGCThreads):
(WTF::registerGCThread):
(WTF::mayBeGCThread):
* wtf/MainThread.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreAPIJSBasecpp">trunk/Source/JavaScriptCore/API/JSBase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWorklistcpp">trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCodeBlockSetcpp">trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCodeBlockSeth">trunk/Source/JavaScriptCore/heap/CodeBlockSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapEdenGCActivityCallbackcpp">trunk/Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapFullGCActivityCallbackcpp">trunk/Source/JavaScriptCore/heap/FullGCActivityCallback.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapGCTypeMaph">trunk/Source/JavaScriptCore/heap/GCTypeMap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeaph">trunk/Source/JavaScriptCore/heap/Heap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapInlinesh">trunk/Source/JavaScriptCore/heap/HeapInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapObserverh">trunk/Source/JavaScriptCore/heap/HeapObserver.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapVerifiercpp">trunk/Source/JavaScriptCore/heap/HeapVerifier.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapVerifierh">trunk/Source/JavaScriptCore/heap/HeapVerifier.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapLargeAllocationcpp">trunk/Source/JavaScriptCore/heap/LargeAllocation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedAllocatorcpp">trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedBlockh">trunk/Source/JavaScriptCore/heap/MarkedBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMarkedSpacecpp">trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapSlotVisitorcpp">trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorHeapAgentcpp">trunk/Source/JavaScriptCore/inspector/agents/InspectorHeapAgent.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectoragentsInspectorHeapAgenth">trunk/Source/JavaScriptCore/inspector/agents/InspectorHeapAgent.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCompletioncpp">trunk/Source/JavaScriptCore/runtime/Completion.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSLockcpp">trunk/Source/JavaScriptCore/runtime/JSLock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSmallStringsh">trunk/Source/JavaScriptCore/runtime/SmallStrings.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretoolsJSDollarVMPrototypecpp">trunk/Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfMainThreadcpp">trunk/Source/WTF/wtf/MainThread.cpp</a></li>
<li><a href="#trunkSourceWTFwtfMainThreadh">trunk/Source/WTF/wtf/MainThread.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsGCControllercpp">trunk/Source/WebCore/bindings/js/GCController.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreheapAllocatingScopeh">trunk/Source/JavaScriptCore/heap/AllocatingScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCollectionScopecpp">trunk/Source/JavaScriptCore/heap/CollectionScope.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCollectionScopeh">trunk/Source/JavaScriptCore/heap/CollectionScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHelpingGCScopeh">trunk/Source/JavaScriptCore/heap/HelpingGCScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMutatorStatecpp">trunk/Source/JavaScriptCore/heap/MutatorState.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMutatorStateh">trunk/Source/JavaScriptCore/heap/MutatorState.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreheapAllocationScopeh">trunk/Source/JavaScriptCore/heap/AllocationScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapOperationcpp">trunk/Source/JavaScriptCore/heap/HeapOperation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapOperationh">trunk/Source/JavaScriptCore/heap/HeapOperation.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreAPIJSBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSBase.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSBase.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/API/JSBase.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2006, 2007, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2006, 2007, 2013, 2016 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">@@ -165,7 +165,7 @@
</span><span class="cx"> 
</span><span class="cx">     ExecState* exec = toJS(ctx);
</span><span class="cx">     JSLockHolder locker(exec);
</span><del>-    exec-&gt;vm().heap.collect(EdenCollection);
</del><ins>+    exec-&gt;vm().heap.collect(CollectionScope::Eden);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSDisableGCTimer(void)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -451,6 +451,7 @@
</span><span class="cx"> 
</span><span class="cx">     heap/AllocatorAttributes.cpp
</span><span class="cx">     heap/CodeBlockSet.cpp
</span><ins>+    heap/CollectionScope.cpp
</ins><span class="cx">     heap/ConservativeRoots.cpp
</span><span class="cx">     heap/DeferGC.cpp
</span><span class="cx">     heap/DestructionMode.cpp
</span><span class="lines">@@ -464,7 +465,6 @@
</span><span class="cx">     heap/Heap.cpp
</span><span class="cx">     heap/HeapCell.cpp
</span><span class="cx">     heap/HeapHelperPool.cpp
</span><del>-    heap/HeapOperation.cpp
</del><span class="cx">     heap/HeapProfiler.cpp
</span><span class="cx">     heap/HeapSnapshot.cpp
</span><span class="cx">     heap/HeapSnapshotBuilder.cpp
</span><span class="lines">@@ -480,6 +480,7 @@
</span><span class="cx">     heap/MarkedAllocator.cpp
</span><span class="cx">     heap/MarkedBlock.cpp
</span><span class="cx">     heap/MarkedSpace.cpp
</span><ins>+    heap/MutatorState.cpp
</ins><span class="cx">     heap/SlotVisitor.cpp
</span><span class="cx">     heap/Weak.cpp
</span><span class="cx">     heap/WeakBlock.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,3 +1,185 @@
</span><ins>+2016-10-20  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        The tracking of the coarse-grain Heap state (allocating or not, collector or not, eden vs full) should respect the orthogonality between allocating and collecting
+        https://bugs.webkit.org/show_bug.cgi?id=163738
+
+        Reviewed by Geoffrey Garen.
+        
+        We need to know if we're currently in an allocation slow path, so that code can assert that
+        it's not being used from inside a destructor that runs during a sweep. We need to know if
+        we're currently collecting, because some code behaves differently during collection, and
+        other code wants to assert that it's not being used from inside a visitChildren method that
+        runs during marking. If we are collecting, we need to know if it's an eden collection or a
+        full collection. If we are requesting a collection, we need to know if we're requesting an
+        eden collection, a full collection, or any kind of collection.
+        
+        Prior to this change, you would reason about all of these things using the HeapOperation. It
+        had the following states: NoOperation, Allocation, FullCollection, EdenCollection, and
+        AnyCollection. NoOperation versus Allocation was primarily for asserting that sweep didn't
+        call arbitrary JS. FullCollection versus EdenCollection was about describing generations. We
+        would even use HeapOperation in places where we knew that it could only be either Full or
+        Eden, because we just needed a variable to tell us which generation we were talking about.
+        It was all very confusing.
+        
+        Where it completely breaks down is the fact that a concurrent GC has two logical threads, the
+        mutator and the collector, which can change state independently. The mutator can be
+        allocating. It can also be doing some work to help the GC. That's three states: running,
+        allocating, or helping GC. At the same time, the GC thread could either be running or not,
+        and if it's running, it could be a full collection or an eden collection. Because the mutator
+        and collector can run at the same time, it means that if we used one enum, we would need nine
+        states: every combination of mutator running, allocating, or helping GC, crossed with
+        collector not running, running eden, or running full. So, this change decouples mutator state
+        from collector state and uses two separate fields with two different types.
+        
+        Mutator state is described using MutatorState, which can be either MutatorState::Running,
+        MutatorState::Allocating, or MutatorState::HelpingGC.
+        
+        Collector state is described using Optional&lt;CollectionScope&gt;. CollectionScope describes how
+        big the scope of the collection is, and it can be either CollectionScope::Eden or
+        CollectionScope::Full. If the Optional is Nullopt, it means that we are not collecting. This
+        way, you can treat collectionScope as a boolean (an Optional is true iff it's engaged). You
+        can pass around just a CollectionScope if you know that you must be collecting and you just
+        want to know about the generation. Also, we can use Nullopt in methods that request
+        collection, which those methods take to mean that they can run any kind of collection (the
+        old AnyCollection).
+        
+        Another use of HeapOperation was to answer questions about whether the caller is running as
+        part of the GC or as part of the mutator. Optional&lt;CollectionScope&gt; does not answer this,
+        since code that runs in the mutator while the mutator is not HelpingGC at the same time as
+        the collector is running should run as if it was part of the mutator not as if it was part of
+        the GC. MutatorState is needed to answer this question, but it doesn't tell the whole story
+        since code that runs in the collector thread at the same time as the mutator is running
+        should run as if it was part of the GC not as if it was part of the mutator. So, we need to
+        know if we're on the collector thread or the mutator thread. We already have a WTF facility
+        for this, which answers if a thread is a GC thread. But we already use this to answer a
+        stronger question: are we part of the parallel GC helpers? Some functions in the GC, like
+        mark bit queries, will work fine in a concurrent collector thread so long as there is no
+        parallel marking. So, this change also changes WTF's mayBeGCThread to tell what kind of GC
+        thread we may be: either GCThreadType::Main or GCThreadType::Helper. The parallel GC safety
+        checks look for GCThreadType::Helper. The &quot;should I run as mutator&quot; query can now be answered
+        by checking with mayBeGCThread, which returns Optional&lt;GCThreadType&gt;; if engaged, then run as
+        GC, else run as GC if MutatorState is HelpingGC, else run as mutator.
+        
+        This doesn't change the way that the GC behaves, but it does change how the GC represents a
+        fundamental piece of state. So, it's a big change. It should be perf-neutral (still testing).
+
+        * API/JSBase.cpp:
+        (JSSynchronousEdenCollectForDebugging):
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::jettison):
+        * dfg/DFGWorklist.cpp:
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::compile):
+        * heap/AllocatingScope.h: Added.
+        (JSC::AllocatingScope::AllocatingScope):
+        (JSC::AllocatingScope::~AllocatingScope):
+        * heap/AllocationScope.h: Removed.
+        * heap/CodeBlockSet.cpp:
+        (JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced):
+        * heap/CodeBlockSet.h:
+        * heap/CollectionScope.cpp: Added.
+        (JSC::collectionScopeName):
+        (WTF::printInternal):
+        * heap/CollectionScope.h: Added.
+        * heap/EdenGCActivityCallback.cpp:
+        (JSC::EdenGCActivityCallback::doCollection):
+        * heap/FullGCActivityCallback.cpp:
+        (JSC::FullGCActivityCallback::doCollection):
+        * heap/GCTypeMap.h:
+        (JSC::GCTypeMap::operator[]):
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::lastChanceToFinalize):
+        (JSC::Heap::markRoots):
+        (JSC::Heap::beginMarking):
+        (JSC::Heap::visitSmallStrings):
+        (JSC::Heap::updateObjectCounts):
+        (JSC::Heap::deleteAllCodeBlocks):
+        (JSC::Heap::deleteUnmarkedCompiledCode):
+        (JSC::Heap::collectAllGarbage):
+        (JSC::Heap::collect):
+        (JSC::Heap::collectWithoutAnySweep):
+        (JSC::Heap::collectImpl):
+        (JSC::Heap::willStartCollection):
+        (JSC::Heap::flushWriteBarrierBuffer):
+        (JSC::Heap::pruneStaleEntriesFromWeakGCMaps):
+        (JSC::Heap::notifyIncrementalSweeper):
+        (JSC::Heap::updateAllocationLimits):
+        (JSC::Heap::didFinishCollection):
+        (JSC::Heap::isValidAllocation):
+        (JSC::Heap::shouldDoFullCollection):
+        * heap/Heap.h:
+        (JSC::Heap::mutatorState):
+        (JSC::Heap::collectionScope):
+        (JSC::Heap::operationInProgress): Deleted.
+        * heap/HeapInlines.h:
+        (JSC::Heap::shouldCollect):
+        (JSC::Heap::isCurrentThreadBusy):
+        (JSC::Heap::isMarked):
+        (JSC::Heap::reportExtraMemoryVisited):
+        (JSC::Heap::reportExternalMemoryVisited):
+        (JSC::Heap::collectAccordingToDeferGCProbability):
+        (JSC::Heap::isBusy): Deleted.
+        (JSC::Heap::isCollecting): Deleted.
+        * heap/HeapObserver.h:
+        * heap/HeapOperation.cpp: Removed.
+        * heap/HeapOperation.h: Removed.
+        * heap/HeapVerifier.cpp:
+        (JSC::HeapVerifier::initializeGCCycle):
+        (JSC::HeapVerifier::reportObject):
+        (JSC::HeapVerifier::collectionTypeName): Deleted.
+        * heap/HeapVerifier.h:
+        (JSC::HeapVerifier::GCCycle::collectionTypeName): Deleted.
+        * heap/HelpingGCScope.h: Added.
+        (JSC::HelpingGCScope::HelpingGCScope):
+        (JSC::HelpingGCScope::~HelpingGCScope):
+        * heap/LargeAllocation.cpp:
+        (JSC::LargeAllocation::flip):
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::doTestCollectionsIfNeeded):
+        (JSC::MarkedAllocator::allocateSlowCaseImpl):
+        * heap/MarkedBlock.h:
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::prepareForAllocation):
+        (JSC::MarkedSpace::visitWeakSets):
+        (JSC::MarkedSpace::reapWeakSets):
+        (JSC::MarkedSpace::prepareForMarking):
+        (JSC::MarkedSpace::beginMarking):
+        (JSC::MarkedSpace::snapshotUnswept):
+        * heap/MutatorState.cpp: Added.
+        (WTF::printInternal):
+        * heap/MutatorState.h: Added.
+        * heap/SlotVisitor.cpp:
+        (JSC::SlotVisitor::didStartMarking):
+        * inspector/agents/InspectorHeapAgent.cpp:
+        (Inspector::protocolTypeForHeapOperation):
+        (Inspector::InspectorHeapAgent::didGarbageCollect):
+        * inspector/agents/InspectorHeapAgent.h:
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        (JSC::Interpreter::prepareForRepeatCall):
+        * jsc.cpp:
+        (functionFullGC):
+        (functionEdenGC):
+        * runtime/Completion.cpp:
+        (JSC::evaluate):
+        (JSC::loadAndEvaluateModule):
+        (JSC::loadModule):
+        (JSC::linkAndEvaluateModule):
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::DropAllLocks::DropAllLocks):
+        * runtime/SmallStrings.h:
+        (JSC::SmallStrings::needsToBeVisited):
+        * runtime/VM.h:
+        (JSC::VM::isCollectorBusyOnCurrentThread):
+        (JSC::VM::isCollectorBusy): Deleted.
+        * tools/JSDollarVMPrototype.cpp:
+        (JSC::JSDollarVMPrototype::edenGC):
+
</ins><span class="cx"> 2016-10-20  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] Drop isEnvironmentRecord type info flag and use JSType information instead
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -510,7 +510,6 @@
</span><span class="cx">                 0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */; };
</span><span class="cx">                 0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */; };
</span><del>-                0F86A26D1D6F796500CB0C92 /* HeapOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F86A26C1D6F796200CB0C92 /* HeapOperation.cpp */; };
</del><span class="cx">                 0F86A26F1D6F7B3300CB0C92 /* GCTypeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F86A26E1D6F7B3100CB0C92 /* GCTypeMap.h */; };
</span><span class="cx">                 0F86AE201C5311C5006BE8EC /* B3ComputeDivisionMagic.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F86AE1F1C5311C5006BE8EC /* B3ComputeDivisionMagic.h */; };
</span><span class="cx">                 0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -592,6 +591,12 @@
</span><span class="cx">                 0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA581B7150E952A00B9A2D9 /* DFGNodeFlags.cpp */; };
</span><span class="cx">                 0FA581BB150E953000B9A2D9 /* DFGNodeFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */; };
</span><span class="cx">                 0FA581BC150E953000B9A2D9 /* DFGNodeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */; };
</span><ins>+                0FA762041DB9242600B7A2FD /* CollectionScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA762001DB9242300B7A2FD /* CollectionScope.cpp */; };
+                0FA762051DB9242900B7A2FD /* CollectionScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA762011DB9242300B7A2FD /* CollectionScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0FA762061DB9243100B7A2FD /* MutatorState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA762021DB9242300B7A2FD /* MutatorState.cpp */; };
+                0FA762071DB9243300B7A2FD /* MutatorState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA762031DB9242300B7A2FD /* MutatorState.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0FA762091DB9283E00B7A2FD /* HelpingGCScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA762081DB9283C00B7A2FD /* HelpingGCScope.h */; };
+                0FA7620B1DB959F900B7A2FD /* AllocatingScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA7620A1DB959F600B7A2FD /* AllocatingScope.h */; };
</ins><span class="cx">                 0FA7A8EB18B413C80052371D /* Reg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8E918B413C80052371D /* Reg.cpp */; };
</span><span class="cx">                 0FA7A8EC18B413C80052371D /* Reg.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA7A8EA18B413C80052371D /* Reg.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FA7A8EE18CE4FD80052371D /* ScratchRegisterAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */; };
</span><span class="lines">@@ -623,7 +628,6 @@
</span><span class="cx">                 0FB4FB731BC843140025CA5A /* FTLLazySlowPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4FB701BC843140025CA5A /* FTLLazySlowPath.cpp */; };
</span><span class="cx">                 0FB4FB741BC843140025CA5A /* FTLLazySlowPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4FB711BC843140025CA5A /* FTLLazySlowPath.h */; };
</span><span class="cx">                 0FB4FB751BC843140025CA5A /* FTLLazySlowPathCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4FB721BC843140025CA5A /* FTLLazySlowPathCall.h */; };
</span><del>-                0FB530391D90404C00F28AE3 /* AllocationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB530381D90404600F28AE3 /* AllocationScope.h */; };
</del><span class="cx">                 0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */; };
</span><span class="cx">                 0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -1156,7 +1160,6 @@
</span><span class="cx">                 2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */; };
</span><span class="cx">                 2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */; };
</span><span class="cx">                 2A4EC90C1860D6C20094F782 /* WriteBarrierBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A4EC90A1860D6C20094F782 /* WriteBarrierBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A6F462517E959CE00C45C98 /* HeapOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 2A7A58EF1808A4C40020BDF7 /* DeferGC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */; };
</span><span class="cx">                 2A83638518D7D0EE0000EBCC /* EdenGCActivityCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A83638318D7D0EE0000EBCC /* EdenGCActivityCallback.cpp */; };
</span><span class="cx">                 2A83638618D7D0EE0000EBCC /* EdenGCActivityCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A83638418D7D0EE0000EBCC /* EdenGCActivityCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2836,7 +2839,6 @@
</span><span class="cx">                 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayAllocationProfile.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayAllocationProfile.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBranchDirection.h; path = dfg/DFGBranchDirection.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F86A26C1D6F796200CB0C92 /* HeapOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapOperation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F86A26E1D6F7B3100CB0C92 /* GCTypeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCTypeMap.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F86AE1F1C5311C5006BE8EC /* B3ComputeDivisionMagic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ComputeDivisionMagic.h; path = b3/B3ComputeDivisionMagic.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeUseDef.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2917,6 +2919,12 @@
</span><span class="cx">                 0FA581B7150E952A00B9A2D9 /* DFGNodeFlags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNodeFlags.cpp; path = dfg/DFGNodeFlags.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNodeFlags.h; path = dfg/DFGNodeFlags.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNodeType.h; path = dfg/DFGNodeType.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FA762001DB9242300B7A2FD /* CollectionScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CollectionScope.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FA762011DB9242300B7A2FD /* CollectionScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectionScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FA762021DB9242300B7A2FD /* MutatorState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MutatorState.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FA762031DB9242300B7A2FD /* MutatorState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MutatorState.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FA762081DB9283C00B7A2FD /* HelpingGCScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HelpingGCScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FA7620A1DB959F600B7A2FD /* AllocatingScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllocatingScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FA7A8E918B413C80052371D /* Reg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Reg.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA7A8EA18B413C80052371D /* Reg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reg.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScratchRegisterAllocator.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2958,7 +2966,6 @@
</span><span class="cx">                 0FB4FB701BC843140025CA5A /* FTLLazySlowPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLLazySlowPath.cpp; path = ftl/FTLLazySlowPath.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FB4FB711BC843140025CA5A /* FTLLazySlowPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLLazySlowPath.h; path = ftl/FTLLazySlowPath.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FB4FB721BC843140025CA5A /* FTLLazySlowPathCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLLazySlowPathCall.h; path = ftl/FTLLazySlowPathCall.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0FB530381D90404600F28AE3 /* AllocationScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllocationScope.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LazyOperandValueProfile.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LazyOperandValueProfile.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MethodOfGettingAValueProfile.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3452,7 +3459,6 @@
</span><span class="cx">                 2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSManagedValueInternal.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierBuffer.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2A4EC90A1860D6C20094F782 /* WriteBarrierBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierBuffer.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                2A6F462517E959CE00C45C98 /* HeapOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapOperation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeferGC.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2A83638318D7D0EE0000EBCC /* EdenGCActivityCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EdenGCActivityCallback.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 2A83638418D7D0EE0000EBCC /* EdenGCActivityCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdenGCActivityCallback.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5451,7 +5457,7 @@
</span><span class="cx">                 142E312A134FF0A600AFADB5 /* heap */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><del>-                                0FB530381D90404600F28AE3 /* AllocationScope.h */,
</del><ins>+                                0FA7620A1DB959F600B7A2FD /* AllocatingScope.h */,
</ins><span class="cx">                                 0F9630351D4192C3005609D9 /* AllocatorAttributes.cpp */,
</span><span class="cx">                                 0F9630361D4192C3005609D9 /* AllocatorAttributes.h */,
</span><span class="cx">                                 0F070A421D543A89006E7232 /* CellContainer.h */,
</span><span class="lines">@@ -5460,6 +5466,8 @@
</span><span class="cx">                                 0FD8A31117D4326C00CA2C40 /* CodeBlockSet.cpp */,
</span><span class="cx">                                 0FD8A31217D4326C00CA2C40 /* CodeBlockSet.h */,
</span><span class="cx">                                 0F664CE71DA304ED00B00A11 /* CodeBlockSetInlines.h */,
</span><ins>+                                0FA762001DB9242300B7A2FD /* CollectionScope.cpp */,
+                                0FA762011DB9242300B7A2FD /* CollectionScope.h */,
</ins><span class="cx">                                 146B14DB12EB5B12001BEC1B /* ConservativeRoots.cpp */,
</span><span class="cx">                                 149DAAF212EB559D0083B12B /* ConservativeRoots.h */,
</span><span class="cx">                                 2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */,
</span><span class="lines">@@ -5504,8 +5512,6 @@
</span><span class="cx">                                 C2DA778218E259990066FCB6 /* HeapInlines.h */,
</span><span class="cx">                                 2AD8932917E3868F00668276 /* HeapIterationScope.h */,
</span><span class="cx">                                 A5339EC81BB4B4510054F005 /* HeapObserver.h */,
</span><del>-                                0F86A26C1D6F796200CB0C92 /* HeapOperation.cpp */,
-                                2A6F462517E959CE00C45C98 /* HeapOperation.h */,
</del><span class="cx">                                 A5398FA91C750D950060A963 /* HeapProfiler.cpp */,
</span><span class="cx">                                 A5398FAA1C750D950060A963 /* HeapProfiler.h */,
</span><span class="cx">                                 14F97446138C853E00DA1C67 /* HeapRootVisitor.h */,
</span><span class="lines">@@ -5520,6 +5526,7 @@
</span><span class="cx">                                 0FADE6721D4D23BC00768457 /* HeapUtil.h */,
</span><span class="cx">                                 FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */,
</span><span class="cx">                                 FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */,
</span><ins>+                                0FA762081DB9283C00B7A2FD /* HelpingGCScope.h */,
</ins><span class="cx">                                 C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */,
</span><span class="cx">                                 C25F8BCC157544A900245B71 /* IncrementalSweeper.h */,
</span><span class="cx">                                 0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */,
</span><span class="lines">@@ -5545,6 +5552,8 @@
</span><span class="cx">                                 0F7C5FB91D8895050044F5E2 /* MarkedSpaceInlines.h */,
</span><span class="cx">                                 142D6F0E13539A4100B02E86 /* MarkStack.cpp */,
</span><span class="cx">                                 142D6F0F13539A4100B02E86 /* MarkStack.h */,
</span><ins>+                                0FA762021DB9242300B7A2FD /* MutatorState.cpp */,
+                                0FA762031DB9242300B7A2FD /* MutatorState.h */,
</ins><span class="cx">                                 ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */,
</span><span class="cx">                                 C225494215F7DBAA0065E898 /* SlotVisitor.cpp */,
</span><span class="cx">                                 14BA78F013AAB88F005B7C2C /* SlotVisitor.h */,
</span><span class="lines">@@ -7506,6 +7515,7 @@
</span><span class="cx">                                 0FEC85031BDACDAC0080FF74 /* B3BasicBlockUtils.h in Headers */,
</span><span class="cx">                                 0FEC85041BDACDAC0080FF74 /* B3BlockWorklist.h in Headers */,
</span><span class="cx">                                 0FEC85061BDACDAC0080FF74 /* B3CheckSpecial.h in Headers */,
</span><ins>+                                0FA762071DB9243300B7A2FD /* MutatorState.h in Headers */,
</ins><span class="cx">                                 0FEC85081BDACDAC0080FF74 /* B3CheckValue.h in Headers */,
</span><span class="cx">                                 0FEC850A1BDACDAC0080FF74 /* B3Common.h in Headers */,
</span><span class="cx">                                 DC454B8D1D00E824004C18AF /* AirDumpAsJS.h in Headers */,
</span><span class="lines">@@ -7606,7 +7616,6 @@
</span><span class="cx">                                 62D755D71B84FB4A001801FA /* CallFrameShuffler.h in Headers */,
</span><span class="cx">                                 0F0B83B114BCF71800885B4F /* CallLinkInfo.h in Headers */,
</span><span class="cx">                                 0F93329E14CA7DC50085F3C6 /* CallLinkStatus.h in Headers */,
</span><del>-                                0FB530391D90404C00F28AE3 /* AllocationScope.h in Headers */,
</del><span class="cx">                                 627673241B680C1E00FD9F2E /* CallMode.h in Headers */,
</span><span class="cx">                                 0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
</span><span class="cx">                                 0F3B7E2B19A11B8000D9BC56 /* CallVariant.h in Headers */,
</span><span class="lines">@@ -7911,6 +7920,8 @@
</span><span class="cx">                                 2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */,
</span><span class="cx">                                 BC3046070E1F497F003232CF /* Error.h in Headers */,
</span><span class="cx">                                 BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */,
</span><ins>+                                0FA7620B1DB959F900B7A2FD /* AllocatingScope.h in Headers */,
+                                0FA762091DB9283E00B7A2FD /* HelpingGCScope.h in Headers */,
</ins><span class="cx">                                 FEB58C15187B8B160098EF0B /* ErrorHandlingScope.h in Headers */,
</span><span class="cx">                                 BC02E98D0E183E38000F9297 /* ErrorInstance.h in Headers */,
</span><span class="cx">                                 BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */,
</span><span class="lines">@@ -8060,7 +8071,6 @@
</span><span class="cx">                                 2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */,
</span><span class="cx">                                 A5339EC91BB4B4600054F005 /* HeapObserver.h in Headers */,
</span><span class="cx">                                 AD2FCBEB1DB58DAD00B3E736 /* JSWebAssemblyTable.h in Headers */,
</span><del>-                                2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */,
</del><span class="cx">                                 14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
</span><span class="cx">                                 C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */,
</span><span class="cx">                                 C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */,
</span><span class="lines">@@ -8123,6 +8133,7 @@
</span><span class="cx">                                 A18193E31B4E0CDB00FC1029 /* IntlCollatorConstructor.lut.h in Headers */,
</span><span class="cx">                                 A1B9E23E1B4E0D6700BC7FED /* IntlCollatorPrototype.h in Headers */,
</span><span class="cx">                                 A18193E41B4E0CDB00FC1029 /* IntlCollatorPrototype.lut.h in Headers */,
</span><ins>+                                0FA762051DB9242900B7A2FD /* CollectionScope.h in Headers */,
</ins><span class="cx">                                 A1587D6E1B4DC14100D69849 /* IntlDateTimeFormat.h in Headers */,
</span><span class="cx">                                 FE187A0F1C030D6C0038BBCA /* SnippetOperand.h in Headers */,
</span><span class="cx">                                 A1587D701B4DC14100D69849 /* IntlDateTimeFormatConstructor.h in Headers */,
</span><span class="lines">@@ -9489,7 +9500,6 @@
</span><span class="cx">                                 A78A977A179738B8009DF744 /* DFGPlan.cpp in Sources */,
</span><span class="cx">                                 0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */,
</span><span class="cx">                                 0FFFC95D14EF90B300C72532 /* DFGPredictionPropagationPhase.cpp in Sources */,
</span><del>-                                0F86A26D1D6F796500CB0C92 /* HeapOperation.cpp in Sources */,
</del><span class="cx">                                 0F3E01AA19D353A500F61B7F /* DFGPrePostNumbering.cpp in Sources */,
</span><span class="cx">                                 0F2B9CEC19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp in Sources */,
</span><span class="cx">                                 0FB17662196B8F9E0091052A /* DFGPureValue.cpp in Sources */,
</span><span class="lines">@@ -9636,6 +9646,7 @@
</span><span class="cx">                                 A58E35911860DECF001F24FE /* InjectedScriptHost.cpp in Sources */,
</span><span class="cx">                                 A513E5CA185F9624007E95AD /* InjectedScriptManager.cpp in Sources */,
</span><span class="cx">                                 A5840E20187B7B8600843B10 /* InjectedScriptModule.cpp in Sources */,
</span><ins>+                                0FA762041DB9242600B7A2FD /* CollectionScope.cpp in Sources */,
</ins><span class="cx">                                 148A7BEF1B82975A002D9157 /* InlineCallFrame.cpp in Sources */,
</span><span class="cx">                                 0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */,
</span><span class="cx">                                 A5CEEE14187F3BAD00E55C99 /* InspectorAgent.cpp in Sources */,
</span><span class="lines">@@ -9791,6 +9802,7 @@
</span><span class="cx">                                 DC17E8171C9C91D6008A6AB3 /* ShadowChicken.cpp in Sources */,
</span><span class="cx">                                 A7299D9D17D12837005F5FF9 /* JSSet.cpp in Sources */,
</span><span class="cx">                                 A790DD6F182F499700588807 /* JSSetIterator.cpp in Sources */,
</span><ins>+                                0FA762061DB9243100B7A2FD /* MutatorState.cpp in Sources */,
</ins><span class="cx">                                 1428083A107EC0750013E7B2 /* CLoopStack.cpp in Sources */,
</span><span class="cx">                                 147F39D5107EC37600427A48 /* JSString.cpp in Sources */,
</span><span class="cx">                                 70EC0EC21AA0D7DA00B6AAFA /* JSStringIterator.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -3474,7 +3474,7 @@
</span><span class="cx">         // This accomplishes (1), and does its own book-keeping about whether it has already happened.
</span><span class="cx">         if (!jitCode()-&gt;dfgCommon()-&gt;invalidate()) {
</span><span class="cx">             // We've already been invalidated.
</span><del>-            RELEASE_ASSERT(this != replacement() || (m_vm-&gt;heap.isCollecting() &amp;&amp; !Heap::isMarked(ownerScriptExecutable())));
</del><ins>+            RELEASE_ASSERT(this != replacement() || (m_vm-&gt;heap.isCurrentThreadBusy() &amp;&amp; !Heap::isMarked(ownerScriptExecutable())));
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -3506,7 +3506,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Jettison can happen during GC. We don't want to install code to a dead executable
</span><span class="cx">     // because that would add a dead object to the remembered set.
</span><del>-    if (m_vm-&gt;heap.isCollecting() &amp;&amp; !Heap::isMarked(ownerScriptExecutable()))
</del><ins>+    if (m_vm-&gt;heap.isCurrentThreadBusy() &amp;&amp; !Heap::isMarked(ownerScriptExecutable()))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // This accomplishes (2).
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWorklistcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -103,9 +103,10 @@
</span><span class="cx">         if (Options::verboseCompilationQueue())
</span><span class="cx">             dataLog(m_worklist, &quot;: Compiling &quot;, m_plan-&gt;key(), &quot; asynchronously\n&quot;);
</span><span class="cx">         
</span><del>-        RELEASE_ASSERT(!m_plan-&gt;vm-&gt;heap.isCollecting());
</del><ins>+        // There's no way for the GC to be safepointing since we own rightToRun.
+        RELEASE_ASSERT(m_plan-&gt;vm-&gt;heap.mutatorState() != MutatorState::HelpingGC);
</ins><span class="cx">         m_plan-&gt;compileInThread(*m_longLivedState, &amp;m_data);
</span><del>-        RELEASE_ASSERT(m_plan-&gt;stage == Plan::Cancelled || !m_plan-&gt;vm-&gt;heap.isCollecting());
</del><ins>+        RELEASE_ASSERT(m_plan-&gt;stage == Plan::Cancelled || m_plan-&gt;vm-&gt;heap.mutatorState() != MutatorState::HelpingGC);
</ins><span class="cx">         
</span><span class="cx">         {
</span><span class="cx">             LockHolder locker(*m_worklist.m_lock);
</span><span class="lines">@@ -123,7 +124,7 @@
</span><span class="cx">             
</span><span class="cx">             m_worklist.m_planCompiled.notifyAll();
</span><span class="cx">         }
</span><del>-        RELEASE_ASSERT(!m_plan-&gt;vm-&gt;heap.isCollecting());
</del><ins>+        RELEASE_ASSERT(m_plan-&gt;vm-&gt;heap.mutatorState() != MutatorState::HelpingGC);
</ins><span class="cx">         
</span><span class="cx">         return WorkResult::Continue;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -65,7 +65,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (safepointResult.didGetCancelled())
</span><span class="cx">         return;
</span><del>-    RELEASE_ASSERT(!state.graph.m_vm.heap.isCollecting());
</del><ins>+    RELEASE_ASSERT(state.graph.m_vm.heap.mutatorState() != MutatorState::HelpingGC);
</ins><span class="cx">     
</span><span class="cx">     if (state.allocationFailed)
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapAllocatingScopeh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/AllocatingScope.h (0 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/AllocatingScope.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/AllocatingScope.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 &quot;Heap.h&quot;
+
+namespace JSC {
+
+class AllocatingScope {
+public:
+    AllocatingScope(Heap&amp; heap)
+        : m_heap(heap)
+    {
+        RELEASE_ASSERT(m_heap.m_mutatorState == MutatorState::Running);
+        m_heap.m_mutatorState = MutatorState::Allocating;
+    }
+    
+    ~AllocatingScope()
+    {
+        RELEASE_ASSERT(m_heap.m_mutatorState == MutatorState::Allocating);
+        m_heap.m_mutatorState = MutatorState::Running;
+    }
+
+private:
+    Heap&amp; m_heap;
+};
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapAllocationScopeh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/AllocationScope.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/AllocationScope.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/AllocationScope.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,53 +0,0 @@
</span><del>-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#pragma once
-
-#include &quot;Heap.h&quot;
-
-namespace JSC {
-
-class AllocationScope {
-public:
-    AllocationScope(Heap&amp; heap)
-        : m_heap(heap)
-        , m_lastOperation(m_heap.m_operationInProgress)
-    {
-        ASSERT(m_lastOperation == NoOperation || m_lastOperation == Allocation);
-        m_heap.m_operationInProgress = Allocation;
-    }
-    
-    ~AllocationScope()
-    {
-        ASSERT(m_heap.m_operationInProgress == Allocation);
-        m_heap.m_operationInProgress = m_lastOperation;
-    }
-private:
-    Heap&amp; m_heap;
-    HeapOperation m_lastOperation;
-};
-
-} // namespace JSC
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCodeBlockSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2016 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">@@ -77,10 +77,10 @@
</span><span class="cx">         codeBlock-&gt;classInfo()-&gt;methodTable.destroy(codeBlock);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CodeBlockSet::deleteUnmarkedAndUnreferenced(HeapOperation collectionType)
</del><ins>+void CodeBlockSet::deleteUnmarkedAndUnreferenced(CollectionScope scope)
</ins><span class="cx"> {
</span><span class="cx">     LockHolder locker(&amp;m_lock);
</span><del>-    HashSet&lt;CodeBlock*&gt;&amp; set = collectionType == EdenCollection ? m_newCodeBlocks : m_oldCodeBlocks;
</del><ins>+    HashSet&lt;CodeBlock*&gt;&amp; set = scope == CollectionScope::Eden ? m_newCodeBlocks : m_oldCodeBlocks;
</ins><span class="cx">     Vector&lt;CodeBlock*&gt; unmarked;
</span><span class="cx">     for (CodeBlock* codeBlock : set) {
</span><span class="cx">         if (Heap::isMarked(codeBlock))
</span><span class="lines">@@ -94,7 +94,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Any remaining young CodeBlocks are live and need to be promoted to the set of old CodeBlocks.
</span><del>-    if (collectionType == EdenCollection)
</del><ins>+    if (scope == CollectionScope::Eden)
</ins><span class="cx">         promoteYoungCodeBlocks(locker);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCodeBlockSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/CodeBlockSet.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CodeBlockSet.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/CodeBlockSet.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2014, 2016 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,8 +25,8 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include &quot;CollectionScope.h&quot;
</ins><span class="cx"> #include &quot;GCSegmentedArray.h&quot;
</span><del>-#include &quot;HeapOperation.h&quot;
</del><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="cx"> #include &lt;wtf/Lock.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="lines">@@ -67,7 +67,7 @@
</span><span class="cx">     
</span><span class="cx">     // Delete all code blocks that are only referenced by this set (i.e. owned
</span><span class="cx">     // by this set), and that have not been marked.
</span><del>-    void deleteUnmarkedAndUnreferenced(HeapOperation);
</del><ins>+    void deleteUnmarkedAndUnreferenced(CollectionScope);
</ins><span class="cx">     
</span><span class="cx">     // Add all currently executing CodeBlocks to the remembered set to be 
</span><span class="cx">     // re-scanned during the next collection.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCollectionScopecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/CollectionScope.cpp (0 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CollectionScope.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/CollectionScope.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;CollectionScope.h&quot;
+
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace JSC {
+
+const char* collectionScopeName(CollectionScope scope)
+{
+    switch (scope) {
+    case CollectionScope::Eden:
+        return &quot;Eden&quot;;
+    case CollectionScope::Full:
+        return &quot;Full&quot;;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+} // namespace JSC
+
+namespace WTF {
+
+void printInternal(PrintStream&amp; out, JSC::CollectionScope scope)
+{
+    out.print(JSC::collectionScopeName(scope));
+}
+
+} // namespace WTF
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCollectionScopeh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/CollectionScope.h (0 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CollectionScope.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/CollectionScope.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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
+
+namespace JSC {
+
+enum class CollectionScope { Eden, Full };
+
+const char* collectionScopeName(CollectionScope);
+
+} // namespace JSC
+
+namespace WTF {
+
+class PrintStream;
+
+void printInternal(PrintStream&amp; out, JSC::CollectionScope);
+
+} // namespace WTF
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapEdenGCActivityCallbackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 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">@@ -39,7 +39,7 @@
</span><span class="cx"> 
</span><span class="cx"> void EdenGCActivityCallback::doCollection()
</span><span class="cx"> {
</span><del>-    m_vm-&gt;heap.collect(EdenCollection);
</del><ins>+    m_vm-&gt;heap.collect(CollectionScope::Eden);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> double EdenGCActivityCallback::lastGCLength()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapFullGCActivityCallbackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/FullGCActivityCallback.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/FullGCActivityCallback.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/FullGCActivityCallback.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 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">@@ -55,7 +55,7 @@
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    heap.collect(FullCollection);
</del><ins>+    heap.collect(CollectionScope::Full);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> double FullGCActivityCallback::lastGCLength()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapGCTypeMaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/GCTypeMap.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/GCTypeMap.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/GCTypeMap.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><del>-#include &quot;HeapOperation.h&quot;
</del><ins>+#include &quot;CollectionScope.h&quot;
</ins><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -35,20 +35,28 @@
</span><span class="cx">     T eden;
</span><span class="cx">     T full;
</span><span class="cx">     
</span><del>-    T&amp; operator[](HeapOperation operation)
</del><ins>+    T&amp; operator[](CollectionScope scope)
</ins><span class="cx">     {
</span><del>-        if (operation == FullCollection)
</del><ins>+        switch (scope) {
+        case CollectionScope::Full:
</ins><span class="cx">             return full;
</span><del>-        ASSERT(operation == EdenCollection);
-        return eden;
</del><ins>+        case CollectionScope::Eden:
+            return eden;
+        }
+        ASSERT_NOT_REACHED();
+        return full;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    const T&amp; operator[](HeapOperation operation) const
</del><ins>+    const T&amp; operator[](CollectionScope scope) const
</ins><span class="cx">     {
</span><del>-        if (operation == FullCollection)
</del><ins>+        switch (scope) {
+        case CollectionScope::Full:
</ins><span class="cx">             return full;
</span><del>-        ASSERT(operation == EdenCollection);
-        return eden;
</del><ins>+        case CollectionScope::Eden:
+            return eden;
+        }
+        RELEASE_ASSERT_NOT_REACHED();
+        return full;
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #include &quot;HeapSnapshot.h&quot;
</span><span class="cx"> #include &quot;HeapStatistics.h&quot;
</span><span class="cx"> #include &quot;HeapVerifier.h&quot;
</span><ins>+#include &quot;HelpingGCScope.h&quot;
</ins><span class="cx"> #include &quot;IncrementalSweeper.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><span class="cx"> #include &quot;JITStubRoutineSet.h&quot;
</span><span class="lines">@@ -140,15 +141,15 @@
</span><span class="cx">     return *result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SimpleStats&amp; timingStats(const char* name, HeapOperation operation)
</del><ins>+SimpleStats&amp; timingStats(const char* name, CollectionScope scope)
</ins><span class="cx"> {
</span><del>-    return timingStats().add(name, GCTypeMap&lt;SimpleStats&gt;()).iterator-&gt;value[operation];
</del><ins>+    return timingStats().add(name, GCTypeMap&lt;SimpleStats&gt;()).iterator-&gt;value[scope];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> class TimingScope {
</span><span class="cx"> public:
</span><del>-    TimingScope(HeapOperation operation, const char* name)
-        : m_operation(operation)
</del><ins>+    TimingScope(Optional&lt;CollectionScope&gt; scope, const char* name)
+        : m_scope(scope)
</ins><span class="cx">         , m_name(name)
</span><span class="cx">     {
</span><span class="cx">         if (measurePhaseTiming())
</span><span class="lines">@@ -156,18 +157,18 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     TimingScope(Heap&amp; heap, const char* name)
</span><del>-        : TimingScope(heap.operationInProgress(), name)
</del><ins>+        : TimingScope(heap.collectionScope(), name)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void setOperation(HeapOperation operation)
</del><ins>+    void setScope(Optional&lt;CollectionScope&gt; scope)
</ins><span class="cx">     {
</span><del>-        m_operation = operation;
</del><ins>+        m_scope = scope;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void setOperation(Heap&amp; heap)
</del><ins>+    void setScope(Heap&amp; heap)
</ins><span class="cx">     {
</span><del>-        setOperation(heap.operationInProgress());
</del><ins>+        setScope(heap.collectionScope());
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     ~TimingScope()
</span><span class="lines">@@ -175,13 +176,13 @@
</span><span class="cx">         if (measurePhaseTiming()) {
</span><span class="cx">             double after = monotonicallyIncreasingTimeMS();
</span><span class="cx">             double timing = after - m_before;
</span><del>-            SimpleStats&amp; stats = timingStats(m_name, m_operation);
</del><ins>+            SimpleStats&amp; stats = timingStats(m_name, *m_scope);
</ins><span class="cx">             stats.add(timing);
</span><del>-            dataLog(&quot;[GC:&quot;, m_operation, &quot;] &quot;, m_name, &quot; took: &quot;, timing, &quot; ms (average &quot;, stats.mean(), &quot; ms).\n&quot;);
</del><ins>+            dataLog(&quot;[GC:&quot;, *m_scope, &quot;] &quot;, m_name, &quot; took: &quot;, timing, &quot; ms (average &quot;, stats.mean(), &quot; ms).\n&quot;);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> private:
</span><del>-    HeapOperation m_operation;
</del><ins>+    Optional&lt;CollectionScope&gt; m_scope;
</ins><span class="cx">     double m_before;
</span><span class="cx">     const char* m_name;
</span><span class="cx"> };
</span><span class="lines">@@ -203,7 +204,6 @@
</span><span class="cx">     , m_maxHeapSize(m_minBytesPerCycle)
</span><span class="cx">     , m_shouldDoFullCollection(false)
</span><span class="cx">     , m_totalBytesVisited(0)
</span><del>-    , m_operationInProgress(NoOperation)
</del><span class="cx">     , m_objectSpace(this)
</span><span class="cx">     , m_extraMemorySize(0)
</span><span class="cx">     , m_deprecatedExtraMemorySize(0)
</span><span class="lines">@@ -252,7 +252,8 @@
</span><span class="cx"> void Heap::lastChanceToFinalize()
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(!m_vm-&gt;entryScope);
</span><del>-    RELEASE_ASSERT(m_operationInProgress == NoOperation);
</del><ins>+    RELEASE_ASSERT(!m_collectionScope);
+    RELEASE_ASSERT(m_mutatorState == MutatorState::Running);
</ins><span class="cx"> 
</span><span class="cx">     m_arrayBuffers.lastChanceToFinalize();
</span><span class="cx">     m_codeBlocks-&gt;lastChanceToFinalize();
</span><span class="lines">@@ -408,7 +409,7 @@
</span><span class="cx">         }
</span><span class="cx"> #endif // ENABLE(SAMPLING_PROFILER)
</span><span class="cx"> 
</span><del>-        if (m_operationInProgress == FullCollection) {
</del><ins>+        if (m_collectionScope == CollectionScope::Full) {
</ins><span class="cx">             m_opaqueRoots.clear();
</span><span class="cx">             m_slotVisitor.clearMarkStack();
</span><span class="cx">         }
</span><span class="lines">@@ -431,7 +432,7 @@
</span><span class="cx">                         slotVisitor = m_availableParallelSlotVisitors.takeLast();
</span><span class="cx">                 }
</span><span class="cx"> 
</span><del>-                WTF::registerGCThread();
</del><ins>+                WTF::registerGCThread(GCThreadType::Helper);
</ins><span class="cx"> 
</span><span class="cx">                 {
</span><span class="cx">                     ParallelModeEnabler parallelModeEnabler(*slotVisitor);
</span><span class="lines">@@ -526,7 +527,7 @@
</span><span class="cx"> void Heap::beginMarking()
</span><span class="cx"> {
</span><span class="cx">     TimingScope timingScope(*this, &quot;Heap::beginMarking&quot;);
</span><del>-    if (m_operationInProgress == FullCollection)
</del><ins>+    if (m_collectionScope == CollectionScope::Full)
</ins><span class="cx">         m_codeBlocks-&gt;clearMarksForFullCollection();
</span><span class="cx">     
</span><span class="cx">     {
</span><span class="lines">@@ -544,7 +545,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Heap::visitSmallStrings()
</span><span class="cx"> {
</span><del>-    if (!m_vm-&gt;smallStrings.needsToBeVisited(m_operationInProgress))
</del><ins>+    if (!m_vm-&gt;smallStrings.needsToBeVisited(*m_collectionScope))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_vm-&gt;smallStrings.visitStrongReferences(m_slotVisitor);
</span><span class="lines">@@ -763,7 +764,7 @@
</span><span class="cx">         dataLogF(&quot;\nNumber of live Objects after GC %lu, took %.6f secs\n&quot;, static_cast&lt;unsigned long&gt;(visitCount), WTF::monotonicallyIncreasingTime() - gcStartTime);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (m_operationInProgress == FullCollection)
</del><ins>+    if (m_collectionScope == CollectionScope::Full)
</ins><span class="cx">         m_totalBytesVisited = 0;
</span><span class="cx"> 
</span><span class="cx">     m_totalBytesVisitedThisCycle = m_slotVisitor.bytesVisited() + threadBytesVisited();
</span><span class="lines">@@ -871,7 +872,7 @@
</span><span class="cx">     // If JavaScript is running, it's not safe to delete all JavaScript code, since
</span><span class="cx">     // we'll end up returning to deleted code.
</span><span class="cx">     RELEASE_ASSERT(!m_vm-&gt;entryScope);
</span><del>-    ASSERT(m_operationInProgress == NoOperation);
</del><ins>+    ASSERT(!m_collectionScope);
</ins><span class="cx"> 
</span><span class="cx">     completeAllJITPlans();
</span><span class="cx"> 
</span><span class="lines">@@ -908,7 +909,7 @@
</span><span class="cx"> void Heap::deleteUnmarkedCompiledCode()
</span><span class="cx"> {
</span><span class="cx">     clearUnmarkedExecutables();
</span><del>-    m_codeBlocks-&gt;deleteUnmarkedAndUnreferenced(m_operationInProgress);
</del><ins>+    m_codeBlocks-&gt;deleteUnmarkedAndUnreferenced(*m_collectionScope);
</ins><span class="cx">     m_jitStubRoutines-&gt;deleteUnmarkedJettisonedStubRoutines();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -932,7 +933,7 @@
</span><span class="cx">     if (!m_isSafeToCollect)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    collectWithoutAnySweep(FullCollection);
</del><ins>+    collectWithoutAnySweep(CollectionScope::Full);
</ins><span class="cx"> 
</span><span class="cx">     DeferGCForAWhile deferGC(*this);
</span><span class="cx">     if (UNLIKELY(Options::useImmortalObjects()))
</span><span class="lines">@@ -955,29 +956,29 @@
</span><span class="cx">     sweepAllLogicallyEmptyWeakBlocks();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::collect(HeapOperation collectionType)
</del><ins>+void Heap::collect(Optional&lt;CollectionScope&gt; scope)
</ins><span class="cx"> {
</span><span class="cx">     SuperSamplerScope superSamplerScope(false);
</span><span class="cx">     if (!m_isSafeToCollect)
</span><span class="cx">         return;
</span><del>-
-    collectWithoutAnySweep(collectionType);
</del><ins>+    
+    collectWithoutAnySweep(scope);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-NEVER_INLINE void Heap::collectWithoutAnySweep(HeapOperation collectionType)
</del><ins>+NEVER_INLINE void Heap::collectWithoutAnySweep(Optional&lt;CollectionScope&gt; scope)
</ins><span class="cx"> {
</span><span class="cx">     void* stackTop;
</span><span class="cx">     ALLOCATE_AND_GET_REGISTER_STATE(registers);
</span><span class="cx"> 
</span><del>-    collectImpl(collectionType, wtfThreadData().stack().origin(), &amp;stackTop, registers);
</del><ins>+    collectImpl(scope, wtfThreadData().stack().origin(), &amp;stackTop, registers);
</ins><span class="cx"> 
</span><span class="cx">     sanitizeStackForVM(m_vm);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NEVER_INLINE void Heap::collectImpl(HeapOperation collectionType, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&amp; calleeSavedRegisters)
</del><ins>+NEVER_INLINE void Heap::collectImpl(Optional&lt;CollectionScope&gt; scope, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&amp; calleeSavedRegisters)
</ins><span class="cx"> {
</span><span class="cx">     SuperSamplerScope superSamplerScope(false);
</span><del>-    TimingScope collectImplTimingScope(collectionType, &quot;Heap::collectImpl&quot;);
</del><ins>+    TimingScope collectImplTimingScope(scope, &quot;Heap::collectImpl&quot;);
</ins><span class="cx">     
</span><span class="cx"> #if ENABLE(ALLOCATION_LOGGING)
</span><span class="cx">     dataLogF(&quot;JSC GC starting collection.\n&quot;);
</span><span class="lines">@@ -990,81 +991,78 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     double gcStartTime;
</span><ins>+    
+    if (vm()-&gt;typeProfiler()) {
+        DeferGCForAWhile awhile(*this);
+        vm()-&gt;typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;GC&quot;));
+    }
+    
+#if ENABLE(JIT)
</ins><span class="cx">     {
</span><del>-        TimingScope earlyTimingScope(collectionType, &quot;Heap::collectImpl before markRoots&quot;);
-
-        if (vm()-&gt;typeProfiler()) {
-            DeferGCForAWhile awhile(*this);
-            vm()-&gt;typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;GC&quot;));
-        }
-
-#if ENABLE(JIT)
-        {
-            DeferGCForAWhile awhile(*this);
-            JITWorklist::instance()-&gt;completeAllForVM(*m_vm);
-        }
</del><ins>+        DeferGCForAWhile awhile(*this);
+        JITWorklist::instance()-&gt;completeAllForVM(*m_vm);
+    }
</ins><span class="cx"> #endif // ENABLE(JIT)
</span><del>-
-        vm()-&gt;shadowChicken().update(*vm(), vm()-&gt;topCallFrame);
-
-        RELEASE_ASSERT(!m_deferralDepth);
-        ASSERT(vm()-&gt;currentThreadIsHoldingAPILock());
-        RELEASE_ASSERT(vm()-&gt;atomicStringTable() == wtfThreadData().atomicStringTable());
-        ASSERT(m_isSafeToCollect);
-        RELEASE_ASSERT(m_operationInProgress == NoOperation);
-
-        suspendCompilerThreads();
-        willStartCollection(collectionType);
</del><ins>+    
+    vm()-&gt;shadowChicken().update(*vm(), vm()-&gt;topCallFrame);
+    
+    RELEASE_ASSERT(!m_deferralDepth);
+    ASSERT(vm()-&gt;currentThreadIsHoldingAPILock());
+    RELEASE_ASSERT(vm()-&gt;atomicStringTable() == wtfThreadData().atomicStringTable());
+    ASSERT(m_isSafeToCollect);
+    RELEASE_ASSERT(!m_collectionScope);
+    
+    suspendCompilerThreads();
+    willStartCollection(scope);
+    {
+        HelpingGCScope helpingHeapScope(*this);
</ins><span class="cx">         
</span><del>-        collectImplTimingScope.setOperation(*this);
-        earlyTimingScope.setOperation(*this);
-
</del><ins>+        collectImplTimingScope.setScope(*this);
+        
</ins><span class="cx">         gcStartTime = WTF::monotonicallyIncreasingTime();
</span><span class="cx">         if (m_verifier) {
</span><span class="cx">             // Verify that live objects from the last GC cycle haven't been corrupted by
</span><span class="cx">             // mutators before we begin this new GC cycle.
</span><span class="cx">             m_verifier-&gt;verify(HeapVerifier::Phase::BeforeGC);
</span><del>-
</del><ins>+            
</ins><span class="cx">             m_verifier-&gt;initializeGCCycle();
</span><span class="cx">             m_verifier-&gt;gatherLiveObjects(HeapVerifier::Phase::BeforeMarking);
</span><span class="cx">         }
</span><del>-
</del><ins>+        
</ins><span class="cx">         flushOldStructureIDTables();
</span><span class="cx">         stopAllocation();
</span><span class="cx">         prepareForMarking();
</span><span class="cx">         flushWriteBarrierBuffer();
</span><del>-
</del><ins>+        
</ins><span class="cx">         if (HasOwnPropertyCache* cache = vm()-&gt;hasOwnPropertyCache())
</span><span class="cx">             cache-&gt;clear();
</span><ins>+        
+        markRoots(gcStartTime, stackOrigin, stackTop, calleeSavedRegisters);
+        
+        if (m_verifier) {
+            m_verifier-&gt;gatherLiveObjects(HeapVerifier::Phase::AfterMarking);
+            m_verifier-&gt;verify(HeapVerifier::Phase::AfterMarking);
+        }
+        
+        if (vm()-&gt;typeProfiler())
+            vm()-&gt;typeProfiler()-&gt;invalidateTypeSetCache();
+        
+        reapWeakHandles();
+        pruneStaleEntriesFromWeakGCMaps();
+        sweepArrayBuffers();
+        snapshotUnswept();
+        finalizeUnconditionalFinalizers();
+        removeDeadCompilerWorklistEntries();
+        deleteUnmarkedCompiledCode();
+        deleteSourceProviderCaches();
+        
+        notifyIncrementalSweeper();
+        m_codeBlocks-&gt;writeBarrierCurrentlyExecuting(this);
+        m_codeBlocks-&gt;clearCurrentlyExecuting();
+        
+        prepareForAllocation();
+        updateAllocationLimits();
</ins><span class="cx">     }
</span><del>-
-    markRoots(gcStartTime, stackOrigin, stackTop, calleeSavedRegisters);
-    
-    TimingScope lateTimingScope(*this, &quot;Heap::collectImpl after markRoots&quot;);
-
-    if (m_verifier) {
-        m_verifier-&gt;gatherLiveObjects(HeapVerifier::Phase::AfterMarking);
-        m_verifier-&gt;verify(HeapVerifier::Phase::AfterMarking);
-    }
-
-    if (vm()-&gt;typeProfiler())
-        vm()-&gt;typeProfiler()-&gt;invalidateTypeSetCache();
-
-    reapWeakHandles();
-    pruneStaleEntriesFromWeakGCMaps();
-    sweepArrayBuffers();
-    snapshotUnswept();
-    finalizeUnconditionalFinalizers();
-    removeDeadCompilerWorklistEntries();
-    deleteUnmarkedCompiledCode();
-    deleteSourceProviderCaches();
-
-    notifyIncrementalSweeper();
-    m_codeBlocks-&gt;writeBarrierCurrentlyExecuting(this);
-    m_codeBlocks-&gt;clearCurrentlyExecuting();
-
-    prepareForAllocation();
-    updateAllocationLimits();
</del><span class="cx">     didFinishCollection(gcStartTime);
</span><span class="cx">     resumeCompilerThreads();
</span><span class="cx">     sweepLargeAllocations();
</span><span class="lines">@@ -1103,22 +1101,22 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Heap::willStartCollection(HeapOperation collectionType)
</del><ins>+void Heap::willStartCollection(Optional&lt;CollectionScope&gt; scope)
</ins><span class="cx"> {
</span><span class="cx">     if (Options::logGC())
</span><span class="cx">         dataLog(&quot;=&gt; &quot;);
</span><span class="cx">     
</span><del>-    if (shouldDoFullCollection(collectionType)) {
-        m_operationInProgress = FullCollection;
</del><ins>+    if (shouldDoFullCollection(scope)) {
+        m_collectionScope = CollectionScope::Full;
</ins><span class="cx">         m_shouldDoFullCollection = false;
</span><span class="cx">         if (Options::logGC())
</span><span class="cx">             dataLog(&quot;FullCollection, &quot;);
</span><span class="cx">     } else {
</span><del>-        m_operationInProgress = EdenCollection;
</del><ins>+        m_collectionScope = CollectionScope::Eden;
</ins><span class="cx">         if (Options::logGC())
</span><span class="cx">             dataLog(&quot;EdenCollection, &quot;);
</span><span class="cx">     }
</span><del>-    if (m_operationInProgress == FullCollection) {
</del><ins>+    if (m_collectionScope == CollectionScope::Full) {
</ins><span class="cx">         m_sizeBeforeLastFullCollect = m_sizeAfterLastCollect + m_bytesAllocatedThisCycle;
</span><span class="cx">         m_extraMemorySize = 0;
</span><span class="cx">         m_deprecatedExtraMemorySize = 0;
</span><span class="lines">@@ -1129,7 +1127,7 @@
</span><span class="cx">         if (m_fullActivityCallback)
</span><span class="cx">             m_fullActivityCallback-&gt;willCollect();
</span><span class="cx">     } else {
</span><del>-        ASSERT(m_operationInProgress == EdenCollection);
</del><ins>+        ASSERT(m_collectionScope == CollectionScope::Eden);
</ins><span class="cx">         m_sizeBeforeLastEdenCollect = m_sizeAfterLastCollect + m_bytesAllocatedThisCycle;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1147,7 +1145,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Heap::flushWriteBarrierBuffer()
</span><span class="cx"> {
</span><del>-    if (m_operationInProgress == EdenCollection) {
</del><ins>+    if (m_collectionScope == CollectionScope::Eden) {
</ins><span class="cx">         m_writeBarrierBuffer.flush(*this);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -1171,7 +1169,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Heap::pruneStaleEntriesFromWeakGCMaps()
</span><span class="cx"> {
</span><del>-    if (m_operationInProgress != FullCollection)
</del><ins>+    if (m_collectionScope != CollectionScope::Full)
</ins><span class="cx">         return;
</span><span class="cx">     for (auto&amp; pruneCallback : m_weakGCMaps.values())
</span><span class="cx">         pruneCallback();
</span><span class="lines">@@ -1195,7 +1193,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Heap::notifyIncrementalSweeper()
</span><span class="cx"> {
</span><del>-    if (m_operationInProgress == FullCollection) {
</del><ins>+    if (m_collectionScope == CollectionScope::Full) {
</ins><span class="cx">         if (!m_logicallyEmptyWeakBlocks.isEmpty())
</span><span class="cx">             m_indexOfNextLogicallyEmptyWeakBlockToSweep = 0;
</span><span class="cx">     }
</span><span class="lines">@@ -1243,7 +1241,7 @@
</span><span class="cx">     if (Options::gcMaxHeapSize() &amp;&amp; currentHeapSize &gt; Options::gcMaxHeapSize())
</span><span class="cx">         HeapStatistics::exitWithFailure();
</span><span class="cx"> 
</span><del>-    if (m_operationInProgress == FullCollection) {
</del><ins>+    if (m_collectionScope == CollectionScope::Full) {
</ins><span class="cx">         // To avoid pathological GC churn in very small and very large heaps, we set
</span><span class="cx">         // the new allocation limit based on the current size of the heap, with a
</span><span class="cx">         // fixed minimum.
</span><span class="lines">@@ -1298,8 +1296,8 @@
</span><span class="cx"> void Heap::didFinishCollection(double gcStartTime)
</span><span class="cx"> {
</span><span class="cx">     double gcEndTime = WTF::monotonicallyIncreasingTime();
</span><del>-    HeapOperation operation = m_operationInProgress;
-    if (m_operationInProgress == FullCollection)
</del><ins>+    CollectionScope scope = *m_collectionScope;
+    if (scope == CollectionScope::Full)
</ins><span class="cx">         m_lastFullGCLength = gcEndTime - gcStartTime;
</span><span class="cx">     else
</span><span class="cx">         m_lastEdenGCLength = gcEndTime - gcStartTime;
</span><span class="lines">@@ -1322,11 +1320,11 @@
</span><span class="cx">         removeDeadHeapSnapshotNodes(*heapProfiler);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    RELEASE_ASSERT(m_operationInProgress == EdenCollection || m_operationInProgress == FullCollection);
-    m_operationInProgress = NoOperation;
</del><ins>+    RELEASE_ASSERT(m_collectionScope);
+    m_collectionScope = Nullopt;
</ins><span class="cx"> 
</span><span class="cx">     for (auto* observer : m_observers)
</span><del>-        observer-&gt;didGarbageCollect(operation);
</del><ins>+        observer-&gt;didGarbageCollect(scope);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Heap::resumeCompilerThreads()
</span><span class="lines">@@ -1388,7 +1386,7 @@
</span><span class="cx">     if (!isValidThreadState(m_vm))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (m_operationInProgress != NoOperation)
</del><ins>+    if (isCurrentThreadBusy())
</ins><span class="cx">         return false;
</span><span class="cx">     
</span><span class="cx">     return true;
</span><span class="lines">@@ -1465,24 +1463,14 @@
</span><span class="cx">     m_writeBarrierBuffer.add(cell);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool Heap::shouldDoFullCollection(HeapOperation requestedCollectionType) const
</del><ins>+bool Heap::shouldDoFullCollection(Optional&lt;CollectionScope&gt; scope) const
</ins><span class="cx"> {
</span><span class="cx">     if (!Options::useGenerationalGC())
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><del>-    switch (requestedCollectionType) {
-    case EdenCollection:
-        return false;
-    case FullCollection:
-        return true;
-    case AnyCollection:
</del><ins>+    if (!scope)
</ins><span class="cx">         return m_shouldDoFullCollection;
</span><del>-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-        return false;
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-    return false;
</del><ins>+    return *scope == CollectionScope::Full;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Heap::addLogicallyEmptyWeakBlock(WeakBlock* block)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/Heap.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -22,11 +22,11 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ArrayBuffer.h&quot;
</span><ins>+#include &quot;CollectionScope.h&quot;
</ins><span class="cx"> #include &quot;GCIncomingRefCountedSet.h&quot;
</span><span class="cx"> #include &quot;HandleSet.h&quot;
</span><span class="cx"> #include &quot;HandleStack.h&quot;
</span><span class="cx"> #include &quot;HeapObserver.h&quot;
</span><del>-#include &quot;HeapOperation.h&quot;
</del><span class="cx"> #include &quot;ListableHandler.h&quot;
</span><span class="cx"> #include &quot;MachineStackMarker.h&quot;
</span><span class="cx"> #include &quot;MarkedAllocator.h&quot;
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;MarkedBlock.h&quot;
</span><span class="cx"> #include &quot;MarkedBlockSet.h&quot;
</span><span class="cx"> #include &quot;MarkedSpace.h&quot;
</span><ins>+#include &quot;MutatorState.h&quot;
</ins><span class="cx"> #include &quot;Options.h&quot;
</span><span class="cx"> #include &quot;SlotVisitor.h&quot;
</span><span class="cx"> #include &quot;StructureIDTable.h&quot;
</span><span class="lines">@@ -48,7 +49,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-class AllocationScope;
</del><span class="cx"> class CodeBlock;
</span><span class="cx"> class CodeBlockSet;
</span><span class="cx"> class GCDeferralContext;
</span><span class="lines">@@ -61,6 +61,7 @@
</span><span class="cx"> class HeapProfiler;
</span><span class="cx"> class HeapRootVisitor;
</span><span class="cx"> class HeapVerifier;
</span><ins>+class HelpingGCScope;
</ins><span class="cx"> class IncrementalSweeper;
</span><span class="cx"> class JITStubRoutine;
</span><span class="cx"> class JITStubRoutineSet;
</span><span class="lines">@@ -139,11 +140,13 @@
</span><span class="cx">     void addObserver(HeapObserver* observer) { m_observers.append(observer); }
</span><span class="cx">     void removeObserver(HeapObserver* observer) { m_observers.removeFirst(observer); }
</span><span class="cx"> 
</span><del>-    // true if collection is in progress
-    bool isCollecting();
-    HeapOperation operationInProgress() { return m_operationInProgress; }
-    // true if an allocation or collection is in progress
-    bool isBusy();
</del><ins>+    MutatorState mutatorState() const { return m_mutatorState; }
+    Optional&lt;CollectionScope&gt; collectionScope() const { return m_collectionScope; }
+
+    // We're always busy on the collection threads. On the main thread, this returns true if we're
+    // helping heap.
+    bool isCurrentThreadBusy();
+    
</ins><span class="cx">     MarkedSpace::Subspace&amp; subspaceForObjectWithoutDestructor() { return m_objectSpace.subspaceForObjectsWithoutDestructor(); }
</span><span class="cx">     MarkedSpace::Subspace&amp; subspaceForObjectDestructor() { return m_objectSpace.subspaceForObjectsWithDestructor(); }
</span><span class="cx">     MarkedSpace::Subspace&amp; subspaceForAuxiliaryData() { return m_objectSpace.subspaceForAuxiliaryData(); }
</span><span class="lines">@@ -171,7 +174,7 @@
</span><span class="cx">     JS_EXPORT_PRIVATE void collectAllGarbage();
</span><span class="cx"> 
</span><span class="cx">     bool shouldCollect();
</span><del>-    JS_EXPORT_PRIVATE void collect(HeapOperation collectionType = AnyCollection);
</del><ins>+    JS_EXPORT_PRIVATE void collect(Optional&lt;CollectionScope&gt; = Nullopt);
</ins><span class="cx">     bool collectIfNecessaryOrDefer(GCDeferralContext* = nullptr); // Returns true if it did collect.
</span><span class="cx">     void collectAccordingToDeferGCProbability();
</span><span class="cx"> 
</span><span class="lines">@@ -268,7 +271,7 @@
</span><span class="cx">     const unsigned* addressOfBarrierThreshold() const { return &amp;m_barrierThreshold; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    friend class AllocationScope;
</del><ins>+    friend class AllocatingScope;
</ins><span class="cx">     friend class CodeBlock;
</span><span class="cx">     friend class DeferGC;
</span><span class="cx">     friend class DeferGCForAWhile;
</span><span class="lines">@@ -278,6 +281,7 @@
</span><span class="cx">     friend class HandleSet;
</span><span class="cx">     friend class HeapUtil;
</span><span class="cx">     friend class HeapVerifier;
</span><ins>+    friend class HelpingGCScope;
</ins><span class="cx">     friend class JITStubRoutine;
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx">     friend class MarkedSpace;
</span><span class="lines">@@ -293,7 +297,7 @@
</span><span class="cx">     template&lt;typename T&gt; friend void* allocateCell(Heap&amp;, GCDeferralContext*);
</span><span class="cx">     template&lt;typename T&gt; friend void* allocateCell(Heap&amp;, GCDeferralContext*, size_t);
</span><span class="cx"> 
</span><del>-    void collectWithoutAnySweep(HeapOperation collectionType = AnyCollection);
</del><ins>+    void collectWithoutAnySweep(Optional&lt;CollectionScope&gt; = Nullopt);
</ins><span class="cx"> 
</span><span class="cx">     void* allocateWithDestructor(size_t); // For use with objects with destructors.
</span><span class="cx">     void* allocateWithoutDestructor(size_t); // For use with objects without destructors.
</span><span class="lines">@@ -312,10 +316,10 @@
</span><span class="cx">     JS_EXPORT_PRIVATE void reportExtraMemoryAllocatedSlowCase(size_t);
</span><span class="cx">     JS_EXPORT_PRIVATE void deprecatedReportExtraMemorySlowCase(size_t);
</span><span class="cx"> 
</span><del>-    void collectImpl(HeapOperation, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&amp;);
</del><ins>+    void collectImpl(Optional&lt;CollectionScope&gt;, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void suspendCompilerThreads();
</span><del>-    void willStartCollection(HeapOperation collectionType);
</del><ins>+    void willStartCollection(Optional&lt;CollectionScope&gt;);
</ins><span class="cx">     void flushOldStructureIDTables();
</span><span class="cx">     void flushWriteBarrierBuffer();
</span><span class="cx">     void stopAllocation();
</span><span class="lines">@@ -366,7 +370,7 @@
</span><span class="cx">     void sweepAllLogicallyEmptyWeakBlocks();
</span><span class="cx">     bool sweepNextLogicallyEmptyWeakBlock();
</span><span class="cx"> 
</span><del>-    bool shouldDoFullCollection(HeapOperation requestedCollectionType) const;
</del><ins>+    bool shouldDoFullCollection(Optional&lt;CollectionScope&gt; requestedCollectionScope) const;
</ins><span class="cx"> 
</span><span class="cx">     void incrementDeferralDepth();
</span><span class="cx">     void decrementDeferralDepth();
</span><span class="lines">@@ -394,7 +398,8 @@
</span><span class="cx">     size_t m_totalBytesVisited;
</span><span class="cx">     size_t m_totalBytesVisitedThisCycle;
</span><span class="cx">     
</span><del>-    HeapOperation m_operationInProgress;
</del><ins>+    Optional&lt;CollectionScope&gt; m_collectionScope;
+    MutatorState m_mutatorState { MutatorState::Running };
</ins><span class="cx">     StructureIDTable m_structureIDTable;
</span><span class="cx">     MarkedSpace m_objectSpace;
</span><span class="cx">     GCIncomingRefCountedSet&lt;ArrayBuffer&gt; m_arrayBuffers;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/HeapInlines.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapInlines.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/HeapInlines.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx">         return false;
</span><span class="cx">     if (!m_isSafeToCollect)
</span><span class="cx">         return false;
</span><del>-    if (m_operationInProgress != NoOperation)
</del><ins>+    if (collectionScope() || mutatorState() == MutatorState::HelpingGC)
</ins><span class="cx">         return false;
</span><span class="cx">     if (Options::gcMaxHeapSize())
</span><span class="cx">         return m_bytesAllocatedThisCycle &gt; Options::gcMaxHeapSize();
</span><span class="lines">@@ -52,16 +52,11 @@
</span><span class="cx">     return m_bytesAllocatedThisCycle &gt; m_maxEdenSize;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline bool Heap::isBusy()
</del><ins>+inline bool Heap::isCurrentThreadBusy()
</ins><span class="cx"> {
</span><del>-    return m_operationInProgress != NoOperation;
</del><ins>+    return mayBeGCThread() || mutatorState() != MutatorState::Running;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline bool Heap::isCollecting()
-{
-    return m_operationInProgress == FullCollection || m_operationInProgress == EdenCollection;
-}
-
</del><span class="cx"> ALWAYS_INLINE Heap* Heap::heap(const HeapCell* cell)
</span><span class="cx"> {
</span><span class="cx">     return cell-&gt;heap();
</span><span class="lines">@@ -76,7 +71,7 @@
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE bool Heap::isMarked(const void* rawCell)
</span><span class="cx"> {
</span><del>-    ASSERT(!mayBeGCThread());
</del><ins>+    ASSERT(mayBeGCThread() != GCThreadType::Helper);
</ins><span class="cx">     HeapCell* cell = bitwise_cast&lt;HeapCell*&gt;(rawCell);
</span><span class="cx">     if (cell-&gt;isLargeAllocation())
</span><span class="cx">         return cell-&gt;largeAllocation().isMarked();
</span><span class="lines">@@ -161,7 +156,7 @@
</span><span class="cx"> inline void Heap::reportExtraMemoryVisited(CellState oldState, size_t size)
</span><span class="cx"> {
</span><span class="cx">     // We don't want to double-count the extra memory that was reported in previous collections.
</span><del>-    if (operationInProgress() == EdenCollection &amp;&amp; oldState == CellState::OldGrey)
</del><ins>+    if (collectionScope() == CollectionScope::Eden &amp;&amp; oldState == CellState::OldGrey)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     size_t* counter = &amp;m_extraMemorySize;
</span><span class="lines">@@ -177,7 +172,7 @@
</span><span class="cx"> inline void Heap::reportExternalMemoryVisited(CellState oldState, size_t size)
</span><span class="cx"> {
</span><span class="cx">     // We don't want to double-count the external memory that was reported in previous collections.
</span><del>-    if (operationInProgress() == EdenCollection &amp;&amp; oldState == CellState::OldGrey)
</del><ins>+    if (collectionScope() == CollectionScope::Eden &amp;&amp; oldState == CellState::OldGrey)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     size_t* counter = &amp;m_externalMemorySize;
</span><span class="lines">@@ -372,7 +367,7 @@
</span><span class="cx"> 
</span><span class="cx"> inline void Heap::collectAccordingToDeferGCProbability()
</span><span class="cx"> {
</span><del>-    if (isDeferred() || !m_isSafeToCollect || m_operationInProgress != NoOperation)
</del><ins>+    if (isDeferred() || !m_isSafeToCollect || collectionScope() || mutatorState() == MutatorState::HelpingGC)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (randomNumber() &lt; Options::deferGCProbability()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapObserverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/HeapObserver.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapObserver.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/HeapObserver.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><del>-#include &quot;HeapOperation.h&quot;
</del><ins>+#include &quot;CollectionScope.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> public:
</span><span class="cx">     virtual ~HeapObserver() { }
</span><span class="cx">     virtual void willGarbageCollect() = 0;
</span><del>-    virtual void didGarbageCollect(HeapOperation) = 0;
</del><ins>+    virtual void didGarbageCollect(CollectionScope) = 0;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapOperationcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/HeapOperation.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapOperation.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/HeapOperation.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,60 +0,0 @@
</span><del>-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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.
- */
-
-#include &quot;config.h&quot;
-#include &quot;HeapOperation.h&quot;
-
-#include &lt;wtf/PrintStream.h&gt;
-
-namespace WTF {
-
-using namespace JSC;
-
-void printInternal(PrintStream&amp; out, HeapOperation operation)
-{
-    switch (operation) {
-    case NoOperation:
-        out.print(&quot;None&quot;);
-        return;
-    case Allocation:
-        out.print(&quot;Alloc&quot;);
-        return;
-    case FullCollection:
-        out.print(&quot;Full&quot;);
-        return;
-    case EdenCollection:
-        out.print(&quot;Eden&quot;);
-        return;
-    case AnyCollection:
-        out.print(&quot;Any&quot;);
-        return;
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-} // namespace WTF
-
-
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapOperationh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/heap/HeapOperation.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapOperation.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/HeapOperation.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,40 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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
-
-namespace JSC {
-
-enum HeapOperation { NoOperation, Allocation, FullCollection, EdenCollection, AnyCollection };
-
-} // namespace JSC
-
-namespace WTF {
-
-class PrintStream;
-
-void printInternal(PrintStream&amp; out, JSC::HeapOperation);
-
-} // namespace WTF
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapVerifiercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/HeapVerifier.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapVerifier.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/HeapVerifier.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -43,24 +43,6 @@
</span><span class="cx">     m_cycles = std::make_unique&lt;GCCycle[]&gt;(m_numberOfCycles);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const char* HeapVerifier::collectionTypeName(HeapOperation type)
-{
-    switch (type) {
-    case NoOperation:
-        return &quot;NoOperation&quot;;
-    case AnyCollection:
-        return &quot;AnyCollection&quot;;
-    case Allocation:
-        return &quot;Allocation&quot;;
-    case EdenCollection:
-        return &quot;EdenCollection&quot;;
-    case FullCollection:
-        return &quot;FullCollection&quot;;
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-    return nullptr; // Silencing a compiler warning.
-}
-
</del><span class="cx"> const char* HeapVerifier::phaseName(HeapVerifier::Phase phase)
</span><span class="cx"> {
</span><span class="cx">     switch (phase) {
</span><span class="lines">@@ -81,7 +63,7 @@
</span><span class="cx"> {
</span><span class="cx">     Heap* heap = m_heap;
</span><span class="cx">     incrementCycle();
</span><del>-    currentCycle().collectionType = heap-&gt;operationInProgress();
</del><ins>+    currentCycle().scope = *heap-&gt;collectionScope();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> struct GatherLiveObjFunctor : MarkedBlock::CountFunctor {
</span><span class="lines">@@ -195,7 +177,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (objData.isConfirmedDead) {
</span><span class="cx">         dataLogF(&quot;FOUND dead obj %p in GC[%d] %s list '%s'\n&quot;,
</span><del>-            obj, cycleIndex, cycle.collectionTypeName(), list.name);
</del><ins>+            obj, cycleIndex, collectionScopeName(cycle.scope), list.name);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -206,7 +188,7 @@
</span><span class="cx">     dataLogF(&quot;FOUND obj %p type '%s' butterfly %p (base %p) in GC[%d] %s list '%s'\n&quot;,
</span><span class="cx">         obj, structure-&gt;classInfo()-&gt;className,
</span><span class="cx">         butterfly, butterflyBase,
</span><del>-        cycleIndex, cycle.collectionTypeName(), list.name);
</del><ins>+        cycleIndex, collectionScopeName(cycle.scope), list.name);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HeapVerifier::checkIfRecorded(JSObject* obj)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapVerifierh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/HeapVerifier.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapVerifier.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/HeapVerifier.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -54,7 +54,6 @@
</span><span class="cx">     // object was in any of those lists.
</span><span class="cx">     JS_EXPORT_PRIVATE void checkIfRecorded(JSObject*);
</span><span class="cx"> 
</span><del>-    static const char* collectionTypeName(HeapOperation);
</del><span class="cx">     static const char* phaseName(Phase);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="lines">@@ -65,14 +64,9 @@
</span><span class="cx">         {
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        HeapOperation collectionType;
</del><ins>+        CollectionScope scope;
</ins><span class="cx">         LiveObjectList before;
</span><span class="cx">         LiveObjectList after;
</span><del>-
-        const char* collectionTypeName() const
-        {
-            return HeapVerifier::collectionTypeName(collectionType);
-        }
</del><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     void incrementCycle() { m_currentCycle = (m_currentCycle + 1) % m_numberOfCycles; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHelpingGCScopeh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/HelpingGCScope.h (0 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HelpingGCScope.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/HelpingGCScope.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 &quot;Heap.h&quot;
+
+namespace JSC {
+
+class HelpingGCScope {
+public:
+    HelpingGCScope(Heap&amp; heap)
+        : m_heap(heap)
+        , m_oldState(m_heap.m_mutatorState)
+    {
+        m_heap.m_mutatorState = MutatorState::HelpingGC;
+    }
+    
+    ~HelpingGCScope()
+    {
+        m_heap.m_mutatorState = m_oldState;
+    }
+
+private:
+    Heap&amp; m_heap;
+    MutatorState m_oldState;
+};
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapLargeAllocationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/LargeAllocation.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/LargeAllocation.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/LargeAllocation.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx"> 
</span><span class="cx"> void LargeAllocation::flip()
</span><span class="cx"> {
</span><del>-    ASSERT(heap()-&gt;operationInProgress() == FullCollection);
</del><ins>+    ASSERT(heap()-&gt;collectionScope() == CollectionScope::Full);
</ins><span class="cx">     clearMarked();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedAllocatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;MarkedAllocator.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;AllocationScope.h&quot;
</del><ins>+#include &quot;AllocatingScope.h&quot;
</ins><span class="cx"> #include &quot;GCActivityCallback.h&quot;
</span><span class="cx"> #include &quot;Heap.h&quot;
</span><span class="cx"> #include &quot;IncrementalSweeper.h&quot;
</span><span class="lines">@@ -185,7 +185,6 @@
</span><span class="cx">             else
</span><span class="cx">                 m_heap-&gt;collectAllGarbage();
</span><span class="cx">         }
</span><del>-        ASSERT(m_heap-&gt;m_operationInProgress == NoOperation);
</del><span class="cx">     }
</span><span class="cx">     if (++allocationCount &gt;= Options::slowPathAllocsBetweenGCs())
</span><span class="cx">         allocationCount = 0;
</span><span class="lines">@@ -214,10 +213,10 @@
</span><span class="cx">     
</span><span class="cx">     didConsumeFreeList();
</span><span class="cx">     
</span><ins>+    AllocatingScope healpingHeap(*m_heap);
+
</ins><span class="cx">     m_heap-&gt;collectIfNecessaryOrDefer(deferralContext);
</span><span class="cx">     
</span><del>-    AllocationScope allocationScope(*m_heap);
-
</del><span class="cx">     void* result = tryAllocateWithoutCollecting();
</span><span class="cx">     
</span><span class="cx">     if (LIKELY(result != 0))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedBlock.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedBlock.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/MarkedBlock.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -25,7 +25,6 @@
</span><span class="cx"> #include &quot;DestructionMode.h&quot;
</span><span class="cx"> #include &quot;FreeList.h&quot;
</span><span class="cx"> #include &quot;HeapCell.h&quot;
</span><del>-#include &quot;HeapOperation.h&quot;
</del><span class="cx"> #include &quot;IterationStatus.h&quot;
</span><span class="cx"> #include &quot;WeakSet.h&quot;
</span><span class="cx"> #include &lt;wtf/Atomics.h&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMarkedSpacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -338,7 +338,7 @@
</span><span class="cx"> 
</span><span class="cx">     m_activeWeakSets.takeFrom(m_newActiveWeakSets);
</span><span class="cx">     
</span><del>-    if (m_heap-&gt;operationInProgress() == EdenCollection)
</del><ins>+    if (m_heap-&gt;collectionScope() == CollectionScope::Eden)
</ins><span class="cx">         m_largeAllocationsNurseryOffsetForSweep = m_largeAllocationsNurseryOffset;
</span><span class="cx">     else
</span><span class="cx">         m_largeAllocationsNurseryOffsetForSweep = 0;
</span><span class="lines">@@ -355,7 +355,7 @@
</span><span class="cx">     
</span><span class="cx">     m_newActiveWeakSets.forEach(visit);
</span><span class="cx">     
</span><del>-    if (m_heap-&gt;operationInProgress() == FullCollection)
</del><ins>+    if (m_heap-&gt;collectionScope() == CollectionScope::Full)
</ins><span class="cx">         m_activeWeakSets.forEach(visit);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -367,7 +367,7 @@
</span><span class="cx">     
</span><span class="cx">     m_newActiveWeakSets.forEach(visit);
</span><span class="cx">     
</span><del>-    if (m_heap-&gt;operationInProgress() == FullCollection)
</del><ins>+    if (m_heap-&gt;collectionScope() == CollectionScope::Full)
</ins><span class="cx">         m_activeWeakSets.forEach(visit);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -383,7 +383,7 @@
</span><span class="cx"> 
</span><span class="cx"> void MarkedSpace::prepareForMarking()
</span><span class="cx"> {
</span><del>-    if (m_heap-&gt;operationInProgress() == EdenCollection)
</del><ins>+    if (m_heap-&gt;collectionScope() == CollectionScope::Eden)
</ins><span class="cx">         m_largeAllocationsOffsetForThisCollection = m_largeAllocationsNurseryOffset;
</span><span class="cx">     else
</span><span class="cx">         m_largeAllocationsOffsetForThisCollection = 0;
</span><span class="lines">@@ -453,7 +453,7 @@
</span><span class="cx"> 
</span><span class="cx"> void MarkedSpace::beginMarking()
</span><span class="cx"> {
</span><del>-    if (m_heap-&gt;operationInProgress() == FullCollection) {
</del><ins>+    if (m_heap-&gt;collectionScope() == CollectionScope::Full) {
</ins><span class="cx">         forEachAllocator(
</span><span class="cx">             [&amp;] (MarkedAllocator&amp; allocator) -&gt; IterationStatus {
</span><span class="cx">                 allocator.beginMarkingForFullCollection();
</span><span class="lines">@@ -597,7 +597,7 @@
</span><span class="cx"> 
</span><span class="cx"> void MarkedSpace::snapshotUnswept()
</span><span class="cx"> {
</span><del>-    if (m_heap-&gt;operationInProgress() == EdenCollection) {
</del><ins>+    if (m_heap-&gt;collectionScope() == CollectionScope::Eden) {
</ins><span class="cx">         forEachAllocator(
</span><span class="cx">             [&amp;] (MarkedAllocator&amp; allocator) -&gt; IterationStatus {
</span><span class="cx">                 allocator.snapshotUnsweptForEdenCollection();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMutatorStatecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/MutatorState.cpp (0 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MutatorState.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/MutatorState.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;MutatorState.h&quot;
+
+#include &lt;wtf/PrintStream.h&gt;
+
+using namespace JSC;
+
+namespace WTF {
+
+void printInternal(PrintStream&amp; out, MutatorState state)
+{
+    switch (state) {
+    case MutatorState::Running:
+        out.print(&quot;Running&quot;);
+        return;
+    case MutatorState::Allocating:
+        out.print(&quot;Allocating&quot;);
+        return;
+    case MutatorState::HelpingGC:
+        out.print(&quot;HelpingGC&quot;);
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMutatorStateh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/MutatorState.h (0 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MutatorState.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/heap/MutatorState.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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
+
+namespace JSC {
+
+enum class MutatorState {
+    // The mutator is running when it's not inside a Heap slow path.
+    Running,
+    
+    // The mutator is in an allocation slow path.
+    Allocating,
+    
+    // The mutator was asked by the GC to do some work.
+    HelpingGC
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+class PrintStream;
+
+void printInternal(PrintStream&amp;, JSC::MutatorState);
+
+} // namespace WTF
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapSlotVisitorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx"> 
</span><span class="cx"> void SlotVisitor::didStartMarking()
</span><span class="cx"> {
</span><del>-    if (heap()-&gt;operationInProgress() == FullCollection)
</del><ins>+    if (heap()-&gt;collectionScope() == CollectionScope::Full)
</ins><span class="cx">         ASSERT(m_opaqueRoots.isEmpty()); // Should have merged by now.
</span><span class="cx">     else
</span><span class="cx">         reset();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorHeapAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorHeapAgent.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorHeapAgent.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorHeapAgent.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -320,17 +320,16 @@
</span><span class="cx">     result = injectedScript.wrapObject(cell, objectGroup, true);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static Inspector::Protocol::Heap::GarbageCollection::Type protocolTypeForHeapOperation(HeapOperation operation)
</del><ins>+static Inspector::Protocol::Heap::GarbageCollection::Type protocolTypeForHeapOperation(CollectionScope scope)
</ins><span class="cx"> {
</span><del>-    switch (operation) {
-    case FullCollection:
</del><ins>+    switch (scope) {
+    case CollectionScope::Full:
</ins><span class="cx">         return Inspector::Protocol::Heap::GarbageCollection::Type::Full;
</span><del>-    case EdenCollection:
</del><ins>+    case CollectionScope::Eden:
</ins><span class="cx">         return Inspector::Protocol::Heap::GarbageCollection::Type::Partial;
</span><del>-    default:
-        ASSERT_NOT_REACHED();
-        return Inspector::Protocol::Heap::GarbageCollection::Type::Full;
</del><span class="cx">     }
</span><ins>+    ASSERT_NOT_REACHED();
+    return Inspector::Protocol::Heap::GarbageCollection::Type::Full;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorHeapAgent::willGarbageCollect()
</span><span class="lines">@@ -341,7 +340,7 @@
</span><span class="cx">     m_gcStartTime = m_environment.executionStopwatch()-&gt;elapsedTime();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InspectorHeapAgent::didGarbageCollect(HeapOperation operation)
</del><ins>+void InspectorHeapAgent::didGarbageCollect(CollectionScope scope)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_enabled);
</span><span class="cx">     ASSERT(!std::isnan(m_gcStartTime));
</span><span class="lines">@@ -356,7 +355,7 @@
</span><span class="cx">     // VM as the inspected page.
</span><span class="cx"> 
</span><span class="cx">     GarbageCollectionData data;
</span><del>-    data.type = protocolTypeForHeapOperation(operation);
</del><ins>+    data.type = protocolTypeForHeapOperation(scope);
</ins><span class="cx">     data.startTime = m_gcStartTime;
</span><span class="cx">     data.endTime = m_environment.executionStopwatch()-&gt;elapsedTime();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectoragentsInspectorHeapAgenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/agents/InspectorHeapAgent.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/agents/InspectorHeapAgent.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/inspector/agents/InspectorHeapAgent.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx"> 
</span><span class="cx">     // HeapObserver
</span><span class="cx">     void willGarbageCollect() override;
</span><del>-    void didGarbageCollect(JSC::HeapOperation) override;
</del><ins>+    void didGarbageCollect(JSC::CollectionScope) override;
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     void clearHeapSnapshots();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -755,9 +755,9 @@
</span><span class="cx">     auto throwScope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(!throwScope.exception());
</span><del>-    ASSERT(!vm.isCollectorBusy());
</del><ins>+    ASSERT(!vm.isCollectorBusyOnCurrentThread());
</ins><span class="cx">     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
</span><del>-    if (vm.isCollectorBusy())
</del><ins>+    if (vm.isCollectorBusyOnCurrentThread())
</ins><span class="cx">         return jsNull();
</span><span class="cx"> 
</span><span class="cx">     if (UNLIKELY(!vm.isSafeToRecurseSoft()))
</span><span class="lines">@@ -900,8 +900,8 @@
</span><span class="cx">     auto throwScope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(!throwScope.exception());
</span><del>-    ASSERT(!vm.isCollectorBusy());
-    if (vm.isCollectorBusy())
</del><ins>+    ASSERT(!vm.isCollectorBusyOnCurrentThread());
+    if (vm.isCollectorBusyOnCurrentThread())
</ins><span class="cx">         return jsNull();
</span><span class="cx"> 
</span><span class="cx">     bool isJSCall = (callType == CallType::JS);
</span><span class="lines">@@ -962,10 +962,10 @@
</span><span class="cx">     auto throwScope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(!throwScope.exception());
</span><del>-    ASSERT(!vm.isCollectorBusy());
</del><ins>+    ASSERT(!vm.isCollectorBusyOnCurrentThread());
</ins><span class="cx">     // We throw in this case because we have to return something &quot;valid&quot; but we're
</span><span class="cx">     // already in an invalid state.
</span><del>-    if (vm.isCollectorBusy())
</del><ins>+    if (vm.isCollectorBusyOnCurrentThread())
</ins><span class="cx">         return checkedReturn(throwStackOverflowError(callFrame, throwScope));
</span><span class="cx"> 
</span><span class="cx">     bool isJSConstruct = (constructType == ConstructType::JS);
</span><span class="lines">@@ -1028,7 +1028,7 @@
</span><span class="cx">     auto throwScope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx">     ASSERT(!throwScope.exception());
</span><span class="cx">     
</span><del>-    if (vm.isCollectorBusy())
</del><ins>+    if (vm.isCollectorBusyOnCurrentThread())
</ins><span class="cx">         return CallFrameClosure();
</span><span class="cx"> 
</span><span class="cx">     // Compile the callee:
</span><span class="lines">@@ -1053,9 +1053,9 @@
</span><span class="cx">     VM&amp; vm = *closure.vm;
</span><span class="cx">     auto throwScope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><del>-    ASSERT(!vm.isCollectorBusy());
</del><ins>+    ASSERT(!vm.isCollectorBusyOnCurrentThread());
</ins><span class="cx">     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
</span><del>-    if (vm.isCollectorBusy())
</del><ins>+    if (vm.isCollectorBusyOnCurrentThread())
</ins><span class="cx">         return jsNull();
</span><span class="cx"> 
</span><span class="cx">     StackStats::CheckPoint stackCheckPoint;
</span><span class="lines">@@ -1076,9 +1076,9 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(scope-&gt;vm() == &amp;callFrame-&gt;vm());
</span><span class="cx">     ASSERT(!throwScope.exception());
</span><del>-    ASSERT(!vm.isCollectorBusy());
</del><ins>+    ASSERT(!vm.isCollectorBusyOnCurrentThread());
</ins><span class="cx">     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
</span><del>-    if (vm.isCollectorBusy())
</del><ins>+    if (vm.isCollectorBusyOnCurrentThread())
</ins><span class="cx">         return jsNull();
</span><span class="cx"> 
</span><span class="cx">     VMEntryScope entryScope(vm, scope-&gt;globalObject());
</span><span class="lines">@@ -1182,9 +1182,9 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(scope-&gt;vm() == &amp;callFrame-&gt;vm());
</span><span class="cx">     ASSERT(!throwScope.exception());
</span><del>-    ASSERT(!vm.isCollectorBusy());
</del><ins>+    ASSERT(!vm.isCollectorBusyOnCurrentThread());
</ins><span class="cx">     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
</span><del>-    if (vm.isCollectorBusy())
</del><ins>+    if (vm.isCollectorBusyOnCurrentThread())
</ins><span class="cx">         return jsNull();
</span><span class="cx"> 
</span><span class="cx">     VMEntryScope entryScope(vm, scope-&gt;globalObject());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1677,7 +1677,7 @@
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL functionFullGC(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     JSLockHolder lock(exec);
</span><del>-    exec-&gt;heap()-&gt;collect(FullCollection);
</del><ins>+    exec-&gt;heap()-&gt;collect(CollectionScope::Full);
</ins><span class="cx">     return JSValue::encode(jsNumber(exec-&gt;heap()-&gt;sizeAfterLastFullCollection()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1684,7 +1684,7 @@
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     JSLockHolder lock(exec);
</span><del>-    exec-&gt;heap()-&gt;collect(EdenCollection);
</del><ins>+    exec-&gt;heap()-&gt;collect(CollectionScope::Eden);
</ins><span class="cx">     return JSValue::encode(jsNumber(exec-&gt;heap()-&gt;sizeAfterLastEdenCollection()));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCompletioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Completion.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Completion.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/runtime/Completion.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx">     JSLockHolder lock(vm);
</span><span class="cx">     auto scope = DECLARE_CATCH_SCOPE(vm);
</span><span class="cx">     RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
</span><del>-    RELEASE_ASSERT(!vm.isCollectorBusy());
</del><ins>+    RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
</ins><span class="cx"> 
</span><span class="cx">     CodeProfiling profile(source);
</span><span class="cx"> 
</span><span class="lines">@@ -174,7 +174,7 @@
</span><span class="cx"> {
</span><span class="cx">     JSLockHolder lock(exec);
</span><span class="cx">     RELEASE_ASSERT(exec-&gt;vm().atomicStringTable() == wtfThreadData().atomicStringTable());
</span><del>-    RELEASE_ASSERT(!exec-&gt;vm().isCollectorBusy());
</del><ins>+    RELEASE_ASSERT(!exec-&gt;vm().isCollectorBusyOnCurrentThread());
</ins><span class="cx"> 
</span><span class="cx">     return loadAndEvaluateModule(lock, exec, exec-&gt;vmEntryGlobalObject(), Identifier::fromString(exec, moduleName), initiator);
</span><span class="cx"> }
</span><span class="lines">@@ -185,7 +185,7 @@
</span><span class="cx">     JSLockHolder lock(vm);
</span><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx">     RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
</span><del>-    RELEASE_ASSERT(!vm.isCollectorBusy());
</del><ins>+    RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
</ins><span class="cx"> 
</span><span class="cx">     Symbol* key = createSymbolForEntryPointModule(vm);
</span><span class="cx"> 
</span><span class="lines">@@ -212,7 +212,7 @@
</span><span class="cx"> {
</span><span class="cx">     JSLockHolder lock(exec);
</span><span class="cx">     RELEASE_ASSERT(exec-&gt;vm().atomicStringTable() == wtfThreadData().atomicStringTable());
</span><del>-    RELEASE_ASSERT(!exec-&gt;vm().isCollectorBusy());
</del><ins>+    RELEASE_ASSERT(!exec-&gt;vm().isCollectorBusyOnCurrentThread());
</ins><span class="cx"> 
</span><span class="cx">     return loadModule(lock, exec, exec-&gt;vmEntryGlobalObject(), Identifier::fromString(exec, moduleName), initiator);
</span><span class="cx"> }
</span><span class="lines">@@ -223,7 +223,7 @@
</span><span class="cx">     JSLockHolder lock(vm);
</span><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx">     RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
</span><del>-    RELEASE_ASSERT(!vm.isCollectorBusy());
</del><ins>+    RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
</ins><span class="cx"> 
</span><span class="cx">     Symbol* key = createSymbolForEntryPointModule(vm);
</span><span class="cx"> 
</span><span class="lines">@@ -241,7 +241,7 @@
</span><span class="cx"> {
</span><span class="cx">     JSLockHolder lock(exec);
</span><span class="cx">     RELEASE_ASSERT(exec-&gt;vm().atomicStringTable() == wtfThreadData().atomicStringTable());
</span><del>-    RELEASE_ASSERT(!exec-&gt;vm().isCollectorBusy());
</del><ins>+    RELEASE_ASSERT(!exec-&gt;vm().isCollectorBusyOnCurrentThread());
</ins><span class="cx"> 
</span><span class="cx">     JSGlobalObject* globalObject = exec-&gt;vmEntryGlobalObject();
</span><span class="cx">     return globalObject-&gt;moduleLoader()-&gt;linkAndEvaluateModule(exec, identifierToJSValue(exec-&gt;vm(), moduleKey), initiator);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSLockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSLock.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSLock.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/runtime/JSLock.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -267,7 +267,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (!m_vm)
</span><span class="cx">         return;
</span><del>-    RELEASE_ASSERT(!m_vm-&gt;apiLock().currentThreadIsHoldingLock() || !m_vm-&gt;isCollectorBusy());
</del><ins>+    RELEASE_ASSERT(!m_vm-&gt;apiLock().currentThreadIsHoldingLock() || !m_vm-&gt;isCollectorBusyOnCurrentThread());
</ins><span class="cx">     m_droppedLockCount = m_vm-&gt;apiLock().dropAllLocks(this);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSmallStringsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SmallStrings.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SmallStrings.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/runtime/SmallStrings.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2009, 2015 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2008-2009, 2015-2016 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">@@ -113,9 +113,9 @@
</span><span class="cx">     JSString* nullObjectString() const { return m_nullObjectString; }
</span><span class="cx">     JSString* undefinedObjectString() const { return m_undefinedObjectString; }
</span><span class="cx"> 
</span><del>-    bool needsToBeVisited(HeapOperation collectionType) const
</del><ins>+    bool needsToBeVisited(CollectionScope scope) const
</ins><span class="cx">     {
</span><del>-        if (collectionType == FullCollection)
</del><ins>+        if (scope == CollectionScope::Full)
</ins><span class="cx">             return true;
</span><span class="cx">         return m_needsToBeVisited;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -576,7 +576,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     JS_EXPORT_PRIVATE void dumpRegExpTrace();
</span><span class="cx"> 
</span><del>-    bool isCollectorBusy() { return heap.isBusy(); }
</del><ins>+    bool isCollectorBusyOnCurrentThread() { return heap.isCurrentThreadBusy(); }
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(GC_VALIDATION)
</span><span class="cx">     bool isInitializingObject() const; 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretoolsJSDollarVMPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -130,7 +130,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (!ensureCurrentThreadOwnsJSLock(exec))
</span><span class="cx">         return;
</span><del>-    exec-&gt;heap()-&gt;collect(EdenCollection);
</del><ins>+    exec-&gt;heap()-&gt;collect(CollectionScope::Eden);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState* exec)
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/WTF/ChangeLog        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-10-20  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        The tracking of the coarse-grain Heap state (allocating or not, collector or not, eden vs full) should respect the orthogonality between allocating and collecting
+        https://bugs.webkit.org/show_bug.cgi?id=163738
+
+        Reviewed by Geoffrey Garen.
+        
+        There will soon be different kinds of GC threads, and WTF's &quot;are you a GC thread&quot; thing
+        should know about this.
+
+        * wtf/MainThread.cpp:
+        (WTF::initializeGCThreads):
+        (WTF::registerGCThread):
+        (WTF::mayBeGCThread):
+        * wtf/MainThread.h:
+
</ins><span class="cx"> 2016-10-19  Sam Weinig  &lt;sam@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Add convenience function that combines WTF::visit(...) with WTF::makeVisitor(...)
</span></span></pre></div>
<a id="trunkSourceWTFwtfMainThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/MainThread.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/MainThread.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/WTF/wtf/MainThread.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -190,14 +190,14 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-static ThreadSpecific&lt;bool&gt;* isGCThread;
</del><ins>+static ThreadSpecific&lt;Optional&lt;GCThreadType&gt;&gt;* isGCThread;
</ins><span class="cx"> 
</span><span class="cx"> void initializeGCThreads()
</span><span class="cx"> {
</span><del>-    isGCThread = new ThreadSpecific&lt;bool&gt;();
</del><ins>+    isGCThread = new ThreadSpecific&lt;Optional&lt;GCThreadType&gt;&gt;();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void registerGCThread()
</del><ins>+void registerGCThread(GCThreadType type)
</ins><span class="cx"> {
</span><span class="cx">     if (!isGCThread) {
</span><span class="cx">         // This happens if we're running in a process that doesn't care about
</span><span class="lines">@@ -205,7 +205,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    **isGCThread = true;
</del><ins>+    **isGCThread = type;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool isMainThreadOrGCThread()
</span><span class="lines">@@ -216,9 +216,13 @@
</span><span class="cx">     return isMainThread();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool mayBeGCThread()
</del><ins>+Optional&lt;GCThreadType&gt; mayBeGCThread()
</ins><span class="cx"> {
</span><del>-    return isGCThread &amp;&amp; isGCThread-&gt;isSet() &amp;&amp; **isGCThread;
</del><ins>+    if (!isGCThread)
+        return Nullopt;
+    if (!isGCThread-&gt;isSet())
+        return Nullopt;
+    return **isGCThread;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span></span></pre></div>
<a id="trunkSourceWTFwtfMainThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/MainThread.h (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/MainThread.h        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/WTF/wtf/MainThread.h        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -33,9 +33,12 @@
</span><span class="cx"> #include &lt;functional&gt;
</span><span class="cx"> #include &lt;stdint.h&gt;
</span><span class="cx"> #include &lt;wtf/Function.h&gt;
</span><ins>+#include &lt;wtf/Optional.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><ins>+class PrintStream;
+
</ins><span class="cx"> typedef uint32_t ThreadIdentifier;
</span><span class="cx"> 
</span><span class="cx"> // Must be called from the main thread.
</span><span class="lines">@@ -67,8 +70,15 @@
</span><span class="cx"> 
</span><span class="cx"> void initializeGCThreads();
</span><span class="cx"> 
</span><del>-WTF_EXPORT_PRIVATE void registerGCThread();
-WTF_EXPORT_PRIVATE bool mayBeGCThread();
</del><ins>+enum class GCThreadType {
+    Main,
+    Helper
+};
+
+void printInternal(PrintStream&amp;, GCThreadType);
+
+WTF_EXPORT_PRIVATE void registerGCThread(GCThreadType);
+WTF_EXPORT_PRIVATE Optional&lt;GCThreadType&gt; mayBeGCThread();
</ins><span class="cx"> WTF_EXPORT_PRIVATE bool isMainThreadOrGCThread();
</span><span class="cx"> 
</span><span class="cx"> // NOTE: these functions are internal to the callOnMainThread implementation.
</span><span class="lines">@@ -88,6 +98,7 @@
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><ins>+using WTF::GCThreadType;
</ins><span class="cx"> using WTF::callOnMainThread;
</span><span class="cx"> using WTF::canAccessThreadLocalDataForThread;
</span><span class="cx"> using WTF::isMainThread;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/WebCore/ChangeLog        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-10-20  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        The tracking of the coarse-grain Heap state (allocating or not, collector or not, eden vs full) should respect the orthogonality between allocating and collecting
+        https://bugs.webkit.org/show_bug.cgi?id=163738
+
+        Reviewed by Geoffrey Garen.
+
+        No new tests because no change in behavior.
+
+        * bindings/js/GCController.cpp:
+        (WebCore::GCController::garbageCollectNow):
+
</ins><span class="cx"> 2016-10-20  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Bindings] Start using signature-&gt;idlType instead of signature-&gt;type in the overload resolution code
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsGCControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/GCController.cpp (207652 => 207653)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/GCController.cpp        2016-10-21 01:33:14 UTC (rev 207652)
+++ trunk/Source/WebCore/bindings/js/GCController.cpp        2016-10-21 02:17:35 UTC (rev 207653)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2007, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2007, 2014, 2016 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"> void GCController::garbageCollectNow()
</span><span class="cx"> {
</span><span class="cx">     JSLockHolder lock(JSDOMWindow::commonVM());
</span><del>-    if (!JSDOMWindow::commonVM().heap.isBusy()) {
</del><ins>+    if (!JSDOMWindow::commonVM().heap.isCurrentThreadBusy()) {
</ins><span class="cx">         JSDOMWindow::commonVM().heap.collectAllGarbage();
</span><span class="cx">         WTF::releaseFastMallocFreeMemory();
</span><span class="cx">     }
</span><span class="lines">@@ -92,7 +92,7 @@
</span><span class="cx"> {
</span><span class="cx"> #if USE(CF) || USE(GLIB)
</span><span class="cx">     JSLockHolder lock(JSDOMWindow::commonVM());
</span><del>-    if (!JSDOMWindow::commonVM().heap.isBusy())
</del><ins>+    if (!JSDOMWindow::commonVM().heap.isCurrentThreadBusy())
</ins><span class="cx">         JSDOMWindow::commonVM().heap.collectAllGarbageIfNotDoneRecently();
</span><span class="cx"> #else
</span><span class="cx">     garbageCollectSoon();
</span></span></pre>
</div>
</div>

</body>
</html>