зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1751959 - Part 2: Remove the auxillary mark stack and use a single stack for both black and gray marking r=sfink
Differential Revision: https://phabricator.services.mozilla.com/D136915
This commit is contained in:
Родитель
bdcdcd67bf
Коммит
fbad14b1c7
|
@ -23,7 +23,6 @@ class WeakMapBase;
|
|||
|
||||
static const size_t NON_INCREMENTAL_MARK_STACK_BASE_CAPACITY = 4096;
|
||||
static const size_t INCREMENTAL_MARK_STACK_BASE_CAPACITY = 32768;
|
||||
static const size_t SMALL_MARK_STACK_BASE_CAPACITY = 256;
|
||||
|
||||
enum class SlotsOrElementsKind { Elements, FixedSlots, DynamicSlots };
|
||||
|
||||
|
@ -144,11 +143,8 @@ class MarkStack {
|
|||
|
||||
size_t position() const { return topIndex_; }
|
||||
|
||||
enum StackType { MainStack, AuxiliaryStack };
|
||||
[[nodiscard]] bool init(StackType which, bool incrementalGCEnabled);
|
||||
|
||||
[[nodiscard]] bool setStackCapacity(StackType which,
|
||||
bool incrementalGCEnabled);
|
||||
[[nodiscard]] bool init(bool incrementalGCEnabled);
|
||||
[[nodiscard]] bool setStackCapacity(bool incrementalGCEnabled);
|
||||
|
||||
size_t maxCapacity() const { return maxCapacity_; }
|
||||
void setMaxCapacity(size_t maxCapacity);
|
||||
|
@ -315,13 +311,8 @@ class GCMarker final : public JSTracer {
|
|||
* objects that are still reachable.
|
||||
*/
|
||||
void setMarkColor(gc::MarkColor newColor);
|
||||
void setMarkColorUnchecked(gc::MarkColor newColor);
|
||||
gc::MarkColor markColor() const { return color; }
|
||||
|
||||
// Declare which color the main mark stack will be used for. The whole stack
|
||||
// must be empty when this is called.
|
||||
void setMainStackColor(gc::MarkColor newColor);
|
||||
|
||||
bool enterWeakMarkingMode();
|
||||
void leaveWeakMarkingMode();
|
||||
|
||||
|
@ -364,7 +355,7 @@ class GCMarker final : public JSTracer {
|
|||
|
||||
void setIncrementalGCEnabled(bool enabled) {
|
||||
// Ignore failure to resize the stack and keep using the existing stack.
|
||||
(void)stack.setStackCapacity(gc::MarkStack::MainStack, enabled);
|
||||
(void)stack.setStackCapacity(enabled);
|
||||
}
|
||||
|
||||
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
|
||||
|
@ -440,27 +431,11 @@ class GCMarker final : public JSTracer {
|
|||
inline void pushValueRange(JSObject* obj, SlotsOrElementsKind kind,
|
||||
size_t start, size_t end);
|
||||
|
||||
gc::MarkStack& getStack(gc::MarkColor which) {
|
||||
return which == mainStackColor ? stack : auxStack;
|
||||
}
|
||||
const gc::MarkStack& getStack(gc::MarkColor which) const {
|
||||
return which == mainStackColor ? stack : auxStack;
|
||||
}
|
||||
bool isMarkStackEmpty() { return stack.isEmpty(); }
|
||||
|
||||
gc::MarkStack& currentStack() {
|
||||
MOZ_ASSERT(currentStackPtr);
|
||||
return *currentStackPtr;
|
||||
}
|
||||
bool hasBlackEntries() const { return stack.position() > grayPosition; }
|
||||
|
||||
bool isMarkStackEmpty() { return stack.isEmpty() && auxStack.isEmpty(); }
|
||||
|
||||
bool hasBlackEntries() const {
|
||||
return !getStack(gc::MarkColor::Black).isEmpty();
|
||||
}
|
||||
|
||||
bool hasGrayEntries() const {
|
||||
return !getStack(gc::MarkColor::Gray).isEmpty();
|
||||
}
|
||||
bool hasGrayEntries() const { return grayPosition > 0 && !stack.isEmpty(); }
|
||||
|
||||
inline void processMarkStackTop(SliceBudget& budget);
|
||||
|
||||
|
@ -491,25 +466,18 @@ class GCMarker final : public JSTracer {
|
|||
friend class gc::BarrierTracer;
|
||||
|
||||
/*
|
||||
* The mark stack. Pointers in this stack are "gray" in the GC sense, but may
|
||||
* mark the contained items either black or gray (in the CC sense) depending
|
||||
* on mainStackColor.
|
||||
* The mark stack. Pointers in this stack are "gray" in the GC sense, but
|
||||
* their references may be marked either black or gray (in the CC sense)
|
||||
* depending on whether they are above or below grayPosition.
|
||||
*/
|
||||
gc::MarkStack stack;
|
||||
|
||||
/*
|
||||
* A smaller, auxiliary stack, currently only used to accumulate the rare
|
||||
* objects that need to be marked black during gray marking.
|
||||
*/
|
||||
gc::MarkStack auxStack;
|
||||
/* Stack entries at positions below this are considered gray. */
|
||||
MainThreadOrGCTaskData<size_t> grayPosition;
|
||||
|
||||
/* The color is only applied to objects and functions. */
|
||||
MainThreadOrGCTaskData<gc::MarkColor> color;
|
||||
|
||||
MainThreadOrGCTaskData<gc::MarkColor> mainStackColor;
|
||||
|
||||
MainThreadOrGCTaskData<gc::MarkStack*> currentStackPtr;
|
||||
|
||||
/* Pointer to the top of the stack of arenas we are delaying marking on. */
|
||||
MainThreadOrGCTaskData<js::gc::Arena*> delayedMarkingList;
|
||||
|
||||
|
|
|
@ -1387,7 +1387,6 @@ inline void js::GCMarker::eagerlyMarkChildren(JSRope* rope) {
|
|||
// users of the stack. This also assumes that a rope can only point to
|
||||
// other ropes or linear strings, it cannot refer to GC things of other
|
||||
// types.
|
||||
gc::MarkStack& stack = currentStack();
|
||||
size_t savedPos = stack.position();
|
||||
MOZ_DIAGNOSTIC_ASSERT(rope->getTraceKind() == JS::TraceKind::String);
|
||||
while (true) {
|
||||
|
@ -1922,8 +1921,6 @@ inline void GCMarker::processMarkStackTop(SliceBudget& budget) {
|
|||
size_t index; // Index of the next slot to mark.
|
||||
size_t end; // End of slot range to mark.
|
||||
|
||||
gc::MarkStack& stack = currentStack();
|
||||
|
||||
switch (stack.peekTag()) {
|
||||
case MarkStack::SlotsOrElementsRangeTag: {
|
||||
auto range = stack.popSlotsOrElementsRange();
|
||||
|
@ -2196,17 +2193,14 @@ MarkStack::~MarkStack() {
|
|||
MOZ_ASSERT(iteratorCount_ == 0);
|
||||
}
|
||||
|
||||
bool MarkStack::init(StackType which, bool incrementalGCEnabled) {
|
||||
bool MarkStack::init(bool incrementalGCEnabled) {
|
||||
MOZ_ASSERT(isEmpty());
|
||||
return setStackCapacity(which, incrementalGCEnabled);
|
||||
return setStackCapacity(incrementalGCEnabled);
|
||||
}
|
||||
|
||||
bool MarkStack::setStackCapacity(StackType which, bool incrementalGCEnabled) {
|
||||
bool MarkStack::setStackCapacity(bool incrementalGCEnabled) {
|
||||
size_t capacity;
|
||||
|
||||
if (which == AuxiliaryStack) {
|
||||
capacity = SMALL_MARK_STACK_BASE_CAPACITY;
|
||||
} else if (incrementalGCEnabled) {
|
||||
if (incrementalGCEnabled) {
|
||||
capacity = INCREMENTAL_MARK_STACK_BASE_CAPACITY;
|
||||
} else {
|
||||
capacity = NON_INCREMENTAL_MARK_STACK_BASE_CAPACITY;
|
||||
|
@ -2394,8 +2388,8 @@ GCMarker::GCMarker(JSRuntime* rt)
|
|||
JS::TraceOptions(JS::WeakMapTraceAction::Expand,
|
||||
JS::WeakEdgeTraceAction::Skip)),
|
||||
stack(),
|
||||
auxStack(),
|
||||
mainStackColor(MarkColor::Black),
|
||||
grayPosition(0),
|
||||
color(MarkColor::Black),
|
||||
delayedMarkingList(nullptr),
|
||||
delayedMarkingWorkAdded(false),
|
||||
state(MarkingState::NotActive),
|
||||
|
@ -2410,13 +2404,11 @@ GCMarker::GCMarker(JSRuntime* rt)
|
|||
queuePos(0)
|
||||
#endif
|
||||
{
|
||||
setMarkColorUnchecked(MarkColor::Black);
|
||||
}
|
||||
|
||||
bool GCMarker::init() {
|
||||
bool incrementalGCEnabled = runtime()->gc.isIncrementalGCEnabled();
|
||||
return stack.init(gc::MarkStack::MainStack, incrementalGCEnabled) &&
|
||||
auxStack.init(gc::MarkStack::AuxiliaryStack, incrementalGCEnabled);
|
||||
return stack.init(incrementalGCEnabled);
|
||||
}
|
||||
|
||||
bool GCMarker::isDrained() {
|
||||
|
@ -2461,8 +2453,6 @@ void GCMarker::stop() {
|
|||
|
||||
barrierBuffer().clearAndFree();
|
||||
stack.clear();
|
||||
auxStack.clear();
|
||||
setMainStackColor(MarkColor::Black);
|
||||
ClearEphemeronEdges(runtime());
|
||||
}
|
||||
|
||||
|
@ -2482,8 +2472,6 @@ void GCMarker::reset() {
|
|||
|
||||
barrierBuffer().clearAndFree();
|
||||
stack.clear();
|
||||
auxStack.clear();
|
||||
setMainStackColor(MarkColor::Black);
|
||||
ClearEphemeronEdges(runtime());
|
||||
MOZ_ASSERT(isMarkStackEmpty());
|
||||
|
||||
|
@ -2502,31 +2490,25 @@ void GCMarker::reset() {
|
|||
}
|
||||
|
||||
void GCMarker::setMarkColor(gc::MarkColor newColor) {
|
||||
if (color != newColor) {
|
||||
MOZ_ASSERT(runtime()->gc.state() == State::Sweep);
|
||||
setMarkColorUnchecked(newColor);
|
||||
if (color == newColor) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void GCMarker::setMarkColorUnchecked(gc::MarkColor newColor) {
|
||||
MOZ_ASSERT(runtime()->gc.state() == State::Sweep);
|
||||
MOZ_ASSERT(!hasBlackEntries());
|
||||
|
||||
color = newColor;
|
||||
currentStackPtr = &getStack(color);
|
||||
}
|
||||
|
||||
void GCMarker::setMainStackColor(gc::MarkColor newColor) {
|
||||
MOZ_ASSERT(isMarkStackEmpty());
|
||||
if (newColor != mainStackColor) {
|
||||
mainStackColor = newColor;
|
||||
|
||||
// Update currentStackPtr without changing the mark color.
|
||||
setMarkColorUnchecked(color);
|
||||
if (color == MarkColor::Black) {
|
||||
grayPosition = stack.position();
|
||||
} else {
|
||||
grayPosition = SIZE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void GCMarker::pushTaggedPtr(T* ptr) {
|
||||
checkZone(ptr);
|
||||
if (!currentStack().push(ptr)) {
|
||||
if (!stack.push(ptr)) {
|
||||
delayMarkingChildrenOnOOM(ptr);
|
||||
}
|
||||
}
|
||||
|
@ -2541,7 +2523,7 @@ void GCMarker::pushValueRange(JSObject* obj, SlotsOrElementsKind kind,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!currentStack().push(obj, kind, start)) {
|
||||
if (!stack.push(obj, kind, start)) {
|
||||
delayMarkingChildrenOnOOM(obj);
|
||||
}
|
||||
}
|
||||
|
@ -2779,7 +2761,6 @@ void GCMarker::checkZone(void* p) {
|
|||
|
||||
size_t GCMarker::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
|
||||
size_t size = stack.sizeOfExcludingThis(mallocSizeOf);
|
||||
size += auxStack.sizeOfExcludingThis(mallocSizeOf);
|
||||
size += barrierBuffer_.ref().sizeOfExcludingThis(mallocSizeOf);
|
||||
return size;
|
||||
}
|
||||
|
|
|
@ -1062,7 +1062,6 @@ IncrementalProgress GCRuntime::beginMarkingSweepGroup(JSFreeOp* fop,
|
|||
}
|
||||
|
||||
AutoSetMarkColor setColorGray(marker, MarkColor::Gray);
|
||||
marker.setMainStackColor(MarkColor::Gray);
|
||||
|
||||
// Mark incoming gray pointers from previously swept compartments.
|
||||
markIncomingGrayCrossCompartmentPointers();
|
||||
|
@ -1087,7 +1086,6 @@ IncrementalProgress GCRuntime::markGray(JSFreeOp* fop, SliceBudget& budget) {
|
|||
return NotFinished;
|
||||
}
|
||||
|
||||
marker.setMainStackColor(MarkColor::Black);
|
||||
return Finished;
|
||||
}
|
||||
|
||||
|
@ -1106,7 +1104,6 @@ IncrementalProgress GCRuntime::endMarkingSweepGroup(JSFreeOp* fop,
|
|||
}
|
||||
|
||||
AutoSetMarkColor setColorGray(marker, MarkColor::Gray);
|
||||
marker.setMainStackColor(MarkColor::Gray);
|
||||
|
||||
// Mark transitively inside the current compartment group.
|
||||
if (markWeakReferencesInCurrentGroup(budget) == NotFinished) {
|
||||
|
@ -1114,7 +1111,6 @@ IncrementalProgress GCRuntime::endMarkingSweepGroup(JSFreeOp* fop,
|
|||
}
|
||||
|
||||
MOZ_ASSERT(marker.isDrained());
|
||||
marker.setMainStackColor(MarkColor::Black);
|
||||
|
||||
// We must not yield after this point before we start sweeping the group.
|
||||
safeToYield = false;
|
||||
|
|
|
@ -618,11 +618,9 @@ void js::gc::MarkingValidator::nonIncrementalMark(AutoGCSession& session) {
|
|||
}
|
||||
|
||||
AutoSetMarkColor setColorGray(*gcmarker, MarkColor::Gray);
|
||||
gcmarker->setMainStackColor(MarkColor::Gray);
|
||||
|
||||
gc->markAllGrayReferences(gcstats::PhaseKind::SWEEP_MARK_GRAY);
|
||||
gc->markAllWeakReferences();
|
||||
gc->marker.setMainStackColor(MarkColor::Black);
|
||||
|
||||
/* Restore zone state. */
|
||||
for (GCZonesIter zone(gc); !zone.done(); zone.next()) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче