зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1551810 - Part 1: return bool in CallbackTracer methods. r=jonco
Differential Revision: https://phabricator.services.mozilla.com/D38980 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
339a4ceab8
Коммит
e17d60cbf4
|
@ -614,9 +614,10 @@ struct VerifyTraceProtoAndIfaceCacheCalledTracer : public JS::CallbackTracer {
|
|||
explicit VerifyTraceProtoAndIfaceCacheCalledTracer(JSContext* cx)
|
||||
: JS::CallbackTracer(cx), ok(false) {}
|
||||
|
||||
void onChild(const JS::GCCellPtr&) override {
|
||||
bool onChild(const JS::GCCellPtr&) override {
|
||||
// We don't do anything here, we only want to verify that
|
||||
// TraceProtoAndIfaceCache was called.
|
||||
return true;
|
||||
}
|
||||
|
||||
TracerKind getTracerKind() const override {
|
||||
|
|
|
@ -154,40 +154,48 @@ class JS_PUBLIC_API CallbackTracer : public JSTracer {
|
|||
// dispatches to the fully-generic onChild implementation, so for cases that
|
||||
// do not care about boxing overhead and do not need the actual edges,
|
||||
// just override the generic onChild.
|
||||
virtual void onObjectEdge(JSObject** objp) { onChild(JS::GCCellPtr(*objp)); }
|
||||
virtual void onStringEdge(JSString** strp) { onChild(JS::GCCellPtr(*strp)); }
|
||||
virtual void onSymbolEdge(JS::Symbol** symp) {
|
||||
onChild(JS::GCCellPtr(*symp));
|
||||
virtual bool onObjectEdge(JSObject** objp) {
|
||||
return onChild(JS::GCCellPtr(*objp));
|
||||
}
|
||||
virtual void onBigIntEdge(JS::BigInt** bip) { onChild(JS::GCCellPtr(*bip)); }
|
||||
virtual void onScriptEdge(JSScript** scriptp) {
|
||||
onChild(JS::GCCellPtr(*scriptp));
|
||||
virtual bool onStringEdge(JSString** strp) {
|
||||
return onChild(JS::GCCellPtr(*strp));
|
||||
}
|
||||
virtual void onShapeEdge(js::Shape** shapep) {
|
||||
onChild(JS::GCCellPtr(*shapep, JS::TraceKind::Shape));
|
||||
virtual bool onSymbolEdge(JS::Symbol** symp) {
|
||||
return onChild(JS::GCCellPtr(*symp));
|
||||
}
|
||||
virtual void onObjectGroupEdge(js::ObjectGroup** groupp) {
|
||||
onChild(JS::GCCellPtr(*groupp, JS::TraceKind::ObjectGroup));
|
||||
virtual bool onBigIntEdge(JS::BigInt** bip) {
|
||||
return onChild(JS::GCCellPtr(*bip));
|
||||
}
|
||||
virtual void onBaseShapeEdge(js::BaseShape** basep) {
|
||||
onChild(JS::GCCellPtr(*basep, JS::TraceKind::BaseShape));
|
||||
virtual bool onScriptEdge(JSScript** scriptp) {
|
||||
return onChild(JS::GCCellPtr(*scriptp));
|
||||
}
|
||||
virtual void onJitCodeEdge(js::jit::JitCode** codep) {
|
||||
onChild(JS::GCCellPtr(*codep, JS::TraceKind::JitCode));
|
||||
virtual bool onShapeEdge(js::Shape** shapep) {
|
||||
return onChild(JS::GCCellPtr(*shapep, JS::TraceKind::Shape));
|
||||
}
|
||||
virtual void onLazyScriptEdge(js::LazyScript** lazyp) {
|
||||
onChild(JS::GCCellPtr(*lazyp, JS::TraceKind::LazyScript));
|
||||
virtual bool onObjectGroupEdge(js::ObjectGroup** groupp) {
|
||||
return onChild(JS::GCCellPtr(*groupp, JS::TraceKind::ObjectGroup));
|
||||
}
|
||||
virtual void onScopeEdge(js::Scope** scopep) {
|
||||
onChild(JS::GCCellPtr(*scopep, JS::TraceKind::Scope));
|
||||
virtual bool onBaseShapeEdge(js::BaseShape** basep) {
|
||||
return onChild(JS::GCCellPtr(*basep, JS::TraceKind::BaseShape));
|
||||
}
|
||||
virtual void onRegExpSharedEdge(js::RegExpShared** sharedp) {
|
||||
onChild(JS::GCCellPtr(*sharedp, JS::TraceKind::RegExpShared));
|
||||
virtual bool onJitCodeEdge(js::jit::JitCode** codep) {
|
||||
return onChild(JS::GCCellPtr(*codep, JS::TraceKind::JitCode));
|
||||
}
|
||||
virtual bool onLazyScriptEdge(js::LazyScript** lazyp) {
|
||||
return onChild(JS::GCCellPtr(*lazyp, JS::TraceKind::LazyScript));
|
||||
}
|
||||
virtual bool onScopeEdge(js::Scope** scopep) {
|
||||
return onChild(JS::GCCellPtr(*scopep, JS::TraceKind::Scope));
|
||||
}
|
||||
virtual bool onRegExpSharedEdge(js::RegExpShared** sharedp) {
|
||||
return onChild(JS::GCCellPtr(*sharedp, JS::TraceKind::RegExpShared));
|
||||
}
|
||||
|
||||
// Override this method to receive notification when a node in the GC
|
||||
// heap graph is visited.
|
||||
virtual void onChild(const JS::GCCellPtr& thing) = 0;
|
||||
// This method should return whether the edge still exists, i.e. return false
|
||||
// if 'thing' is cleared by the CallbackTracer, return true otherwise.
|
||||
virtual bool onChild(const JS::GCCellPtr& thing) = 0;
|
||||
|
||||
// Access to the tracing context:
|
||||
// When tracing with a JS::CallbackTracer, we invoke the callback with the
|
||||
|
@ -254,19 +262,27 @@ class JS_PUBLIC_API CallbackTracer : public JSTracer {
|
|||
// methods have to have distinct names to allow us to override them
|
||||
// individually, which is freqently useful if, for example, we only want to
|
||||
// process only one type of edge.
|
||||
void dispatchToOnEdge(JSObject** objp) { onObjectEdge(objp); }
|
||||
void dispatchToOnEdge(JSString** strp) { onStringEdge(strp); }
|
||||
void dispatchToOnEdge(JS::Symbol** symp) { onSymbolEdge(symp); }
|
||||
void dispatchToOnEdge(JS::BigInt** bip) { onBigIntEdge(bip); }
|
||||
void dispatchToOnEdge(JSScript** scriptp) { onScriptEdge(scriptp); }
|
||||
void dispatchToOnEdge(js::Shape** shapep) { onShapeEdge(shapep); }
|
||||
void dispatchToOnEdge(js::ObjectGroup** groupp) { onObjectGroupEdge(groupp); }
|
||||
void dispatchToOnEdge(js::BaseShape** basep) { onBaseShapeEdge(basep); }
|
||||
void dispatchToOnEdge(js::jit::JitCode** codep) { onJitCodeEdge(codep); }
|
||||
void dispatchToOnEdge(js::LazyScript** lazyp) { onLazyScriptEdge(lazyp); }
|
||||
void dispatchToOnEdge(js::Scope** scopep) { onScopeEdge(scopep); }
|
||||
void dispatchToOnEdge(js::RegExpShared** sharedp) {
|
||||
onRegExpSharedEdge(sharedp);
|
||||
bool dispatchToOnEdge(JSObject** objp) { return onObjectEdge(objp); }
|
||||
bool dispatchToOnEdge(JSString** strp) { return onStringEdge(strp); }
|
||||
bool dispatchToOnEdge(JS::Symbol** symp) { return onSymbolEdge(symp); }
|
||||
bool dispatchToOnEdge(JS::BigInt** bip) { return onBigIntEdge(bip); }
|
||||
bool dispatchToOnEdge(JSScript** scriptp) { return onScriptEdge(scriptp); }
|
||||
bool dispatchToOnEdge(js::Shape** shapep) { return onShapeEdge(shapep); }
|
||||
bool dispatchToOnEdge(js::ObjectGroup** groupp) {
|
||||
return onObjectGroupEdge(groupp);
|
||||
}
|
||||
bool dispatchToOnEdge(js::BaseShape** basep) {
|
||||
return onBaseShapeEdge(basep);
|
||||
}
|
||||
bool dispatchToOnEdge(js::jit::JitCode** codep) {
|
||||
return onJitCodeEdge(codep);
|
||||
}
|
||||
bool dispatchToOnEdge(js::LazyScript** lazyp) {
|
||||
return onLazyScriptEdge(lazyp);
|
||||
}
|
||||
bool dispatchToOnEdge(js::Scope** scopep) { return onScopeEdge(scopep); }
|
||||
bool dispatchToOnEdge(js::RegExpShared** sharedp) {
|
||||
return onRegExpSharedEdge(sharedp);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -1466,10 +1466,11 @@ class HasChildTracer final : public JS::CallbackTracer {
|
|||
RootedValue child_;
|
||||
bool found_;
|
||||
|
||||
void onChild(const JS::GCCellPtr& thing) override {
|
||||
bool onChild(const JS::GCCellPtr& thing) override {
|
||||
if (thing.asCell() == child_.toGCThing()) {
|
||||
found_ = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -20,21 +20,21 @@ struct ClearEdgesTracer final : public JS::CallbackTracer {
|
|||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline void clearEdge(T** thingp);
|
||||
inline bool clearEdge(T** thingp);
|
||||
|
||||
void onObjectEdge(JSObject** objp) override;
|
||||
void onStringEdge(JSString** strp) override;
|
||||
void onSymbolEdge(JS::Symbol** symp) override;
|
||||
void onBigIntEdge(JS::BigInt** bip) override;
|
||||
void onScriptEdge(JSScript** scriptp) override;
|
||||
void onShapeEdge(js::Shape** shapep) override;
|
||||
void onObjectGroupEdge(js::ObjectGroup** groupp) override;
|
||||
void onBaseShapeEdge(js::BaseShape** basep) override;
|
||||
void onJitCodeEdge(js::jit::JitCode** codep) override;
|
||||
void onLazyScriptEdge(js::LazyScript** lazyp) override;
|
||||
void onScopeEdge(js::Scope** scopep) override;
|
||||
void onRegExpSharedEdge(js::RegExpShared** sharedp) override;
|
||||
void onChild(const JS::GCCellPtr& thing) override;
|
||||
bool onObjectEdge(JSObject** objp) override;
|
||||
bool onStringEdge(JSString** strp) override;
|
||||
bool onSymbolEdge(JS::Symbol** symp) override;
|
||||
bool onBigIntEdge(JS::BigInt** bip) override;
|
||||
bool onScriptEdge(JSScript** scriptp) override;
|
||||
bool onShapeEdge(js::Shape** shapep) override;
|
||||
bool onObjectGroupEdge(js::ObjectGroup** groupp) override;
|
||||
bool onBaseShapeEdge(js::BaseShape** basep) override;
|
||||
bool onJitCodeEdge(js::jit::JitCode** codep) override;
|
||||
bool onLazyScriptEdge(js::LazyScript** lazyp) override;
|
||||
bool onScopeEdge(js::Scope** scopep) override;
|
||||
bool onRegExpSharedEdge(js::RegExpShared** sharedp) override;
|
||||
bool onChild(const JS::GCCellPtr& thing) override;
|
||||
};
|
||||
|
||||
} // namespace gc
|
||||
|
|
|
@ -2611,24 +2611,34 @@ bool GCRuntime::relocateArenas(Zone* zone, JS::GCReason reason,
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
inline void MovingTracer::updateEdge(T** thingp) {
|
||||
inline bool MovingTracer::updateEdge(T** thingp) {
|
||||
auto thing = *thingp;
|
||||
if (thing->runtimeFromAnyThread() == runtime() && IsForwarded(thing)) {
|
||||
*thingp = Forwarded(thing);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MovingTracer::onObjectEdge(JSObject** objp) { updateEdge(objp); }
|
||||
void MovingTracer::onShapeEdge(Shape** shapep) { updateEdge(shapep); }
|
||||
void MovingTracer::onStringEdge(JSString** stringp) { updateEdge(stringp); }
|
||||
void MovingTracer::onScriptEdge(JSScript** scriptp) { updateEdge(scriptp); }
|
||||
void MovingTracer::onLazyScriptEdge(LazyScript** lazyp) { updateEdge(lazyp); }
|
||||
void MovingTracer::onBaseShapeEdge(BaseShape** basep) { updateEdge(basep); }
|
||||
void MovingTracer::onScopeEdge(Scope** scopep) { updateEdge(scopep); }
|
||||
void MovingTracer::onRegExpSharedEdge(RegExpShared** sharedp) {
|
||||
updateEdge(sharedp);
|
||||
bool MovingTracer::onObjectEdge(JSObject** objp) { return updateEdge(objp); }
|
||||
bool MovingTracer::onShapeEdge(Shape** shapep) { return updateEdge(shapep); }
|
||||
bool MovingTracer::onStringEdge(JSString** stringp) {
|
||||
return updateEdge(stringp);
|
||||
}
|
||||
void MovingTracer::onBigIntEdge(BigInt** bip) { updateEdge(bip); }
|
||||
bool MovingTracer::onScriptEdge(JSScript** scriptp) {
|
||||
return updateEdge(scriptp);
|
||||
}
|
||||
bool MovingTracer::onLazyScriptEdge(LazyScript** lazyp) {
|
||||
return updateEdge(lazyp);
|
||||
}
|
||||
bool MovingTracer::onBaseShapeEdge(BaseShape** basep) {
|
||||
return updateEdge(basep);
|
||||
}
|
||||
bool MovingTracer::onScopeEdge(Scope** scopep) { return updateEdge(scopep); }
|
||||
bool MovingTracer::onRegExpSharedEdge(RegExpShared** sharedp) {
|
||||
return updateEdge(sharedp);
|
||||
}
|
||||
bool MovingTracer::onBigIntEdge(BigInt** bip) { return updateEdge(bip); }
|
||||
|
||||
void Zone::prepareForCompacting() {
|
||||
FreeOp* fop = runtimeFromMainThread()->defaultFreeOp();
|
||||
|
@ -4237,7 +4247,7 @@ bool GCRuntime::shouldPreserveJITCode(Realm* realm,
|
|||
|
||||
#ifdef DEBUG
|
||||
class CompartmentCheckTracer final : public JS::CallbackTracer {
|
||||
void onChild(const JS::GCCellPtr& thing) override;
|
||||
bool onChild(const JS::GCCellPtr& thing) override;
|
||||
|
||||
public:
|
||||
explicit CompartmentCheckTracer(JSRuntime* rt)
|
||||
|
@ -4280,7 +4290,7 @@ static bool InCrossCompartmentMap(JSObject* src, JS::GCCellPtr dst) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void CompartmentCheckTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
bool CompartmentCheckTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
Compartment* comp =
|
||||
MapGCThingTyped(thing, [](auto t) { return t->maybeCompartment(); });
|
||||
if (comp && compartment) {
|
||||
|
@ -4292,6 +4302,7 @@ void CompartmentCheckTracer::onChild(const JS::GCCellPtr& thing) {
|
|||
Zone* thingZone = tenured->zoneFromAnyThread();
|
||||
MOZ_ASSERT(thingZone == zone || thingZone->isAtomsZone());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GCRuntime::checkForCompartmentMismatches() {
|
||||
|
@ -9296,48 +9307,50 @@ js::gc::ClearEdgesTracer::ClearEdgesTracer()
|
|||
: CallbackTracer(TlsContext.get(), TraceWeakMapKeysValues) {}
|
||||
|
||||
template <typename S>
|
||||
inline void js::gc::ClearEdgesTracer::clearEdge(S** thingp) {
|
||||
inline bool js::gc::ClearEdgesTracer::clearEdge(S** thingp) {
|
||||
InternalBarrierMethods<S*>::preBarrier(*thingp);
|
||||
InternalBarrierMethods<S*>::postBarrier(thingp, *thingp, nullptr);
|
||||
*thingp = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
void js::gc::ClearEdgesTracer::onObjectEdge(JSObject** objp) {
|
||||
clearEdge(objp);
|
||||
bool js::gc::ClearEdgesTracer::onObjectEdge(JSObject** objp) {
|
||||
return clearEdge(objp);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onStringEdge(JSString** strp) {
|
||||
clearEdge(strp);
|
||||
bool js::gc::ClearEdgesTracer::onStringEdge(JSString** strp) {
|
||||
return clearEdge(strp);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onSymbolEdge(JS::Symbol** symp) {
|
||||
clearEdge(symp);
|
||||
bool js::gc::ClearEdgesTracer::onSymbolEdge(JS::Symbol** symp) {
|
||||
return clearEdge(symp);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onBigIntEdge(JS::BigInt** bip) {
|
||||
clearEdge(bip);
|
||||
bool js::gc::ClearEdgesTracer::onBigIntEdge(JS::BigInt** bip) {
|
||||
return clearEdge(bip);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onScriptEdge(JSScript** scriptp) {
|
||||
clearEdge(scriptp);
|
||||
bool js::gc::ClearEdgesTracer::onScriptEdge(JSScript** scriptp) {
|
||||
return clearEdge(scriptp);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onShapeEdge(js::Shape** shapep) {
|
||||
clearEdge(shapep);
|
||||
bool js::gc::ClearEdgesTracer::onShapeEdge(js::Shape** shapep) {
|
||||
return clearEdge(shapep);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onObjectGroupEdge(js::ObjectGroup** groupp) {
|
||||
clearEdge(groupp);
|
||||
bool js::gc::ClearEdgesTracer::onObjectGroupEdge(js::ObjectGroup** groupp) {
|
||||
return clearEdge(groupp);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onBaseShapeEdge(js::BaseShape** basep) {
|
||||
clearEdge(basep);
|
||||
bool js::gc::ClearEdgesTracer::onBaseShapeEdge(js::BaseShape** basep) {
|
||||
return clearEdge(basep);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onJitCodeEdge(js::jit::JitCode** codep) {
|
||||
clearEdge(codep);
|
||||
bool js::gc::ClearEdgesTracer::onJitCodeEdge(js::jit::JitCode** codep) {
|
||||
return clearEdge(codep);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onLazyScriptEdge(js::LazyScript** lazyp) {
|
||||
clearEdge(lazyp);
|
||||
bool js::gc::ClearEdgesTracer::onLazyScriptEdge(js::LazyScript** lazyp) {
|
||||
return clearEdge(lazyp);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onScopeEdge(js::Scope** scopep) {
|
||||
clearEdge(scopep);
|
||||
bool js::gc::ClearEdgesTracer::onScopeEdge(js::Scope** scopep) {
|
||||
return clearEdge(scopep);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onRegExpSharedEdge(js::RegExpShared** sharedp) {
|
||||
clearEdge(sharedp);
|
||||
bool js::gc::ClearEdgesTracer::onRegExpSharedEdge(js::RegExpShared** sharedp) {
|
||||
return clearEdge(sharedp);
|
||||
}
|
||||
void js::gc::ClearEdgesTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
bool js::gc::ClearEdgesTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
MOZ_CRASH();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -153,17 +153,18 @@ struct MovingTracer final : public JS::CallbackTracer {
|
|||
explicit MovingTracer(JSRuntime* rt)
|
||||
: CallbackTracer(rt, TraceWeakMapKeysValues) {}
|
||||
|
||||
void onObjectEdge(JSObject** objp) override;
|
||||
void onShapeEdge(Shape** shapep) override;
|
||||
void onStringEdge(JSString** stringp) override;
|
||||
void onScriptEdge(JSScript** scriptp) override;
|
||||
void onLazyScriptEdge(LazyScript** lazyp) override;
|
||||
void onBaseShapeEdge(BaseShape** basep) override;
|
||||
void onScopeEdge(Scope** basep) override;
|
||||
void onRegExpSharedEdge(RegExpShared** sharedp) override;
|
||||
void onBigIntEdge(BigInt** bip) override;
|
||||
void onChild(const JS::GCCellPtr& thing) override {
|
||||
bool onObjectEdge(JSObject** objp) override;
|
||||
bool onShapeEdge(Shape** shapep) override;
|
||||
bool onStringEdge(JSString** stringp) override;
|
||||
bool onScriptEdge(JSScript** scriptp) override;
|
||||
bool onLazyScriptEdge(LazyScript** lazyp) override;
|
||||
bool onBaseShapeEdge(BaseShape** basep) override;
|
||||
bool onScopeEdge(Scope** scopep) override;
|
||||
bool onRegExpSharedEdge(RegExpShared** sharedp) override;
|
||||
bool onBigIntEdge(BigInt** bip) override;
|
||||
bool onChild(const JS::GCCellPtr& thing) override {
|
||||
MOZ_ASSERT(!thing.asCell()->isForwarded());
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -172,7 +173,7 @@ struct MovingTracer final : public JS::CallbackTracer {
|
|||
|
||||
private:
|
||||
template <typename T>
|
||||
void updateEdge(T** thingp);
|
||||
bool updateEdge(T** thingp);
|
||||
};
|
||||
|
||||
// Structure for counting how many times objects in a particular group have
|
||||
|
|
|
@ -3526,8 +3526,9 @@ FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(INSTANTIATE_INTERNAL_MARKING_FUNCTIONS)
|
|||
#ifdef DEBUG
|
||||
struct AssertNonGrayTracer final : public JS::CallbackTracer {
|
||||
explicit AssertNonGrayTracer(JSRuntime* rt) : JS::CallbackTracer(rt) {}
|
||||
void onChild(const JS::GCCellPtr& thing) override {
|
||||
bool onChild(const JS::GCCellPtr& thing) override {
|
||||
MOZ_ASSERT(!thing.asCell()->isMarkedGray());
|
||||
return true;
|
||||
}
|
||||
// This is used by the UnmarkGray tracer only, and needs to report itself
|
||||
// as the non-gray tracer to not trigger assertions. Do not use it in another
|
||||
|
@ -3558,14 +3559,14 @@ class UnmarkGrayTracer final : public JS::CallbackTracer {
|
|||
// Stack of cells to traverse.
|
||||
Vector<JS::GCCellPtr, 0, SystemAllocPolicy>& stack;
|
||||
|
||||
void onChild(const JS::GCCellPtr& thing) override;
|
||||
bool onChild(const JS::GCCellPtr& thing) override;
|
||||
|
||||
#ifdef DEBUG
|
||||
TracerKind getTracerKind() const override { return TracerKind::UnmarkGray; }
|
||||
#endif
|
||||
};
|
||||
|
||||
void UnmarkGrayTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
bool UnmarkGrayTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
Cell* cell = thing.asCell();
|
||||
|
||||
// Cells in the nursery cannot be gray, and nor can certain kinds of tenured
|
||||
|
@ -3577,7 +3578,7 @@ void UnmarkGrayTracer::onChild(const JS::GCCellPtr& thing) {
|
|||
AssertNonGrayTracer nongray(runtime());
|
||||
TraceChildren(&nongray, cell, thing.kind());
|
||||
#endif
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
TenuredCell& tenured = cell->asTenured();
|
||||
|
@ -3595,11 +3596,11 @@ void UnmarkGrayTracer::onChild(const JS::GCCellPtr& thing) {
|
|||
MOZ_ASSERT(tmp == cell);
|
||||
unmarkedAny = true;
|
||||
}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!tenured.isMarkedGray()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
tenured.markBlack();
|
||||
|
@ -3608,6 +3609,7 @@ void UnmarkGrayTracer::onChild(const JS::GCCellPtr& thing) {
|
|||
if (!stack.append(thing)) {
|
||||
oom = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void UnmarkGrayTracer::unmark(JS::GCCellPtr cell) {
|
||||
|
|
|
@ -416,8 +416,9 @@ void js::gc::GCRuntime::traceRuntimeCommon(JSTracer* trc,
|
|||
|
||||
#ifdef DEBUG
|
||||
class AssertNoRootsTracer final : public JS::CallbackTracer {
|
||||
void onChild(const JS::GCCellPtr& thing) override {
|
||||
bool onChild(const JS::GCCellPtr& thing) override {
|
||||
MOZ_CRASH("There should not be any roots after finishRoots");
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -464,18 +465,25 @@ class BufferGrayRootsTracer final : public JS::CallbackTracer {
|
|||
// Set to false if we OOM while buffering gray roots.
|
||||
bool bufferingGrayRootsFailed;
|
||||
|
||||
void onObjectEdge(JSObject** objp) override { bufferRoot(*objp); }
|
||||
void onStringEdge(JSString** stringp) override { bufferRoot(*stringp); }
|
||||
void onScriptEdge(JSScript** scriptp) override { bufferRoot(*scriptp); }
|
||||
void onSymbolEdge(JS::Symbol** symbolp) override { bufferRoot(*symbolp); }
|
||||
void onBigIntEdge(JS::BigInt** bip) override { bufferRoot(*bip); }
|
||||
bool onObjectEdge(JSObject** objp) override { return bufferRoot(*objp); }
|
||||
bool onStringEdge(JSString** stringp) override {
|
||||
return bufferRoot(*stringp);
|
||||
}
|
||||
bool onScriptEdge(JSScript** scriptp) override {
|
||||
return bufferRoot(*scriptp);
|
||||
}
|
||||
bool onSymbolEdge(JS::Symbol** symbolp) override {
|
||||
return bufferRoot(*symbolp);
|
||||
}
|
||||
bool onBigIntEdge(JS::BigInt** bip) override { return bufferRoot(*bip); }
|
||||
|
||||
void onChild(const JS::GCCellPtr& thing) override {
|
||||
bool onChild(const JS::GCCellPtr& thing) override {
|
||||
MOZ_CRASH("Unexpected gray root kind");
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void bufferRoot(T* thing);
|
||||
inline bool bufferRoot(T* thing);
|
||||
|
||||
public:
|
||||
explicit BufferGrayRootsTracer(JSRuntime* rt)
|
||||
|
@ -514,7 +522,7 @@ void js::gc::GCRuntime::bufferGrayRoots() {
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
inline void BufferGrayRootsTracer::bufferRoot(T* thing) {
|
||||
inline bool BufferGrayRootsTracer::bufferRoot(T* thing) {
|
||||
MOZ_ASSERT(JS::RuntimeHeapIsBusy());
|
||||
MOZ_ASSERT(thing);
|
||||
// Check if |thing| is corrupt by calling a method that touches the heap.
|
||||
|
@ -536,6 +544,8 @@ inline void BufferGrayRootsTracer::bufferRoot(T* thing) {
|
|||
bufferingGrayRootsFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GCRuntime::markBufferedGrayRoots(JS::Zone* zone) {
|
||||
|
|
|
@ -88,7 +88,7 @@ typedef HashMap<void*, VerifyNode*, DefaultHasher<void*>, SystemAllocPolicy>
|
|||
class js::VerifyPreTracer final : public JS::CallbackTracer {
|
||||
JS::AutoDisableGenerationalGC noggc;
|
||||
|
||||
void onChild(const JS::GCCellPtr& thing) override;
|
||||
bool onChild(const JS::GCCellPtr& thing) override;
|
||||
|
||||
public:
|
||||
/* The gcNumber when the verification began. */
|
||||
|
@ -121,18 +121,18 @@ class js::VerifyPreTracer final : public JS::CallbackTracer {
|
|||
* This function builds up the heap snapshot by adding edges to the current
|
||||
* node.
|
||||
*/
|
||||
void VerifyPreTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
bool VerifyPreTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
MOZ_ASSERT(!IsInsideNursery(thing.asCell()));
|
||||
|
||||
// Skip things in other runtimes.
|
||||
if (thing.asCell()->asTenured().runtimeFromAnyThread() != runtime()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
edgeptr += sizeof(EdgeValue);
|
||||
if (edgeptr >= term) {
|
||||
edgeptr = term;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
VerifyNode* node = curnode;
|
||||
|
@ -142,6 +142,7 @@ void VerifyPreTracer::onChild(const JS::GCCellPtr& thing) {
|
|||
node->edges[i].kind = thing.kind();
|
||||
node->edges[i].label = contextName();
|
||||
node->count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
static VerifyNode* MakeNode(VerifyPreTracer* trc, void* thing,
|
||||
|
@ -273,7 +274,7 @@ struct CheckEdgeTracer final : public JS::CallbackTracer {
|
|||
VerifyNode* node;
|
||||
explicit CheckEdgeTracer(JSRuntime* rt)
|
||||
: JS::CallbackTracer(rt), node(nullptr) {}
|
||||
void onChild(const JS::GCCellPtr& thing) override;
|
||||
bool onChild(const JS::GCCellPtr& thing) override;
|
||||
};
|
||||
|
||||
static const uint32_t MAX_VERIFIER_EDGES = 1000;
|
||||
|
@ -285,24 +286,25 @@ static const uint32_t MAX_VERIFIER_EDGES = 1000;
|
|||
* non-nullptr edges (i.e., the ones from the original snapshot that must have
|
||||
* been modified) must point to marked objects.
|
||||
*/
|
||||
void CheckEdgeTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
bool CheckEdgeTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
// Skip things in other runtimes.
|
||||
if (thing.asCell()->asTenured().runtimeFromAnyThread() != runtime()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Avoid n^2 behavior. */
|
||||
if (node->count > MAX_VERIFIER_EDGES) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < node->count; i++) {
|
||||
if (node->edges[i].thing == thing.asCell()) {
|
||||
MOZ_ASSERT(node->edges[i].kind == thing.kind());
|
||||
node->edges[i].thing = nullptr;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void js::gc::AssertSafeToSkipBarrier(TenuredCell* thing) {
|
||||
|
@ -485,7 +487,7 @@ class HeapCheckTracerBase : public JS::CallbackTracer {
|
|||
size_t failures;
|
||||
|
||||
private:
|
||||
void onChild(const JS::GCCellPtr& thing) override;
|
||||
bool onChild(const JS::GCCellPtr& thing) override;
|
||||
|
||||
struct WorkItem {
|
||||
WorkItem(JS::GCCellPtr thing, const char* name, int parentIndex)
|
||||
|
@ -519,22 +521,22 @@ HeapCheckTracerBase::HeapCheckTracerBase(JSRuntime* rt,
|
|||
# endif
|
||||
}
|
||||
|
||||
void HeapCheckTracerBase::onChild(const JS::GCCellPtr& thing) {
|
||||
bool HeapCheckTracerBase::onChild(const JS::GCCellPtr& thing) {
|
||||
Cell* cell = thing.asCell();
|
||||
checkCell(cell);
|
||||
|
||||
if (visited.lookup(cell)) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!visited.put(cell)) {
|
||||
oom = true;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't trace into GC things owned by another runtime.
|
||||
if (cell->runtimeFromAnyThread() != rt) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't trace into GC in zones being used by helper threads.
|
||||
|
@ -548,13 +550,15 @@ void HeapCheckTracerBase::onChild(const JS::GCCellPtr& thing) {
|
|||
}
|
||||
|
||||
if (zone->usedByHelperThread()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
WorkItem item(thing, contextName(), parentIndex);
|
||||
if (!stack.append(item)) {
|
||||
oom = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HeapCheckTracerBase::traceHeap(AutoTraceSession& session) {
|
||||
|
|
|
@ -72,7 +72,7 @@ static bool ConstructCCW(JSContext* cx, const JSClass* globalClasp,
|
|||
}
|
||||
|
||||
class CCWTestTracer final : public JS::CallbackTracer {
|
||||
void onChild(const JS::GCCellPtr& thing) override {
|
||||
bool onChild(const JS::GCCellPtr& thing) override {
|
||||
numberOfThingsTraced++;
|
||||
|
||||
printf("*thingp = %p\n", thing.asCell());
|
||||
|
@ -84,6 +84,7 @@ class CCWTestTracer final : public JS::CallbackTracer {
|
|||
if (thing.asCell() != *expectedThingp || thing.kind() != expectedKind) {
|
||||
okay = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -16,10 +16,11 @@
|
|||
#include "jsapi-tests/tests.h"
|
||||
|
||||
class TestTracer final : public JS::CallbackTracer {
|
||||
void onChild(const JS::GCCellPtr& thing) override {
|
||||
bool onChild(const JS::GCCellPtr& thing) override {
|
||||
if (thing.asCell() == expectedCell && thing.kind() == expectedKind) {
|
||||
found = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -1019,7 +1019,7 @@ struct DumpHeapTracer final : public JS::CallbackTracer, public WeakMapTracer {
|
|||
key.asCell(), kdelegate, value.asCell());
|
||||
}
|
||||
|
||||
void onChild(const JS::GCCellPtr& thing) override;
|
||||
bool onChild(const JS::GCCellPtr& thing) override;
|
||||
};
|
||||
|
||||
static char MarkDescriptor(void* thing) {
|
||||
|
@ -1081,15 +1081,16 @@ static void DumpHeapVisitCell(JSRuntime* rt, void* data, void* thing,
|
|||
js::TraceChildren(dtrc, thing, traceKind);
|
||||
}
|
||||
|
||||
void DumpHeapTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
bool DumpHeapTracer::onChild(const JS::GCCellPtr& thing) {
|
||||
if (gc::IsInsideNursery(thing.asCell())) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
getTracingEdgeName(buffer, sizeof(buffer));
|
||||
fprintf(output, "%s%p %c %s\n", prefix, thing.asCell(),
|
||||
MarkDescriptor(thing.asCell()), buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void js::DumpHeap(JSContext* cx, FILE* fp,
|
||||
|
|
|
@ -198,18 +198,18 @@ class EdgeVectorTracer final : public JS::CallbackTracer {
|
|||
// True if we should populate the edge's names.
|
||||
bool wantNames;
|
||||
|
||||
void onChild(const JS::GCCellPtr& thing) override {
|
||||
bool onChild(const JS::GCCellPtr& thing) override {
|
||||
if (!okay) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't trace permanent atoms and well-known symbols that are owned by
|
||||
// a parent JSRuntime.
|
||||
if (thing.is<JSString>() && thing.as<JSString>().isPermanentAtom()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (thing.is<JS::Symbol>() && thing.as<JS::Symbol>().isWellKnownSymbol()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
char16_t* name16 = nullptr;
|
||||
|
@ -223,7 +223,7 @@ class EdgeVectorTracer final : public JS::CallbackTracer {
|
|||
name16 = js_pod_malloc<char16_t>(strlen(name) + 1);
|
||||
if (!name16) {
|
||||
okay = false;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
|
@ -239,8 +239,10 @@ class EdgeVectorTracer final : public JS::CallbackTracer {
|
|||
// retains it, and its destructor will free it.
|
||||
if (!vec->append(Edge(name16, Node(thing)))) {
|
||||
okay = false;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -152,7 +152,7 @@ struct NoteWeakMapChildrenTracer : public JS::CallbackTracer {
|
|||
mKeyDelegate(nullptr) {
|
||||
setCanSkipJsids(true);
|
||||
}
|
||||
void onChild(const JS::GCCellPtr& aThing) override;
|
||||
bool onChild(const JS::GCCellPtr& aThing) override;
|
||||
nsCycleCollectionNoteRootCallback& mCb;
|
||||
bool mTracedAny;
|
||||
JSObject* mMap;
|
||||
|
@ -160,13 +160,13 @@ struct NoteWeakMapChildrenTracer : public JS::CallbackTracer {
|
|||
JSObject* mKeyDelegate;
|
||||
};
|
||||
|
||||
void NoteWeakMapChildrenTracer::onChild(const JS::GCCellPtr& aThing) {
|
||||
bool NoteWeakMapChildrenTracer::onChild(const JS::GCCellPtr& aThing) {
|
||||
if (aThing.is<JSString>()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!JS::GCThingIsMarkedGray(aThing) && !mCb.WantAllTraces()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (JS::IsCCTraceKind(aThing.kind())) {
|
||||
|
@ -175,6 +175,7 @@ void NoteWeakMapChildrenTracer::onChild(const JS::GCCellPtr& aThing) {
|
|||
} else {
|
||||
JS::TraceChildren(this, aThing);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct NoteWeakMapsTracer : public js::WeakMapTracer {
|
||||
|
@ -388,20 +389,20 @@ struct TraversalTracer : public JS::CallbackTracer {
|
|||
: JS::CallbackTracer(aRt, DoNotTraceWeakMaps), mCb(aCb) {
|
||||
setCanSkipJsids(true);
|
||||
}
|
||||
void onChild(const JS::GCCellPtr& aThing) override;
|
||||
bool onChild(const JS::GCCellPtr& aThing) override;
|
||||
nsCycleCollectionTraversalCallback& mCb;
|
||||
};
|
||||
|
||||
void TraversalTracer::onChild(const JS::GCCellPtr& aThing) {
|
||||
bool TraversalTracer::onChild(const JS::GCCellPtr& aThing) {
|
||||
// Checking strings and symbols for being gray is rather slow, and we don't
|
||||
// need either of them for the cycle collector.
|
||||
if (aThing.is<JSString>() || aThing.is<JS::Symbol>()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't traverse non-gray objects, unless we want all traces.
|
||||
if (!JS::GCThingIsMarkedGray(aThing) && !mCb.WantAllTraces()) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -430,6 +431,7 @@ void TraversalTracer::onChild(const JS::GCCellPtr& aThing) {
|
|||
} else {
|
||||
JS::TraceChildren(this, aThing);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void NoteJSChildGrayWrapperShim(void* aData, JS::GCCellPtr aThing) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче