зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1668825 - Change GenericTracer API so that it doesn't include details of heap storage r=sfink
The final patch in this series. This changes the GenericTracer APIs to take a thing pointer and return a possibly updated versions, rather than taking a double pointer to the thing. This means that we can change the details of how pointers are stored in the heap without chaning this interface. Differential Revision: https://phabricator.services.mozilla.com/D93336
This commit is contained in:
Родитель
2eb7622b4a
Коммит
16aaee1d65
|
@ -238,25 +238,28 @@ class GenericTracer : public JSTracer {
|
|||
MOZ_ASSERT(isGenericTracer());
|
||||
}
|
||||
|
||||
// Override these methods to receive notification when an edge is visited
|
||||
// with the type contained in the callback.
|
||||
// These methods are called when the tracer encounters an edge. Clients should
|
||||
// override them to receive notifications when an edge of each type is
|
||||
// visited.
|
||||
//
|
||||
// The caller updates the edge with the return value (if different).
|
||||
//
|
||||
// In C++, overriding a method hides all methods in the base class with that
|
||||
// name, not just methods with that signature. Thus, the typed edge 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 one type
|
||||
// of edge.
|
||||
virtual bool onObjectEdge(JSObject** objp) = 0;
|
||||
virtual bool onStringEdge(JSString** strp) = 0;
|
||||
virtual bool onSymbolEdge(JS::Symbol** symp) = 0;
|
||||
virtual bool onBigIntEdge(JS::BigInt** bip) = 0;
|
||||
virtual bool onScriptEdge(js::BaseScript** scriptp) = 0;
|
||||
virtual bool onShapeEdge(js::Shape** shapep) = 0;
|
||||
virtual bool onRegExpSharedEdge(js::RegExpShared** sharedp) = 0;
|
||||
virtual bool onObjectGroupEdge(js::ObjectGroup** groupp) = 0;
|
||||
virtual bool onBaseShapeEdge(js::BaseShape** basep) = 0;
|
||||
virtual bool onJitCodeEdge(js::jit::JitCode** codep) = 0;
|
||||
virtual bool onScopeEdge(js::Scope** scopep) = 0;
|
||||
virtual JSObject* onObjectEdge(JSObject* obj) = 0;
|
||||
virtual JSString* onStringEdge(JSString* str) = 0;
|
||||
virtual JS::Symbol* onSymbolEdge(JS::Symbol* sym) = 0;
|
||||
virtual JS::BigInt* onBigIntEdge(JS::BigInt* bi) = 0;
|
||||
virtual js::BaseScript* onScriptEdge(js::BaseScript* script) = 0;
|
||||
virtual js::Shape* onShapeEdge(js::Shape* shape) = 0;
|
||||
virtual js::RegExpShared* onRegExpSharedEdge(js::RegExpShared* shared) = 0;
|
||||
virtual js::ObjectGroup* onObjectGroupEdge(js::ObjectGroup* group) = 0;
|
||||
virtual js::BaseShape* onBaseShapeEdge(js::BaseShape* base) = 0;
|
||||
virtual js::jit::JitCode* onJitCodeEdge(js::jit::JitCode* code) = 0;
|
||||
virtual js::Scope* onScopeEdge(js::Scope* scope) = 0;
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
@ -282,49 +285,49 @@ class JS_PUBLIC_API CallbackTracer : public js::GenericTracer {
|
|||
|
||||
private:
|
||||
// This class implements the GenericTracer interface to dispatches to onChild.
|
||||
virtual bool onObjectEdge(JSObject** objp) {
|
||||
onChild(JS::GCCellPtr(*objp));
|
||||
return true;
|
||||
virtual JSObject* onObjectEdge(JSObject* obj) {
|
||||
onChild(JS::GCCellPtr(obj));
|
||||
return obj;
|
||||
}
|
||||
virtual bool onStringEdge(JSString** strp) {
|
||||
onChild(JS::GCCellPtr(*strp));
|
||||
return true;
|
||||
virtual JSString* onStringEdge(JSString* str) {
|
||||
onChild(JS::GCCellPtr(str));
|
||||
return str;
|
||||
}
|
||||
virtual bool onSymbolEdge(JS::Symbol** symp) {
|
||||
onChild(JS::GCCellPtr(*symp));
|
||||
return true;
|
||||
virtual JS::Symbol* onSymbolEdge(JS::Symbol* sym) {
|
||||
onChild(JS::GCCellPtr(sym));
|
||||
return sym;
|
||||
}
|
||||
virtual bool onBigIntEdge(JS::BigInt** bip) {
|
||||
onChild(JS::GCCellPtr(*bip));
|
||||
return true;
|
||||
virtual JS::BigInt* onBigIntEdge(JS::BigInt* bi) {
|
||||
onChild(JS::GCCellPtr(bi));
|
||||
return bi;
|
||||
}
|
||||
virtual bool onScriptEdge(js::BaseScript** scriptp) {
|
||||
onChild(JS::GCCellPtr(*scriptp));
|
||||
return true;
|
||||
virtual js::BaseScript* onScriptEdge(js::BaseScript* script) {
|
||||
onChild(JS::GCCellPtr(script));
|
||||
return script;
|
||||
}
|
||||
virtual bool onShapeEdge(js::Shape** shapep) {
|
||||
onChild(JS::GCCellPtr(*shapep, JS::TraceKind::Shape));
|
||||
return true;
|
||||
virtual js::Shape* onShapeEdge(js::Shape* shape) {
|
||||
onChild(JS::GCCellPtr(shape, JS::TraceKind::Shape));
|
||||
return shape;
|
||||
}
|
||||
virtual bool onObjectGroupEdge(js::ObjectGroup** groupp) {
|
||||
onChild(JS::GCCellPtr(*groupp, JS::TraceKind::ObjectGroup));
|
||||
return true;
|
||||
virtual js::ObjectGroup* onObjectGroupEdge(js::ObjectGroup* group) {
|
||||
onChild(JS::GCCellPtr(group, JS::TraceKind::ObjectGroup));
|
||||
return group;
|
||||
}
|
||||
virtual bool onBaseShapeEdge(js::BaseShape** basep) {
|
||||
onChild(JS::GCCellPtr(*basep, JS::TraceKind::BaseShape));
|
||||
return true;
|
||||
virtual js::BaseShape* onBaseShapeEdge(js::BaseShape* base) {
|
||||
onChild(JS::GCCellPtr(base, JS::TraceKind::BaseShape));
|
||||
return base;
|
||||
}
|
||||
virtual bool onJitCodeEdge(js::jit::JitCode** codep) {
|
||||
onChild(JS::GCCellPtr(*codep, JS::TraceKind::JitCode));
|
||||
return true;
|
||||
virtual js::jit::JitCode* onJitCodeEdge(js::jit::JitCode* code) {
|
||||
onChild(JS::GCCellPtr(code, JS::TraceKind::JitCode));
|
||||
return code;
|
||||
}
|
||||
virtual bool onScopeEdge(js::Scope** scopep) {
|
||||
onChild(JS::GCCellPtr(*scopep, JS::TraceKind::Scope));
|
||||
return true;
|
||||
virtual js::Scope* onScopeEdge(js::Scope* scope) {
|
||||
onChild(JS::GCCellPtr(scope, JS::TraceKind::Scope));
|
||||
return scope;
|
||||
}
|
||||
virtual bool onRegExpSharedEdge(js::RegExpShared** sharedp) {
|
||||
onChild(JS::GCCellPtr(*sharedp, JS::TraceKind::RegExpShared));
|
||||
return true;
|
||||
virtual js::RegExpShared* onRegExpSharedEdge(js::RegExpShared* shared) {
|
||||
onChild(JS::GCCellPtr(shared, JS::TraceKind::RegExpShared));
|
||||
return shared;
|
||||
}
|
||||
|
||||
TracingContext context_;
|
||||
|
|
|
@ -17,19 +17,19 @@ struct ClearEdgesTracer final : public GenericTracer {
|
|||
ClearEdgesTracer();
|
||||
|
||||
template <typename T>
|
||||
inline bool clearEdge(T** thingp);
|
||||
inline T* onEdge(T* thing);
|
||||
|
||||
bool onObjectEdge(JSObject** objp) override;
|
||||
bool onStringEdge(JSString** strp) override;
|
||||
bool onSymbolEdge(JS::Symbol** symp) override;
|
||||
bool onBigIntEdge(JS::BigInt** bip) override;
|
||||
bool onScriptEdge(js::BaseScript** 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 onScopeEdge(js::Scope** scopep) override;
|
||||
bool onRegExpSharedEdge(js::RegExpShared** sharedp) override;
|
||||
JSObject* onObjectEdge(JSObject* obj) override;
|
||||
JSString* onStringEdge(JSString* str) override;
|
||||
JS::Symbol* onSymbolEdge(JS::Symbol* sym) override;
|
||||
JS::BigInt* onBigIntEdge(JS::BigInt* bi) override;
|
||||
js::BaseScript* onScriptEdge(js::BaseScript* script) override;
|
||||
js::Shape* onShapeEdge(js::Shape* shape) override;
|
||||
js::ObjectGroup* onObjectGroupEdge(js::ObjectGroup* group) override;
|
||||
js::BaseShape* onBaseShapeEdge(js::BaseShape* base) override;
|
||||
js::jit::JitCode* onJitCodeEdge(js::jit::JitCode* code) override;
|
||||
js::Scope* onScopeEdge(js::Scope* scope) override;
|
||||
js::RegExpShared* onRegExpSharedEdge(js::RegExpShared* shared) override;
|
||||
};
|
||||
|
||||
} // namespace gc
|
||||
|
|
108
js/src/gc/GC.cpp
108
js/src/gc/GC.cpp
|
@ -2178,41 +2178,40 @@ bool GCRuntime::relocateArenas(Zone* zone, JS::GCReason reason,
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool MovingTracer::updateEdge(T** thingp) {
|
||||
auto thing = *thingp;
|
||||
inline T* MovingTracer::onEdge(T* thing) {
|
||||
if (thing->runtimeFromAnyThread() == runtime() && IsForwarded(thing)) {
|
||||
*thingp = Forwarded(thing);
|
||||
thing = Forwarded(thing);
|
||||
}
|
||||
|
||||
return true;
|
||||
return thing;
|
||||
}
|
||||
|
||||
bool MovingTracer::onObjectEdge(JSObject** objp) { return updateEdge(objp); }
|
||||
bool MovingTracer::onShapeEdge(Shape** shapep) { return updateEdge(shapep); }
|
||||
bool MovingTracer::onStringEdge(JSString** stringp) {
|
||||
return updateEdge(stringp);
|
||||
JSObject* MovingTracer::onObjectEdge(JSObject* obj) { return onEdge(obj); }
|
||||
Shape* MovingTracer::onShapeEdge(Shape* shape) { return onEdge(shape); }
|
||||
JSString* MovingTracer::onStringEdge(JSString* string) {
|
||||
return onEdge(string);
|
||||
}
|
||||
bool MovingTracer::onScriptEdge(js::BaseScript** scriptp) {
|
||||
return updateEdge(scriptp);
|
||||
js::BaseScript* MovingTracer::onScriptEdge(js::BaseScript* script) {
|
||||
return onEdge(script);
|
||||
}
|
||||
bool MovingTracer::onBaseShapeEdge(BaseShape** basep) {
|
||||
return updateEdge(basep);
|
||||
BaseShape* MovingTracer::onBaseShapeEdge(BaseShape* base) {
|
||||
return onEdge(base);
|
||||
}
|
||||
bool MovingTracer::onScopeEdge(Scope** scopep) { return updateEdge(scopep); }
|
||||
bool MovingTracer::onRegExpSharedEdge(RegExpShared** sharedp) {
|
||||
return updateEdge(sharedp);
|
||||
Scope* MovingTracer::onScopeEdge(Scope* scope) { return onEdge(scope); }
|
||||
RegExpShared* MovingTracer::onRegExpSharedEdge(RegExpShared* shared) {
|
||||
return onEdge(shared);
|
||||
}
|
||||
bool MovingTracer::onBigIntEdge(BigInt** bip) { return updateEdge(bip); }
|
||||
bool MovingTracer::onObjectGroupEdge(ObjectGroup** groupp) {
|
||||
return updateEdge(groupp);
|
||||
BigInt* MovingTracer::onBigIntEdge(BigInt* bi) { return onEdge(bi); }
|
||||
ObjectGroup* MovingTracer::onObjectGroupEdge(ObjectGroup* group) {
|
||||
return onEdge(group);
|
||||
}
|
||||
bool MovingTracer::onSymbolEdge(JS::Symbol** symp) {
|
||||
MOZ_ASSERT(!(*symp)->isForwarded());
|
||||
return true;
|
||||
JS::Symbol* MovingTracer::onSymbolEdge(JS::Symbol* sym) {
|
||||
MOZ_ASSERT(!sym->isForwarded());
|
||||
return sym;
|
||||
}
|
||||
bool MovingTracer::onJitCodeEdge(jit::JitCode** jitp) {
|
||||
MOZ_ASSERT(!(*jitp)->isForwarded());
|
||||
return true;
|
||||
jit::JitCode* MovingTracer::onJitCodeEdge(jit::JitCode* jit) {
|
||||
MOZ_ASSERT(!jit->isForwarded());
|
||||
return jit;
|
||||
}
|
||||
|
||||
void Zone::prepareForCompacting() {
|
||||
|
@ -8903,48 +8902,53 @@ js::gc::ClearEdgesTracer::ClearEdgesTracer()
|
|||
: ClearEdgesTracer(TlsContext.get()->runtime()) {}
|
||||
|
||||
template <typename S>
|
||||
inline bool js::gc::ClearEdgesTracer::clearEdge(S** thingp) {
|
||||
inline S* js::gc::ClearEdgesTracer::onEdge(S* thing) {
|
||||
// We don't handle removing pointers to nursery edges from the store buffer
|
||||
// with this tracer.
|
||||
MOZ_ASSERT(!IsInsideNursery(*thingp));
|
||||
// with this tracer. Check that this doesn't happen.
|
||||
MOZ_ASSERT(!IsInsideNursery(thing));
|
||||
|
||||
InternalBarrierMethods<S*>::preBarrier(*thingp);
|
||||
*thingp = nullptr;
|
||||
return false;
|
||||
// Fire the pre-barrier since we're removing an edge from the graph.
|
||||
InternalBarrierMethods<S*>::preBarrier(thing);
|
||||
|
||||
// Return nullptr to clear the edge.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool js::gc::ClearEdgesTracer::onObjectEdge(JSObject** objp) {
|
||||
return clearEdge(objp);
|
||||
JSObject* js::gc::ClearEdgesTracer::onObjectEdge(JSObject* obj) {
|
||||
return onEdge(obj);
|
||||
}
|
||||
bool js::gc::ClearEdgesTracer::onStringEdge(JSString** strp) {
|
||||
return clearEdge(strp);
|
||||
JSString* js::gc::ClearEdgesTracer::onStringEdge(JSString* str) {
|
||||
return onEdge(str);
|
||||
}
|
||||
bool js::gc::ClearEdgesTracer::onSymbolEdge(JS::Symbol** symp) {
|
||||
return clearEdge(symp);
|
||||
JS::Symbol* js::gc::ClearEdgesTracer::onSymbolEdge(JS::Symbol* sym) {
|
||||
return onEdge(sym);
|
||||
}
|
||||
bool js::gc::ClearEdgesTracer::onBigIntEdge(JS::BigInt** bip) {
|
||||
return clearEdge(bip);
|
||||
JS::BigInt* js::gc::ClearEdgesTracer::onBigIntEdge(JS::BigInt* bi) {
|
||||
return onEdge(bi);
|
||||
}
|
||||
bool js::gc::ClearEdgesTracer::onScriptEdge(js::BaseScript** scriptp) {
|
||||
return clearEdge(scriptp);
|
||||
js::BaseScript* js::gc::ClearEdgesTracer::onScriptEdge(js::BaseScript* script) {
|
||||
return onEdge(script);
|
||||
}
|
||||
bool js::gc::ClearEdgesTracer::onShapeEdge(js::Shape** shapep) {
|
||||
return clearEdge(shapep);
|
||||
js::Shape* js::gc::ClearEdgesTracer::onShapeEdge(js::Shape* shape) {
|
||||
return onEdge(shape);
|
||||
}
|
||||
bool js::gc::ClearEdgesTracer::onObjectGroupEdge(js::ObjectGroup** groupp) {
|
||||
return clearEdge(groupp);
|
||||
js::ObjectGroup* js::gc::ClearEdgesTracer::onObjectGroupEdge(
|
||||
js::ObjectGroup* group) {
|
||||
return onEdge(group);
|
||||
}
|
||||
bool js::gc::ClearEdgesTracer::onBaseShapeEdge(js::BaseShape** basep) {
|
||||
return clearEdge(basep);
|
||||
js::BaseShape* js::gc::ClearEdgesTracer::onBaseShapeEdge(js::BaseShape* base) {
|
||||
return onEdge(base);
|
||||
}
|
||||
bool js::gc::ClearEdgesTracer::onJitCodeEdge(js::jit::JitCode** codep) {
|
||||
return clearEdge(codep);
|
||||
js::jit::JitCode* js::gc::ClearEdgesTracer::onJitCodeEdge(
|
||||
js::jit::JitCode* code) {
|
||||
return onEdge(code);
|
||||
}
|
||||
bool js::gc::ClearEdgesTracer::onScopeEdge(js::Scope** scopep) {
|
||||
return clearEdge(scopep);
|
||||
js::Scope* js::gc::ClearEdgesTracer::onScopeEdge(js::Scope* scope) {
|
||||
return onEdge(scope);
|
||||
}
|
||||
bool js::gc::ClearEdgesTracer::onRegExpSharedEdge(js::RegExpShared** sharedp) {
|
||||
return clearEdge(sharedp);
|
||||
js::RegExpShared* js::gc::ClearEdgesTracer::onRegExpSharedEdge(
|
||||
js::RegExpShared* shared) {
|
||||
return onEdge(shared);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API void js::gc::FinalizeDeadNurseryObject(JSContext* cx,
|
||||
|
|
|
@ -223,21 +223,21 @@ struct MovingTracer final : public GenericTracer {
|
|||
: GenericTracer(rt, JS::TracerKind::Moving,
|
||||
JS::WeakMapTraceAction::TraceKeysAndValues) {}
|
||||
|
||||
bool onObjectEdge(JSObject** objp) override;
|
||||
bool onShapeEdge(Shape** shapep) override;
|
||||
bool onStringEdge(JSString** stringp) override;
|
||||
bool onScriptEdge(js::BaseScript** scriptp) override;
|
||||
bool onBaseShapeEdge(BaseShape** basep) override;
|
||||
bool onScopeEdge(Scope** scopep) override;
|
||||
bool onRegExpSharedEdge(RegExpShared** sharedp) override;
|
||||
bool onBigIntEdge(BigInt** bip) override;
|
||||
bool onObjectGroupEdge(ObjectGroup** groupp) override;
|
||||
bool onSymbolEdge(JS::Symbol** symp) override;
|
||||
bool onJitCodeEdge(jit::JitCode** jitp) override;
|
||||
JSObject* onObjectEdge(JSObject* obj) override;
|
||||
Shape* onShapeEdge(Shape* shape) override;
|
||||
JSString* onStringEdge(JSString* string) override;
|
||||
js::BaseScript* onScriptEdge(js::BaseScript* script) override;
|
||||
BaseShape* onBaseShapeEdge(BaseShape* base) override;
|
||||
Scope* onScopeEdge(Scope* scope) override;
|
||||
RegExpShared* onRegExpSharedEdge(RegExpShared* shared) override;
|
||||
BigInt* onBigIntEdge(BigInt* bi) override;
|
||||
ObjectGroup* onObjectGroupEdge(ObjectGroup* group) override;
|
||||
JS::Symbol* onSymbolEdge(JS::Symbol* sym) override;
|
||||
jit::JitCode* onJitCodeEdge(jit::JitCode* jit) override;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
bool updateEdge(T** thingp);
|
||||
T* onEdge(T* thingp);
|
||||
};
|
||||
|
||||
struct SweepingTracer final : public GenericTracer {
|
||||
|
@ -245,21 +245,21 @@ struct SweepingTracer final : public GenericTracer {
|
|||
: GenericTracer(rt, JS::TracerKind::Sweeping,
|
||||
JS::WeakMapTraceAction::TraceKeysAndValues) {}
|
||||
|
||||
bool onObjectEdge(JSObject** objp) override;
|
||||
bool onShapeEdge(Shape** shapep) override;
|
||||
bool onStringEdge(JSString** stringp) override;
|
||||
bool onScriptEdge(js::BaseScript** scriptp) override;
|
||||
bool onBaseShapeEdge(BaseShape** basep) override;
|
||||
bool onJitCodeEdge(jit::JitCode** jitp) override;
|
||||
bool onScopeEdge(Scope** scopep) override;
|
||||
bool onRegExpSharedEdge(RegExpShared** sharedp) override;
|
||||
bool onBigIntEdge(BigInt** bip) override;
|
||||
bool onObjectGroupEdge(js::ObjectGroup** groupp) override;
|
||||
bool onSymbolEdge(JS::Symbol** symp) override;
|
||||
JSObject* onObjectEdge(JSObject* obj) override;
|
||||
Shape* onShapeEdge(Shape* shape) override;
|
||||
JSString* onStringEdge(JSString* string) override;
|
||||
js::BaseScript* onScriptEdge(js::BaseScript* script) override;
|
||||
BaseShape* onBaseShapeEdge(BaseShape* base) override;
|
||||
jit::JitCode* onJitCodeEdge(jit::JitCode* jit) override;
|
||||
Scope* onScopeEdge(Scope* scope) override;
|
||||
RegExpShared* onRegExpSharedEdge(RegExpShared* shared) override;
|
||||
BigInt* onBigIntEdge(BigInt* bi) override;
|
||||
js::ObjectGroup* onObjectGroupEdge(js::ObjectGroup* group) override;
|
||||
JS::Symbol* onSymbolEdge(JS::Symbol* sym) override;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
bool sweepEdge(T** thingp);
|
||||
T* onEdge(T* thingp);
|
||||
};
|
||||
|
||||
// Structure for counting how many times objects in a particular group have
|
||||
|
|
|
@ -3774,19 +3774,17 @@ size_t js::TenuringTracer::moveBigIntToTenured(JS::BigInt* dst, JS::BigInt* src,
|
|||
/*** IsMarked / IsAboutToBeFinalized ****************************************/
|
||||
|
||||
template <typename T>
|
||||
static inline void CheckIsMarkedThing(T* thingp) {
|
||||
#define IS_SAME_TYPE_OR(name, type, _, _1) std::is_same_v<type*, T> ||
|
||||
static inline void CheckIsMarkedThing(T* thing) {
|
||||
#define IS_SAME_TYPE_OR(name, type, _, _1) std::is_same_v<type, T> ||
|
||||
static_assert(JS_FOR_EACH_TRACEKIND(IS_SAME_TYPE_OR) false,
|
||||
"Only the base cell layout types are allowed into "
|
||||
"marking/tracing internals");
|
||||
#undef IS_SAME_TYPE_OR
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(thingp);
|
||||
MOZ_ASSERT(*thingp);
|
||||
MOZ_ASSERT(thing);
|
||||
|
||||
// Allow any thread access to uncollected things.
|
||||
T thing = *thingp;
|
||||
if (thing->isPermanentAndMayBeShared()) {
|
||||
return;
|
||||
}
|
||||
|
@ -3812,7 +3810,8 @@ static inline void CheckIsMarkedThing(T* thingp) {
|
|||
|
||||
template <typename T>
|
||||
static inline bool ShouldCheckMarkState(JSRuntime* rt, T** thingp) {
|
||||
CheckIsMarkedThing(thingp);
|
||||
MOZ_ASSERT(thingp);
|
||||
CheckIsMarkedThing(*thingp);
|
||||
MOZ_ASSERT(!IsInsideNursery(*thingp));
|
||||
|
||||
TenuredCell& thing = (*thingp)->asTenured();
|
||||
|
@ -3863,8 +3862,9 @@ bool js::gc::IsAboutToBeFinalizedInternal(T** thingp) {
|
|||
// Don't depend on the mark state of other cells during finalization.
|
||||
MOZ_ASSERT(!CurrentThreadIsGCFinalizing());
|
||||
|
||||
CheckIsMarkedThing(thingp);
|
||||
MOZ_ASSERT(thingp);
|
||||
T* thing = *thingp;
|
||||
CheckIsMarkedThing(thing);
|
||||
JSRuntime* rt = thing->runtimeFromAnyThread();
|
||||
|
||||
/* Permanent atoms are never finalized by non-owning runtimes. */
|
||||
|
@ -3904,13 +3904,13 @@ bool js::gc::IsAboutToBeFinalizedInternal(T* thingp) {
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool SweepingTracer::sweepEdge(T** thingp) {
|
||||
CheckIsMarkedThing(thingp);
|
||||
T* thing = *thingp;
|
||||
inline T* SweepingTracer::onEdge(T* thing) {
|
||||
CheckIsMarkedThing(thing);
|
||||
|
||||
JSRuntime* rt = thing->runtimeFromAnyThread();
|
||||
|
||||
if (thing->isPermanentAndMayBeShared() && runtime() != rt) {
|
||||
return true;
|
||||
return thing;
|
||||
}
|
||||
|
||||
// TODO: We should assert the zone of the tenured cell is in Sweeping state,
|
||||
|
@ -3919,36 +3919,37 @@ inline bool SweepingTracer::sweepEdge(T** thingp) {
|
|||
// Bug 1071218 : Refactor Debugger::sweepAll and
|
||||
// JitRuntime::SweepJitcodeGlobalTable to work per sweep group
|
||||
if (!thing->isMarkedAny()) {
|
||||
*thingp = nullptr;
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
return thing;
|
||||
}
|
||||
|
||||
bool SweepingTracer::onObjectEdge(JSObject** objp) { return sweepEdge(objp); }
|
||||
bool SweepingTracer::onShapeEdge(Shape** shapep) { return sweepEdge(shapep); }
|
||||
bool SweepingTracer::onStringEdge(JSString** stringp) {
|
||||
return sweepEdge(stringp);
|
||||
JSObject* SweepingTracer::onObjectEdge(JSObject* obj) { return onEdge(obj); }
|
||||
Shape* SweepingTracer::onShapeEdge(Shape* shape) { return onEdge(shape); }
|
||||
JSString* SweepingTracer::onStringEdge(JSString* string) {
|
||||
return onEdge(string);
|
||||
}
|
||||
bool SweepingTracer::onScriptEdge(js::BaseScript** scriptp) {
|
||||
return sweepEdge(scriptp);
|
||||
js::BaseScript* SweepingTracer::onScriptEdge(js::BaseScript* script) {
|
||||
return onEdge(script);
|
||||
}
|
||||
bool SweepingTracer::onBaseShapeEdge(BaseShape** basep) {
|
||||
return sweepEdge(basep);
|
||||
BaseShape* SweepingTracer::onBaseShapeEdge(BaseShape* base) {
|
||||
return onEdge(base);
|
||||
}
|
||||
bool SweepingTracer::onJitCodeEdge(jit::JitCode** jitp) {
|
||||
return sweepEdge(jitp);
|
||||
jit::JitCode* SweepingTracer::onJitCodeEdge(jit::JitCode* jit) {
|
||||
return onEdge(jit);
|
||||
}
|
||||
bool SweepingTracer::onScopeEdge(Scope** scopep) { return sweepEdge(scopep); }
|
||||
bool SweepingTracer::onRegExpSharedEdge(RegExpShared** sharedp) {
|
||||
return sweepEdge(sharedp);
|
||||
Scope* SweepingTracer::onScopeEdge(Scope* scope) { return onEdge(scope); }
|
||||
RegExpShared* SweepingTracer::onRegExpSharedEdge(RegExpShared* shared) {
|
||||
return onEdge(shared);
|
||||
}
|
||||
bool SweepingTracer::onObjectGroupEdge(ObjectGroup** groupp) {
|
||||
return sweepEdge(groupp);
|
||||
ObjectGroup* SweepingTracer::onObjectGroupEdge(ObjectGroup* group) {
|
||||
return onEdge(group);
|
||||
}
|
||||
BigInt* SweepingTracer::onBigIntEdge(BigInt* bi) { return onEdge(bi); }
|
||||
JS::Symbol* SweepingTracer::onSymbolEdge(JS::Symbol* sym) {
|
||||
return onEdge(sym);
|
||||
}
|
||||
bool SweepingTracer::onBigIntEdge(BigInt** bip) { return sweepEdge(bip); }
|
||||
bool SweepingTracer::onSymbolEdge(JS::Symbol** symp) { return sweepEdge(symp); }
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
|
|
@ -496,37 +496,47 @@ class BufferGrayRootsTracer final : public GenericTracer {
|
|||
// Set to false if we OOM while buffering gray roots.
|
||||
bool bufferingGrayRootsFailed;
|
||||
|
||||
bool onObjectEdge(JSObject** objp) override { return bufferRoot(*objp); }
|
||||
bool onStringEdge(JSString** stringp) override {
|
||||
return bufferRoot(*stringp);
|
||||
JSObject* onObjectEdge(JSObject* obj) override { return bufferRoot(obj); }
|
||||
JSString* onStringEdge(JSString* string) override {
|
||||
return bufferRoot(string);
|
||||
}
|
||||
bool onScriptEdge(js::BaseScript** scriptp) override {
|
||||
return bufferRoot(*scriptp);
|
||||
js::BaseScript* onScriptEdge(js::BaseScript* script) override {
|
||||
return bufferRoot(script);
|
||||
}
|
||||
bool onSymbolEdge(JS::Symbol** symbolp) override {
|
||||
return bufferRoot(*symbolp);
|
||||
JS::Symbol* onSymbolEdge(JS::Symbol* symbol) override {
|
||||
return bufferRoot(symbol);
|
||||
}
|
||||
bool onBigIntEdge(JS::BigInt** bip) override { return bufferRoot(*bip); }
|
||||
JS::BigInt* onBigIntEdge(JS::BigInt* bi) override { return bufferRoot(bi); }
|
||||
|
||||
bool onShapeEdge(js::Shape** shapep) override { return unsupportedEdge(); }
|
||||
bool onObjectGroupEdge(js::ObjectGroup** groupp) override {
|
||||
return unsupportedEdge();
|
||||
js::Shape* onShapeEdge(js::Shape* shape) override {
|
||||
unsupportedEdge();
|
||||
return nullptr;
|
||||
}
|
||||
bool onBaseShapeEdge(js::BaseShape** basep) override {
|
||||
return unsupportedEdge();
|
||||
js::ObjectGroup* onObjectGroupEdge(js::ObjectGroup* group) override {
|
||||
unsupportedEdge();
|
||||
return nullptr;
|
||||
}
|
||||
bool onJitCodeEdge(js::jit::JitCode** codep) override {
|
||||
return unsupportedEdge();
|
||||
js::BaseShape* onBaseShapeEdge(js::BaseShape* base) override {
|
||||
unsupportedEdge();
|
||||
return nullptr;
|
||||
}
|
||||
bool onScopeEdge(js::Scope** scopep) override { return unsupportedEdge(); }
|
||||
bool onRegExpSharedEdge(js::RegExpShared** sharedp) override {
|
||||
return unsupportedEdge();
|
||||
js::jit::JitCode* onJitCodeEdge(js::jit::JitCode* code) override {
|
||||
unsupportedEdge();
|
||||
return nullptr;
|
||||
}
|
||||
js::Scope* onScopeEdge(js::Scope* scope) override {
|
||||
unsupportedEdge();
|
||||
return nullptr;
|
||||
}
|
||||
js::RegExpShared* onRegExpSharedEdge(js::RegExpShared* shared) override {
|
||||
unsupportedEdge();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool unsupportedEdge() { MOZ_CRASH("Unsupported gray root edge kind"); }
|
||||
void unsupportedEdge() { MOZ_CRASH("Unsupported gray root edge kind"); }
|
||||
|
||||
template <typename T>
|
||||
inline bool bufferRoot(T* thing);
|
||||
inline T* bufferRoot(T* thing);
|
||||
|
||||
public:
|
||||
explicit BufferGrayRootsTracer(JSRuntime* rt)
|
||||
|
@ -560,7 +570,7 @@ void js::gc::GCRuntime::bufferGrayRoots() {
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool BufferGrayRootsTracer::bufferRoot(T* thing) {
|
||||
inline T* BufferGrayRootsTracer::bufferRoot(T* thing) {
|
||||
MOZ_ASSERT(JS::RuntimeHeapIsBusy());
|
||||
MOZ_ASSERT(thing);
|
||||
// Check if |thing| is corrupt by calling a method that touches the heap.
|
||||
|
@ -583,7 +593,7 @@ inline bool BufferGrayRootsTracer::bufferRoot(T* thing) {
|
|||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return thing;
|
||||
}
|
||||
|
||||
void GCRuntime::markBufferedGrayRoots(JS::Zone* zone) {
|
||||
|
|
|
@ -38,42 +38,46 @@ void CheckTracedThing(JSTracer* trc, T thing);
|
|||
|
||||
/*** Callback Tracer Dispatch ***********************************************/
|
||||
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc, JSObject** objp) {
|
||||
return trc->onObjectEdge(objp);
|
||||
static inline JSObject* DispatchToOnEdge(GenericTracer* trc, JSObject* obj) {
|
||||
return trc->onObjectEdge(obj);
|
||||
}
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc, JSString** strp) {
|
||||
return trc->onStringEdge(strp);
|
||||
static inline JSString* DispatchToOnEdge(GenericTracer* trc, JSString* str) {
|
||||
return trc->onStringEdge(str);
|
||||
}
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc, JS::Symbol** symp) {
|
||||
return trc->onSymbolEdge(symp);
|
||||
static inline JS::Symbol* DispatchToOnEdge(GenericTracer* trc,
|
||||
JS::Symbol* sym) {
|
||||
return trc->onSymbolEdge(sym);
|
||||
}
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc, JS::BigInt** bip) {
|
||||
return trc->onBigIntEdge(bip);
|
||||
static inline JS::BigInt* DispatchToOnEdge(GenericTracer* trc, JS::BigInt* bi) {
|
||||
return trc->onBigIntEdge(bi);
|
||||
}
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc,
|
||||
js::BaseScript** scriptp) {
|
||||
return trc->onScriptEdge(scriptp);
|
||||
static inline js::BaseScript* DispatchToOnEdge(GenericTracer* trc,
|
||||
js::BaseScript* script) {
|
||||
return trc->onScriptEdge(script);
|
||||
}
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc, js::Shape** shapep) {
|
||||
return trc->onShapeEdge(shapep);
|
||||
static inline js::Shape* DispatchToOnEdge(GenericTracer* trc,
|
||||
js::Shape* shape) {
|
||||
return trc->onShapeEdge(shape);
|
||||
}
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc,
|
||||
js::ObjectGroup** groupp) {
|
||||
return trc->onObjectGroupEdge(groupp);
|
||||
static inline js::ObjectGroup* DispatchToOnEdge(GenericTracer* trc,
|
||||
js::ObjectGroup* group) {
|
||||
return trc->onObjectGroupEdge(group);
|
||||
}
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc, js::BaseShape** basep) {
|
||||
return trc->onBaseShapeEdge(basep);
|
||||
static inline js::BaseShape* DispatchToOnEdge(GenericTracer* trc,
|
||||
js::BaseShape* base) {
|
||||
return trc->onBaseShapeEdge(base);
|
||||
}
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc,
|
||||
js::jit::JitCode** codep) {
|
||||
return trc->onJitCodeEdge(codep);
|
||||
static inline js::jit::JitCode* DispatchToOnEdge(GenericTracer* trc,
|
||||
js::jit::JitCode* code) {
|
||||
return trc->onJitCodeEdge(code);
|
||||
}
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc, js::Scope** scopep) {
|
||||
return trc->onScopeEdge(scopep);
|
||||
static inline js::Scope* DispatchToOnEdge(GenericTracer* trc,
|
||||
js::Scope* scope) {
|
||||
return trc->onScopeEdge(scope);
|
||||
}
|
||||
static inline bool DispatchToOnEdge(GenericTracer* trc,
|
||||
js::RegExpShared** sharedp) {
|
||||
return trc->onRegExpSharedEdge(sharedp);
|
||||
static inline js::RegExpShared* DispatchToOnEdge(GenericTracer* trc,
|
||||
js::RegExpShared* shared) {
|
||||
return trc->onRegExpSharedEdge(shared);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -81,7 +85,13 @@ bool DoCallback(GenericTracer* trc, T** thingp, const char* name) {
|
|||
CheckTracedThing(trc, *thingp);
|
||||
JS::AutoTracingName ctx(trc, name);
|
||||
|
||||
return DispatchToOnEdge(trc, thingp);
|
||||
T* thing = *thingp;
|
||||
T* post = DispatchToOnEdge(trc, thing);
|
||||
if (post != thing) {
|
||||
*thingp = post;
|
||||
}
|
||||
|
||||
return post;
|
||||
}
|
||||
#define INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS(name, type, _, _1) \
|
||||
template bool DoCallback<type>(GenericTracer*, type**, const char*);
|
||||
|
@ -90,21 +100,29 @@ JS_FOR_EACH_TRACEKIND(INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS);
|
|||
|
||||
template <typename T>
|
||||
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, name, &ret](auto t) {
|
||||
if (!DoCallback(trc, &t, name)) {
|
||||
auto thing = MapGCThingTyped(*thingp, [trc, &ret](auto thing) {
|
||||
CheckTracedThing(trc, thing);
|
||||
|
||||
auto* post = DispatchToOnEdge(trc, thing);
|
||||
if (!post) {
|
||||
ret = false;
|
||||
return TaggedPtr<T>::empty();
|
||||
}
|
||||
return TaggedPtr<T>::wrap(t);
|
||||
|
||||
return TaggedPtr<T>::wrap(post);
|
||||
});
|
||||
|
||||
// Only update *thingp if the value changed, to avoid TSan false positives for
|
||||
// template objects when using DumpHeapTracer or UbiNode tracers while Ion
|
||||
// compiling off-thread.
|
||||
if (thing.isSome() && thing.value() != *thingp) {
|
||||
*thingp = thing.value();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
template bool DoCallback<JS::Value>(GenericTracer*, JS::Value*, const char*);
|
||||
|
|
Загрузка…
Ссылка в новой задаче