fe14c27a6a2c9b3beed721da94cd2e748731bb08
[WebKit-https.git] / Source / JavaScriptCore / heap / Heap.h
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #pragma once
23
24 #include "ArrayBuffer.h"
25 #include "CellState.h"
26 #include "CollectionScope.h"
27 #include "CollectorPhase.h"
28 #include "DeleteAllCodeEffort.h"
29 #include "GCConductor.h"
30 #include "GCIncomingRefCountedSet.h"
31 #include "GCRequest.h"
32 #include "HandleSet.h"
33 #include "HandleStack.h"
34 #include "HeapFinalizerCallback.h"
35 #include "HeapObserver.h"
36 #include "ListableHandler.h"
37 #include "MarkedBlock.h"
38 #include "MarkedSpace.h"
39 #include "MutatorState.h"
40 #include "Options.h"
41 #include "StructureIDTable.h"
42 #include "Synchronousness.h"
43 #include "UnconditionalFinalizer.h"
44 #include "WeakHandleOwner.h"
45 #include "WeakReferenceHarvester.h"
46 #include <wtf/AutomaticThread.h>
47 #include <wtf/Deque.h>
48 #include <wtf/HashCountedSet.h>
49 #include <wtf/HashSet.h>
50 #include <wtf/ParallelHelperPool.h>
51 #include <wtf/Threading.h>
52
53 namespace JSC {
54
55 class CodeBlock;
56 class CodeBlockSet;
57 class CollectingScope;
58 class ConservativeRoots;
59 class GCDeferralContext;
60 class EdenGCActivityCallback;
61 class ExecutableBase;
62 class FullGCActivityCallback;
63 class GCActivityCallback;
64 class GCAwareJITStubRoutine;
65 class Heap;
66 class HeapProfiler;
67 class HeapVerifier;
68 class IncrementalSweeper;
69 class JITStubRoutine;
70 class JITStubRoutineSet;
71 class JSCell;
72 class JSValue;
73 class LLIntOffsetsExtractor;
74 class MachineThreads;
75 class MarkStackArray;
76 class MarkedAllocator;
77 class MarkedArgumentBuffer;
78 class MarkingConstraint;
79 class MarkingConstraintSet;
80 class MutatorScheduler;
81 class RunningScope;
82 class SlotVisitor;
83 class SpaceTimeMutatorScheduler;
84 class StopIfNecessaryTimer;
85 class SweepingScope;
86 class VM;
87 class WeakGCMapBase;
88 struct CurrentThreadState;
89
90 namespace DFG {
91 class SpeculativeJIT;
92 class Worklist;
93 }
94
95 typedef HashCountedSet<JSCell*> ProtectCountSet;
96 typedef HashCountedSet<const char*> TypeCountSet;
97
98 enum HeapType { SmallHeap, LargeHeap };
99
100 class HeapUtil;
101
102 class Heap {
103     WTF_MAKE_NONCOPYABLE(Heap);
104 public:
105     friend class JIT;
106     friend class DFG::SpeculativeJIT;
107     static Heap* heap(const JSValue); // 0 for immediate values
108     static Heap* heap(const HeapCell*);
109
110     // This constant determines how many blocks we iterate between checks of our 
111     // deadline when calling Heap::isPagedOut. Decreasing it will cause us to detect 
112     // overstepping our deadline more quickly, while increasing it will cause 
113     // our scan to run faster. 
114     static const unsigned s_timeCheckResolution = 16;
115
116     static bool isMarked(const void*);
117     static bool isMarkedConcurrently(const void*);
118     static bool testAndSetMarked(HeapVersion, const void*);
119     
120     static size_t cellSize(const void*);
121
122     void writeBarrier(const JSCell* from);
123     void writeBarrier(const JSCell* from, JSValue to);
124     void writeBarrier(const JSCell* from, JSCell* to);
125     
126     void writeBarrierWithoutFence(const JSCell* from);
127     
128     void mutatorFence();
129     
130     // Take this if you know that from->cellState() < barrierThreshold.
131     JS_EXPORT_PRIVATE void writeBarrierSlowPath(const JSCell* from);
132
133     Heap(VM*, HeapType);
134     ~Heap();
135     void lastChanceToFinalize();
136     void releaseDelayedReleasedObjects();
137
138     VM* vm() const;
139
140     MarkedSpace& objectSpace() { return m_objectSpace; }
141     MachineThreads& machineThreads() { return *m_machineThreads; }
142
143     SlotVisitor& collectorSlotVisitor() { return *m_collectorSlotVisitor; }
144
145     JS_EXPORT_PRIVATE GCActivityCallback* fullActivityCallback();
146     JS_EXPORT_PRIVATE GCActivityCallback* edenActivityCallback();
147     JS_EXPORT_PRIVATE void setGarbageCollectionTimerEnabled(bool);
148
149     JS_EXPORT_PRIVATE IncrementalSweeper& sweeper();
150
151     void addObserver(HeapObserver* observer) { m_observers.append(observer); }
152     void removeObserver(HeapObserver* observer) { m_observers.removeFirst(observer); }
153
154     MutatorState mutatorState() const { return m_mutatorState; }
155     std::optional<CollectionScope> collectionScope() const { return m_collectionScope; }
156     bool hasHeapAccess() const;
157     bool collectorBelievesThatTheWorldIsStopped() const;
158
159     // We're always busy on the collection threads. On the main thread, this returns true if we're
160     // helping heap.
161     JS_EXPORT_PRIVATE bool isCurrentThreadBusy();
162     
163     typedef void (*Finalizer)(JSCell*);
164     JS_EXPORT_PRIVATE void addFinalizer(JSCell*, Finalizer);
165     void addExecutable(ExecutableBase*);
166
167     void notifyIsSafeToCollect();
168     bool isSafeToCollect() const { return m_isSafeToCollect; }
169
170     JS_EXPORT_PRIVATE bool isHeapSnapshotting() const;
171
172     JS_EXPORT_PRIVATE void sweepSynchronously();
173
174     bool shouldCollectHeuristic();
175     
176     // Queue up a collection. Returns immediately. This will not queue a collection if a collection
177     // of equal or greater strength exists. Full collections are stronger than std::nullopt collections
178     // and std::nullopt collections are stronger than Eden collections. std::nullopt means that the GC can
179     // choose Eden or Full. This implies that if you request a GC while that GC is ongoing, nothing
180     // will happen.
181     JS_EXPORT_PRIVATE void collectAsync(GCRequest = GCRequest());
182     
183     // Queue up a collection and wait for it to complete. This won't return until you get your own
184     // complete collection. For example, if there was an ongoing asynchronous collection at the time
185     // you called this, then this would wait for that one to complete and then trigger your
186     // collection and then return. In weird cases, there could be multiple GC requests in the backlog
187     // and this will wait for that backlog before running its GC and returning.
188     JS_EXPORT_PRIVATE void collectSync(GCRequest = GCRequest());
189     
190     JS_EXPORT_PRIVATE void collect(Synchronousness, GCRequest = GCRequest());
191     
192     // Like collect(), but in the case of Async this will stopIfNecessary() and in the case of
193     // Sync this will sweep synchronously.
194     JS_EXPORT_PRIVATE void collectNow(Synchronousness, GCRequest = GCRequest());
195     
196     JS_EXPORT_PRIVATE void collectNowFullIfNotDoneRecently(Synchronousness);
197     
198     void collectIfNecessaryOrDefer(GCDeferralContext* = nullptr);
199
200     void completeAllJITPlans();
201     
202     // Use this API to report non-GC memory referenced by GC objects. Be sure to
203     // call both of these functions: Calling only one may trigger catastropic
204     // memory growth.
205     void reportExtraMemoryAllocated(size_t);
206     JS_EXPORT_PRIVATE void reportExtraMemoryVisited(size_t);
207
208 #if ENABLE(RESOURCE_USAGE)
209     // Use this API to report the subset of extra memory that lives outside this process.
210     JS_EXPORT_PRIVATE void reportExternalMemoryVisited(size_t);
211     size_t externalMemorySize() { return m_externalMemorySize; }
212 #endif
213
214     // Use this API to report non-GC memory if you can't use the better API above.
215     void deprecatedReportExtraMemory(size_t);
216
217     JS_EXPORT_PRIVATE void reportAbandonedObjectGraph();
218
219     JS_EXPORT_PRIVATE void protect(JSValue);
220     JS_EXPORT_PRIVATE bool unprotect(JSValue); // True when the protect count drops to 0.
221     
222     JS_EXPORT_PRIVATE size_t extraMemorySize(); // Non-GC memory referenced by GC objects.
223     JS_EXPORT_PRIVATE size_t size();
224     JS_EXPORT_PRIVATE size_t capacity();
225     JS_EXPORT_PRIVATE size_t objectCount();
226     JS_EXPORT_PRIVATE size_t globalObjectCount();
227     JS_EXPORT_PRIVATE size_t protectedObjectCount();
228     JS_EXPORT_PRIVATE size_t protectedGlobalObjectCount();
229     JS_EXPORT_PRIVATE std::unique_ptr<TypeCountSet> protectedObjectTypeCounts();
230     JS_EXPORT_PRIVATE std::unique_ptr<TypeCountSet> objectTypeCounts();
231
232     HashSet<MarkedArgumentBuffer*>& markListSet();
233     
234     template<typename Functor> void forEachProtectedCell(const Functor&);
235     template<typename Functor> void forEachCodeBlock(const Functor&);
236     template<typename Functor> void forEachCodeBlockIgnoringJITPlans(const AbstractLocker& codeBlockSetLocker, const Functor&);
237
238     HandleSet* handleSet() { return &m_handleSet; }
239     HandleStack* handleStack() { return &m_handleStack; }
240
241     void willStartIterating();
242     void didFinishIterating();
243
244     Seconds lastFullGCLength() const { return m_lastFullGCLength; }
245     Seconds lastEdenGCLength() const { return m_lastEdenGCLength; }
246     void increaseLastFullGCLength(Seconds amount) { m_lastFullGCLength += amount; }
247
248     size_t sizeBeforeLastEdenCollection() const { return m_sizeBeforeLastEdenCollect; }
249     size_t sizeAfterLastEdenCollection() const { return m_sizeAfterLastEdenCollect; }
250     size_t sizeBeforeLastFullCollection() const { return m_sizeBeforeLastFullCollect; }
251     size_t sizeAfterLastFullCollection() const { return m_sizeAfterLastFullCollect; }
252
253     void deleteAllCodeBlocks(DeleteAllCodeEffort);
254     void deleteAllUnlinkedCodeBlocks(DeleteAllCodeEffort);
255
256     void didAllocate(size_t);
257     bool isPagedOut(double deadline);
258     
259     const JITStubRoutineSet& jitStubRoutines() { return *m_jitStubRoutines; }
260     
261     void addReference(JSCell*, ArrayBuffer*);
262     
263     bool isDeferred() const { return !!m_deferralDepth; }
264
265     StructureIDTable& structureIDTable() { return m_structureIDTable; }
266
267     CodeBlockSet& codeBlockSet() { return *m_codeBlocks; }
268
269 #if USE(FOUNDATION)
270     template<typename T> void releaseSoon(RetainPtr<T>&&);
271 #endif
272
273     JS_EXPORT_PRIVATE void registerWeakGCMap(WeakGCMapBase* weakGCMap);
274     JS_EXPORT_PRIVATE void unregisterWeakGCMap(WeakGCMapBase* weakGCMap);
275
276     void addLogicallyEmptyWeakBlock(WeakBlock*);
277
278 #if ENABLE(RESOURCE_USAGE)
279     size_t blockBytesAllocated() const { return m_blockBytesAllocated; }
280 #endif
281
282     void didAllocateBlock(size_t capacity);
283     void didFreeBlock(size_t capacity);
284     
285     bool mutatorShouldBeFenced() const { return m_mutatorShouldBeFenced; }
286     const bool* addressOfMutatorShouldBeFenced() const { return &m_mutatorShouldBeFenced; }
287     
288     unsigned barrierThreshold() const { return m_barrierThreshold; }
289     const unsigned* addressOfBarrierThreshold() const { return &m_barrierThreshold; }
290
291     // If true, the GC believes that the mutator is currently messing with the heap. We call this
292     // "having heap access". The GC may block if the mutator is in this state. If false, the GC may
293     // currently be doing things to the heap that make the heap unsafe to access for the mutator.
294     bool hasAccess() const;
295     
296     // If the mutator does not currently have heap access, this function will acquire it. If the GC
297     // is currently using the lack of heap access to do dangerous things to the heap then this
298     // function will block, waiting for the GC to finish. It's not valid to call this if the mutator
299     // already has heap access. The mutator is required to precisely track whether or not it has
300     // heap access.
301     //
302     // It's totally fine to acquireAccess() upon VM instantiation and keep it that way. This is how
303     // WebCore uses us. For most other clients, JSLock does acquireAccess()/releaseAccess() for you.
304     void acquireAccess();
305     
306     // Releases heap access. If the GC is blocking waiting to do bad things to the heap, it will be
307     // allowed to run now.
308     //
309     // Ordinarily, you should use the ReleaseHeapAccessScope to release and then reacquire heap
310     // access. You should do this anytime you're about do perform a blocking operation, like waiting
311     // on the ParkingLot.
312     void releaseAccess();
313     
314     // This is like a super optimized way of saying:
315     //
316     //     releaseAccess()
317     //     acquireAccess()
318     //
319     // The fast path is an inlined relaxed load and branch. The slow path will block the mutator if
320     // the GC wants to do bad things to the heap.
321     //
322     // All allocations logically call this. As an optimization to improve GC progress, you can call
323     // this anywhere that you can afford a load-branch and where an object allocation would have been
324     // safe.
325     //
326     // The GC will also push a stopIfNecessary() event onto the runloop of the thread that
327     // instantiated the VM whenever it wants the mutator to stop. This means that if you never block
328     // but instead use the runloop to wait for events, then you could safely run in a mode where the
329     // mutator has permanent heap access (like the DOM does). If you have good event handling
330     // discipline (i.e. you don't block the runloop) then you can be sure that stopIfNecessary() will
331     // already be called for you at the right times.
332     void stopIfNecessary();
333     
334     // This gives the conn to the collector.
335     void relinquishConn();
336     
337     bool mayNeedToStop();
338
339     void performIncrement(size_t bytes);
340     
341     // This is a much stronger kind of stopping of the collector, and it may require waiting for a
342     // while. This is meant to be a legacy API for clients of collectAllGarbage that expect that there
343     // is no GC before or after that function call. After calling this, you are free to start GCs
344     // yourself but you can be sure that none are running.
345     //
346     // This both prevents new collections from being started asynchronously and waits for any
347     // outstanding collections to complete.
348     void preventCollection();
349     void allowCollection();
350     
351     uint64_t mutatorExecutionVersion() const { return m_mutatorExecutionVersion; }
352     
353     JS_EXPORT_PRIVATE void addMarkingConstraint(std::unique_ptr<MarkingConstraint>);
354     
355     size_t numOpaqueRoots() const { return m_opaqueRoots.size(); }
356
357     HeapVerifier* verifier() const { return m_verifier.get(); }
358     
359     void addHeapFinalizerCallback(const HeapFinalizerCallback&);
360     void removeHeapFinalizerCallback(const HeapFinalizerCallback&);
361
362 private:
363     friend class AllocatingScope;
364     friend class CodeBlock;
365     friend class CollectingScope;
366     friend class DeferGC;
367     friend class DeferGCForAWhile;
368     friend class GCAwareJITStubRoutine;
369     friend class GCLogging;
370     friend class GCThread;
371     friend class HandleSet;
372     friend class HeapUtil;
373     friend class HeapVerifier;
374     friend class JITStubRoutine;
375     friend class LLIntOffsetsExtractor;
376     friend class MarkedSpace;
377     friend class MarkedAllocator;
378     friend class MarkedBlock;
379     friend class RunningScope;
380     friend class SlotVisitor;
381     friend class SpaceTimeMutatorScheduler;
382     friend class StochasticSpaceTimeMutatorScheduler;
383     friend class SweepingScope;
384     friend class IncrementalSweeper;
385     friend class HeapStatistics;
386     friend class VM;
387     friend class WeakSet;
388
389     class Thread;
390     friend class Thread;
391
392     static const size_t minExtraMemory = 256;
393     
394     class FinalizerOwner : public WeakHandleOwner {
395         void finalize(Handle<Unknown>, void* context) override;
396     };
397
398     JS_EXPORT_PRIVATE bool isValidAllocation(size_t);
399     JS_EXPORT_PRIVATE void reportExtraMemoryAllocatedSlowCase(size_t);
400     JS_EXPORT_PRIVATE void deprecatedReportExtraMemorySlowCase(size_t);
401     
402     bool shouldCollectInCollectorThread(const AbstractLocker&);
403     void collectInCollectorThread();
404     
405     void checkConn(GCConductor);
406
407     enum class RunCurrentPhaseResult {
408         Finished,
409         Continue,
410         NeedCurrentThreadState
411     };
412     RunCurrentPhaseResult runCurrentPhase(GCConductor, CurrentThreadState*);
413     
414     // Returns true if we should keep doing things.
415     bool runNotRunningPhase(GCConductor);
416     bool runBeginPhase(GCConductor);
417     bool runFixpointPhase(GCConductor);
418     bool runConcurrentPhase(GCConductor);
419     bool runReloopPhase(GCConductor);
420     bool runEndPhase(GCConductor);
421     bool changePhase(GCConductor, CollectorPhase);
422     bool finishChangingPhase(GCConductor);
423     
424     void collectInMutatorThread();
425     
426     void stopThePeriphery(GCConductor);
427     void resumeThePeriphery();
428     
429     // Returns true if the mutator is stopped, false if the mutator has the conn now.
430     bool stopTheMutator();
431     void resumeTheMutator();
432     
433     JS_EXPORT_PRIVATE void stopIfNecessarySlow();
434     bool stopIfNecessarySlow(unsigned extraStateBits);
435     
436     template<typename Func>
437     void waitForCollector(const Func&);
438     
439     JS_EXPORT_PRIVATE void acquireAccessSlow();
440     JS_EXPORT_PRIVATE void releaseAccessSlow();
441     
442     bool handleGCDidJIT(unsigned);
443     void handleGCDidJIT();
444     
445     bool handleNeedFinalize(unsigned);
446     void handleNeedFinalize();
447     
448     bool relinquishConn(unsigned);
449     void finishRelinquishingConn();
450     
451     void setGCDidJIT();
452     void setNeedFinalize();
453     void waitWhileNeedFinalize();
454     
455     void setMutatorWaiting();
456     void clearMutatorWaiting();
457     void notifyThreadStopping(const AbstractLocker&);
458     
459     typedef uint64_t Ticket;
460     Ticket requestCollection(GCRequest);
461     void waitForCollection(Ticket);
462     
463     void suspendCompilerThreads();
464     void willStartCollection();
465     void prepareForMarking();
466     
467     void gatherStackRoots(ConservativeRoots&);
468     void gatherJSStackRoots(ConservativeRoots&);
469     void gatherScratchBufferRoots(ConservativeRoots&);
470     void beginMarking();
471     void visitCompilerWorklistWeakReferences();
472     void removeDeadCompilerWorklistEntries();
473     void updateObjectCounts();
474     void endMarking();
475
476     void reapWeakHandles();
477     void pruneStaleEntriesFromWeakGCMaps();
478     void sweepArrayBuffers();
479     void snapshotUnswept();
480     void deleteSourceProviderCaches();
481     void notifyIncrementalSweeper();
482     void harvestWeakReferences();
483     void finalizeUnconditionalFinalizers();
484     void clearUnmarkedExecutables();
485     void deleteUnmarkedCompiledCode();
486     JS_EXPORT_PRIVATE void addToRememberedSet(const JSCell*);
487     void updateAllocationLimits();
488     void didFinishCollection();
489     void resumeCompilerThreads();
490     void gatherExtraHeapSnapshotData(HeapProfiler&);
491     void removeDeadHeapSnapshotNodes(HeapProfiler&);
492     void finalize();
493     void sweepInFinalize();
494     
495     void sweepAllLogicallyEmptyWeakBlocks();
496     bool sweepNextLogicallyEmptyWeakBlock();
497
498     bool shouldDoFullCollection();
499
500     void incrementDeferralDepth();
501     void decrementDeferralDepth();
502     void decrementDeferralDepthAndGCIfNeeded();
503     JS_EXPORT_PRIVATE void decrementDeferralDepthAndGCIfNeededSlow();
504
505     size_t visitCount();
506     size_t bytesVisited();
507     
508     void forEachCodeBlockImpl(const ScopedLambda<bool(CodeBlock*)>&);
509     void forEachCodeBlockIgnoringJITPlansImpl(const AbstractLocker& codeBlockSetLocker, const ScopedLambda<bool(CodeBlock*)>&);
510     
511     void setMutatorShouldBeFenced(bool value);
512     
513     void addCoreConstraints();
514
515     enum class MemoryThresholdCallType {
516         Cached,
517         Direct
518     };
519
520     bool overCriticalMemoryThreshold(MemoryThresholdCallType memoryThresholdCallType = MemoryThresholdCallType::Cached);
521     
522     template<typename Func>
523     void iterateExecutingAndCompilingCodeBlocks(const Func&);
524     
525     template<typename Func>
526     void iterateExecutingAndCompilingCodeBlocksWithoutHoldingLocks(const Func&);
527     
528     void assertSharedMarkStacksEmpty();
529
530     const HeapType m_heapType;
531     const size_t m_ramSize;
532     const size_t m_minBytesPerCycle;
533     size_t m_sizeAfterLastCollect;
534     size_t m_sizeAfterLastFullCollect;
535     size_t m_sizeBeforeLastFullCollect;
536     size_t m_sizeAfterLastEdenCollect;
537     size_t m_sizeBeforeLastEdenCollect;
538
539     size_t m_bytesAllocatedThisCycle;
540     size_t m_bytesAbandonedSinceLastFullCollect;
541     size_t m_maxEdenSize;
542     size_t m_maxEdenSizeWhenCritical;
543     size_t m_maxHeapSize;
544     bool m_shouldDoFullCollection;
545     size_t m_totalBytesVisited;
546     size_t m_totalBytesVisitedThisCycle;
547     double m_incrementBalance { 0 };
548     
549     std::optional<CollectionScope> m_collectionScope;
550     std::optional<CollectionScope> m_lastCollectionScope;
551     MutatorState m_mutatorState { MutatorState::Running };
552     StructureIDTable m_structureIDTable;
553     MarkedSpace m_objectSpace;
554     GCIncomingRefCountedSet<ArrayBuffer> m_arrayBuffers;
555     size_t m_extraMemorySize;
556     size_t m_deprecatedExtraMemorySize;
557
558     HashSet<const JSCell*> m_copyingRememberedSet;
559
560     ProtectCountSet m_protectedValues;
561     std::unique_ptr<HashSet<MarkedArgumentBuffer*>> m_markListSet;
562
563     std::unique_ptr<MachineThreads> m_machineThreads;
564     
565     std::unique_ptr<SlotVisitor> m_collectorSlotVisitor;
566     std::unique_ptr<SlotVisitor> m_mutatorSlotVisitor;
567     std::unique_ptr<MarkStackArray> m_mutatorMarkStack;
568
569     Lock m_raceMarkStackLock;
570     std::unique_ptr<MarkStackArray> m_raceMarkStack;
571
572     std::unique_ptr<MarkingConstraintSet> m_constraintSet;
573
574     // We pool the slot visitors used by parallel marking threads. It's useful to be able to
575     // enumerate over them, and it's useful to have them cache some small amount of memory from
576     // one GC to the next. GC marking threads claim these at the start of marking, and return
577     // them at the end.
578     Vector<std::unique_ptr<SlotVisitor>> m_parallelSlotVisitors;
579     Vector<SlotVisitor*> m_availableParallelSlotVisitors;
580     Lock m_parallelSlotVisitorLock;
581     
582     template<typename Func>
583     void forEachSlotVisitor(const Func&);
584
585     HandleSet m_handleSet;
586     HandleStack m_handleStack;
587     std::unique_ptr<CodeBlockSet> m_codeBlocks;
588     std::unique_ptr<JITStubRoutineSet> m_jitStubRoutines;
589     FinalizerOwner m_finalizerOwner;
590     
591     bool m_isSafeToCollect;
592
593     bool m_mutatorShouldBeFenced { Options::forceFencedBarrier() };
594     unsigned m_barrierThreshold { Options::forceFencedBarrier() ? tautologicalThreshold : blackThreshold };
595
596     VM* m_vm;
597     Seconds m_lastFullGCLength;
598     Seconds m_lastEdenGCLength;
599
600     Vector<ExecutableBase*> m_executables;
601
602     Vector<WeakBlock*> m_logicallyEmptyWeakBlocks;
603     size_t m_indexOfNextLogicallyEmptyWeakBlockToSweep { WTF::notFound };
604     
605     RefPtr<FullGCActivityCallback> m_fullActivityCallback;
606     RefPtr<GCActivityCallback> m_edenActivityCallback;
607     RefPtr<IncrementalSweeper> m_sweeper;
608     RefPtr<StopIfNecessaryTimer> m_stopIfNecessaryTimer;
609
610     Vector<HeapObserver*> m_observers;
611     
612     Vector<HeapFinalizerCallback> m_heapFinalizerCallbacks;
613     
614     unsigned m_deferralDepth;
615     bool m_didDeferGCWork { false };
616
617     std::unique_ptr<HeapVerifier> m_verifier;
618
619 #if USE(FOUNDATION)
620     Vector<RetainPtr<CFTypeRef>> m_delayedReleaseObjects;
621     unsigned m_delayedReleaseRecursionCount;
622 #endif
623
624     HashSet<WeakGCMapBase*> m_weakGCMaps;
625     
626     Lock m_visitRaceLock;
627
628     Lock m_markingMutex;
629     Condition m_markingConditionVariable;
630     std::unique_ptr<MarkStackArray> m_sharedCollectorMarkStack;
631     std::unique_ptr<MarkStackArray> m_sharedMutatorMarkStack;
632     unsigned m_numberOfActiveParallelMarkers { 0 };
633     unsigned m_numberOfWaitingParallelMarkers { 0 };
634     bool m_parallelMarkersShouldExit { false };
635
636     Lock m_opaqueRootsMutex;
637     HashSet<const void*> m_opaqueRoots;
638
639     static const size_t s_blockFragmentLength = 32;
640
641     ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters;
642     ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers;
643
644     ParallelHelperClient m_helperClient;
645
646 #if ENABLE(RESOURCE_USAGE)
647     size_t m_blockBytesAllocated { 0 };
648     size_t m_externalMemorySize { 0 };
649 #endif
650     
651     std::unique_ptr<MutatorScheduler> m_scheduler;
652     
653     static const unsigned mutatorHasConnBit = 1u << 0u; // Must also be protected by threadLock.
654     static const unsigned stoppedBit = 1u << 1u; // Only set when !hasAccessBit
655     static const unsigned hasAccessBit = 1u << 2u;
656     static const unsigned gcDidJITBit = 1u << 3u; // Set when the GC did some JITing, so on resume we need to cpuid.
657     static const unsigned needFinalizeBit = 1u << 4u;
658     static const unsigned mutatorWaitingBit = 1u << 5u; // Allows the mutator to use this as a condition variable.
659     Atomic<unsigned> m_worldState;
660     bool m_collectorBelievesThatTheWorldIsStopped { false };
661     MonotonicTime m_beforeGC;
662     MonotonicTime m_afterGC;
663     MonotonicTime m_stopTime;
664     
665     Deque<GCRequest> m_requests;
666     GCRequest m_currentRequest;
667     Ticket m_lastServedTicket { 0 };
668     Ticket m_lastGrantedTicket { 0 };
669     CollectorPhase m_currentPhase { CollectorPhase::NotRunning };
670     CollectorPhase m_nextPhase { CollectorPhase::NotRunning };
671     bool m_threadShouldStop { false };
672     bool m_threadIsStopping { false };
673     bool m_mutatorDidRun { true };
674     uint64_t m_mutatorExecutionVersion { 0 };
675     Box<Lock> m_threadLock;
676     RefPtr<AutomaticThreadCondition> m_threadCondition; // The mutator must not wait on this. It would cause a deadlock.
677     RefPtr<AutomaticThread> m_thread;
678
679 #if PLATFORM(IOS)
680     unsigned m_precentAvailableMemoryCachedCallCount;
681     bool m_overCriticalMemoryThreshold;
682 #endif
683
684     Lock m_collectContinuouslyLock;
685     Condition m_collectContinuouslyCondition;
686     bool m_shouldStopCollectingContinuously { false };
687     RefPtr<WTF::Thread> m_collectContinuouslyThread { nullptr };
688     
689     MonotonicTime m_lastGCStartTime;
690     MonotonicTime m_lastGCEndTime;
691     MonotonicTime m_currentGCStartTime;
692     
693     uintptr_t m_barriersExecuted { 0 };
694     
695     CurrentThreadState* m_currentThreadState { nullptr };
696 };
697
698 } // namespace JSC