Title: [216218] trunk/Source
Revision
216218
Author
[email protected]
Date
2017-05-04 16:37:52 -0700 (Thu, 04 May 2017)

Log Message

JSC::Heap should expose a richer API for requesting GCs
https://bugs.webkit.org/show_bug.cgi?id=171690

Reviewed by Geoffrey Garen.
Source/_javascript_Core:

        
I want to stop WebCore from requesting synchronous GCs. But various parts of that work
may cause regressions, so I'd like to land it separately from the functionality that is
needed on the JSC side. This change is mostly a JSC-side refactoring that does not
change behavior. In the future I'll land the behavior changes (i.e. not requesting sync
GCs).
        
This change allows you to enumerate over synchronousness, so that we can make all APIs
take synchronousness as an argument. It replaces the collectAllGarbage API with a
collectNow(Synchronousness, GCRequest) API. GCRequest is a new concept, which subsumes
std::optional<CollectionScope> and gives us the ability to register callbacks along
with a GC. So, you can ask for an async GC and get a callback when it's done.
        
Also adds ability to request that fastMalloc memory be released after the incremental
sweeper finishes.
        
* API/JSBase.cpp:
(JSSynchronousGarbageCollectForDebugging):
* CMakeLists.txt:
* _javascript_Core.xcodeproj/project.pbxproj:
* heap/FullGCActivityCallback.cpp:
(JSC::FullGCActivityCallback::doCollection):
* heap/FullGCActivityCallback.h:
* heap/GCRequest.cpp: Added.
(JSC::GCRequest::subsumedBy):
(JSC::GCRequest::dump):
* heap/GCRequest.h: Added.
(JSC::GCRequest::GCRequest):
* heap/Heap.cpp:
(JSC::Heap::collect):
(JSC::Heap::collectNow):
(JSC::Heap::collectAsync):
(JSC::Heap::collectSync):
(JSC::Heap::runBeginPhase):
(JSC::Heap::runEndPhase):
(JSC::Heap::requestCollection):
(JSC::Heap::willStartCollection):
(JSC::Heap::sweeper):
(JSC::Heap::collectNowFullIfNotDoneRecently):
(JSC::Heap::shouldDoFullCollection):
(JSC::Heap::collectAllGarbage): Deleted.
(JSC::Heap::collectAllGarbageIfNotDoneRecently): Deleted.
* heap/Heap.h:
* heap/HeapSnapshotBuilder.cpp:
(JSC::HeapSnapshotBuilder::buildSnapshot):
* heap/IncrementalSweeper.cpp:
(JSC::IncrementalSweeper::doSweep):
* heap/IncrementalSweeper.h:
(JSC::IncrementalSweeper::freeFastMallocMemoryAfterSweeping):
* heap/MarkedAllocator.cpp:
(JSC::MarkedAllocator::doTestCollectionsIfNeeded):
* heap/MarkedSpace.cpp:
(JSC::MarkedSpace::sweep):
* heap/Synchronousness.cpp: Added.
(WTF::printInternal):
* heap/Synchronousness.h: Added.
* inspector/agents/InspectorHeapAgent.cpp:
(Inspector::InspectorHeapAgent::gc):
* jsc.cpp:
(functionGCAndSweep):
(runJSC):
* tools/JSDollarVMPrototype.cpp:
(JSC::JSDollarVMPrototype::gc):
* wasm/WasmMemory.cpp:

Source/WebCore:


No new tests because this is just a refactoring.
        
Change some function calls now that some JSC::Heap APIs got renamed.

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

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/API/JSBase.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/API/JSBase.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/API/JSBase.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -157,7 +157,7 @@
 
     ExecState* exec = toJS(ctx);
     JSLockHolder locker(exec);
-    exec->vm().heap.collectAllGarbage();
+    exec->vm().heap.collectNow(Sync, CollectionScope::Full);
 }
 
 void JSSynchronousEdenCollectForDebugging(JSContextRef ctx)

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (216217 => 216218)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2017-05-04 23:37:52 UTC (rev 216218)
@@ -502,6 +502,7 @@
     heap/GCActivityCallback.cpp
     heap/GCConductor.cpp
     heap/GCLogging.cpp
+    heap/GCRequest.cpp
     heap/HandleSet.cpp
     heap/HandleStack.cpp
     heap/Heap.cpp
@@ -528,6 +529,7 @@
     heap/StopIfNecessaryTimer.cpp
     heap/Subspace.cpp
     heap/SynchronousStopTheWorldMutatorScheduler.cpp
+    heap/Synchronousness.cpp
     heap/VisitRaceKey.cpp
     heap/Weak.cpp
     heap/WeakBlock.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (216217 => 216218)


--- trunk/Source/_javascript_Core/ChangeLog	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-05-04 23:37:52 UTC (rev 216218)
@@ -1,3 +1,74 @@
+2017-05-04  Filip Pizlo  <[email protected]>
+
+        JSC::Heap should expose a richer API for requesting GCs
+        https://bugs.webkit.org/show_bug.cgi?id=171690
+
+        Reviewed by Geoffrey Garen.
+        
+        I want to stop WebCore from requesting synchronous GCs. But various parts of that work
+        may cause regressions, so I'd like to land it separately from the functionality that is
+        needed on the JSC side. This change is mostly a JSC-side refactoring that does not
+        change behavior. In the future I'll land the behavior changes (i.e. not requesting sync
+        GCs).
+        
+        This change allows you to enumerate over synchronousness, so that we can make all APIs
+        take synchronousness as an argument. It replaces the collectAllGarbage API with a
+        collectNow(Synchronousness, GCRequest) API. GCRequest is a new concept, which subsumes
+        std::optional<CollectionScope> and gives us the ability to register callbacks along
+        with a GC. So, you can ask for an async GC and get a callback when it's done.
+        
+        Also adds ability to request that fastMalloc memory be released after the incremental
+        sweeper finishes.
+        
+        * API/JSBase.cpp:
+        (JSSynchronousGarbageCollectForDebugging):
+        * CMakeLists.txt:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * heap/FullGCActivityCallback.cpp:
+        (JSC::FullGCActivityCallback::doCollection):
+        * heap/FullGCActivityCallback.h:
+        * heap/GCRequest.cpp: Added.
+        (JSC::GCRequest::subsumedBy):
+        (JSC::GCRequest::dump):
+        * heap/GCRequest.h: Added.
+        (JSC::GCRequest::GCRequest):
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        (JSC::Heap::collectNow):
+        (JSC::Heap::collectAsync):
+        (JSC::Heap::collectSync):
+        (JSC::Heap::runBeginPhase):
+        (JSC::Heap::runEndPhase):
+        (JSC::Heap::requestCollection):
+        (JSC::Heap::willStartCollection):
+        (JSC::Heap::sweeper):
+        (JSC::Heap::collectNowFullIfNotDoneRecently):
+        (JSC::Heap::shouldDoFullCollection):
+        (JSC::Heap::collectAllGarbage): Deleted.
+        (JSC::Heap::collectAllGarbageIfNotDoneRecently): Deleted.
+        * heap/Heap.h:
+        * heap/HeapSnapshotBuilder.cpp:
+        (JSC::HeapSnapshotBuilder::buildSnapshot):
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::doSweep):
+        * heap/IncrementalSweeper.h:
+        (JSC::IncrementalSweeper::freeFastMallocMemoryAfterSweeping):
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::doTestCollectionsIfNeeded):
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::sweep):
+        * heap/Synchronousness.cpp: Added.
+        (WTF::printInternal):
+        * heap/Synchronousness.h: Added.
+        * inspector/agents/InspectorHeapAgent.cpp:
+        (Inspector::InspectorHeapAgent::gc):
+        * jsc.cpp:
+        (functionGCAndSweep):
+        (runJSC):
+        * tools/JSDollarVMPrototype.cpp:
+        (JSC::JSDollarVMPrototype::gc):
+        * wasm/WasmMemory.cpp:
+
 2017-05-04  Mark Lam  <[email protected]>
 
         NeverDestroyed<String>(ASCIILiteral(...)) is not thread safe.

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (216217 => 216218)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-05-04 23:37:52 UTC (rev 216218)
@@ -633,6 +633,8 @@
 		0F96303C1D4192CD005609D9 /* DestructionMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9630381D4192C3005609D9 /* DestructionMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F9715301EB28BEB00A1645D /* GCRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F97152E1EB28BE900A1645D /* GCRequest.cpp */; };
+		0F9715311EB28BEE00A1645D /* GCRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F97152F1EB28BE900A1645D /* GCRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F978B3B1AAEA71D007C7369 /* ConstantMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */; };
 		0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */; };
@@ -785,6 +787,8 @@
 		0FD3E40C1B618B6600C80E1E /* ObjectPropertyConditionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD3E4061B618B6600C80E1E /* ObjectPropertyConditionSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FD3E40D1B618B6600C80E1E /* PropertyCondition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD3E4071B618B6600C80E1E /* PropertyCondition.cpp */; };
 		0FD3E40E1B618B6600C80E1E /* PropertyCondition.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD3E4081B618B6600C80E1E /* PropertyCondition.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FD79A2D1EBBBDBB00DA88D3 /* Synchronousness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD79A2C1EBBBDB200DA88D3 /* Synchronousness.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FD79A2E1EBBBDC000DA88D3 /* Synchronousness.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD79A2B1EBBBDB200DA88D3 /* Synchronousness.cpp */; };
 		0FD81AD3154FB4F000983E72 /* DFGDominators.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD81AD0154FB4EB00983E72 /* DFGDominators.h */; };
 		0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD82E1E14172C2F00179C94 /* DFGCapabilities.cpp */; };
 		0FD82E39141AB14D00179C94 /* CompactJITCodeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3192,6 +3196,8 @@
 		0F9630381D4192C3005609D9 /* DestructionMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DestructionMode.h; sourceTree = "<group>"; };
 		0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueProfile.h; sourceTree = "<group>"; };
 		0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockWithJITType.h; sourceTree = "<group>"; };
+		0F97152E1EB28BE900A1645D /* GCRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCRequest.cpp; sourceTree = "<group>"; };
+		0F97152F1EB28BE900A1645D /* GCRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCRequest.h; sourceTree = "<group>"; };
 		0F97496F1687ADE200A4FF6A /* JSCellInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCellInlines.h; sourceTree = "<group>"; };
 		0F978B3A1AAEA71D007C7369 /* ConstantMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantMode.cpp; sourceTree = "<group>"; };
 		0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreciseJumpTargets.cpp; sourceTree = "<group>"; };
@@ -3357,6 +3363,8 @@
 		0FD3E4071B618B6600C80E1E /* PropertyCondition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyCondition.cpp; sourceTree = "<group>"; };
 		0FD3E4081B618B6600C80E1E /* PropertyCondition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyCondition.h; sourceTree = "<group>"; };
 		0FD5652216AB780A00197653 /* DFGBasicBlockInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBasicBlockInlines.h; path = dfg/DFGBasicBlockInlines.h; sourceTree = "<group>"; };
+		0FD79A2B1EBBBDB200DA88D3 /* Synchronousness.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Synchronousness.cpp; sourceTree = "<group>"; };
+		0FD79A2C1EBBBDB200DA88D3 /* Synchronousness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Synchronousness.h; sourceTree = "<group>"; };
 		0FD81AD0154FB4EB00983E72 /* DFGDominators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDominators.h; path = dfg/DFGDominators.h; sourceTree = "<group>"; };
 		0FD82E1E14172C2F00179C94 /* DFGCapabilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCapabilities.cpp; path = dfg/DFGCapabilities.cpp; sourceTree = "<group>"; };
 		0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCapabilities.h; path = dfg/DFGCapabilities.h; sourceTree = "<group>"; };
@@ -5999,6 +6007,8 @@
 				0F2B66AB17B6B53D00A7AE3F /* GCIncomingRefCountedSetInlines.h */,
 				2ADFA26218EF3540004F9FCC /* GCLogging.cpp */,
 				2AABCDE618EF294200002096 /* GCLogging.h */,
+				0F97152E1EB28BE900A1645D /* GCRequest.cpp */,
+				0F97152F1EB28BE900A1645D /* GCRequest.h */,
 				2A343F7418A1748B0039B085 /* GCSegmentedArray.h */,
 				2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */,
 				0F86A26E1D6F7B3100CB0C92 /* GCTypeMap.h */,
@@ -6079,6 +6089,8 @@
 				0F7DF1321E2970D50095951B /* Subspace.h */,
 				0F7DF1331E2970D50095951B /* SubspaceInlines.h */,
 				0FD0E5ED1E468A540006AB08 /* SweepingScope.h */,
+				0FD79A2B1EBBBDB200DA88D3 /* Synchronousness.cpp */,
+				0FD79A2C1EBBBDB200DA88D3 /* Synchronousness.h */,
 				0F1FB38A1E173A6200A9BE50 /* SynchronousStopTheWorldMutatorScheduler.cpp */,
 				0F1FB38B1E173A6200A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h */,
 				141448CC13A1783700F5BA1A /* TinyBloomFilter.h */,
@@ -8659,6 +8671,7 @@
 				0F63943F15C75F19006A597C /* DFGTypeCheckHoistingPhase.h in Headers */,
 				0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */,
 				0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */,
+				0F9715311EB28BEE00A1645D /* GCRequest.h in Headers */,
 				0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */,
 				0F2BDC481522802900CD8910 /* DFGValueSource.h in Headers */,
 				0F0123331944EA1B00843A0C /* DFGValueStrength.h in Headers */,
@@ -9357,6 +9370,7 @@
 				A55D93A6185012A800400DED /* ScriptFunctionCall.h in Headers */,
 				A54CF2FA184EAEDA00237F19 /* ScriptObject.h in Headers */,
 				A55165D51BDF135A003B75C1 /* ScriptProfilingScope.h in Headers */,
+				0FD79A2D1EBBBDBB00DA88D3 /* Synchronousness.h in Headers */,
 				A54CF2F6184EAB2400237F19 /* ScriptValue.h in Headers */,
 				A7299DA617D12858005F5FF9 /* SetConstructor.h in Headers */,
 				A790DD6E182F499700588807 /* SetIteratorPrototype.h in Headers */,
@@ -10106,6 +10120,7 @@
 				0FEC85901BDACDC70080FF74 /* AirValidate.cpp in Sources */,
 				0F9630391D4192C6005609D9 /* AllocatorAttributes.cpp in Sources */,
 				147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
+				0F9715301EB28BEB00A1645D /* GCRequest.cpp in Sources */,
 				79A228351D35D71E00D8E067 /* ArithProfile.cpp in Sources */,
 				0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */,
 				86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */,
@@ -10810,6 +10825,7 @@
 				DC605B5D1CE26EA000593718 /* ProfilerEvent.cpp in Sources */,
 				0F190CAC189D82F6000AE5F0 /* ProfilerJettisonReason.cpp in Sources */,
 				0FF729B3166AD35C000F5BA3 /* ProfilerOrigin.cpp in Sources */,
+				0FD79A2E1EBBBDC000DA88D3 /* Synchronousness.cpp in Sources */,
 				0FF729B4166AD35C000F5BA3 /* ProfilerOriginStack.cpp in Sources */,
 				0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
 				0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/heap/FullGCActivityCallback.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/heap/FullGCActivityCallback.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/heap/FullGCActivityCallback.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -42,7 +42,7 @@
 void FullGCActivityCallback::doCollection()
 {
     Heap& heap = m_vm->heap;
-    m_didSyncGCRecently = false;
+    m_didGCRecently = false;
 
 #if !PLATFORM(IOS)
     double startTime = WTF::monotonicallyIncreasingTime();

Modified: trunk/Source/_javascript_Core/heap/FullGCActivityCallback.h (216217 => 216218)


--- trunk/Source/_javascript_Core/heap/FullGCActivityCallback.h	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/heap/FullGCActivityCallback.h	2017-05-04 23:37:52 UTC (rev 216218)
@@ -35,8 +35,8 @@
 
     void doCollection() override;
 
-    bool didSyncGCRecently() const { return m_didSyncGCRecently; }
-    void setDidSyncGCRecently() { m_didSyncGCRecently = true; }
+    bool didGCRecently() const { return m_didGCRecently; }
+    void setDidGCRecently() { m_didGCRecently = true; }
 
 protected:
     Seconds lastGCLength() override;
@@ -43,7 +43,7 @@
     double gcTimeSlice(size_t bytes) override;
     double deathRate() override;
 
-    bool m_didSyncGCRecently { false };
+    bool m_didGCRecently { false };
 };
 
 inline RefPtr<FullGCActivityCallback> GCActivityCallback::createFullTimer(Heap* heap)

Added: trunk/Source/_javascript_Core/heap/GCRequest.cpp (0 => 216218)


--- trunk/Source/_javascript_Core/heap/GCRequest.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/heap/GCRequest.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "GCRequest.h"
+
+namespace JSC {
+
+bool GCRequest::subsumedBy(const GCRequest& other) const
+{
+    // If we have callbacks, then there is no chance that we're subsumed by an existing request.
+    if (didFinishEndPhase)
+        return false;
+    
+    if (other.scope == CollectionScope::Full)
+        return true;
+    
+    if (scope) {
+        // If we're eden, then we're subsumed by the other scope because the other scope is either eden
+        // or disengaged (so either eden or full). If we're full, then we're not subsumed, for the same
+        // reason.
+        return scope == CollectionScope::Eden;
+    }
+    
+    // At this point we know that other.scope is either not engaged or Eden, and this.scope is not
+    // engaged. So, we're expecting to do either an eden or full collection, and the other scope is
+    // either the same or is requesting specifically a full collection. We are subsumed if the other
+    // scope is disengaged (so same as us).
+    return !other.scope;
+}
+
+void GCRequest::dump(PrintStream& out) const
+{
+    out.print("{scope = ", scope, ", didFinishEndPhase = ", didFinishEndPhase ? "engaged" : "null", "}");
+}
+
+} // namespace JSC
+

Added: trunk/Source/_javascript_Core/heap/GCRequest.h (0 => 216218)


--- trunk/Source/_javascript_Core/heap/GCRequest.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/heap/GCRequest.h	2017-05-04 23:37:52 UTC (rev 216218)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#pragma once
+
+#include "CollectionScope.h"
+#include <wtf/Optional.h>
+#include <wtf/PrintStream.h>
+#include <wtf/RefPtr.h>
+#include <wtf/SharedTask.h>
+
+namespace JSC {
+
+struct GCRequest {
+    GCRequest() { }
+    
+    GCRequest(CollectionScope scope)
+        : scope(scope)
+    {
+    }
+    
+    GCRequest(std::optional<CollectionScope> scope)
+        : scope(scope)
+    {
+    }
+    
+    bool subsumedBy(const GCRequest& other) const;
+    
+    void dump(PrintStream&) const;
+    
+    std::optional<CollectionScope> scope;
+    RefPtr<SharedTask<void()>> didFinishEndPhase;
+};
+
+} // namespace JSC
+

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -940,31 +940,52 @@
     }
 }
 
-void Heap::collectAllGarbage()
+void Heap::collect(Synchronousness synchronousness, GCRequest request)
 {
-    if (!m_isSafeToCollect)
+    switch (synchronousness) {
+    case Async:
+        collectAsync(request);
         return;
-    
-    collectSync(CollectionScope::Full);
+    case Sync:
+        collectSync(request);
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
 
-    DeferGCForAWhile deferGC(*this);
-    if (UNLIKELY(Options::useImmortalObjects()))
-        sweeper()->stopSweeping();
-
-    bool alreadySweptInCollectSync = Options::sweepSynchronously();
-    if (!alreadySweptInCollectSync) {
-        if (Options::logGC())
-            dataLog("[GC<", RawPointer(this), ">: ");
-        sweepSynchronously();
-        if (Options::logGC())
-            dataLog("]\n");
+void Heap::collectNow(Synchronousness synchronousness, GCRequest request)
+{
+    switch (synchronousness) {
+    case Async: {
+        collectAsync(request);
+        stopIfNecessary();
+        return;
     }
-    m_objectSpace.assertNoUnswept();
-
-    sweepAllLogicallyEmptyWeakBlocks();
+        
+    case Sync: {
+        collectSync(request);
+        
+        DeferGCForAWhile deferGC(*this);
+        if (UNLIKELY(Options::useImmortalObjects()))
+            sweeper().stopSweeping();
+        
+        bool alreadySweptInCollectSync = Options::sweepSynchronously();
+        if (!alreadySweptInCollectSync) {
+            if (Options::logGC())
+                dataLog("[GC<", RawPointer(this), ">: ");
+            sweepSynchronously();
+            if (Options::logGC())
+                dataLog("]\n");
+        }
+        m_objectSpace.assertNoUnswept();
+        
+        sweepAllLogicallyEmptyWeakBlocks();
+        return;
+    } }
+    RELEASE_ASSERT_NOT_REACHED();
 }
 
-void Heap::collectAsync(std::optional<CollectionScope> scope)
+void Heap::collectAsync(GCRequest request)
 {
     if (!m_isSafeToCollect)
         return;
@@ -972,23 +993,10 @@
     bool alreadyRequested = false;
     {
         LockHolder locker(*m_threadLock);
-        for (std::optional<CollectionScope> request : m_requests) {
-            if (scope) {
-                if (scope == CollectionScope::Eden) {
-                    alreadyRequested = true;
-                    break;
-                } else {
-                    RELEASE_ASSERT(scope == CollectionScope::Full);
-                    if (request == CollectionScope::Full) {
-                        alreadyRequested = true;
-                        break;
-                    }
-                }
-            } else {
-                if (!request || request == CollectionScope::Full) {
-                    alreadyRequested = true;
-                    break;
-                }
+        for (const GCRequest& previousRequest : m_requests) {
+            if (request.subsumedBy(previousRequest)) {
+                alreadyRequested = true;
+                break;
             }
         }
     }
@@ -995,15 +1003,15 @@
     if (alreadyRequested)
         return;
 
-    requestCollection(scope);
+    requestCollection(request);
 }
 
-void Heap::collectSync(std::optional<CollectionScope> scope)
+void Heap::collectSync(GCRequest request)
 {
     if (!m_isSafeToCollect)
         return;
     
-    waitForCollection(requestCollection(scope));
+    waitForCollection(requestCollection(request));
 }
 
 bool Heap::shouldCollectInCollectorThread(const AbstractLocker&)
@@ -1108,12 +1116,11 @@
 NEVER_INLINE bool Heap::runBeginPhase(GCConductor conn)
 {
     m_currentGCStartTime = MonotonicTime::now();
-        
-    std::optional<CollectionScope> scope;
+    
     {
         LockHolder locker(*m_threadLock);
         RELEASE_ASSERT(!m_requests.isEmpty());
-        scope = m_requests.first();
+        m_currentRequest = m_requests.first();
     }
         
     if (Options::logGC())
@@ -1125,9 +1132,9 @@
         dataLog("Collection scope already set during GC: ", *m_collectionScope, "\n");
         RELEASE_ASSERT_NOT_REACHED();
     }
+    
+    willStartCollection();
         
-    willStartCollection(scope);
-        
     if (UNLIKELY(m_verifier)) {
         // Verify that live objects from the last GC cycle haven't been corrupted by
         // mutators before we begin this new GC cycle.
@@ -1394,7 +1401,10 @@
     }
 
     didFinishCollection();
-
+    
+    if (m_currentRequest.didFinishEndPhase)
+        m_currentRequest.didFinishEndPhase->run();
+    
     if (false) {
         dataLog("Heap state after GC:\n");
         m_objectSpace.dumpBits();
@@ -1956,7 +1966,7 @@
     }
 }
 
-Heap::Ticket Heap::requestCollection(std::optional<CollectionScope> scope)
+Heap::Ticket Heap::requestCollection(GCRequest request)
 {
     stopIfNecessary();
     
@@ -1974,7 +1984,7 @@
         m_worldState.exchangeOr(mutatorHasConnBit);
     }
     
-    m_requests.append(scope);
+    m_requests.append(request);
     m_lastGrantedTicket++;
     if (!(m_worldState.load() & mutatorHasConnBit))
         m_threadCondition->notifyOne(locker);
@@ -2005,12 +2015,12 @@
 #endif
 }
 
-void Heap::willStartCollection(std::optional<CollectionScope> scope)
+void Heap::willStartCollection()
 {
     if (Options::logGC())
         dataLog("=> ");
     
-    if (shouldDoFullCollection(scope)) {
+    if (shouldDoFullCollection()) {
         m_collectionScope = CollectionScope::Full;
         m_shouldDoFullCollection = false;
         if (Options::logGC())
@@ -2229,9 +2239,9 @@
     return m_edenActivityCallback.get();
 }
 
-IncrementalSweeper* Heap::sweeper()
+IncrementalSweeper& Heap::sweeper()
 {
-    return m_sweeper.get();
+    return *m_sweeper;
 }
 
 void Heap::setGarbageCollectionTimerEnabled(bool enable)
@@ -2284,31 +2294,31 @@
     m_executables.append(executable);
 }
 
-void Heap::collectAllGarbageIfNotDoneRecently()
+void Heap::collectNowFullIfNotDoneRecently(Synchronousness synchronousness)
 {
     if (!m_fullActivityCallback) {
-        collectAllGarbage();
+        collectNow(synchronousness, CollectionScope::Full);
         return;
     }
 
-    if (m_fullActivityCallback->didSyncGCRecently()) {
+    if (m_fullActivityCallback->didGCRecently()) {
         // A synchronous GC was already requested recently so we merely accelerate next collection.
         reportAbandonedObjectGraph();
         return;
     }
 
-    m_fullActivityCallback->setDidSyncGCRecently();
-    collectAllGarbage();
+    m_fullActivityCallback->setDidGCRecently();
+    collectNow(synchronousness, CollectionScope::Full);
 }
 
-bool Heap::shouldDoFullCollection(std::optional<CollectionScope> scope) const
+bool Heap::shouldDoFullCollection() const
 {
     if (!Options::useGenerationalGC())
         return true;
 
-    if (!scope)
+    if (!m_currentRequest.scope)
         return m_shouldDoFullCollection || webAssemblyFastMemoriesThisCycleAtThreshold();
-    return *scope == CollectionScope::Full;
+    return *m_currentRequest.scope == CollectionScope::Full;
 }
 
 void Heap::addLogicallyEmptyWeakBlock(WeakBlock* block)

Modified: trunk/Source/_javascript_Core/heap/Heap.h (216217 => 216218)


--- trunk/Source/_javascript_Core/heap/Heap.h	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/heap/Heap.h	2017-05-04 23:37:52 UTC (rev 216218)
@@ -28,6 +28,7 @@
 #include "DeleteAllCodeEffort.h"
 #include "GCConductor.h"
 #include "GCIncomingRefCountedSet.h"
+#include "GCRequest.h"
 #include "HandleSet.h"
 #include "HandleStack.h"
 #include "HeapObserver.h"
@@ -38,6 +39,7 @@
 #include "MutatorState.h"
 #include "Options.h"
 #include "StructureIDTable.h"
+#include "Synchronousness.h"
 #include "TinyBloomFilter.h"
 #include "UnconditionalFinalizer.h"
 #include "VisitRaceKey.h"
@@ -146,7 +148,7 @@
     JS_EXPORT_PRIVATE GCActivityCallback* edenActivityCallback();
     JS_EXPORT_PRIVATE void setGarbageCollectionTimerEnabled(bool);
 
-    JS_EXPORT_PRIVATE IncrementalSweeper* sweeper();
+    JS_EXPORT_PRIVATE IncrementalSweeper& sweeper();
 
     void addObserver(HeapObserver* observer) { m_observers.append(observer); }
     void removeObserver(HeapObserver* observer) { m_observers.removeFirst(observer); }
@@ -169,8 +171,6 @@
 
     JS_EXPORT_PRIVATE bool isHeapSnapshotting() const;
 
-    JS_EXPORT_PRIVATE void collectAllGarbageIfNotDoneRecently();
-    JS_EXPORT_PRIVATE void collectAllGarbage();
     JS_EXPORT_PRIVATE void sweepSynchronously();
 
     bool shouldCollectHeuristic();
@@ -180,7 +180,7 @@
     // and std::nullopt collections are stronger than Eden collections. std::nullopt means that the GC can
     // choose Eden or Full. This implies that if you request a GC while that GC is ongoing, nothing
     // will happen.
-    JS_EXPORT_PRIVATE void collectAsync(std::optional<CollectionScope> = std::nullopt);
+    JS_EXPORT_PRIVATE void collectAsync(GCRequest = GCRequest());
     
     // Queue up a collection and wait for it to complete. This won't return until you get your own
     // complete collection. For example, if there was an ongoing asynchronous collection at the time
@@ -187,8 +187,16 @@
     // you called this, then this would wait for that one to complete and then trigger your
     // collection and then return. In weird cases, there could be multiple GC requests in the backlog
     // and this will wait for that backlog before running its GC and returning.
-    JS_EXPORT_PRIVATE void collectSync(std::optional<CollectionScope> = std::nullopt);
+    JS_EXPORT_PRIVATE void collectSync(GCRequest = GCRequest());
     
+    JS_EXPORT_PRIVATE void collect(Synchronousness, GCRequest = GCRequest());
+    
+    // Like collect(), but in the case of Async this will stopIfNecessary() and in the case of
+    // Sync this will sweep synchronously.
+    JS_EXPORT_PRIVATE void collectNow(Synchronousness, GCRequest = GCRequest());
+    
+    JS_EXPORT_PRIVATE void collectNowFullIfNotDoneRecently(Synchronousness);
+    
     void collectIfNecessaryOrDefer(GCDeferralContext* = nullptr);
 
     void completeAllJITPlans();
@@ -438,7 +446,7 @@
     bool stopTheMutator();
     void resumeTheMutator();
     
-    void stopIfNecessarySlow();
+    JS_EXPORT_PRIVATE void stopIfNecessarySlow();
     bool stopIfNecessarySlow(unsigned extraStateBits);
     
     template<typename Func>
@@ -465,11 +473,11 @@
     void notifyThreadStopping(const AbstractLocker&);
     
     typedef uint64_t Ticket;
-    Ticket requestCollection(std::optional<CollectionScope>);
+    Ticket requestCollection(GCRequest);
     void waitForCollection(Ticket);
     
     void suspendCompilerThreads();
-    void willStartCollection(std::optional<CollectionScope>);
+    void willStartCollection();
     void prepareForMarking();
     
     void gatherStackRoots(ConservativeRoots&);
@@ -503,7 +511,7 @@
     void sweepAllLogicallyEmptyWeakBlocks();
     bool sweepNextLogicallyEmptyWeakBlock();
 
-    bool shouldDoFullCollection(std::optional<CollectionScope> requestedCollectionScope) const;
+    bool shouldDoFullCollection() const;
 
     void incrementDeferralDepth();
     void decrementDeferralDepth();
@@ -664,7 +672,8 @@
     MonotonicTime m_afterGC;
     MonotonicTime m_stopTime;
     
-    Deque<std::optional<CollectionScope>> m_requests;
+    Deque<GCRequest> m_requests;
+    GCRequest m_currentRequest;
     Ticket m_lastServedTicket { 0 };
     Ticket m_lastGrantedTicket { 0 };
     CollectorPhase m_currentPhase { CollectorPhase::NotRunning };

Modified: trunk/Source/_javascript_Core/heap/HeapSnapshotBuilder.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/heap/HeapSnapshotBuilder.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/heap/HeapSnapshotBuilder.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -58,7 +58,7 @@
     m_snapshot = std::make_unique<HeapSnapshot>(m_profiler.mostRecentSnapshot());
     {
         m_profiler.setActiveSnapshotBuilder(this);
-        m_profiler.vm().heap.collectAllGarbage();
+        m_profiler.vm().heap.collectNow(Sync, CollectionScope::Full);
         m_profiler.setActiveSnapshotBuilder(nullptr);
     }
     m_snapshot->finalize();

Modified: trunk/Source/_javascript_Core/heap/IncrementalSweeper.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/heap/IncrementalSweeper.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/heap/IncrementalSweeper.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -66,6 +66,10 @@
         return;
     }
 
+    if (m_shouldFreeFastMallocMemoryAfterSweeping) {
+        WTF::releaseFastMallocFreeMemory();
+        m_shouldFreeFastMallocMemoryAfterSweeping = false;
+    }
     cancelTimer();
 }
 

Modified: trunk/Source/_javascript_Core/heap/IncrementalSweeper.h (216217 => 216218)


--- trunk/Source/_javascript_Core/heap/IncrementalSweeper.h	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/heap/IncrementalSweeper.h	2017-05-04 23:37:52 UTC (rev 216218)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,6 +39,7 @@
     JS_EXPORT_PRIVATE explicit IncrementalSweeper(Heap*);
 
     JS_EXPORT_PRIVATE void startSweeping();
+    void freeFastMallocMemoryAfterSweeping() { m_shouldFreeFastMallocMemoryAfterSweeping = true; }
 
     JS_EXPORT_PRIVATE void doWork() override;
     bool sweepNextBlock();
@@ -49,6 +50,7 @@
     void scheduleTimer();
     
     MarkedAllocator* m_currentAllocator;
+    bool m_shouldFreeFastMallocMemoryAfterSweeping { false };
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -182,7 +182,7 @@
             if (deferralContext)
                 deferralContext->m_shouldGC = true;
             else
-                m_heap->collectAllGarbage();
+                m_heap->collectNow(Sync, CollectionScope::Full);
         }
     }
     if (++allocationCount >= Options::slowPathAllocsBetweenGCs())

Modified: trunk/Source/_javascript_Core/heap/MarkedSpace.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/heap/MarkedSpace.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/heap/MarkedSpace.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -225,7 +225,7 @@
 
 void MarkedSpace::sweep()
 {
-    m_heap->sweeper()->stopSweeping();
+    m_heap->sweeper().stopSweeping();
     forEachAllocator(
         [&] (MarkedAllocator& allocator) -> IterationStatus {
             allocator.sweep();

Added: trunk/Source/_javascript_Core/heap/Synchronousness.cpp (0 => 216218)


--- trunk/Source/_javascript_Core/heap/Synchronousness.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/heap/Synchronousness.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Synchronousness.h"
+
+#include <wtf/PrintStream.h>
+
+using namespace JSC;
+
+namespace WTF {
+
+void printInternal(PrintStream& out, Synchronousness synchronousness)
+{
+    switch (synchronousness) {
+    case Async:
+        out.print("Async");
+        return;
+    case Sync:
+        out.print("Sync");
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+

Added: trunk/Source/_javascript_Core/heap/Synchronousness.h (0 => 216218)


--- trunk/Source/_javascript_Core/heap/Synchronousness.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/heap/Synchronousness.h	2017-05-04 23:37:52 UTC (rev 216218)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace JSC {
+
+enum Synchronousness {
+    Async,
+    Sync
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+class PrintStream;
+
+void printInternal(PrintStream& out, JSC::Synchronousness);
+
+} // namespace WTF
+

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorHeapAgent.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorHeapAgent.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorHeapAgent.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -91,7 +91,7 @@
     VM& vm = m_environment.vm();
     JSLockHolder lock(vm);
     sanitizeStackForVM(&vm);
-    vm.heap.collectAllGarbage();
+    vm.heap.collectNow(Sync, CollectionScope::Full);
 }
 
 void InspectorHeapAgent::snapshot(ErrorString&, double* timestamp, String* snapshotData)

Modified: trunk/Source/_javascript_Core/jsc.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/jsc.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/jsc.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -2025,7 +2025,7 @@
 EncodedJSValue JSC_HOST_CALL functionGCAndSweep(ExecState* exec)
 {
     JSLockHolder lock(exec);
-    exec->heap()->collectAllGarbage();
+    exec->heap()->collectNow(Sync, CollectionScope::Full);
     return JSValue::encode(jsNumber(exec->heap()->sizeAfterLastFullCollection()));
 }
 
@@ -3858,7 +3858,7 @@
     if (Options::gcAtEnd()) {
         // We need to hold the API lock to do a GC.
         JSLockHolder locker(&vm);
-        vm.heap.collectAllGarbage();
+        vm.heap.collectNow(Sync, CollectionScope::Full);
     }
 
     if (options.m_dumpSamplingProfilerData) {

Modified: trunk/Source/_javascript_Core/tools/JSDollarVMPrototype.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/tools/JSDollarVMPrototype.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/tools/JSDollarVMPrototype.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -118,7 +118,7 @@
 {
     if (!ensureCurrentThreadOwnsJSLock(exec))
         return;
-    exec->heap()->collectAllGarbage();
+    exec->heap()->collectNow(Sync, CollectionScope::Full);
 }
     
 static EncodedJSValue JSC_HOST_CALL functionGC(ExecState* exec)

Modified: trunk/Source/_javascript_Core/wasm/WasmMemory.cpp (216217 => 216218)


--- trunk/Source/_javascript_Core/wasm/WasmMemory.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/_javascript_Core/wasm/WasmMemory.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -151,9 +151,9 @@
             dataLogLnIf(verbose, "tryGetFastMemory re-using ", RawPointer(memory));
         else if (currentlyAllocatedFastMemories.load(std::memory_order_acquire) >= 1) {
             // No memory was available in the cache, but we know there's at least one currently live. Maybe GC will find a free one.
-            // FIXME collectSync(Full) and custom eager destruction of wasm memories could be better. For now use collectAllGarbage. Also, nothing tells us the current VM is holding onto fast memories. https://bugs.webkit.org/show_bug.cgi?id=170748
+            // FIXME collectSync(Full) and custom eager destruction of wasm memories could be better. For now use collectNow. Also, nothing tells us the current VM is holding onto fast memories. https://bugs.webkit.org/show_bug.cgi?id=170748
             dataLogLnIf(verbose, "tryGetFastMemory waiting on GC and retrying");
-            vm.heap.collectAllGarbage();
+            vm.heap.collectNow(Sync, CollectionScope::Full);
             memory = tryGetCachedFastMemory();
             dataLogLnIf(verbose, "tryGetFastMemory waited on GC and retried ", memory? "successfully" : "unseccessfully");
         }

Modified: trunk/Source/WebCore/ChangeLog (216217 => 216218)


--- trunk/Source/WebCore/ChangeLog	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/WebCore/ChangeLog	2017-05-04 23:37:52 UTC (rev 216218)
@@ -1,3 +1,19 @@
+2017-05-04  Filip Pizlo  <[email protected]>
+
+        JSC::Heap should expose a richer API for requesting GCs
+        https://bugs.webkit.org/show_bug.cgi?id=171690
+
+        Reviewed by Geoffrey Garen.
+
+        No new tests because this is just a refactoring.
+        
+        Change some function calls now that some JSC::Heap APIs got renamed.
+
+        * bindings/js/GCController.cpp:
+        (WebCore::collect):
+        (WebCore::GCController::garbageCollectNow):
+        (WebCore::GCController::garbageCollectNowIfNotDoneRecently):
+
 2017-05-04  Mark Lam  <[email protected]>
 
         NeverDestroyed<String>(ASCIILiteral(...)) is not thread safe.

Modified: trunk/Source/WebCore/bindings/js/GCController.cpp (216217 => 216218)


--- trunk/Source/WebCore/bindings/js/GCController.cpp	2017-05-04 23:24:13 UTC (rev 216217)
+++ trunk/Source/WebCore/bindings/js/GCController.cpp	2017-05-04 23:37:52 UTC (rev 216218)
@@ -41,7 +41,7 @@
 static void collect(void*)
 {
     JSLockHolder lock(commonVM());
-    commonVM().heap.collectAllGarbage();
+    commonVM().heap.collectNow(Sync, CollectionScope::Full);
 }
 
 GCController& GCController::singleton()
@@ -83,7 +83,7 @@
 {
     JSLockHolder lock(commonVM());
     if (!commonVM().heap.isCurrentThreadBusy()) {
-        commonVM().heap.collectAllGarbage();
+        commonVM().heap.collectNow(Sync, CollectionScope::Full);
         WTF::releaseFastMallocFreeMemory();
     }
 }
@@ -93,7 +93,7 @@
 #if USE(CF) || USE(GLIB)
     JSLockHolder lock(commonVM());
     if (!commonVM().heap.isCurrentThreadBusy())
-        commonVM().heap.collectAllGarbageIfNotDoneRecently();
+        commonVM().heap.collectNowFullIfNotDoneRecently(Sync);
 #else
     garbageCollectSoon();
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to