зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1334837 - Add JSContext* to runtime for the active cooperatively scheduled thread, r=jandem,jonco,h4writer.
--HG-- extra : rebase_source : 6cdc3cc3d50e1ab3863d56a4c588ca5663a2fb1c
This commit is contained in:
Родитель
077e1ba24c
Коммит
0051d4ae6b
|
@ -102,7 +102,7 @@ class BackgroundDecommitTask : public GCParallelTask
|
|||
void run() override;
|
||||
|
||||
private:
|
||||
UnprotectedData<ChunkVector> toDecommit;
|
||||
ActiveThreadOrGCTaskData<ChunkVector> toDecommit;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -120,14 +120,14 @@ class GCSchedulingTunables
|
|||
UnprotectedData<size_t> gcMaxBytes_;
|
||||
|
||||
/* Maximum nursery size for each zone group. */
|
||||
UnprotectedData<size_t> gcMaxNurseryBytes_;
|
||||
ActiveThreadData<size_t> gcMaxNurseryBytes_;
|
||||
|
||||
/*
|
||||
* The base value used to compute zone->trigger.gcBytes(). When
|
||||
* usage.gcBytes() surpasses threshold.gcBytes() for a zone, the zone may
|
||||
* be scheduled for a GC, depending on the exact circumstances.
|
||||
*/
|
||||
UnprotectedData<size_t> gcZoneAllocThresholdBase_;
|
||||
ActiveThreadOrGCTaskData<size_t> gcZoneAllocThresholdBase_;
|
||||
|
||||
/* Fraction of threshold.gcBytes() which triggers an incremental GC. */
|
||||
UnprotectedData<double> zoneAllocThresholdFactor_;
|
||||
|
@ -142,38 +142,38 @@ class GCSchedulingTunables
|
|||
* Totally disables |highFrequencyGC|, the HeapGrowthFactor, and other
|
||||
* tunables that make GC non-deterministic.
|
||||
*/
|
||||
UnprotectedData<bool> dynamicHeapGrowthEnabled_;
|
||||
ActiveThreadData<bool> dynamicHeapGrowthEnabled_;
|
||||
|
||||
/*
|
||||
* We enter high-frequency mode if we GC a twice within this many
|
||||
* microseconds. This value is stored directly in microseconds.
|
||||
*/
|
||||
UnprotectedData<uint64_t> highFrequencyThresholdUsec_;
|
||||
ActiveThreadData<uint64_t> highFrequencyThresholdUsec_;
|
||||
|
||||
/*
|
||||
* When in the |highFrequencyGC| mode, these parameterize the per-zone
|
||||
* "HeapGrowthFactor" computation.
|
||||
*/
|
||||
UnprotectedData<uint64_t> highFrequencyLowLimitBytes_;
|
||||
UnprotectedData<uint64_t> highFrequencyHighLimitBytes_;
|
||||
UnprotectedData<double> highFrequencyHeapGrowthMax_;
|
||||
UnprotectedData<double> highFrequencyHeapGrowthMin_;
|
||||
ActiveThreadData<uint64_t> highFrequencyLowLimitBytes_;
|
||||
ActiveThreadData<uint64_t> highFrequencyHighLimitBytes_;
|
||||
ActiveThreadData<double> highFrequencyHeapGrowthMax_;
|
||||
ActiveThreadData<double> highFrequencyHeapGrowthMin_;
|
||||
|
||||
/*
|
||||
* When not in |highFrequencyGC| mode, this is the global (stored per-zone)
|
||||
* "HeapGrowthFactor".
|
||||
*/
|
||||
UnprotectedData<double> lowFrequencyHeapGrowth_;
|
||||
ActiveThreadData<double> lowFrequencyHeapGrowth_;
|
||||
|
||||
/*
|
||||
* Doubles the length of IGC slices when in the |highFrequencyGC| mode.
|
||||
*/
|
||||
UnprotectedData<bool> dynamicMarkSliceEnabled_;
|
||||
ActiveThreadData<bool> dynamicMarkSliceEnabled_;
|
||||
|
||||
/*
|
||||
* Controls whether painting can trigger IGC slices.
|
||||
*/
|
||||
UnprotectedData<bool> refreshFrameSlicesEnabled_;
|
||||
ActiveThreadData<bool> refreshFrameSlicesEnabled_;
|
||||
|
||||
/*
|
||||
* Controls the number of empty chunks reserved for future allocation.
|
||||
|
@ -526,7 +526,7 @@ class GCSchedulingState
|
|||
* growth factor is a measure of how large (as a percentage of the last GC)
|
||||
* the heap is allowed to grow before we try to schedule another GC.
|
||||
*/
|
||||
UnprotectedData<bool> inHighFrequencyGCMode_;
|
||||
ActiveThreadData<bool> inHighFrequencyGCMode_;
|
||||
|
||||
public:
|
||||
GCSchedulingState()
|
||||
|
@ -545,8 +545,8 @@ class GCSchedulingState
|
|||
|
||||
template<typename F>
|
||||
struct Callback {
|
||||
UnprotectedData<F> op;
|
||||
UnprotectedData<void*> data;
|
||||
ActiveThreadData<F> op;
|
||||
ActiveThreadData<void*> data;
|
||||
|
||||
Callback()
|
||||
: op(nullptr), data(nullptr)
|
||||
|
@ -557,7 +557,7 @@ struct Callback {
|
|||
};
|
||||
|
||||
template<typename F>
|
||||
using CallbackVector = UnprotectedData<Vector<Callback<F>, 4, SystemAllocPolicy>>;
|
||||
using CallbackVector = ActiveThreadData<Vector<Callback<F>, 4, SystemAllocPolicy>>;
|
||||
|
||||
template <typename T, typename Iter0, typename Iter1>
|
||||
class ChainedIter
|
||||
|
@ -979,7 +979,7 @@ class GCRuntime
|
|||
UnprotectedData<JS::Zone*> systemZone;
|
||||
|
||||
// List of all zone groups (protected by the GC lock).
|
||||
UnprotectedData<ZoneGroupVector> groups;
|
||||
ActiveThreadData<ZoneGroupVector> groups;
|
||||
|
||||
// The unique atoms zone, which has no zone group.
|
||||
WriteOnceData<Zone*> atomsZone;
|
||||
|
@ -1023,9 +1023,9 @@ class GCRuntime
|
|||
// so as to reduce the cost of operations on the available lists.
|
||||
UnprotectedData<ChunkPool> fullChunks_;
|
||||
|
||||
UnprotectedData<RootedValueMap> rootsHash;
|
||||
ActiveThreadData<RootedValueMap> rootsHash;
|
||||
|
||||
UnprotectedData<size_t> maxMallocBytes;
|
||||
ActiveThreadData<size_t> maxMallocBytes;
|
||||
|
||||
// An incrementing id used to assign unique ids to cells that require one.
|
||||
mozilla::Atomic<uint64_t, mozilla::ReleaseAcquire> nextCellUniqueId_;
|
||||
|
@ -1034,18 +1034,18 @@ class GCRuntime
|
|||
* Number of the committed arenas in all GC chunks including empty chunks.
|
||||
*/
|
||||
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> numArenasFreeCommitted;
|
||||
UnprotectedData<VerifyPreTracer*> verifyPreData;
|
||||
ActiveThreadData<VerifyPreTracer*> verifyPreData;
|
||||
|
||||
private:
|
||||
UnprotectedData<bool> chunkAllocationSinceLastGC;
|
||||
UnprotectedData<int64_t> lastGCTime;
|
||||
ActiveThreadData<int64_t> lastGCTime;
|
||||
|
||||
UnprotectedData<JSGCMode> mode;
|
||||
ActiveThreadData<JSGCMode> mode;
|
||||
|
||||
mozilla::Atomic<size_t, mozilla::ReleaseAcquire> numActiveZoneIters;
|
||||
|
||||
/* During shutdown, the GC needs to clean up every possible object. */
|
||||
UnprotectedData<bool> cleanUpEverything;
|
||||
ActiveThreadData<bool> cleanUpEverything;
|
||||
|
||||
// Gray marking must be done after all black marking is complete. However,
|
||||
// we do not have write barriers on XPConnect roots. Therefore, XPConnect
|
||||
|
@ -1058,7 +1058,7 @@ class GCRuntime
|
|||
Okay,
|
||||
Failed
|
||||
};
|
||||
UnprotectedData<GrayBufferState> grayBufferState;
|
||||
ActiveThreadData<GrayBufferState> grayBufferState;
|
||||
bool hasBufferedGrayRoots() const { return grayBufferState == GrayBufferState::Okay; }
|
||||
|
||||
// Clear each zone's gray buffers, but do not change the current state.
|
||||
|
@ -1079,83 +1079,83 @@ class GCRuntime
|
|||
mozilla::Atomic<JS::gcreason::Reason, mozilla::Relaxed> majorGCTriggerReason;
|
||||
|
||||
public:
|
||||
UnprotectedData<JS::gcreason::Reason> minorGCTriggerReason;
|
||||
ActiveThreadData<JS::gcreason::Reason> minorGCTriggerReason;
|
||||
|
||||
private:
|
||||
/* Perform full GC if rt->keepAtoms() becomes false. */
|
||||
UnprotectedData<bool> fullGCForAtomsRequested_;
|
||||
ActiveThreadData<bool> fullGCForAtomsRequested_;
|
||||
|
||||
/* Incremented at the start of every minor GC. */
|
||||
UnprotectedData<uint64_t> minorGCNumber;
|
||||
ActiveThreadData<uint64_t> minorGCNumber;
|
||||
|
||||
/* Incremented at the start of every major GC. */
|
||||
UnprotectedData<uint64_t> majorGCNumber;
|
||||
ActiveThreadData<uint64_t> majorGCNumber;
|
||||
|
||||
/* The major GC number at which to release observed type information. */
|
||||
UnprotectedData<uint64_t> jitReleaseNumber;
|
||||
ActiveThreadData<uint64_t> jitReleaseNumber;
|
||||
|
||||
/* Incremented on every GC slice. */
|
||||
UnprotectedData<uint64_t> number;
|
||||
ActiveThreadData<uint64_t> number;
|
||||
|
||||
/* The number at the time of the most recent GC's first slice. */
|
||||
UnprotectedData<uint64_t> startNumber;
|
||||
ActiveThreadData<uint64_t> startNumber;
|
||||
|
||||
/* Whether the currently running GC can finish in multiple slices. */
|
||||
UnprotectedData<bool> isIncremental;
|
||||
ActiveThreadData<bool> isIncremental;
|
||||
|
||||
/* Whether all zones are being collected in first GC slice. */
|
||||
UnprotectedData<bool> isFull;
|
||||
ActiveThreadData<bool> isFull;
|
||||
|
||||
/* Whether the heap will be compacted at the end of GC. */
|
||||
UnprotectedData<bool> isCompacting;
|
||||
ActiveThreadData<bool> isCompacting;
|
||||
|
||||
/* The invocation kind of the current GC, taken from the first slice. */
|
||||
UnprotectedData<JSGCInvocationKind> invocationKind;
|
||||
ActiveThreadData<JSGCInvocationKind> invocationKind;
|
||||
|
||||
/* The initial GC reason, taken from the first slice. */
|
||||
UnprotectedData<JS::gcreason::Reason> initialReason;
|
||||
ActiveThreadData<JS::gcreason::Reason> initialReason;
|
||||
|
||||
/*
|
||||
* The current incremental GC phase. This is also used internally in
|
||||
* non-incremental GC.
|
||||
*/
|
||||
UnprotectedData<State> incrementalState;
|
||||
ActiveThreadOrGCTaskData<State> incrementalState;
|
||||
|
||||
/* Indicates that the last incremental slice exhausted the mark stack. */
|
||||
UnprotectedData<bool> lastMarkSlice;
|
||||
ActiveThreadData<bool> lastMarkSlice;
|
||||
|
||||
/* Whether any sweeping will take place in the separate GC helper thread. */
|
||||
UnprotectedData<bool> sweepOnBackgroundThread;
|
||||
ActiveThreadData<bool> sweepOnBackgroundThread;
|
||||
|
||||
/* Whether observed type information is being released in the current GC. */
|
||||
UnprotectedData<bool> releaseObservedTypes;
|
||||
ActiveThreadData<bool> releaseObservedTypes;
|
||||
|
||||
/* Whether any black->gray edges were found during marking. */
|
||||
UnprotectedData<BlackGrayEdgeVector> foundBlackGrayEdges;
|
||||
ActiveThreadData<BlackGrayEdgeVector> foundBlackGrayEdges;
|
||||
|
||||
/* Singly linked list of zones to be swept in the background. */
|
||||
UnprotectedData<ZoneList> backgroundSweepZones;
|
||||
ActiveThreadOrGCTaskData<ZoneList> backgroundSweepZones;
|
||||
|
||||
/*
|
||||
* Free LIFO blocks are transferred to this allocator before being freed on
|
||||
* the background GC thread after sweeping.
|
||||
*/
|
||||
UnprotectedData<LifoAlloc> blocksToFreeAfterSweeping;
|
||||
ActiveThreadOrGCTaskData<LifoAlloc> blocksToFreeAfterSweeping;
|
||||
|
||||
private:
|
||||
/* Index of current zone group (for stats). */
|
||||
UnprotectedData<unsigned> zoneGroupIndex;
|
||||
ActiveThreadData<unsigned> zoneGroupIndex;
|
||||
|
||||
/*
|
||||
* Incremental sweep state.
|
||||
*/
|
||||
UnprotectedData<JS::Zone*> zoneGroups;
|
||||
UnprotectedData<JS::Zone*> currentZoneGroup;
|
||||
UnprotectedData<bool> sweepingTypes;
|
||||
UnprotectedData<unsigned> finalizePhase;
|
||||
UnprotectedData<JS::Zone*> sweepZone;
|
||||
UnprotectedData<AllocKind> sweepKind;
|
||||
UnprotectedData<bool> abortSweepAfterCurrentGroup;
|
||||
ActiveThreadData<JS::Zone*> zoneGroups;
|
||||
ActiveThreadOrGCTaskData<JS::Zone*> currentZoneGroup;
|
||||
ActiveThreadData<bool> sweepingTypes;
|
||||
ActiveThreadData<unsigned> finalizePhase;
|
||||
ActiveThreadData<JS::Zone*> sweepZone;
|
||||
ActiveThreadData<AllocKind> sweepKind;
|
||||
ActiveThreadData<bool> abortSweepAfterCurrentGroup;
|
||||
|
||||
/*
|
||||
* Concurrent sweep infrastructure.
|
||||
|
@ -1166,17 +1166,17 @@ class GCRuntime
|
|||
/*
|
||||
* List head of arenas allocated during the sweep phase.
|
||||
*/
|
||||
UnprotectedData<Arena*> arenasAllocatedDuringSweep;
|
||||
ActiveThreadData<Arena*> arenasAllocatedDuringSweep;
|
||||
|
||||
/*
|
||||
* Incremental compacting state.
|
||||
*/
|
||||
UnprotectedData<bool> startedCompacting;
|
||||
UnprotectedData<ZoneList> zonesToMaybeCompact;
|
||||
UnprotectedData<Arena*> relocatedArenasToRelease;
|
||||
ActiveThreadData<bool> startedCompacting;
|
||||
ActiveThreadData<ZoneList> zonesToMaybeCompact;
|
||||
ActiveThreadData<Arena*> relocatedArenasToRelease;
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
UnprotectedData<MarkingValidator*> markingValidator;
|
||||
ActiveThreadData<MarkingValidator*> markingValidator;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -1184,23 +1184,23 @@ class GCRuntime
|
|||
* frame, rather than at the beginning. In this case, the next slice will be
|
||||
* delayed so that we don't get back-to-back slices.
|
||||
*/
|
||||
UnprotectedData<bool> interFrameGC;
|
||||
ActiveThreadData<bool> interFrameGC;
|
||||
|
||||
/* Default budget for incremental GC slice. See js/SliceBudget.h. */
|
||||
UnprotectedData<int64_t> defaultTimeBudget_;
|
||||
ActiveThreadData<int64_t> defaultTimeBudget_;
|
||||
|
||||
/*
|
||||
* We disable incremental GC if we encounter a Class with a trace hook
|
||||
* that does not implement write barriers.
|
||||
*/
|
||||
UnprotectedData<bool> incrementalAllowed;
|
||||
ActiveThreadData<bool> incrementalAllowed;
|
||||
|
||||
/*
|
||||
* Whether compacting GC can is enabled globally.
|
||||
*/
|
||||
UnprotectedData<bool> compactingEnabled;
|
||||
ActiveThreadData<bool> compactingEnabled;
|
||||
|
||||
UnprotectedData<bool> poked;
|
||||
ActiveThreadData<bool> poked;
|
||||
|
||||
/*
|
||||
* These options control the zealousness of the GC. At every allocation,
|
||||
|
@ -1227,16 +1227,16 @@ class GCRuntime
|
|||
* zeal_ value 14 performs periodic shrinking collections.
|
||||
*/
|
||||
#ifdef JS_GC_ZEAL
|
||||
UnprotectedData<uint32_t> zealModeBits;
|
||||
UnprotectedData<int> zealFrequency;
|
||||
UnprotectedData<int> nextScheduled;
|
||||
UnprotectedData<bool> deterministicOnly;
|
||||
UnprotectedData<int> incrementalLimit;
|
||||
ActiveThreadData<uint32_t> zealModeBits;
|
||||
ActiveThreadData<int> zealFrequency;
|
||||
ActiveThreadData<int> nextScheduled;
|
||||
ActiveThreadData<bool> deterministicOnly;
|
||||
ActiveThreadData<int> incrementalLimit;
|
||||
|
||||
UnprotectedData<Vector<JSObject*, 0, SystemAllocPolicy>> selectedForMarking;
|
||||
ActiveThreadData<Vector<JSObject*, 0, SystemAllocPolicy>> selectedForMarking;
|
||||
#endif
|
||||
|
||||
UnprotectedData<bool> fullCompartmentChecks;
|
||||
ActiveThreadData<bool> fullCompartmentChecks;
|
||||
|
||||
Callback<JSGCCallback> gcCallback;
|
||||
Callback<JS::DoCycleCollectionCallback> gcDoCycleCollectionCallback;
|
||||
|
@ -1267,10 +1267,10 @@ class GCRuntime
|
|||
Callback<JSTraceDataOp> grayRootTracer;
|
||||
|
||||
/* Always preserve JIT code during GCs, for testing. */
|
||||
UnprotectedData<bool> alwaysPreserveCode;
|
||||
ActiveThreadData<bool> alwaysPreserveCode;
|
||||
|
||||
#ifdef DEBUG
|
||||
UnprotectedData<bool> arenasEmptyAtShutdown;
|
||||
ActiveThreadData<bool> arenasEmptyAtShutdown;
|
||||
#endif
|
||||
|
||||
/* Synchronize GC heap access among GC helper threads and main threads. */
|
||||
|
@ -1286,7 +1286,7 @@ class GCRuntime
|
|||
* During incremental sweeping, this field temporarily holds the arenas of
|
||||
* the current AllocKind being swept in order of increasing free space.
|
||||
*/
|
||||
UnprotectedData<SortedArenaList> incrementalSweepList;
|
||||
ActiveThreadData<SortedArenaList> incrementalSweepList;
|
||||
|
||||
friend class js::GCHelperState;
|
||||
friend class MarkingValidator;
|
||||
|
|
|
@ -57,13 +57,13 @@ class MarkStack
|
|||
{
|
||||
friend class GCMarker;
|
||||
|
||||
UnprotectedData<uintptr_t*> stack_;
|
||||
UnprotectedData<uintptr_t*> tos_;
|
||||
UnprotectedData<uintptr_t*> end_;
|
||||
ActiveThreadData<uintptr_t*> stack_;
|
||||
ActiveThreadData<uintptr_t*> tos_;
|
||||
ActiveThreadData<uintptr_t*> end_;
|
||||
|
||||
// The capacity we start with and reset() to.
|
||||
UnprotectedData<size_t> baseCapacity_;
|
||||
UnprotectedData<size_t> maxCapacity_;
|
||||
ActiveThreadData<size_t> baseCapacity_;
|
||||
ActiveThreadData<size_t> maxCapacity_;
|
||||
|
||||
public:
|
||||
explicit MarkStack(size_t maxCapacity)
|
||||
|
@ -336,29 +336,29 @@ class GCMarker : public JSTracer
|
|||
MarkStack stack;
|
||||
|
||||
/* The color is only applied to objects and functions. */
|
||||
UnprotectedData<uint32_t> color;
|
||||
ActiveThreadData<uint32_t> color;
|
||||
|
||||
/* Pointer to the top of the stack of arenas we are delaying marking on. */
|
||||
UnprotectedData<js::gc::Arena*> unmarkedArenaStackTop;
|
||||
ActiveThreadData<js::gc::Arena*> unmarkedArenaStackTop;
|
||||
|
||||
/*
|
||||
* If the weakKeys table OOMs, disable the linear algorithm and fall back
|
||||
* to iterating until the next GC.
|
||||
*/
|
||||
UnprotectedData<bool> linearWeakMarkingDisabled_;
|
||||
ActiveThreadData<bool> linearWeakMarkingDisabled_;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Count of arenas that are currently in the stack. */
|
||||
UnprotectedData<size_t> markLaterArenas;
|
||||
ActiveThreadData<size_t> markLaterArenas;
|
||||
|
||||
/* Assert that start and stop are called with correct ordering. */
|
||||
UnprotectedData<bool> started;
|
||||
ActiveThreadData<bool> started;
|
||||
|
||||
/*
|
||||
* If this is true, all marked objects must belong to a compartment being
|
||||
* GCed. This is used to look for compartment bugs.
|
||||
*/
|
||||
UnprotectedData<bool> strictCompartmentChecking;
|
||||
ActiveThreadData<bool> strictCompartmentChecking;
|
||||
#endif // DEBUG
|
||||
};
|
||||
|
||||
|
|
|
@ -341,7 +341,7 @@ struct Zone : public JS::shadow::Zone,
|
|||
|
||||
private:
|
||||
// The set of compartments in this zone.
|
||||
js::UnprotectedData<CompartmentVector> compartments_;
|
||||
js::ActiveThreadOrGCTaskData<CompartmentVector> compartments_;
|
||||
public:
|
||||
CompartmentVector& compartments() { return compartments_.ref(); }
|
||||
|
||||
|
@ -410,7 +410,7 @@ struct Zone : public JS::shadow::Zone,
|
|||
mozilla::Atomic<ptrdiff_t, mozilla::ReleaseAcquire> gcMallocBytes;
|
||||
|
||||
// GC trigger threshold for allocations on the C heap.
|
||||
js::UnprotectedData<size_t> gcMaxMallocBytes;
|
||||
js::ActiveThreadData<size_t> gcMaxMallocBytes;
|
||||
|
||||
// Whether a GC has been triggered as a result of gcMallocBytes falling
|
||||
// below zero.
|
||||
|
@ -582,7 +582,7 @@ struct Zone : public JS::shadow::Zone,
|
|||
js::ZoneGroupData<js::jit::JitZone*> jitZone_;
|
||||
|
||||
js::UnprotectedData<GCState> gcState_;
|
||||
js::UnprotectedData<bool> gcScheduled_;
|
||||
js::ActiveThreadData<bool> gcScheduled_;
|
||||
js::ZoneGroupData<bool> gcPreserveCode_;
|
||||
js::ZoneGroupData<bool> jitUsingBarriers_;
|
||||
js::ZoneGroupData<bool> keepShapeTables_;
|
||||
|
|
|
@ -17,7 +17,7 @@ ZoneGroup::ZoneGroup(JSRuntime* runtime)
|
|||
context(TlsContext.get()),
|
||||
enterCount(this, 1),
|
||||
zones_(),
|
||||
nursery_(this),
|
||||
nursery_(this, this),
|
||||
storeBuffer_(this, runtime, nursery()),
|
||||
blocksToFreeAfterMinorGC((size_t) JSContext::TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
|
||||
caches_(this),
|
||||
|
|
|
@ -54,7 +54,7 @@ class ZoneGroup
|
|||
|
||||
// All zones in the group.
|
||||
private:
|
||||
UnprotectedData<ZoneVector> zones_;
|
||||
ActiveThreadOrGCTaskData<ZoneVector> zones_;
|
||||
public:
|
||||
ZoneVector& zones() { return zones_.ref(); }
|
||||
|
||||
|
@ -64,7 +64,7 @@ class ZoneGroup
|
|||
bool init(size_t maxNurseryBytes);
|
||||
|
||||
private:
|
||||
UnprotectedData<Nursery> nursery_;
|
||||
ZoneGroupData<Nursery> nursery_;
|
||||
ZoneGroupData<gc::StoreBuffer> storeBuffer_;
|
||||
public:
|
||||
Nursery& nursery() { return nursery_.ref(); }
|
||||
|
@ -72,7 +72,7 @@ class ZoneGroup
|
|||
|
||||
// Free LIFO blocks are transferred to this allocator before being freed
|
||||
// after minor GC.
|
||||
UnprotectedData<LifoAlloc> blocksToFreeAfterMinorGC;
|
||||
ActiveThreadData<LifoAlloc> blocksToFreeAfterMinorGC;
|
||||
|
||||
void minorGC(JS::gcreason::Reason reason,
|
||||
gcstats::Phase phase = gcstats::PHASE_MINOR_GC) JS_HAZ_GC_CALL;
|
||||
|
|
|
@ -87,10 +87,10 @@ class JitRuntime
|
|||
|
||||
// Executable allocator for all code except wasm code and Ion code with
|
||||
// patchable backedges (see below).
|
||||
UnprotectedData<ExecutableAllocator> execAlloc_;
|
||||
ActiveThreadData<ExecutableAllocator> execAlloc_;
|
||||
|
||||
// Executable allocator for Ion scripts with patchable backedges.
|
||||
UnprotectedData<ExecutableAllocator> backedgeExecAlloc_;
|
||||
ActiveThreadData<ExecutableAllocator> backedgeExecAlloc_;
|
||||
|
||||
// Shared exception-handler tail.
|
||||
ExclusiveAccessLockWriteOnceData<JitCode*> exceptionTail_;
|
||||
|
@ -152,7 +152,7 @@ class JitRuntime
|
|||
mozilla::Atomic<bool> preventBackedgePatching_;
|
||||
|
||||
// Global table of jitcode native address => bytecode address mappings.
|
||||
UnprotectedData<JitcodeGlobalTable*> jitcodeGlobalTable_;
|
||||
ActiveThreadData<JitcodeGlobalTable*> jitcodeGlobalTable_;
|
||||
|
||||
private:
|
||||
JitCode* generateLazyLinkStub(JSContext* cx);
|
||||
|
|
|
@ -651,7 +651,7 @@ class ArenaLists
|
|||
const BackgroundFinalizeState& backgroundFinalizeState(AllocKind i) const { return backgroundFinalizeState_.ref()[i]; }
|
||||
|
||||
/* For each arena kind, a list of arenas remaining to be swept. */
|
||||
UnprotectedData<AllAllocKindArray<Arena*>> arenaListsToSweep_;
|
||||
ActiveThreadOrGCTaskData<AllAllocKindArray<Arena*>> arenaListsToSweep_;
|
||||
Arena*& arenaListsToSweep(AllocKind i) { return arenaListsToSweep_.ref()[i]; }
|
||||
Arena* arenaListsToSweep(AllocKind i) const { return arenaListsToSweep_.ref()[i]; }
|
||||
|
||||
|
@ -877,7 +877,7 @@ class GCHelperState
|
|||
js::ConditionVariable done;
|
||||
|
||||
// Activity for the helper to do, protected by the GC lock.
|
||||
UnprotectedData<State> state_;
|
||||
ActiveThreadOrGCTaskData<State> state_;
|
||||
|
||||
// Whether work is being performed on some thread.
|
||||
GCLockData<bool> hasThread;
|
||||
|
@ -949,7 +949,7 @@ class GCParallelTask
|
|||
UnprotectedData<TaskState> state;
|
||||
|
||||
// Amount of time this task took to execute.
|
||||
UnprotectedData<mozilla::TimeDuration> duration_;
|
||||
ActiveThreadOrGCTaskData<mozilla::TimeDuration> duration_;
|
||||
|
||||
explicit GCParallelTask(const GCParallelTask&) = delete;
|
||||
|
||||
|
|
|
@ -34,6 +34,27 @@ OnBackgroundThread()
|
|||
return false;
|
||||
}
|
||||
|
||||
template <AllowedBackgroundThread Background>
|
||||
void
|
||||
CheckActiveThread<Background>::check() const
|
||||
{
|
||||
// When interrupting a thread on Windows, changes are made to the runtime
|
||||
// and active thread's state from another thread while the active thread is
|
||||
// suspended. We need a way to mark these accesses as being tantamount to
|
||||
// accesses by the active thread. See bug 1323066.
|
||||
#ifndef XP_WIN
|
||||
if (OnBackgroundThread<Background>())
|
||||
return;
|
||||
|
||||
JSContext* cx = TlsContext.get();
|
||||
MOZ_ASSERT(cx == cx->runtime()->activeContext);
|
||||
#endif // XP_WIN
|
||||
}
|
||||
|
||||
template class CheckActiveThread<AllowedBackgroundThread::None>;
|
||||
template class CheckActiveThread<AllowedBackgroundThread::GCTask>;
|
||||
template class CheckActiveThread<AllowedBackgroundThread::IonCompile>;
|
||||
|
||||
template <AllowedBackgroundThread Background>
|
||||
void
|
||||
CheckZoneGroup<Background>::check() const
|
||||
|
|
|
@ -201,6 +201,28 @@ enum class AllowedBackgroundThread
|
|||
GCTaskOrIonCompile
|
||||
};
|
||||
|
||||
template <AllowedBackgroundThread Background>
|
||||
class CheckActiveThread
|
||||
{
|
||||
public:
|
||||
void check() const;
|
||||
};
|
||||
|
||||
// Data which may only be accessed by the runtime's cooperatively scheduled
|
||||
// active thread.
|
||||
template <typename T>
|
||||
using ActiveThreadData =
|
||||
ProtectedDataNoCheckArgs<CheckActiveThread<AllowedBackgroundThread::None>, T>;
|
||||
|
||||
// Data which may only be accessed by the runtime's cooperatively scheduled
|
||||
// active thread, or by various helper thread tasks.
|
||||
template <typename T>
|
||||
using ActiveThreadOrGCTaskData =
|
||||
ProtectedDataNoCheckArgs<CheckActiveThread<AllowedBackgroundThread::GCTask>, T>;
|
||||
template <typename T>
|
||||
using ActiveThreadOrIonCompileData =
|
||||
ProtectedDataNoCheckArgs<CheckActiveThread<AllowedBackgroundThread::IonCompile>, T>;
|
||||
|
||||
template <AllowedBackgroundThread Background>
|
||||
class CheckZoneGroup
|
||||
{
|
||||
|
@ -223,19 +245,13 @@ using ZoneGroupData =
|
|||
ProtectedDataZoneGroupArg<CheckZoneGroup<AllowedBackgroundThread::None>, T>;
|
||||
|
||||
// Data which may only be accessed by threads with exclusive access to the
|
||||
// associated zone group, or by GC helper thread tasks.
|
||||
// associated zone group, or by various helper thread tasks.
|
||||
template <typename T>
|
||||
using ZoneGroupOrGCTaskData =
|
||||
ProtectedDataZoneGroupArg<CheckZoneGroup<AllowedBackgroundThread::GCTask>, T>;
|
||||
|
||||
// Data which may only be accessed by threads with exclusive access to the
|
||||
// associated zone group, or by Ion compilation helper thread tasks.
|
||||
template <typename T>
|
||||
using ZoneGroupOrIonCompileData =
|
||||
ProtectedDataZoneGroupArg<CheckZoneGroup<AllowedBackgroundThread::IonCompile>, T>;
|
||||
|
||||
// Data which may only be accessed by threads with exclusive access to the
|
||||
// associated zone group, or by either GC helper or Ion compilation tasks.
|
||||
template <typename T>
|
||||
using ZoneGroupOrGCTaskOrIonCompileData =
|
||||
ProtectedDataZoneGroupArg<CheckZoneGroup<AllowedBackgroundThread::GCTaskOrIonCompile>, T>;
|
||||
|
|
|
@ -1183,10 +1183,10 @@ void
|
|||
js::GCParallelTask::runFromHelperThread(AutoLockHelperThreadState& locked)
|
||||
{
|
||||
JSContext cx(runtime(), JS::ContextOptions());
|
||||
gc::AutoSetThreadIsPerformingGC performingGC;
|
||||
|
||||
{
|
||||
AutoUnlockHelperThreadState parallelSection(locked);
|
||||
gc::AutoSetThreadIsPerformingGC performingGC;
|
||||
mozilla::TimeStamp timeStart = mozilla::TimeStamp::Now();
|
||||
cx.heapState = JS::HeapState::MajorCollecting;
|
||||
run();
|
||||
|
|
|
@ -95,6 +95,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
|
|||
#ifdef DEBUG
|
||||
updateChildRuntimeCount(parentRuntime),
|
||||
#endif
|
||||
activeContext(nullptr),
|
||||
profilerSampleBufferGen_(0),
|
||||
profilerSampleBufferLapCount_(1),
|
||||
telemetryCallback(nullptr),
|
||||
|
@ -191,6 +192,8 @@ JSRuntime::init(JSContext* cx, uint32_t maxbytes, uint32_t maxNurseryBytes)
|
|||
if (CanUseExtraThreads() && !EnsureHelperThreadsInitialized())
|
||||
return false;
|
||||
|
||||
activeContext = cx;
|
||||
|
||||
singletonContext = cx;
|
||||
|
||||
defaultFreeOp_ = js_new<js::FreeOp>(this);
|
||||
|
|
|
@ -297,6 +297,11 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
AutoUpdateChildRuntimeCount updateChildRuntimeCount;
|
||||
#endif
|
||||
|
||||
// The context for the thread which currently has exclusive access to most
|
||||
// contents of the runtime. When execution on the runtime is cooperatively
|
||||
// scheduled, this is the thread which is currently running.
|
||||
mozilla::Atomic<JSContext*, mozilla::ReleaseAcquire> activeContext;
|
||||
|
||||
/*
|
||||
* The profiler sampler generation after the latest sample.
|
||||
*
|
||||
|
@ -354,7 +359,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
}
|
||||
|
||||
/* Call this to accumulate telemetry data. */
|
||||
js::UnprotectedData<JSAccumulateTelemetryDataCallback> telemetryCallback;
|
||||
js::ActiveThreadData<JSAccumulateTelemetryDataCallback> telemetryCallback;
|
||||
public:
|
||||
// Accumulates data for Firefox telemetry. |id| is the ID of a JS_TELEMETRY_*
|
||||
// histogram. |key| provides an additional key to identify the histogram.
|
||||
|
@ -364,14 +369,14 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
void setTelemetryCallback(JSRuntime* rt, JSAccumulateTelemetryDataCallback callback);
|
||||
|
||||
public:
|
||||
js::UnprotectedData<JSGetIncumbentGlobalCallback> getIncumbentGlobalCallback;
|
||||
js::UnprotectedData<JSEnqueuePromiseJobCallback> enqueuePromiseJobCallback;
|
||||
js::UnprotectedData<void*> enqueuePromiseJobCallbackData;
|
||||
js::ActiveThreadData<JSGetIncumbentGlobalCallback> getIncumbentGlobalCallback;
|
||||
js::ActiveThreadData<JSEnqueuePromiseJobCallback> enqueuePromiseJobCallback;
|
||||
js::ActiveThreadData<void*> enqueuePromiseJobCallbackData;
|
||||
|
||||
js::UnprotectedData<JSPromiseRejectionTrackerCallback> promiseRejectionTrackerCallback;
|
||||
js::UnprotectedData<void*> promiseRejectionTrackerCallbackData;
|
||||
js::ActiveThreadData<JSPromiseRejectionTrackerCallback> promiseRejectionTrackerCallback;
|
||||
js::ActiveThreadData<void*> promiseRejectionTrackerCallbackData;
|
||||
|
||||
js::UnprotectedData<JS::StartAsyncTaskCallback> startAsyncTaskCallback;
|
||||
js::ActiveThreadData<JS::StartAsyncTaskCallback> startAsyncTaskCallback;
|
||||
js::UnprotectedData<JS::FinishAsyncTaskCallback> finishAsyncTaskCallback;
|
||||
js::ExclusiveData<js::PromiseTaskPtrVector> promiseTasksToDestroy;
|
||||
|
||||
|
@ -388,35 +393,35 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
* Allow relazifying functions in compartments that are active. This is
|
||||
* only used by the relazifyFunctions() testing function.
|
||||
*/
|
||||
js::UnprotectedData<bool> allowRelazificationForTesting;
|
||||
js::ActiveThreadData<bool> allowRelazificationForTesting;
|
||||
|
||||
/* Compartment destroy callback. */
|
||||
js::UnprotectedData<JSDestroyCompartmentCallback> destroyCompartmentCallback;
|
||||
js::ActiveThreadData<JSDestroyCompartmentCallback> destroyCompartmentCallback;
|
||||
|
||||
/* Compartment memory reporting callback. */
|
||||
js::UnprotectedData<JSSizeOfIncludingThisCompartmentCallback> sizeOfIncludingThisCompartmentCallback;
|
||||
js::ActiveThreadData<JSSizeOfIncludingThisCompartmentCallback> sizeOfIncludingThisCompartmentCallback;
|
||||
|
||||
/* Zone destroy callback. */
|
||||
js::UnprotectedData<JSZoneCallback> destroyZoneCallback;
|
||||
js::ActiveThreadData<JSZoneCallback> destroyZoneCallback;
|
||||
|
||||
/* Zone sweep callback. */
|
||||
js::UnprotectedData<JSZoneCallback> sweepZoneCallback;
|
||||
js::ActiveThreadData<JSZoneCallback> sweepZoneCallback;
|
||||
|
||||
/* Call this to get the name of a compartment. */
|
||||
js::UnprotectedData<JSCompartmentNameCallback> compartmentNameCallback;
|
||||
js::ActiveThreadData<JSCompartmentNameCallback> compartmentNameCallback;
|
||||
|
||||
/* Callback for doing memory reporting on external strings. */
|
||||
js::UnprotectedData<JSExternalStringSizeofCallback> externalStringSizeofCallback;
|
||||
js::ActiveThreadData<JSExternalStringSizeofCallback> externalStringSizeofCallback;
|
||||
|
||||
js::UnprotectedData<mozilla::UniquePtr<js::SourceHook>> sourceHook;
|
||||
js::ActiveThreadData<mozilla::UniquePtr<js::SourceHook>> sourceHook;
|
||||
|
||||
js::UnprotectedData<const JSSecurityCallbacks*> securityCallbacks;
|
||||
js::UnprotectedData<const js::DOMCallbacks*> DOMcallbacks;
|
||||
js::UnprotectedData<JSDestroyPrincipalsOp> destroyPrincipals;
|
||||
js::UnprotectedData<JSReadPrincipalsOp> readPrincipals;
|
||||
js::ActiveThreadData<const JSSecurityCallbacks*> securityCallbacks;
|
||||
js::ActiveThreadData<const js::DOMCallbacks*> DOMcallbacks;
|
||||
js::ActiveThreadData<JSDestroyPrincipalsOp> destroyPrincipals;
|
||||
js::ActiveThreadData<JSReadPrincipalsOp> readPrincipals;
|
||||
|
||||
/* Optional warning reporter. */
|
||||
js::UnprotectedData<JS::WarningReporter> warningReporter;
|
||||
js::ActiveThreadData<JS::WarningReporter> warningReporter;
|
||||
|
||||
private:
|
||||
/* Gecko profiling metadata */
|
||||
|
@ -425,7 +430,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
js::GeckoProfiler& geckoProfiler() { return geckoProfiler_.ref(); }
|
||||
|
||||
// Heap GC roots for PersistentRooted pointers.
|
||||
js::UnprotectedData<mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
|
||||
js::ActiveThreadData<mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
|
||||
mozilla::LinkedList<JS::PersistentRooted<void*>>>> heapRoots;
|
||||
|
||||
void tracePersistentRoots(JSTracer* trc);
|
||||
|
@ -445,15 +450,15 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
void setTrustedPrincipals(const JSPrincipals* p) { trustedPrincipals_ = p; }
|
||||
const JSPrincipals* trustedPrincipals() const { return trustedPrincipals_; }
|
||||
|
||||
js::UnprotectedData<const JSWrapObjectCallbacks*> wrapObjectCallbacks;
|
||||
js::UnprotectedData<js::PreserveWrapperCallback> preserveWrapperCallback;
|
||||
js::ActiveThreadData<const JSWrapObjectCallbacks*> wrapObjectCallbacks;
|
||||
js::ActiveThreadData<js::PreserveWrapperCallback> preserveWrapperCallback;
|
||||
|
||||
js::UnprotectedData<js::ScriptEnvironmentPreparer*> scriptEnvironmentPreparer;
|
||||
js::ActiveThreadData<js::ScriptEnvironmentPreparer*> scriptEnvironmentPreparer;
|
||||
|
||||
js::UnprotectedData<js::CTypesActivityCallback> ctypesActivityCallback;
|
||||
js::ActiveThreadData<js::CTypesActivityCallback> ctypesActivityCallback;
|
||||
|
||||
private:
|
||||
js::UnprotectedData<const js::Class*> windowProxyClass_;
|
||||
js::WriteOnceData<const js::Class*> windowProxyClass_;
|
||||
|
||||
public:
|
||||
const js::Class* maybeWindowProxyClass() const {
|
||||
|
@ -468,7 +473,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
* Head of circular list of all enabled Debuggers that have
|
||||
* onNewGlobalObject handler methods established.
|
||||
*/
|
||||
js::UnprotectedData<JSCList> onNewGlobalObjectWatchers_;
|
||||
js::ActiveThreadData<JSCList> onNewGlobalObjectWatchers_;
|
||||
public:
|
||||
JSCList& onNewGlobalObjectWatchers() { return onNewGlobalObjectWatchers_.ref(); }
|
||||
|
||||
|
@ -508,16 +513,16 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
// How many compartments there are across all zones. This number includes
|
||||
// off main thread context compartments, so it isn't necessarily equal to the
|
||||
// number of compartments visited by CompartmentsIter.
|
||||
js::UnprotectedData<size_t> numCompartments;
|
||||
js::ActiveThreadData<size_t> numCompartments;
|
||||
|
||||
/* Locale-specific callbacks for string conversion. */
|
||||
js::UnprotectedData<const JSLocaleCallbacks*> localeCallbacks;
|
||||
js::ActiveThreadData<const JSLocaleCallbacks*> localeCallbacks;
|
||||
|
||||
/* Default locale for Internationalization API */
|
||||
js::UnprotectedData<char*> defaultLocale;
|
||||
js::ActiveThreadData<char*> defaultLocale;
|
||||
|
||||
/* Default JSVersion. */
|
||||
js::UnprotectedData<JSVersion> defaultVersion_;
|
||||
js::ActiveThreadData<JSVersion> defaultVersion_;
|
||||
|
||||
private:
|
||||
/* Code coverage output. */
|
||||
|
@ -526,7 +531,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
js::coverage::LCovRuntime& lcovOutput() { return lcovOutput_.ref(); }
|
||||
|
||||
private:
|
||||
js::UnprotectedData<js::jit::JitRuntime*> jitRuntime_;
|
||||
js::ActiveThreadOrIonCompileData<js::jit::JitRuntime*> jitRuntime_;
|
||||
|
||||
/*
|
||||
* Self-hosting state cloned on demand into other compartments. Shared with the parent
|
||||
|
@ -780,7 +785,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
js::WriteOnceData<js::WellKnownSymbols*> wellKnownSymbols;
|
||||
|
||||
/* Shared Intl data for this runtime. */
|
||||
js::UnprotectedData<js::SharedIntlData> sharedIntlData;
|
||||
js::ActiveThreadData<js::SharedIntlData> sharedIntlData;
|
||||
|
||||
void traceSharedIntlData(JSTracer* trc);
|
||||
|
||||
|
@ -851,7 +856,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
mozilla::Atomic<bool> offthreadIonCompilationEnabled_;
|
||||
mozilla::Atomic<bool> parallelParsingEnabled_;
|
||||
|
||||
js::UnprotectedData<bool> autoWritableJitCodeActive_;
|
||||
js::ActiveThreadData<bool> autoWritableJitCodeActive_;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -876,12 +881,12 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
}
|
||||
|
||||
/* See comment for JS::SetLargeAllocationFailureCallback in jsapi.h. */
|
||||
js::UnprotectedData<JS::LargeAllocationFailureCallback> largeAllocationFailureCallback;
|
||||
js::UnprotectedData<void*> largeAllocationFailureCallbackData;
|
||||
js::ActiveThreadData<JS::LargeAllocationFailureCallback> largeAllocationFailureCallback;
|
||||
js::ActiveThreadData<void*> largeAllocationFailureCallbackData;
|
||||
|
||||
/* See comment for JS::SetOutOfMemoryCallback in jsapi.h. */
|
||||
js::UnprotectedData<JS::OutOfMemoryCallback> oomCallback;
|
||||
js::UnprotectedData<void*> oomCallbackData;
|
||||
js::ActiveThreadData<JS::OutOfMemoryCallback> oomCallback;
|
||||
js::ActiveThreadData<void*> oomCallbackData;
|
||||
|
||||
/*
|
||||
* These variations of malloc/calloc/realloc will call the
|
||||
|
@ -919,13 +924,13 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
|||
* Debugger.Memory functions like takeCensus use this embedding-provided
|
||||
* function to assess the size of malloc'd blocks of memory.
|
||||
*/
|
||||
js::UnprotectedData<mozilla::MallocSizeOf> debuggerMallocSizeOf;
|
||||
js::ActiveThreadData<mozilla::MallocSizeOf> debuggerMallocSizeOf;
|
||||
|
||||
/* Last time at which an animation was played for this runtime. */
|
||||
mozilla::Atomic<int64_t> lastAnimationTime;
|
||||
|
||||
private:
|
||||
js::UnprotectedData<js::PerformanceMonitoring> performanceMonitoring_;
|
||||
js::ActiveThreadData<js::PerformanceMonitoring> performanceMonitoring_;
|
||||
public:
|
||||
js::PerformanceMonitoring& performanceMonitoring() { return performanceMonitoring_.ref(); }
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче