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:
Yoshi Cheng-Hao Huang 2019-07-26 08:59:38 +00:00
Родитель 339a4ceab8
Коммит e17d60cbf4
14 изменённых файлов: 205 добавлений и 150 удалений

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

@ -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) {