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

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

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