Bug 1373214 - Change Zone::isGCMarking() to avoid a TLS lookup r=sfink

This commit is contained in:
Jon Coppeard 2017-06-16 10:25:41 +01:00
Родитель 092c893028
Коммит a76430d89e
3 изменённых файлов: 26 добавлений и 28 удалений

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

@ -168,6 +168,7 @@ struct Zone
bool isGCSweeping() const { return gcState_ == Sweep; }
bool isGCFinished() const { return gcState_ == Finished; }
bool isGCCompacting() const { return gcState_ == Compact; }
bool isGCMarking() const { return gcState_ == Mark || gcState_ == MarkGray; }
bool isGCSweepingOrCompacting() const { return gcState_ == Sweep || gcState_ == Compact; }
static MOZ_ALWAYS_INLINE JS::shadow::Zone* asShadowZone(JS::Zone* zone) {

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

@ -340,26 +340,26 @@ ShouldTraceCrossCompartment(JSTracer* trc, JSObject* src, const Value& val)
}
static void
AssertZoneIsMarking(Cell* thing)
AssertShouldMarkInZone(Cell* thing)
{
MOZ_ASSERT(TenuredCell::fromPointer(thing)->zone()->isGCMarking());
MOZ_ASSERT(thing->asTenured().zone()->shouldMarkInZone());
}
static void
AssertZoneIsMarking(JSString* str)
AssertShouldMarkInZone(JSString* str)
{
#ifdef DEBUG
Zone* zone = TenuredCell::fromPointer(str)->zone();
MOZ_ASSERT(zone->isGCMarking() || zone->isAtomsZone());
Zone* zone = str->asTenured().zone();
MOZ_ASSERT(zone->shouldMarkInZone() || zone->isAtomsZone());
#endif
}
static void
AssertZoneIsMarking(JS::Symbol* sym)
AssertShouldMarkInZone(JS::Symbol* sym)
{
#ifdef DEBUG
Zone* zone = TenuredCell::fromPointer(sym)->zone();
MOZ_ASSERT(zone->isGCMarking() || zone->isAtomsZone());
Zone* zone = sym->asTenured().zone();
MOZ_ASSERT(zone->shouldMarkInZone() || zone->isAtomsZone());
#endif
}
@ -771,35 +771,35 @@ GCMarker::markImplicitEdges(T* thing)
template <typename T>
static inline bool
MustSkipMarking(GCMarker* gcmarker, T thing)
ShouldMark(GCMarker* gcmarker, T thing)
{
// Don't trace things that are owned by another runtime.
if (IsOwnedByOtherRuntime(gcmarker->runtime(), thing))
return true;
return false;
// Don't mark things outside a zone if we are in a per-zone GC.
return !thing->zone()->isGCMarking();
return thing->zone()->shouldMarkInZone();
}
template <>
bool
MustSkipMarking<JSObject*>(GCMarker* gcmarker, JSObject* obj)
ShouldMark<JSObject*>(GCMarker* gcmarker, JSObject* obj)
{
// Don't trace things that are owned by another runtime.
if (IsOwnedByOtherRuntime(gcmarker->runtime(), obj))
return true;
return false;
// We may mark a Nursery thing outside the context of the
// MinorCollectionTracer because of a pre-barrier. The pre-barrier is not
// needed in this case because we perform a minor collection before each
// incremental slice.
if (IsInsideNursery(obj))
return true;
return false;
// Don't mark things outside a zone if we are in a per-zone GC. It is
// faster to check our own arena, which we can do since we know that
// the object is tenured.
return !TenuredCell::fromPointer(obj)->zone()->isGCMarking();
return obj->asTenured().zone()->shouldMarkInZone();
}
template <typename T>
@ -807,7 +807,7 @@ void
DoMarking(GCMarker* gcmarker, T* thing)
{
// Do per-type marking precondition checks.
if (MustSkipMarking(gcmarker, thing))
if (!ShouldMark(gcmarker, thing))
return;
CheckTracedThing(gcmarker, thing);
@ -834,7 +834,7 @@ void
NoteWeakEdge(GCMarker* gcmarker, T** thingp)
{
// Do per-type marking precondition checks.
if (MustSkipMarking(gcmarker, *thingp))
if (!ShouldMark(gcmarker, *thingp))
return;
CheckTracedThing(gcmarker, *thingp);
@ -990,7 +990,7 @@ template <typename T>
bool
js::GCMarker::mark(T* thing)
{
AssertZoneIsMarking(thing);
AssertShouldMarkInZone(thing);
MOZ_ASSERT(!IsInsideNursery(gc::TenuredCell::fromPointer(thing)));
return gc::ParticipatesInCC<T>::value
? gc::TenuredCell::fromPointer(thing)->markIfUnmarked(markColor())
@ -1125,7 +1125,7 @@ JSString::traceBase(JSTracer* trc)
inline void
js::GCMarker::eagerlyMarkChildren(JSLinearString* linearStr)
{
AssertZoneIsMarking(linearStr);
AssertShouldMarkInZone(linearStr);
MOZ_ASSERT(linearStr->isMarked());
MOZ_ASSERT(linearStr->JSString::isLinear());
@ -1135,7 +1135,7 @@ js::GCMarker::eagerlyMarkChildren(JSLinearString* linearStr)
MOZ_ASSERT(linearStr->JSString::isLinear());
if (linearStr->isPermanentAtom())
break;
AssertZoneIsMarking(linearStr);
AssertShouldMarkInZone(linearStr);
if (!mark(static_cast<JSString*>(linearStr)))
break;
}
@ -1188,7 +1188,7 @@ js::GCMarker::eagerlyMarkChildren(JSRope* rope)
JS_DIAGNOSTICS_ASSERT(rope->getTraceKind() == JS::TraceKind::String);
JS_DIAGNOSTICS_ASSERT(rope->JSString::isRope());
AssertZoneIsMarking(rope);
AssertShouldMarkInZone(rope);
MOZ_ASSERT(rope->isMarked());
JSRope* next = nullptr;
@ -1674,7 +1674,7 @@ GCMarker::processMarkStackTop(SliceBudget& budget)
case MarkStack::ObjectTag: {
obj = stack.popPtr().as<JSObject>();
AssertZoneIsMarking(obj);
AssertShouldMarkInZone(obj);
goto scan_obj;
}
@ -1738,7 +1738,7 @@ GCMarker::processMarkStackTop(SliceBudget& budget)
scan_obj:
{
AssertZoneIsMarking(obj);
AssertShouldMarkInZone(obj);
budget.step();
if (budget.isOverBudget()) {

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

@ -242,11 +242,8 @@ struct Zone : public JS::shadow::Zone,
return CurrentThreadIsHeapMajorCollecting() && !rt->gc.isHeapCompacting() && gcState_ != NoGC;
}
bool isGCMarking() {
if (CurrentThreadIsHeapCollecting())
return gcState_ == Mark || gcState_ == MarkGray;
else
return needsIncrementalBarrier();
bool shouldMarkInZone() const {
return needsIncrementalBarrier() || isGCMarking();
}
// Get a number that is incremented whenever this zone is collected, and