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:
Brian Hackett 2017-02-06 12:40:11 -07:00
Родитель 077e1ba24c
Коммит 0051d4ae6b
12 изменённых файлов: 188 добавлений и 143 удалений

Просмотреть файл

@ -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(); }