зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1526375 - Replace DispatchTaceKindTyped for cell pointers with another version of MapGCThingTyped and use this where possible r=sfink
This commit is contained in:
Родитель
1aa258e905
Коммит
510569c075
|
@ -226,20 +226,33 @@ auto DispatchTraceKindTyped(F f, JS::TraceKind traceKind, Args&&... args) {
|
|||
}
|
||||
#undef JS_DEPENDENT_TEMPLATE_HINT
|
||||
|
||||
template <typename F, typename... Args>
|
||||
auto DispatchTraceKindTyped(F f, void* thing, JS::TraceKind traceKind,
|
||||
Args&&... args) {
|
||||
// Given a GC thing specified by pointer and trace kind, calls the functor |f|
|
||||
// with a template argument of the actual type of the pointer and returns the
|
||||
// result.
|
||||
template <typename F>
|
||||
auto MapGCThingTyped(void* thing, JS::TraceKind traceKind, F&& f) {
|
||||
switch (traceKind) {
|
||||
#define JS_EXPAND_DEF(name, type, _) \
|
||||
case JS::TraceKind::name: \
|
||||
return f(static_cast<type*>(thing), std::forward<Args>(args)...);
|
||||
return f(static_cast<type*>(thing));
|
||||
JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF);
|
||||
#undef JS_EXPAND_DEF
|
||||
default:
|
||||
MOZ_CRASH("Invalid trace kind in DispatchTraceKindTyped.");
|
||||
MOZ_CRASH("Invalid trace kind in MapGCThingTyped.");
|
||||
}
|
||||
}
|
||||
|
||||
// Given a GC thing specified by pointer and trace kind, calls the functor |f|
|
||||
// with a template argument of the actual type of the pointer and ignores the
|
||||
// result.
|
||||
template <typename F>
|
||||
void ApplyGCThingTyped(void* thing, JS::TraceKind traceKind, F&& f) {
|
||||
// This function doesn't do anything but is supplied for symmetry with other
|
||||
// MapGCThingTyped/ApplyGCThingTyped implementations that have to wrap the
|
||||
// functor to return a dummy value that is ignored.
|
||||
MapGCThingTyped(thing, traceKind, std::move(f));
|
||||
}
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif // js_TraceKind_h
|
||||
|
|
|
@ -3674,21 +3674,16 @@ void GCRuntime::freeFromBackgroundThread(AutoLockHelperThreadState& lock) {
|
|||
|
||||
void GCRuntime::waitBackgroundFreeEnd() { freeTask.join(); }
|
||||
|
||||
struct IsAboutToBeFinalizedFunctor {
|
||||
template <typename T>
|
||||
bool operator()(Cell** t) {
|
||||
mozilla::DebugOnly<const Cell*> prior = *t;
|
||||
bool result = IsAboutToBeFinalizedUnbarriered(reinterpret_cast<T**>(t));
|
||||
/* static */ bool UniqueIdGCPolicy::needsSweep(Cell** cellp, uint64_t*) {
|
||||
Cell* cell = *cellp;
|
||||
return MapGCThingTyped(cell, cell->getTraceKind(), [](auto t) {
|
||||
mozilla::DebugOnly<const Cell*> prior = t;
|
||||
bool result = IsAboutToBeFinalizedUnbarriered(&t);
|
||||
// Sweep should not have to deal with moved pointers, since moving GC
|
||||
// handles updating the UID table manually.
|
||||
MOZ_ASSERT(*t == prior);
|
||||
MOZ_ASSERT(t == prior);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/* static */ bool UniqueIdGCPolicy::needsSweep(Cell** cell, uint64_t*) {
|
||||
return DispatchTraceKindTyped(IsAboutToBeFinalizedFunctor(),
|
||||
(*cell)->getTraceKind(), cell);
|
||||
});
|
||||
}
|
||||
|
||||
void JS::Zone::sweepUniqueIds() { uniqueIds().sweep(); }
|
||||
|
@ -4037,13 +4032,6 @@ static bool InCrossCompartmentMap(JSObject* src, JS::GCCellPtr dst) {
|
|||
return false;
|
||||
}
|
||||
|
||||
struct MaybeCompartmentFunctor {
|
||||
template <typename T>
|
||||
JS::Compartment* operator()(T* t) {
|
||||
return t->maybeCompartment();
|
||||
}
|
||||
};
|
||||
|
||||
void CompartmentCheckTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
Compartment* comp = MapGCThingTyped(thing, [](auto t) {
|
||||
return t->maybeCompartment();
|
||||
|
@ -4074,8 +4062,9 @@ void GCRuntime::checkForCompartmentMismatches() {
|
|||
i.next()) {
|
||||
trc.src = i.getCell();
|
||||
trc.srcKind = MapAllocToTraceKind(thingKind);
|
||||
trc.compartment = DispatchTraceKindTyped(MaybeCompartmentFunctor(),
|
||||
trc.src, trc.srcKind);
|
||||
trc.compartment = MapGCThingTyped(trc.src, trc.srcKind, [](auto t) {
|
||||
return t->maybeCompartment();
|
||||
});
|
||||
js::TraceChildren(&trc, trc.src, trc.srcKind);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "gc/Marking-inl.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/IntegerRange.h"
|
||||
#include "mozilla/ReentrancyGuard.h"
|
||||
|
@ -512,40 +513,40 @@ template void js::TraceProcessGlobalRoot<JSAtom>(JSTracer*, JSAtom*,
|
|||
template void js::TraceProcessGlobalRoot<JS::Symbol>(JSTracer*, JS::Symbol*,
|
||||
const char*);
|
||||
|
||||
// A typed functor adaptor for TraceRoot.
|
||||
struct TraceRootFunctor {
|
||||
template <typename T>
|
||||
void operator()(JSTracer* trc, Cell** thingp, const char* name) {
|
||||
TraceRoot(trc, reinterpret_cast<T**>(thingp), name);
|
||||
}
|
||||
};
|
||||
|
||||
void js::TraceGenericPointerRoot(JSTracer* trc, Cell** thingp,
|
||||
const char* name) {
|
||||
MOZ_ASSERT(thingp);
|
||||
if (!*thingp) {
|
||||
Cell* thing = *thingp;
|
||||
if (!thing) {
|
||||
return;
|
||||
}
|
||||
TraceRootFunctor f;
|
||||
DispatchTraceKindTyped(f, (*thingp)->getTraceKind(), trc, thingp, name);
|
||||
}
|
||||
|
||||
// A typed functor adaptor for TraceManuallyBarrieredEdge.
|
||||
struct TraceManuallyBarrieredEdgeFunctor {
|
||||
template <typename T>
|
||||
void operator()(JSTracer* trc, Cell** thingp, const char* name) {
|
||||
TraceManuallyBarrieredEdge(trc, reinterpret_cast<T**>(thingp), name);
|
||||
auto traced = MapGCThingTyped(thing, thing->getTraceKind(),
|
||||
[trc, name](auto t) -> Cell* {
|
||||
TraceRoot(trc, &t, name);
|
||||
return t;
|
||||
});
|
||||
if (traced != thing) {
|
||||
*thingp = traced;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void js::TraceManuallyBarrieredGenericPointerEdge(JSTracer* trc, Cell** thingp,
|
||||
const char* name) {
|
||||
MOZ_ASSERT(thingp);
|
||||
Cell* thing = *thingp;
|
||||
if (!*thingp) {
|
||||
return;
|
||||
}
|
||||
TraceManuallyBarrieredEdgeFunctor f;
|
||||
DispatchTraceKindTyped(f, (*thingp)->getTraceKind(), trc, thingp, name);
|
||||
|
||||
auto traced = MapGCThingTyped(thing, thing->getTraceKind(),
|
||||
[trc, name](auto t) -> Cell* {
|
||||
TraceManuallyBarrieredEdge(trc, &t, name);
|
||||
return t;
|
||||
});
|
||||
if (traced != thing) {
|
||||
*thingp = traced;
|
||||
}
|
||||
}
|
||||
|
||||
// This method is responsible for dynamic dispatch to the real tracer
|
||||
|
|
|
@ -88,22 +88,14 @@ JS_PUBLIC_API void JS::TraceChildren(JSTracer* trc, GCCellPtr thing) {
|
|||
js::TraceChildren(trc, thing.asCell(), thing.kind());
|
||||
}
|
||||
|
||||
struct TraceChildrenFunctor {
|
||||
template <typename T>
|
||||
void operator()(JSTracer* trc, void* thingArg) {
|
||||
T* thing = static_cast<T*>(thingArg);
|
||||
MOZ_ASSERT_IF(thing->runtimeFromAnyThread() != trc->runtime(),
|
||||
ThingIsPermanentAtomOrWellKnownSymbol(thing) ||
|
||||
thing->zoneFromAnyThread()->isSelfHostingZone());
|
||||
|
||||
thing->traceChildren(trc);
|
||||
}
|
||||
};
|
||||
|
||||
void js::TraceChildren(JSTracer* trc, void* thing, JS::TraceKind kind) {
|
||||
MOZ_ASSERT(thing);
|
||||
TraceChildrenFunctor f;
|
||||
DispatchTraceKindTyped(f, kind, trc, thing);
|
||||
ApplyGCThingTyped(thing, kind, [trc](auto t) {
|
||||
MOZ_ASSERT_IF(t->runtimeFromAnyThread() != trc->runtime(),
|
||||
ThingIsPermanentAtomOrWellKnownSymbol(t) ||
|
||||
t->zoneFromAnyThread()->isSelfHostingZone());
|
||||
t->traceChildren(trc);
|
||||
});
|
||||
}
|
||||
|
||||
JS_PUBLIC_API void JS::TraceIncomingCCWs(
|
||||
|
|
Загрузка…
Ссылка в новой задаче