Bug 1785804 - Part 2: Remove tracing name context and pass name through the trace methods r=sfink

One point of difference between the DoMarking fast path and other tracers is
handling the edge name. Passing this through to the concrete tracer and
handling it there removes this differemce.

Eventually we should be able to inline some of these these calls at which point
it should get optimsed away for tracers that ignore it.

Depends on D156559

Differential Revision: https://phabricator.services.mozilla.com/D156560
This commit is contained in:
Jon Coppeard 2022-09-07 09:49:58 +00:00
parent d6a8f56a10
commit e418b6997d
21 changed files with 108 additions and 119 deletions

View File

@ -636,7 +636,7 @@ struct VerifyTraceProtoAndIfaceCacheCalledTracer : public JS::CallbackTracer {
: JS::CallbackTracer(cx, JS::TracerKind::VerifyTraceProtoAndIface),
ok(false) {}
void onChild(JS::GCCellPtr) override {
void onChild(JS::GCCellPtr, const char* name) override {
// We don't do anything here, we only want to verify that
// TraceProtoAndIfaceCache was called.
}

View File

@ -101,7 +101,6 @@ struct TraceOptions {
: weakEdgeAction(weakEdgeActionArg) {}
};
class AutoTracingName;
class AutoTracingIndex;
// Optional context information that can be used to construct human readable
@ -124,13 +123,6 @@ class TracingContext {
// complexity), by associating a functor with the tracer so that, when
// requested, the user can generate totally custom edge descriptions.
// Returns the current edge's name. It is only valid to call this when
// inside the trace callback, however, the edge name will always be set.
const char* name() const {
MOZ_ASSERT(name_);
return name_;
}
// Returns the current edge's index, if marked as part of an array of edges.
// This must be called only inside the trace callback. When not tracing an
// array, the value will be InvalidIndex.
@ -142,7 +134,7 @@ class TracingContext {
// heap. On the other hand, the description provided by this method may be
// substantially more accurate and useful than those provided by only the
// name and index.
void getEdgeName(char* buffer, size_t bufferSize);
void getEdgeName(const char* name, char* buffer, size_t bufferSize);
// The trace implementation may associate a callback with one or more edges
// using AutoTracingDetails. This functor is called by getEdgeName and
@ -155,9 +147,6 @@ class TracingContext {
};
private:
friend class AutoTracingName;
const char* name_ = nullptr;
friend class AutoTracingIndex;
size_t index_ = InvalidIndex;
@ -228,7 +217,7 @@ class GenericTracer : public JSTracer {
// which is freqently useful if, for example, we only want to process one type
// of edge.
#define DEFINE_ON_EDGE_METHOD(name, type, _1, _2) \
virtual type* on##name##Edge(type* thing) = 0;
virtual type* on##name##Edge(type* thing, const char* name) = 0;
JS_FOR_EACH_TRACEKIND(DEFINE_ON_EDGE_METHOD)
#undef DEFINE_ON_EDGE_METHOD
};
@ -245,8 +234,10 @@ class GenericTracerImpl : public GenericTracer {
private:
T* derived() { return static_cast<T*>(this); }
#define DEFINE_ON_EDGE_METHOD(name, type, _1, _2) \
type* on##name##Edge(type* thing) final { return derived()->onEdge(thing); }
#define DEFINE_ON_EDGE_METHOD(name, type, _1, _2) \
type* on##name##Edge(type* thing, const char* name) final { \
return derived()->onEdge(thing, name); \
}
JS_FOR_EACH_TRACEKIND(DEFINE_ON_EDGE_METHOD)
#undef DEFINE_ON_EDGE_METHOD
};
@ -268,33 +259,17 @@ class JS_PUBLIC_API CallbackTracer
// Override this method to receive notification when a node in the GC
// heap graph is visited.
virtual void onChild(JS::GCCellPtr thing) = 0;
virtual void onChild(JS::GCCellPtr thing, const char* name) = 0;
private:
template <typename T>
T* onEdge(T* thing) {
onChild(JS::GCCellPtr(thing));
T* onEdge(T* thing, const char* name) {
onChild(JS::GCCellPtr(thing), name);
return thing;
}
friend class js::GenericTracerImpl<CallbackTracer>;
};
// Set the name portion of the tracer's context for the current edge.
class MOZ_RAII AutoTracingName {
JSTracer* trc_;
public:
AutoTracingName(JSTracer* trc, const char* name) : trc_(trc) {
MOZ_ASSERT(name);
MOZ_ASSERT(!trc_->context().name_);
trc_->context().name_ = name;
}
~AutoTracingName() {
MOZ_ASSERT(trc_->context().name_);
trc_->context().name_ = nullptr;
}
};
// Set the index portion of the tracer's context for the current range.
class MOZ_RAII AutoTracingIndex {
JSTracer* trc_;

View File

@ -2651,7 +2651,7 @@ class HasChildTracer final : public JS::CallbackTracer {
RootedValue child_;
bool found_;
void onChild(JS::GCCellPtr thing) override {
void onChild(JS::GCCellPtr thing, const char* name) override {
if (thing.asCell() == child_.toGCThing()) {
found_ = true;
}

View File

@ -17,7 +17,7 @@ struct ClearEdgesTracer final : public GenericTracerImpl<ClearEdgesTracer> {
private:
template <typename T>
T* onEdge(T* thing);
T* onEdge(T* thing, const char* name);
friend class GenericTracerImpl<ClearEdgesTracer>;
};

View File

@ -441,7 +441,7 @@ MovingTracer::MovingTracer(JSRuntime* rt)
JS::WeakMapTraceAction::TraceKeysAndValues) {}
template <typename T>
inline T* MovingTracer::onEdge(T* thing) {
inline T* MovingTracer::onEdge(T* thing, const char* name) {
if (thing->runtimeFromAnyThread() == runtime() && IsForwarded(thing)) {
thing = Forwarded(thing);
}

View File

@ -2178,7 +2178,7 @@ bool GCRuntime::shouldPreserveJITCode(Realm* realm,
#ifdef DEBUG
class CompartmentCheckTracer final : public JS::CallbackTracer {
void onChild(JS::GCCellPtr thing) override;
void onChild(JS::GCCellPtr thing, const char* name) override;
bool edgeIsInCrossCompartmentMap(JS::GCCellPtr dst);
public:
@ -2217,7 +2217,7 @@ static bool InCrossCompartmentMap(JSRuntime* rt, JSObject* src,
return false;
}
void CompartmentCheckTracer::onChild(JS::GCCellPtr thing) {
void CompartmentCheckTracer::onChild(JS::GCCellPtr thing, const char* name) {
Compartment* comp =
MapGCThingTyped(thing, [](auto t) { return t->maybeCompartment(); });
if (comp && compartment) {
@ -4735,7 +4735,7 @@ js::gc::ClearEdgesTracer::ClearEdgesTracer(JSRuntime* rt)
JS::WeakMapTraceAction::TraceKeysAndValues) {}
template <typename T>
T* js::gc::ClearEdgesTracer::onEdge(T* thing) {
T* js::gc::ClearEdgesTracer::onEdge(T* thing, const char* name) {
// We don't handle removing pointers to nursery edges from the store buffer
// with this tracer. Check that this doesn't happen.
MOZ_ASSERT(!IsInsideNursery(thing));

View File

@ -306,7 +306,7 @@ struct MovingTracer final : public GenericTracerImpl<MovingTracer> {
private:
template <typename T>
T* onEdge(T* thingp);
T* onEdge(T* thingp, const char* name);
friend class GenericTracerImpl<MovingTracer>;
};
@ -316,7 +316,7 @@ struct MinorSweepingTracer final
private:
template <typename T>
T* onEdge(T* thingp);
T* onEdge(T* thingp, const char* name);
friend class GenericTracerImpl<MinorSweepingTracer>;
};

View File

@ -263,7 +263,7 @@ class BarrierTracer final : public GenericTracerImpl<BarrierTracer> {
private:
template <typename T>
T* onEdge(T* thing);
T* onEdge(T* thing, const char* name);
friend class GenericTracerImpl<BarrierTracer>;
void handleBufferFull(JS::GCCellPtr cell);
@ -276,7 +276,7 @@ struct SweepingTracer final : public GenericTracerImpl<SweepingTracer> {
private:
template <typename T>
T* onEdge(T* thingp);
T* onEdge(T* thingp, const char* name);
friend class GenericTracerImpl<SweepingTracer>;
};

View File

@ -646,10 +646,9 @@ void js::TraceGCCellPtrRoot(JSTracer* trc, JS::GCCellPtr* thingp,
template <typename T>
inline bool DoCallback(GenericTracer* trc, T** thingp, const char* name) {
CheckTracedThing(trc, *thingp);
JS::AutoTracingName ctx(trc, name);
T* thing = *thingp;
T* post = DispatchToOnEdge(trc, thing);
T* post = DispatchToOnEdge(trc, thing, name);
if (post != thing) {
*thingp = post;
}
@ -659,14 +658,12 @@ inline bool DoCallback(GenericTracer* trc, T** thingp, const char* name) {
template <typename T>
inline bool DoCallback(GenericTracer* trc, T* thingp, const char* name) {
JS::AutoTracingName ctx(trc, name);
// Return true by default. For some types the lambda below won't be called.
bool ret = true;
auto thing = MapGCThingTyped(*thingp, [trc, &ret](auto thing) {
auto thing = MapGCThingTyped(*thingp, [&](auto thing) {
CheckTracedThing(trc, thing);
auto* post = DispatchToOnEdge(trc, thing);
auto* post = DispatchToOnEdge(trc, thing, name);
if (!post) {
ret = false;
return TaggedPtr<T>::empty();
@ -2440,7 +2437,7 @@ SweepingTracer::SweepingTracer(JSRuntime* rt)
JS::WeakMapTraceAction::TraceKeysAndValues) {}
template <typename T>
inline T* SweepingTracer::onEdge(T* thing) {
inline T* SweepingTracer::onEdge(T* thing, const char* name) {
CheckIsMarkedThing(thing);
if (!thing->isTenured()) {
@ -2560,7 +2557,7 @@ struct AssertNonGrayTracer final : public JS::CallbackTracer {
// context without making this more generic.
explicit AssertNonGrayTracer(JSRuntime* rt)
: JS::CallbackTracer(rt, JS::TracerKind::UnmarkGray) {}
void onChild(JS::GCCellPtr thing) override {
void onChild(JS::GCCellPtr thing, const char* name) override {
MOZ_ASSERT(!thing.asCell()->isMarkedGray());
}
};
@ -2589,10 +2586,10 @@ class UnmarkGrayTracer final : public JS::CallbackTracer {
// Stack of cells to traverse.
Vector<JS::GCCellPtr, 0, SystemAllocPolicy>& stack;
void onChild(JS::GCCellPtr thing) override;
void onChild(JS::GCCellPtr thing, const char* name) override;
};
void UnmarkGrayTracer::onChild(JS::GCCellPtr thing) {
void UnmarkGrayTracer::onChild(JS::GCCellPtr thing, const char* name) {
Cell* cell = thing.asCell();
// Cells in the nursery cannot be gray, and nor can certain kinds of tenured
@ -2645,7 +2642,7 @@ void UnmarkGrayTracer::onChild(JS::GCCellPtr thing) {
void UnmarkGrayTracer::unmark(JS::GCCellPtr cell) {
MOZ_ASSERT(stack.empty());
onChild(cell);
onChild(cell, "unmarking root");
while (!stack.empty() && !oom) {
TraceChildren(this, stack.popCopy());
@ -2705,7 +2702,7 @@ static bool CellHasChildren(JS::GCCellPtr cell) {
struct Tracer : public JS::CallbackTracer {
bool hasChildren = false;
explicit Tracer(JSRuntime* runtime) : JS::CallbackTracer(runtime) {}
void onChild(JS::GCCellPtr thing) { hasChildren = true; }
void onChild(JS::GCCellPtr thing, const char* name) { hasChildren = true; }
};
Tracer trc(cell.asCell()->runtimeFromMainThread());
@ -2749,7 +2746,7 @@ BarrierTracer::BarrierTracer(JSRuntime* rt)
marker(rt->gc.marker) {}
template <typename T>
T* BarrierTracer::onEdge(T* thing) {
T* BarrierTracer::onEdge(T* thing, const char* name) {
PreWriteBarrier(thing);
return thing;
}

View File

@ -400,7 +400,7 @@ IncrementalProgress GCRuntime::traceEmbeddingGrayRoots(JSTracer* trc,
#ifdef DEBUG
class AssertNoRootsTracer final : public JS::CallbackTracer {
void onChild(JS::GCCellPtr thing) override {
void onChild(JS::GCCellPtr thing, const char* name) override {
MOZ_CRASH("There should not be any roots during runtime shutdown");
}

View File

@ -59,7 +59,7 @@ static inline void UpdateAllocSiteOnTenure(Cell* cell) {
site->incTenuredCount();
}
JSObject* TenuringTracer::onObjectEdge(JSObject* obj) {
JSObject* TenuringTracer::onObjectEdge(JSObject* obj, const char* name) {
if (!IsInsideNursery(obj)) {
return obj;
}
@ -80,7 +80,7 @@ JSObject* TenuringTracer::onObjectEdge(JSObject* obj) {
return moveToTenuredSlow(obj);
}
JSString* TenuringTracer::onStringEdge(JSString* str) {
JSString* TenuringTracer::onStringEdge(JSString* str, const char* name) {
if (!IsInsideNursery(str)) {
return str;
}
@ -95,7 +95,7 @@ JSString* TenuringTracer::onStringEdge(JSString* str) {
return moveToTenured(str);
}
JS::BigInt* TenuringTracer::onBigIntEdge(JS::BigInt* bi) {
JS::BigInt* TenuringTracer::onBigIntEdge(JS::BigInt* bi, const char* name) {
if (!IsInsideNursery(bi)) {
return bi;
}
@ -110,23 +110,38 @@ JS::BigInt* TenuringTracer::onBigIntEdge(JS::BigInt* bi) {
return moveToTenured(bi);
}
JS::Symbol* TenuringTracer::onSymbolEdge(JS::Symbol* sym) { return sym; }
js::BaseScript* TenuringTracer::onScriptEdge(BaseScript* script) {
JS::Symbol* TenuringTracer::onSymbolEdge(JS::Symbol* sym, const char* name) {
return sym;
}
js::BaseScript* TenuringTracer::onScriptEdge(BaseScript* script,
const char* name) {
return script;
}
js::Shape* TenuringTracer::onShapeEdge(Shape* shape) { return shape; }
js::RegExpShared* TenuringTracer::onRegExpSharedEdge(RegExpShared* shared) {
js::Shape* TenuringTracer::onShapeEdge(Shape* shape, const char* name) {
return shape;
}
js::RegExpShared* TenuringTracer::onRegExpSharedEdge(RegExpShared* shared,
const char* name) {
return shared;
}
js::BaseShape* TenuringTracer::onBaseShapeEdge(BaseShape* base) { return base; }
js::GetterSetter* TenuringTracer::onGetterSetterEdge(GetterSetter* gs) {
js::BaseShape* TenuringTracer::onBaseShapeEdge(BaseShape* base,
const char* name) {
return base;
}
js::GetterSetter* TenuringTracer::onGetterSetterEdge(GetterSetter* gs,
const char* name) {
return gs;
}
js::PropMap* TenuringTracer::onPropMapEdge(PropMap* map) { return map; }
js::jit::JitCode* TenuringTracer::onJitCodeEdge(jit::JitCode* code) {
js::PropMap* TenuringTracer::onPropMapEdge(PropMap* map, const char* name) {
return map;
}
js::jit::JitCode* TenuringTracer::onJitCodeEdge(jit::JitCode* code,
const char* name) {
return code;
}
js::Scope* TenuringTracer::onScopeEdge(Scope* scope) { return scope; }
js::Scope* TenuringTracer::onScopeEdge(Scope* scope, const char* name) {
return scope;
}
void TenuringTracer::traverse(JS::Value* thingp) {
MOZ_ASSERT(!nursery().isInside(thingp));
@ -138,18 +153,18 @@ void TenuringTracer::traverse(JS::Value* thingp) {
// tighter code than using MapGCThingTyped.
Value post;
if (value.isObject()) {
post = JS::ObjectValue(*onObjectEdge(&value.toObject()));
post = JS::ObjectValue(*onObjectEdge(&value.toObject(), "value"));
}
#ifdef ENABLE_RECORD_TUPLE
else if (value.isExtendedPrimitive()) {
post =
JS::ExtendedPrimitiveValue(*onObjectEdge(&value.toExtendedPrimitive()));
post = JS::ExtendedPrimitiveValue(
*onObjectEdge(&value.toExtendedPrimitive(), "value"));
}
#endif
else if (value.isString()) {
post = JS::StringValue(onStringEdge(value.toString()));
post = JS::StringValue(onStringEdge(value.toString(), "value"));
} else if (value.isBigInt()) {
post = JS::BigIntValue(onBigIntEdge(value.toBigInt()));
post = JS::BigIntValue(onBigIntEdge(value.toBigInt(), "value"));
} else {
MOZ_ASSERT_IF(value.isGCThing(), !IsInsideNursery(value.toGCThing()));
return;
@ -397,7 +412,7 @@ void js::gc::StoreBuffer::CellPtrEdge<T>::trace(TenuringTracer& mover) const {
edge, JS::TraceKind::String));
}
*edge = DispatchToOnEdge(&mover, thing);
*edge = DispatchToOnEdge(&mover, thing, "CellPtrEdge");
}
void js::gc::StoreBuffer::ValueEdge::trace(TenuringTracer& mover) const {
@ -986,7 +1001,7 @@ MinorSweepingTracer::MinorSweepingTracer(JSRuntime* rt)
}
template <typename T>
inline T* MinorSweepingTracer::onEdge(T* thing) {
inline T* MinorSweepingTracer::onEdge(T* thing, const char* name) {
if (thing->isTenured()) {
return thing;
}

View File

@ -36,7 +36,7 @@ class TenuringTracer final : public GenericTracer {
gc::StringRelocationOverlay* stringHead = nullptr;
#define DEFINE_ON_EDGE_METHOD(name, type, _1, _2) \
type* on##name##Edge(type* thing) override;
type* on##name##Edge(type* thing, const char* name) override;
JS_FOR_EACH_TRACEKIND(DEFINE_ON_EDGE_METHOD)
#undef DEFINE_ON_EDGE_METHOD

View File

@ -39,17 +39,18 @@ template void RuntimeScopeData<EvalScope::SlotInfo>::trace(JSTracer* trc);
template void RuntimeScopeData<WasmFunctionScope::SlotInfo>::trace(
JSTracer* trc);
void JS::TracingContext::getEdgeName(char* buffer, size_t bufferSize) {
void JS::TracingContext::getEdgeName(const char* name, char* buffer,
size_t bufferSize) {
MOZ_ASSERT(bufferSize > 0);
if (functor_) {
(*functor_)(this, buffer, bufferSize);
return;
}
if (index_ != InvalidIndex) {
snprintf(buffer, bufferSize, "%s[%zu]", name_, index_);
snprintf(buffer, bufferSize, "%s[%zu]", name, index_);
return;
}
snprintf(buffer, bufferSize, "%s", name_);
snprintf(buffer, bufferSize, "%s", name);
}
/*** Public Tracing API *****************************************************/

View File

@ -355,9 +355,10 @@ void GetTraceThingInfo(char* buf, size_t bufsize, void* thing,
// Overloaded function to call the correct GenericTracer method based on the
// argument type.
#define DEFINE_DISPATCH_FUNCTION(name, type, _1, _2) \
inline type* DispatchToOnEdge(GenericTracer* trc, type* thing) { \
return trc->on##name##Edge(thing); \
#define DEFINE_DISPATCH_FUNCTION(name, type, _1, _2) \
inline type* DispatchToOnEdge(GenericTracer* trc, type* thing, \
const char* name) { \
return trc->on##name##Edge(thing, name); \
}
JS_FOR_EACH_TRACEKIND(DEFINE_DISPATCH_FUNCTION)
#undef DEFINE_DISPATCH_FUNCTION

View File

@ -86,7 +86,7 @@ typedef HashMap<Cell*, VerifyNode*, DefaultHasher<Cell*>, SystemAllocPolicy>
class js::VerifyPreTracer final : public JS::CallbackTracer {
JS::AutoDisableGenerationalGC noggc;
void onChild(JS::GCCellPtr thing) override;
void onChild(JS::GCCellPtr thing, const char* name) override;
public:
/* The gcNumber when the verification began. */
@ -123,7 +123,7 @@ class js::VerifyPreTracer final : public JS::CallbackTracer {
* This function builds up the heap snapshot by adding edges to the current
* node.
*/
void VerifyPreTracer::onChild(JS::GCCellPtr thing) {
void VerifyPreTracer::onChild(JS::GCCellPtr thing, const char* name) {
MOZ_ASSERT(!IsInsideNursery(thing.asCell()));
// Skip things in other runtimes.
@ -141,7 +141,7 @@ void VerifyPreTracer::onChild(JS::GCCellPtr thing) {
uint32_t i = node->count;
node->edges[i].thing = thing;
node->edges[i].label = context().name();
node->edges[i].label = name;
node->count++;
}
@ -280,7 +280,7 @@ struct CheckEdgeTracer final : public JS::CallbackTracer {
VerifyNode* node;
explicit CheckEdgeTracer(JSRuntime* rt)
: JS::CallbackTracer(rt), node(nullptr) {}
void onChild(JS::GCCellPtr thing) override;
void onChild(JS::GCCellPtr thing, const char* name) override;
};
static const uint32_t MAX_VERIFIER_EDGES = 1000;
@ -292,7 +292,7 @@ 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(JS::GCCellPtr thing) {
void CheckEdgeTracer::onChild(JS::GCCellPtr thing, const char* name) {
// Skip things in other runtimes.
if (thing.asCell()->asTenured().runtimeFromAnyThread() != runtime()) {
return;
@ -781,11 +781,11 @@ class HeapCheckTracerBase : public JS::CallbackTracer {
public:
explicit HeapCheckTracerBase(JSRuntime* rt, JS::TraceOptions options);
bool traceHeap(AutoTraceSession& session);
virtual void checkCell(Cell* cell) = 0;
virtual void checkCell(Cell* cell, const char* name) = 0;
protected:
void dumpCellInfo(Cell* cell);
void dumpCellPath();
void dumpCellPath(const char* name);
Cell* parentCell() {
return parentIndex == -1 ? nullptr : stack[parentIndex].thing.asCell();
@ -794,7 +794,7 @@ class HeapCheckTracerBase : public JS::CallbackTracer {
size_t failures;
private:
void onChild(JS::GCCellPtr thing) override;
void onChild(JS::GCCellPtr thing, const char* name) override;
struct WorkItem {
WorkItem(JS::GCCellPtr thing, const char* name, int parentIndex)
@ -824,9 +824,9 @@ HeapCheckTracerBase::HeapCheckTracerBase(JSRuntime* rt,
oom(false),
parentIndex(-1) {}
void HeapCheckTracerBase::onChild(JS::GCCellPtr thing) {
void HeapCheckTracerBase::onChild(JS::GCCellPtr thing, const char* name) {
Cell* cell = thing.asCell();
checkCell(cell);
checkCell(cell, name);
if (visited.lookup(cell)) {
return;
@ -842,7 +842,7 @@ void HeapCheckTracerBase::onChild(JS::GCCellPtr thing) {
return;
}
WorkItem item(thing, context().name(), parentIndex);
WorkItem item(thing, name, parentIndex);
if (!stack.append(item)) {
oom = true;
}
@ -884,8 +884,7 @@ void HeapCheckTracerBase::dumpCellInfo(Cell* cell) {
}
}
void HeapCheckTracerBase::dumpCellPath() {
const char* name = context().name();
void HeapCheckTracerBase::dumpCellPath(const char* name) {
for (int index = parentIndex; index != -1; index = stack[index].parentIndex) {
const WorkItem& parent = stack[index];
Cell* cell = parent.thing.asCell();
@ -905,7 +904,7 @@ class CheckHeapTracer final : public HeapCheckTracerBase {
void check(AutoTraceSession& session);
private:
void checkCell(Cell* cell) override;
void checkCell(Cell* cell, const char* name) override;
GCType gcType;
};
@ -917,14 +916,14 @@ inline static bool IsValidGCThingPointer(Cell* cell) {
return (uintptr_t(cell) & CellAlignMask) == 0;
}
void CheckHeapTracer::checkCell(Cell* cell) {
void CheckHeapTracer::checkCell(Cell* cell, const char* name) {
// Moving
if (!IsValidGCThingPointer(cell) ||
((gcType == GCType::Moving) && !IsGCThingValidAfterMovingGC(cell)) ||
((gcType == GCType::NonMoving) && cell->isForwarded())) {
failures++;
fprintf(stderr, "Bad pointer %p\n", cell);
dumpCellPath();
dumpCellPath(name);
}
}
@ -959,7 +958,7 @@ class CheckGrayMarkingTracer final : public HeapCheckTracerBase {
bool check(AutoTraceSession& session);
private:
void checkCell(Cell* cell) override;
void checkCell(Cell* cell, const char* name) override;
};
CheckGrayMarkingTracer::CheckGrayMarkingTracer(JSRuntime* rt)
@ -968,7 +967,7 @@ CheckGrayMarkingTracer::CheckGrayMarkingTracer(JSRuntime* rt)
// Weak gray->black edges are allowed.
}
void CheckGrayMarkingTracer::checkCell(Cell* cell) {
void CheckGrayMarkingTracer::checkCell(Cell* cell, const char* name) {
Cell* parent = parentCell();
if (!parent) {
return;
@ -980,7 +979,7 @@ void CheckGrayMarkingTracer::checkCell(Cell* cell) {
fprintf(stderr, "Found black to gray edge to ");
dumpCellInfo(cell);
fprintf(stderr, "\n");
dumpCellPath();
dumpCellPath(name);
# ifdef DEBUG
if (parent->is<JSObject>()) {

View File

@ -75,7 +75,7 @@ static bool ConstructCCW(JSContext* cx, const JSClass* globalClasp,
}
class CCWTestTracer final : public JS::CallbackTracer {
void onChild(JS::GCCellPtr thing) override {
void onChild(JS::GCCellPtr thing, const char* name) override {
numberOfThingsTraced++;
printf("*thingp = %p\n", thing.asCell());

View File

@ -16,7 +16,7 @@
#include "util/Text.h"
class TestTracer final : public JS::CallbackTracer {
void onChild(JS::GCCellPtr thing) override {
void onChild(JS::GCCellPtr thing, const char* name) override {
if (thing.asCell() == expectedCell && thing.kind() == expectedKind) {
found = true;
}

View File

@ -537,7 +537,7 @@ struct DumpHeapTracer final : public JS::CallbackTracer, public WeakMapTracer {
key.asCell(), kdelegate, value.asCell());
}
void onChild(JS::GCCellPtr thing) override;
void onChild(JS::GCCellPtr thing, const char* name) override;
};
static char MarkDescriptor(js::gc::Cell* thing) {
@ -603,13 +603,13 @@ static void DumpHeapVisitCell(JSRuntime* rt, void* data, JS::GCCellPtr cellptr,
JS::TraceChildren(dtrc, cellptr);
}
void DumpHeapTracer::onChild(JS::GCCellPtr thing) {
void DumpHeapTracer::onChild(JS::GCCellPtr thing, const char* name) {
if (js::gc::IsInsideNursery(thing.asCell())) {
return;
}
char buffer[1024];
context().getEdgeName(buffer, sizeof(buffer));
context().getEdgeName(name, buffer, sizeof(buffer));
fprintf(output, "%s%p %c %s\n", prefix, thing.asCell(),
MarkDescriptor(thing.asCell()), buffer);
}

View File

@ -2229,7 +2229,7 @@ class CheckTenuredTracer : public JS::CallbackTracer {
JS::TraceChildren(this, stack.popCopy());
}
}
void onChild(JS::GCCellPtr thing) override {
void onChild(JS::GCCellPtr thing, const char* name) override {
gc::Cell* cell = thing.asCell();
MOZ_RELEASE_ASSERT(cell->isTenured(), "Expected tenured cell");
if (!visited.has(cell)) {

View File

@ -196,7 +196,7 @@ class EdgeVectorTracer final : public JS::CallbackTracer {
// True if we should populate the edge's names.
bool wantNames;
void onChild(JS::GCCellPtr thing) override {
void onChild(JS::GCCellPtr thing, const char* name) override {
if (!okay) {
return;
}
@ -214,8 +214,8 @@ class EdgeVectorTracer final : public JS::CallbackTracer {
if (wantNames) {
// Ask the tracer to compute an edge name for us.
char buffer[1024];
context().getEdgeName(buffer, sizeof(buffer));
const char* name = buffer;
context().getEdgeName(name, buffer, sizeof(buffer));
name = buffer;
// Convert the name to char16_t characters.
name16 = js_pod_malloc<char16_t>(strlen(name) + 1);

View File

@ -161,7 +161,7 @@ struct NoteWeakMapChildrenTracer : public JS::CallbackTracer {
mMap(nullptr),
mKey(nullptr),
mKeyDelegate(nullptr) {}
void onChild(JS::GCCellPtr aThing) override;
void onChild(JS::GCCellPtr aThing, const char* name) override;
nsCycleCollectionNoteRootCallback& mCb;
bool mTracedAny;
JSObject* mMap;
@ -169,7 +169,8 @@ struct NoteWeakMapChildrenTracer : public JS::CallbackTracer {
JSObject* mKeyDelegate;
};
void NoteWeakMapChildrenTracer::onChild(JS::GCCellPtr aThing) {
void NoteWeakMapChildrenTracer::onChild(JS::GCCellPtr aThing,
const char* name) {
if (aThing.is<JSString>()) {
return;
}
@ -399,11 +400,11 @@ struct TraversalTracer : public JS::CallbackTracer {
JS::TraceOptions(JS::WeakMapTraceAction::Skip,
JS::WeakEdgeTraceAction::Trace)),
mCb(aCb) {}
void onChild(JS::GCCellPtr aThing) override;
void onChild(JS::GCCellPtr aThing, const char* name) override;
nsCycleCollectionTraversalCallback& mCb;
};
void TraversalTracer::onChild(JS::GCCellPtr aThing) {
void TraversalTracer::onChild(JS::GCCellPtr aThing, const char* name) {
// 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>()) {
@ -425,7 +426,7 @@ void TraversalTracer::onChild(JS::GCCellPtr aThing) {
if (JS::IsCCTraceKind(aThing.kind())) {
if (MOZ_UNLIKELY(mCb.WantDebugInfo())) {
char buffer[200];
context().getEdgeName(buffer, sizeof(buffer));
context().getEdgeName(name, buffer, sizeof(buffer));
mCb.NoteNextEdgeName(buffer);
}
mCb.NoteJSChild(aThing);
@ -746,7 +747,7 @@ class JSLeakTracer : public JS::CallbackTracer {
JS::WeakMapTraceAction::TraceKeysAndValues) {}
private:
void onChild(JS::GCCellPtr thing) override {
void onChild(JS::GCCellPtr thing, const char* name) override {
const char* kindName = JS::GCTraceKindToAscii(thing.kind());
size_t size = JS::GCTraceKindSize(thing.kind());
MOZ_LOG_CTOR(thing.asCell(), kindName, size);