зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1135985 - Split callback and marking tracers completely; r=jonco, r=mccr8
--HG-- extra : rebase_source : b2e435ebf64ec0bac42af7a8f0968578599fd67b
This commit is contained in:
Родитель
1ef53522bf
Коммит
dd4ddb761b
|
@ -2299,7 +2299,7 @@ IsInCertifiedApp(JSContext* aCx, JSObject* aObj)
|
|||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
VerifyTraceProtoAndIfaceCacheCalled(JSTracer *trc, void **thingp,
|
||||
VerifyTraceProtoAndIfaceCacheCalled(JS::CallbackTracer *trc, void **thingp,
|
||||
JSGCTraceKind kind)
|
||||
{
|
||||
// We don't do anything here, we only want to verify that
|
||||
|
|
|
@ -526,15 +526,15 @@ AllocateProtoAndIfaceCache(JSObject* obj, ProtoAndIfaceCache::Kind aKind)
|
|||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
VerifyTraceProtoAndIfaceCacheCalled(JSTracer *trc, void **thingp,
|
||||
VerifyTraceProtoAndIfaceCacheCalled(JS::CallbackTracer *trc, void **thingp,
|
||||
JSGCTraceKind kind);
|
||||
|
||||
struct VerifyTraceProtoAndIfaceCacheCalledTracer : public JSTracer
|
||||
struct VerifyTraceProtoAndIfaceCacheCalledTracer : public JS::CallbackTracer
|
||||
{
|
||||
bool ok;
|
||||
|
||||
explicit VerifyTraceProtoAndIfaceCacheCalledTracer(JSRuntime *rt)
|
||||
: JSTracer(rt, VerifyTraceProtoAndIfaceCacheCalled), ok(false)
|
||||
: JS::CallbackTracer(rt, VerifyTraceProtoAndIfaceCacheCalled), ok(false)
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
|
@ -545,7 +545,9 @@ TraceProtoAndIfaceCache(JSTracer* trc, JSObject* obj)
|
|||
MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (trc->callback == VerifyTraceProtoAndIfaceCacheCalled) {
|
||||
if (trc->isCallbackTracer() &&
|
||||
trc->asCallbackTracer()->hasCallback(
|
||||
VerifyTraceProtoAndIfaceCacheCalled)) {
|
||||
// We don't do anything here, we only want to verify that
|
||||
// TraceProtoAndIfaceCache was called.
|
||||
static_cast<VerifyTraceProtoAndIfaceCacheCalledTracer*>(trc)->ok = true;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
class JS_PUBLIC_API(JSTracer);
|
||||
|
||||
namespace JS {
|
||||
class JS_PUBLIC_API(CallbackTracer);
|
||||
template <typename T> class Heap;
|
||||
template <typename T> class TenuredHeap;
|
||||
}
|
||||
|
@ -77,7 +78,7 @@ GCTraceKindToAscii(JSGCTraceKind kind);
|
|||
// of its mappings. This should be used in cases where the tracer
|
||||
// wants to use the existing liveness of entries.
|
||||
typedef void
|
||||
(* JSTraceCallback)(JSTracer *trc, void **thingp, JSGCTraceKind kind);
|
||||
(* JSTraceCallback)(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind);
|
||||
|
||||
// Callback that JSTraceOp implementation can provide to return a string
|
||||
// describing the reference traced with JS_CallTracer.
|
||||
|
@ -93,9 +94,6 @@ enum WeakMapTraceKind {
|
|||
class JS_PUBLIC_API(JSTracer)
|
||||
{
|
||||
public:
|
||||
JSTracer(JSRuntime *rt, JSTraceCallback traceCallback,
|
||||
WeakMapTraceKind weakTraceKind = TraceWeakMapValues);
|
||||
|
||||
// Set debugging information about a reference to a traceable thing to prepare
|
||||
// for the following call to JS_CallTracer.
|
||||
//
|
||||
|
@ -152,9 +150,6 @@ class JS_PUBLIC_API(JSTracer)
|
|||
// Return the weak map tracing behavior set on this tracer.
|
||||
WeakMapTraceKind eagerlyTraceWeakMaps() const { return eagerlyTraceWeakMaps_; }
|
||||
|
||||
// Update the trace callback.
|
||||
void setTraceCallback(JSTraceCallback traceCallback);
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
// Sets the "real" location for a marked reference, when passing the address
|
||||
// directly is not feasable. This address is used for matching against the
|
||||
|
@ -171,12 +166,22 @@ class JS_PUBLIC_API(JSTracer)
|
|||
void **tracingLocation(void **thingp) { return nullptr; }
|
||||
#endif
|
||||
|
||||
// We expose |callback| directly so that IS_GC_MARKING_TRACER can compare
|
||||
// it to GCMarker::GrayCallback.
|
||||
JSTraceCallback callback;
|
||||
// An intermediate state on the road from C to C++ style dispatch.
|
||||
enum TracerKindTag {
|
||||
MarkingTracer,
|
||||
CallbackTracer
|
||||
};
|
||||
bool isMarkingTracer() const { return tag == MarkingTracer; }
|
||||
bool isCallbackTracer() const { return tag == CallbackTracer; }
|
||||
inline JS::CallbackTracer *asCallbackTracer();
|
||||
|
||||
protected:
|
||||
JSTracer(JSRuntime *rt, TracerKindTag tag,
|
||||
WeakMapTraceKind weakTraceKind = TraceWeakMapValues);
|
||||
|
||||
private:
|
||||
JSRuntime *runtime_;
|
||||
TracerKindTag tag;
|
||||
JSTraceNamePrinter debugPrinter_;
|
||||
const void *debugPrintArg_;
|
||||
size_t debugPrintIndex_;
|
||||
|
@ -186,6 +191,44 @@ class JS_PUBLIC_API(JSTracer)
|
|||
#endif
|
||||
};
|
||||
|
||||
namespace JS {
|
||||
|
||||
class JS_PUBLIC_API(CallbackTracer) : public JSTracer
|
||||
{
|
||||
public:
|
||||
CallbackTracer(JSRuntime *rt, JSTraceCallback traceCallback,
|
||||
WeakMapTraceKind weakTraceKind = TraceWeakMapValues)
|
||||
: JSTracer(rt, JSTracer::CallbackTracer, weakTraceKind), callback(traceCallback)
|
||||
{}
|
||||
|
||||
// Update the trace callback.
|
||||
void setTraceCallback(JSTraceCallback traceCallback);
|
||||
|
||||
// Test if the given callback is the same as our callback.
|
||||
bool hasCallback(JSTraceCallback maybeCallback) const {
|
||||
return maybeCallback == callback;
|
||||
}
|
||||
|
||||
// Call the callback.
|
||||
void invoke(void **thing, JSGCTraceKind kind) {
|
||||
callback(this, thing, kind);
|
||||
}
|
||||
|
||||
private:
|
||||
// Exposed publicly for several callers that need to check if the tracer
|
||||
// calling them is of the right type.
|
||||
JSTraceCallback callback;
|
||||
};
|
||||
|
||||
} // namespace JS
|
||||
|
||||
JS::CallbackTracer *
|
||||
JSTracer::asCallbackTracer()
|
||||
{
|
||||
MOZ_ASSERT(isCallbackTracer());
|
||||
return static_cast<JS::CallbackTracer *>(this);
|
||||
}
|
||||
|
||||
// The JS_Call*Tracer family of functions traces the given GC thing reference.
|
||||
// This performs the tracing action configured on the given JSTracer:
|
||||
// typically calling the JSTracer::callback or marking the thing as live.
|
||||
|
|
|
@ -782,12 +782,11 @@ struct JSCountHeapNode {
|
|||
|
||||
typedef HashSet<void *, PointerHasher<void *, 3>, SystemAllocPolicy> VisitedSet;
|
||||
|
||||
class CountHeapTracer
|
||||
class CountHeapTracer : public JS::CallbackTracer
|
||||
{
|
||||
public:
|
||||
CountHeapTracer(JSRuntime *rt, JSTraceCallback callback) : base(rt, callback) {}
|
||||
CountHeapTracer(JSRuntime *rt, JSTraceCallback callback) : CallbackTracer(rt, callback) {}
|
||||
|
||||
JSTracer base;
|
||||
VisitedSet visited;
|
||||
JSCountHeapNode *traceList;
|
||||
JSCountHeapNode *recycleList;
|
||||
|
@ -795,10 +794,8 @@ class CountHeapTracer
|
|||
};
|
||||
|
||||
static void
|
||||
CountHeapNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
CountHeapNotify(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
MOZ_ASSERT(trc->callback == CountHeapNotify);
|
||||
|
||||
CountHeapTracer *countTracer = (CountHeapTracer *)trc;
|
||||
void *thing = *thingp;
|
||||
|
||||
|
@ -906,9 +903,9 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp)
|
|||
countTracer.recycleList = nullptr;
|
||||
|
||||
if (startValue.isUndefined()) {
|
||||
JS_TraceRuntime(&countTracer.base);
|
||||
JS_TraceRuntime(&countTracer);
|
||||
} else {
|
||||
JS_CallUnbarrieredValueTracer(&countTracer.base, startValue.address(), "root");
|
||||
JS_CallUnbarrieredValueTracer(&countTracer, startValue.address(), "root");
|
||||
}
|
||||
|
||||
JSCountHeapNode *node;
|
||||
|
@ -926,7 +923,7 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp)
|
|||
countTracer.traceList = node->next;
|
||||
node->next = countTracer.recycleList;
|
||||
countTracer.recycleList = node;
|
||||
JS_TraceChildren(&countTracer.base, node->thing, node->kind);
|
||||
JS_TraceChildren(&countTracer, node->thing, node->kind);
|
||||
}
|
||||
while ((node = countTracer.recycleList) != nullptr) {
|
||||
countTracer.recycleList = node->next;
|
||||
|
|
|
@ -57,7 +57,7 @@ function indirectCallCannotGC(fullCaller, fullVariable)
|
|||
|
||||
// Ignore calls through functions pointers with these types
|
||||
var ignoreClasses = {
|
||||
"JSTracer" : true,
|
||||
"JS::CallbackTracer" : true,
|
||||
"JSStringFinalizer" : true,
|
||||
"SprintfState" : true,
|
||||
"SprintfStateStr" : true,
|
||||
|
|
|
@ -140,12 +140,12 @@ void
|
|||
CheckHashTablesAfterMovingGC(JSRuntime *rt);
|
||||
#endif
|
||||
|
||||
struct MovingTracer : JSTracer {
|
||||
explicit MovingTracer(JSRuntime *rt) : JSTracer(rt, Visit, TraceWeakMapKeysValues) {}
|
||||
struct MovingTracer : JS::CallbackTracer {
|
||||
explicit MovingTracer(JSRuntime *rt) : CallbackTracer(rt, Visit, TraceWeakMapKeysValues) {}
|
||||
|
||||
static void Visit(JSTracer *jstrc, void **thingp, JSGCTraceKind kind);
|
||||
static void Visit(JS::CallbackTracer *jstrc, void **thingp, JSGCTraceKind kind);
|
||||
static bool IsMovingTracer(JSTracer *trc) {
|
||||
return trc->callback == Visit;
|
||||
return trc->isCallbackTracer() && trc->asCallbackTracer()->hasCallback(Visit);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ using namespace js::gc;
|
|||
void
|
||||
js::TraceRuntime(JSTracer *trc)
|
||||
{
|
||||
MOZ_ASSERT(!IsMarkingTracer(trc));
|
||||
MOZ_ASSERT(!trc->isMarkingTracer());
|
||||
|
||||
JSRuntime *rt = trc->runtime();
|
||||
rt->gc.evictNursery();
|
||||
|
|
|
@ -143,7 +143,7 @@ IsThingPoisoned(T *thing)
|
|||
static GCMarker *
|
||||
AsGCMarker(JSTracer *trc)
|
||||
{
|
||||
MOZ_ASSERT(IsMarkingTracer(trc));
|
||||
MOZ_ASSERT(trc->isMarkingTracer());
|
||||
return static_cast<GCMarker *>(trc);
|
||||
}
|
||||
|
||||
|
@ -198,7 +198,7 @@ CheckMarkedThing(JSTracer *trc, T **thingp)
|
|||
* Do not check IsMarkingTracer directly -- it should only be used in paths
|
||||
* where we cannot be the gray buffering tracer.
|
||||
*/
|
||||
bool isGcMarkingTracer = (trc->callback == nullptr);
|
||||
bool isGcMarkingTracer = trc->isMarkingTracer();
|
||||
|
||||
MOZ_ASSERT_IF(zone->requireGCTracer(), isGcMarkingTracer || IsBufferingGrayRoots(trc));
|
||||
|
||||
|
@ -267,7 +267,7 @@ MarkInternal(JSTracer *trc, T **thingp)
|
|||
CheckMarkedThing(trc, thingp);
|
||||
T *thing = *thingp;
|
||||
|
||||
if (!trc->callback) {
|
||||
if (trc->isMarkingTracer()) {
|
||||
/*
|
||||
* We may mark a Nursery thing outside the context of the
|
||||
* MinorCollectionTracer because of a pre-barrier. The pre-barrier is
|
||||
|
@ -295,7 +295,7 @@ MarkInternal(JSTracer *trc, T **thingp)
|
|||
PushMarkStack(AsGCMarker(trc), thing);
|
||||
SetMaybeAliveFlag(thing);
|
||||
} else {
|
||||
trc->callback(trc, (void **)thingp, MapTypeToTraceKind<T>::kind);
|
||||
trc->asCallbackTracer()->invoke((void **)thingp, MapTypeToTraceKind<T>::kind);
|
||||
trc->unsetTracingLocation();
|
||||
}
|
||||
|
||||
|
@ -303,7 +303,7 @@ MarkInternal(JSTracer *trc, T **thingp)
|
|||
}
|
||||
|
||||
#define JS_ROOT_MARKING_ASSERT(trc) \
|
||||
MOZ_ASSERT_IF(IsMarkingTracer(trc), \
|
||||
MOZ_ASSERT_IF(trc->isMarkingTracer(), \
|
||||
trc->runtime()->gc.state() == NO_INCREMENTAL || \
|
||||
trc->runtime()->gc.state() == MARK_ROOTS);
|
||||
|
||||
|
@ -335,13 +335,13 @@ MarkPermanentAtom(JSTracer *trc, JSAtom *atom, const char *name)
|
|||
|
||||
CheckMarkedThing(trc, &atom);
|
||||
|
||||
if (!trc->callback) {
|
||||
if (trc->isMarkingTracer()) {
|
||||
// Atoms do not refer to other GC things so don't need to go on the mark stack.
|
||||
// Additionally, PushMarkStack will ignore permanent atoms.
|
||||
atom->markIfUnmarked();
|
||||
} else {
|
||||
void *thing = atom;
|
||||
trc->callback(trc, &thing, JSTRACE_STRING);
|
||||
trc->asCallbackTracer()->invoke(&thing, JSTRACE_STRING);
|
||||
MOZ_ASSERT(thing == atom);
|
||||
trc->unsetTracingLocation();
|
||||
}
|
||||
|
@ -359,13 +359,13 @@ MarkWellKnownSymbol(JSTracer *trc, JS::Symbol *sym)
|
|||
|
||||
MOZ_ASSERT(sym->isWellKnownSymbol());
|
||||
CheckMarkedThing(trc, &sym);
|
||||
if (!trc->callback) {
|
||||
if (trc->isMarkingTracer()) {
|
||||
// Permanent atoms are marked before well-known symbols.
|
||||
MOZ_ASSERT(sym->description()->isMarked());
|
||||
sym->markIfUnmarked();
|
||||
} else {
|
||||
void *thing = sym;
|
||||
trc->callback(trc, &thing, JSTRACE_SYMBOL);
|
||||
trc->asCallbackTracer()->invoke(&thing, JSTRACE_SYMBOL);
|
||||
MOZ_ASSERT(thing == sym);
|
||||
trc->unsetTracingLocation();
|
||||
}
|
||||
|
@ -957,7 +957,7 @@ gc::MarkObjectSlots(JSTracer *trc, NativeObject *obj, uint32_t start, uint32_t n
|
|||
static bool
|
||||
ShouldMarkCrossCompartment(JSTracer *trc, JSObject *src, Cell *cell)
|
||||
{
|
||||
if (!IsMarkingTracer(trc))
|
||||
if (!trc->isMarkingTracer())
|
||||
return true;
|
||||
|
||||
uint32_t color = AsGCMarker(trc)->markColor();
|
||||
|
@ -1866,7 +1866,7 @@ js::TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind)
|
|||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
AssertNonGrayGCThing(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
AssertNonGrayGCThing(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
DebugOnly<Cell *> thing(static_cast<Cell *>(*thingp));
|
||||
MOZ_ASSERT_IF(thing->isTenured(), !thing->asTenured().isMarked(js::gc::GRAY));
|
||||
|
@ -1891,23 +1891,23 @@ js::gc::ZoneIsAtomsZoneForString(JSRuntime *rt, T *thing)
|
|||
#endif
|
||||
|
||||
static void
|
||||
UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind);
|
||||
UnmarkGrayChildren(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind);
|
||||
|
||||
struct UnmarkGrayTracer : public JSTracer
|
||||
struct UnmarkGrayTracer : public JS::CallbackTracer
|
||||
{
|
||||
/*
|
||||
* We set eagerlyTraceWeakMaps to false because the cycle collector will fix
|
||||
* up any color mismatches involving weakmaps when it runs.
|
||||
*/
|
||||
explicit UnmarkGrayTracer(JSRuntime *rt)
|
||||
: JSTracer(rt, UnmarkGrayChildren, DoNotTraceWeakMaps),
|
||||
: JS::CallbackTracer(rt, UnmarkGrayChildren, DoNotTraceWeakMaps),
|
||||
tracingShape(false),
|
||||
previousShape(nullptr),
|
||||
unmarkedAny(false)
|
||||
{}
|
||||
|
||||
UnmarkGrayTracer(JSTracer *trc, bool tracingShape)
|
||||
: JSTracer(trc->runtime(), UnmarkGrayChildren, DoNotTraceWeakMaps),
|
||||
: JS::CallbackTracer(trc->runtime(), UnmarkGrayChildren, DoNotTraceWeakMaps),
|
||||
tracingShape(tracingShape),
|
||||
previousShape(nullptr),
|
||||
unmarkedAny(false)
|
||||
|
@ -1954,7 +1954,7 @@ struct UnmarkGrayTracer : public JSTracer
|
|||
* containers.
|
||||
*/
|
||||
static void
|
||||
UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
UnmarkGrayChildren(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
int stackDummy;
|
||||
if (!JS_CHECK_STACK_SIZE(trc->runtime()->mainThread.nativeStackLimit[StackForSystemCode],
|
||||
|
@ -1974,7 +1974,7 @@ UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
|||
// to only black edges.
|
||||
if (!cell->isTenured()) {
|
||||
#ifdef DEBUG
|
||||
JSTracer nongray(trc->runtime(), AssertNonGrayGCThing);
|
||||
JS::CallbackTracer nongray(trc->runtime(), AssertNonGrayGCThing);
|
||||
TraceChildren(&nongray, cell, kind);
|
||||
#endif
|
||||
return;
|
||||
|
|
|
@ -350,7 +350,7 @@ js::Nursery::allocateHugeSlots(JS::Zone *zone, size_t nslots)
|
|||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
class MinorCollectionTracer : public JSTracer
|
||||
class MinorCollectionTracer : public JS::CallbackTracer
|
||||
{
|
||||
public:
|
||||
Nursery *nursery;
|
||||
|
@ -380,7 +380,7 @@ class MinorCollectionTracer : public JSTracer
|
|||
}
|
||||
|
||||
MinorCollectionTracer(JSRuntime *rt, Nursery *nursery)
|
||||
: JSTracer(rt, Nursery::MinorGCCallback, TraceWeakMapKeysValues),
|
||||
: JS::CallbackTracer(rt, Nursery::MinorGCCallback, TraceWeakMapKeysValues),
|
||||
nursery(nursery),
|
||||
session(rt, MinorCollecting),
|
||||
tenuredSize(0),
|
||||
|
@ -776,7 +776,7 @@ ShouldMoveToTenured(MinorCollectionTracer *trc, void **thingp)
|
|||
}
|
||||
|
||||
/* static */ void
|
||||
js::Nursery::MinorGCCallback(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
js::Nursery::MinorGCCallback(JS::CallbackTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
MinorCollectionTracer *trc = static_cast<MinorCollectionTracer *>(jstrc);
|
||||
if (ShouldMoveToTenured(trc, thingp))
|
||||
|
|
|
@ -165,7 +165,7 @@ class Nursery
|
|||
}
|
||||
|
||||
static bool IsMinorCollectionTracer(JSTracer *trc) {
|
||||
return trc->callback == MinorGCCallback;
|
||||
return trc->isCallbackTracer() && trc->asCallbackTracer()->hasCallback(MinorGCCallback);
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
|
@ -347,7 +347,7 @@ class Nursery
|
|||
void growAllocableSpace();
|
||||
void shrinkAllocableSpace();
|
||||
|
||||
static void MinorGCCallback(JSTracer *trc, void **thingp, JSGCTraceKind kind);
|
||||
static void MinorGCCallback(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind);
|
||||
|
||||
friend class gc::MinorCollectionTracer;
|
||||
friend class jit::MacroAssembler;
|
||||
|
|
|
@ -325,10 +325,10 @@ JS_GetTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, void *thing,
|
|||
buf[bufsize - 1] = '\0';
|
||||
}
|
||||
|
||||
JSTracer::JSTracer(JSRuntime *rt, JSTraceCallback traceCallback,
|
||||
JSTracer::JSTracer(JSRuntime *rt, TracerKindTag kindTag,
|
||||
WeakMapTraceKind weakTraceKind /* = TraceWeakMapValues */)
|
||||
: callback(traceCallback)
|
||||
, runtime_(rt)
|
||||
: runtime_(rt)
|
||||
, tag(kindTag)
|
||||
, debugPrinter_(nullptr)
|
||||
, debugPrintArg_(nullptr)
|
||||
, debugPrintIndex_(size_t(-1))
|
||||
|
@ -387,7 +387,7 @@ JSTracer::debugPrintIndex() const
|
|||
}
|
||||
|
||||
void
|
||||
JSTracer::setTraceCallback(JSTraceCallback traceCallback)
|
||||
JS::CallbackTracer::setTraceCallback(JSTraceCallback traceCallback)
|
||||
{
|
||||
callback = traceCallback;
|
||||
}
|
||||
|
@ -512,7 +512,7 @@ MarkStack::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
|
|||
* so we delay visting entries.
|
||||
*/
|
||||
GCMarker::GCMarker(JSRuntime *rt)
|
||||
: JSTracer(rt, nullptr, DoNotTraceWeakMaps),
|
||||
: JSTracer(rt, JSTracer::MarkingTracer, DoNotTraceWeakMaps),
|
||||
stack(size_t(-1)),
|
||||
color(BLACK),
|
||||
unmarkedArenaStackTop(nullptr),
|
||||
|
|
|
@ -327,7 +327,7 @@ class GCMarker : public JSTracer
|
|||
|
||||
// Append traced things to a buffer on the zone for use later in the GC.
|
||||
// See the comment in GCRuntime.h above grayBufferState for details.
|
||||
class BufferGrayRootsTracer : public JSTracer
|
||||
class BufferGrayRootsTracer : public JS::CallbackTracer
|
||||
{
|
||||
// Set to false if we OOM while buffering gray roots.
|
||||
bool bufferingGrayRootsFailed;
|
||||
|
@ -336,10 +336,10 @@ class BufferGrayRootsTracer : public JSTracer
|
|||
|
||||
public:
|
||||
explicit BufferGrayRootsTracer(JSRuntime *rt)
|
||||
: JSTracer(rt, grayTraceCallback), bufferingGrayRootsFailed(false)
|
||||
: JS::CallbackTracer(rt, grayTraceCallback), bufferingGrayRootsFailed(false)
|
||||
{}
|
||||
|
||||
static void grayTraceCallback(JSTracer *trc, void **thingp, JSGCTraceKind kind) {
|
||||
static void grayTraceCallback(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind) {
|
||||
static_cast<BufferGrayRootsTracer *>(trc)->appendGrayRoot(*thingp, kind);
|
||||
}
|
||||
|
||||
|
@ -354,18 +354,8 @@ SetMarkStackLimit(JSRuntime *rt, size_t limit);
|
|||
inline bool
|
||||
IsBufferingGrayRoots(JSTracer *trc)
|
||||
{
|
||||
return trc->callback == BufferGrayRootsTracer::grayTraceCallback;
|
||||
}
|
||||
|
||||
// Return true if this trace is happening on behalf of the marking phase of GC.
|
||||
inline bool
|
||||
IsMarkingTracer(JSTracer *trc)
|
||||
{
|
||||
// If we call this on the gray-buffering tracer, then we have encountered a
|
||||
// marking path that will be wrong when tracing with a callback marker to
|
||||
// enqueue for deferred gray marking.
|
||||
MOZ_ASSERT(!IsBufferingGrayRoots(trc));
|
||||
return trc->callback == nullptr;
|
||||
return trc->isCallbackTracer() &&
|
||||
trc->asCallbackTracer()->hasCallback(BufferGrayRootsTracer::grayTraceCallback);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
|
|
@ -84,7 +84,7 @@ typedef HashMap<void *, VerifyNode *, DefaultHasher<void *>, SystemAllocPolicy>
|
|||
* The nodemap field is a hashtable that maps from the address of the GC thing
|
||||
* to the VerifyNode that represents it.
|
||||
*/
|
||||
struct VerifyPreTracer : JSTracer
|
||||
struct VerifyPreTracer : JS::CallbackTracer
|
||||
{
|
||||
JS::AutoDisableGenerationalGC noggc;
|
||||
|
||||
|
@ -102,7 +102,8 @@ struct VerifyPreTracer : JSTracer
|
|||
NodeMap nodemap;
|
||||
|
||||
VerifyPreTracer(JSRuntime *rt, JSTraceCallback callback)
|
||||
: JSTracer(rt, callback), noggc(rt), number(rt->gc.gcNumber()), count(0), root(nullptr)
|
||||
: JS::CallbackTracer(rt, callback), noggc(rt), number(rt->gc.gcNumber()), count(0),
|
||||
root(nullptr)
|
||||
{}
|
||||
|
||||
~VerifyPreTracer() {
|
||||
|
@ -115,7 +116,7 @@ struct VerifyPreTracer : JSTracer
|
|||
* node.
|
||||
*/
|
||||
static void
|
||||
AccumulateEdge(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
AccumulateEdge(JS::CallbackTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
VerifyPreTracer *trc = (VerifyPreTracer *)jstrc;
|
||||
|
||||
|
@ -280,7 +281,7 @@ static const uint32_t MAX_VERIFIER_EDGES = 1000;
|
|||
* been modified) must point to marked objects.
|
||||
*/
|
||||
static void
|
||||
CheckEdge(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
CheckEdge(JS::CallbackTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
VerifyPreTracer *trc = (VerifyPreTracer *)jstrc;
|
||||
VerifyNode *node = trc->curnode;
|
||||
|
@ -379,7 +380,7 @@ gc::GCRuntime::endVerifyPreBarriers()
|
|||
|
||||
/*** Post-Barrier Verifyier ***/
|
||||
|
||||
struct VerifyPostTracer : JSTracer
|
||||
struct VerifyPostTracer : JS::CallbackTracer
|
||||
{
|
||||
/* The gcNumber when the verification began. */
|
||||
uint64_t number;
|
||||
|
@ -392,7 +393,7 @@ struct VerifyPostTracer : JSTracer
|
|||
EdgeSet *edges;
|
||||
|
||||
VerifyPostTracer(JSRuntime *rt, JSTraceCallback callback)
|
||||
: JSTracer(rt, callback), number(rt->gc.gcNumber()), count(0)
|
||||
: JS::CallbackTracer(rt, callback), number(rt->gc.gcNumber()), count(0)
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -419,7 +420,7 @@ gc::GCRuntime::startVerifyPostBarriers()
|
|||
}
|
||||
|
||||
void
|
||||
PostVerifierCollectStoreBufferEdges(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
PostVerifierCollectStoreBufferEdges(JS::CallbackTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
VerifyPostTracer *trc = (VerifyPostTracer *)jstrc;
|
||||
|
||||
|
@ -456,7 +457,7 @@ AssertStoreBufferContainsEdge(VerifyPostTracer::EdgeSet *edges, void **loc, JSOb
|
|||
}
|
||||
|
||||
void
|
||||
PostVerifierVisitEdge(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
PostVerifierVisitEdge(JS::CallbackTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
VerifyPostTracer *trc = (VerifyPostTracer *)jstrc;
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
class CCWTestTracer : public JSTracer {
|
||||
static void staticCallback(JSTracer *trc, void **thingp, JSGCTraceKind kind) {
|
||||
class CCWTestTracer : public JS::CallbackTracer {
|
||||
static void staticCallback(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind) {
|
||||
static_cast<CCWTestTracer *>(trc)->callback(thingp, kind);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ class CCWTestTracer : public JSTracer {
|
|||
JSGCTraceKind expectedKind;
|
||||
|
||||
CCWTestTracer(JSContext *cx, void **expectedThingp, JSGCTraceKind expectedKind)
|
||||
: JSTracer(JS_GetRuntime(cx), staticCallback),
|
||||
: JS::CallbackTracer(JS_GetRuntime(cx), staticCallback),
|
||||
okay(true),
|
||||
numberOfThingsTraced(0),
|
||||
expectedThingp(expectedThingp),
|
||||
|
|
|
@ -1415,12 +1415,6 @@ JS_RemoveExtraGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data)
|
|||
return rt->gc.removeBlackRootsTracer(traceOp, data);
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_IsGCMarkingTracer(JSTracer *trc)
|
||||
{
|
||||
return js::IsMarkingTracer(trc);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_GC(JSRuntime *rt)
|
||||
{
|
||||
|
|
|
@ -1724,9 +1724,6 @@ JS_AddFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb, void *data);
|
|||
extern JS_PUBLIC_API(void)
|
||||
JS_RemoveFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_IsGCMarkingTracer(JSTracer *trc);
|
||||
|
||||
/*
|
||||
* Weak pointers and garbage collection
|
||||
*
|
||||
|
|
|
@ -878,13 +878,13 @@ JS::FormatStackDump(JSContext *cx, char *buf, bool showArgs, bool showLocals, bo
|
|||
return buf;
|
||||
}
|
||||
|
||||
struct DumpHeapTracer : public JSTracer
|
||||
struct DumpHeapTracer : public JS::CallbackTracer
|
||||
{
|
||||
FILE *output;
|
||||
|
||||
DumpHeapTracer(FILE *fp, JSRuntime *rt, JSTraceCallback callback,
|
||||
WeakMapTraceKind weakTraceKind)
|
||||
: JSTracer(rt, callback, weakTraceKind), output(fp)
|
||||
: JS::CallbackTracer(rt, callback, weakTraceKind), output(fp)
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -939,7 +939,7 @@ DumpHeapVisitCell(JSRuntime *rt, void *data, void *thing,
|
|||
}
|
||||
|
||||
static void
|
||||
DumpHeapVisitChild(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
DumpHeapVisitChild(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
if (gc::IsInsideNursery((js::gc::Cell *)*thingp))
|
||||
return;
|
||||
|
@ -951,7 +951,7 @@ DumpHeapVisitChild(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
|||
}
|
||||
|
||||
static void
|
||||
DumpHeapVisitRoot(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
DumpHeapVisitRoot(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
if (gc::IsInsideNursery((js::gc::Cell *)*thingp))
|
||||
return;
|
||||
|
|
|
@ -745,7 +745,7 @@ JSFunction::trace(JSTracer *trc)
|
|||
// self-hosted function which can be cloned over again. The latter
|
||||
// is stored in the first extended slot.
|
||||
JSRuntime *rt = trc->runtime();
|
||||
if (IsMarkingTracer(trc) &&
|
||||
if (trc->isMarkingTracer() &&
|
||||
(rt->allowRelazificationForTesting || !compartment()->hasBeenEntered()) &&
|
||||
!compartment()->isDebuggee() && !compartment()->isSelfHosting &&
|
||||
u.i.s.script_->isRelazifiable() && (!isSelfHostedBuiltin() || isExtended()))
|
||||
|
|
|
@ -2162,7 +2162,7 @@ GCRuntime::relocateArenas(Zone *zone, JS::gcreason::Reason reason, SliceBudget &
|
|||
|
||||
|
||||
void
|
||||
MovingTracer::Visit(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
MovingTracer::Visit(JS::CallbackTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
TenuredCell *thing = TenuredCell::fromPointer(*thingp);
|
||||
|
||||
|
@ -3620,11 +3620,11 @@ GCRuntime::shouldPreserveJITCode(JSCompartment *comp, int64_t currentTime,
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
class CompartmentCheckTracer : public JSTracer
|
||||
class CompartmentCheckTracer : public JS::CallbackTracer
|
||||
{
|
||||
public:
|
||||
CompartmentCheckTracer(JSRuntime *rt, JSTraceCallback callback)
|
||||
: JSTracer(rt, callback)
|
||||
: JS::CallbackTracer(rt, callback)
|
||||
{}
|
||||
|
||||
Cell *src;
|
||||
|
@ -3684,7 +3684,7 @@ CompartmentOfCell(Cell *thing, JSGCTraceKind kind)
|
|||
}
|
||||
|
||||
static void
|
||||
CheckCompartmentCallback(JSTracer *trcArg, void **thingp, JSGCTraceKind kind)
|
||||
CheckCompartmentCallback(JS::CallbackTracer *trcArg, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
CompartmentCheckTracer *trc = static_cast<CompartmentCheckTracer *>(trcArg);
|
||||
TenuredCell *thing = TenuredCell::fromPointer(*thingp);
|
||||
|
@ -3804,8 +3804,7 @@ GCRuntime::beginMarkPhase(JS::gcreason::Reason reason)
|
|||
}
|
||||
|
||||
marker.start();
|
||||
MOZ_ASSERT(!marker.callback);
|
||||
MOZ_ASSERT(IsMarkingTracer(&marker));
|
||||
GCMarker *gcmarker = ▮
|
||||
|
||||
/* For non-incremental GC the following sweep discards the jit code. */
|
||||
if (isIncremental) {
|
||||
|
@ -3815,8 +3814,6 @@ GCRuntime::beginMarkPhase(JS::gcreason::Reason reason)
|
|||
}
|
||||
}
|
||||
|
||||
GCMarker *gcmarker = ▮
|
||||
|
||||
startNumber = number;
|
||||
|
||||
/*
|
||||
|
|
|
@ -3412,7 +3412,7 @@ JSScript::markChildren(JSTracer *trc)
|
|||
// JSScript::Create(), but not yet finished initializing it with
|
||||
// fullyInitFromEmitter() or fullyInitTrivial().
|
||||
|
||||
MOZ_ASSERT_IF(IsMarkingTracer(trc) &&
|
||||
MOZ_ASSERT_IF(trc->isMarkingTracer() &&
|
||||
static_cast<GCMarker *>(trc)->shouldCheckCompartments(),
|
||||
zone()->isCollecting());
|
||||
|
||||
|
@ -3450,7 +3450,7 @@ JSScript::markChildren(JSTracer *trc)
|
|||
if (maybeLazyScript())
|
||||
MarkLazyScriptUnbarriered(trc, &lazyScript, "lazyScript");
|
||||
|
||||
if (IsMarkingTracer(trc)) {
|
||||
if (trc->isMarkingTracer()) {
|
||||
compartment()->mark();
|
||||
|
||||
if (code())
|
||||
|
|
|
@ -46,7 +46,7 @@ void
|
|||
WeakMapBase::trace(JSTracer *tracer)
|
||||
{
|
||||
MOZ_ASSERT(isInList());
|
||||
if (IsMarkingTracer(tracer)) {
|
||||
if (tracer->isMarkingTracer()) {
|
||||
// We don't trace any of the WeakMap entries at this time, just record
|
||||
// record the fact that the WeakMap has been marked. Enties are marked
|
||||
// in the iterative marking phase by markAllIteratively(), which happens
|
||||
|
|
|
@ -249,7 +249,7 @@ RegExpObject::trace(JSTracer *trc, JSObject *obj)
|
|||
// 2. When a write barrier executes, IsMarkingTracer is true, but
|
||||
// isHeapBusy() will be false.
|
||||
if (trc->runtime()->isHeapBusy() &&
|
||||
IsMarkingTracer(trc) &&
|
||||
trc->isMarkingTracer() &&
|
||||
!obj->asTenured().zone()->isPreservingCode())
|
||||
{
|
||||
obj->as<RegExpObject>().NativeObject::setPrivate(nullptr);
|
||||
|
@ -577,7 +577,7 @@ RegExpShared::~RegExpShared()
|
|||
void
|
||||
RegExpShared::trace(JSTracer *trc)
|
||||
{
|
||||
if (IsMarkingTracer(trc))
|
||||
if (trc->isMarkingTracer())
|
||||
marked_ = true;
|
||||
|
||||
if (source)
|
||||
|
|
|
@ -329,7 +329,7 @@ InterpreterFrame::mark(JSTracer *trc)
|
|||
} else {
|
||||
gc::MarkScriptUnbarriered(trc, &exec.script, "script");
|
||||
}
|
||||
if (IsMarkingTracer(trc))
|
||||
if (trc->isMarkingTracer())
|
||||
script()->compartment()->zone()->active = true;
|
||||
if (hasReturnValue())
|
||||
gc::MarkValueUnbarriered(trc, &rval_, "rval");
|
||||
|
|
|
@ -113,16 +113,16 @@ Node::exposeToJS() const
|
|||
}
|
||||
|
||||
|
||||
// A JSTracer subclass that adds a SimpleEdge to a Vector for each edge on
|
||||
// which it is invoked.
|
||||
class SimpleEdgeVectorTracer : public JSTracer {
|
||||
// A JS::CallbackTracer subclass that adds a SimpleEdge to a Vector for each
|
||||
// edge on which it is invoked.
|
||||
class SimpleEdgeVectorTracer : public JS::CallbackTracer {
|
||||
// The vector to which we add SimpleEdges.
|
||||
SimpleEdgeVector *vec;
|
||||
|
||||
// True if we should populate the edge's names.
|
||||
bool wantNames;
|
||||
|
||||
static void staticCallback(JSTracer *trc, void **thingp, JSGCTraceKind kind) {
|
||||
static void staticCallback(JS::CallbackTracer *trc, void **thingp, JSGCTraceKind kind) {
|
||||
static_cast<SimpleEdgeVectorTracer *>(trc)->callback(thingp, kind);
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ class SimpleEdgeVectorTracer : public JSTracer {
|
|||
bool okay;
|
||||
|
||||
SimpleEdgeVectorTracer(JSContext *cx, SimpleEdgeVector *vec, bool wantNames)
|
||||
: JSTracer(JS_GetRuntime(cx), staticCallback),
|
||||
: JS::CallbackTracer(JS_GetRuntime(cx), staticCallback),
|
||||
vec(vec),
|
||||
wantNames(wantNames),
|
||||
okay(true)
|
||||
|
|
|
@ -1874,7 +1874,7 @@ public:
|
|||
}
|
||||
|
||||
void TraceInside(JSTracer *trc) {
|
||||
if (JS_IsGCMarkingTracer(trc)) {
|
||||
if (trc->isMarkingTracer()) {
|
||||
mSet->Mark();
|
||||
if (mScriptableInfo)
|
||||
mScriptableInfo->Mark();
|
||||
|
@ -2177,7 +2177,7 @@ public:
|
|||
|
||||
// Yes, we *do* need to mark the mScriptableInfo in both cases.
|
||||
inline void TraceInside(JSTracer *trc) {
|
||||
if (JS_IsGCMarkingTracer(trc)) {
|
||||
if (trc->isMarkingTracer()) {
|
||||
mSet->Mark();
|
||||
if (mScriptableInfo)
|
||||
mScriptableInfo->Mark();
|
||||
|
|
|
@ -118,14 +118,16 @@ public:
|
|||
} // namespace mozilla
|
||||
|
||||
static void
|
||||
TraceWeakMappingChild(JSTracer* aTrc, void** aThingp, JSGCTraceKind aKind);
|
||||
TraceWeakMappingChild(JS::CallbackTracer* aTrc, void** aThingp,
|
||||
JSGCTraceKind aKind);
|
||||
|
||||
struct NoteWeakMapChildrenTracer : public JSTracer
|
||||
struct NoteWeakMapChildrenTracer : public JS::CallbackTracer
|
||||
{
|
||||
NoteWeakMapChildrenTracer(JSRuntime* aRt,
|
||||
nsCycleCollectionNoteRootCallback& aCb)
|
||||
: JSTracer(aRt, TraceWeakMappingChild), mCb(aCb), mTracedAny(false),
|
||||
mMap(nullptr), mKey(JS::GCCellPtr::NullPtr()), mKeyDelegate(nullptr)
|
||||
: JS::CallbackTracer(aRt, TraceWeakMappingChild), mCb(aCb),
|
||||
mTracedAny(false), mMap(nullptr), mKey(JS::GCCellPtr::NullPtr()),
|
||||
mKeyDelegate(nullptr)
|
||||
{
|
||||
}
|
||||
nsCycleCollectionNoteRootCallback& mCb;
|
||||
|
@ -136,9 +138,10 @@ struct NoteWeakMapChildrenTracer : public JSTracer
|
|||
};
|
||||
|
||||
static void
|
||||
TraceWeakMappingChild(JSTracer* aTrc, void** aThingp, JSGCTraceKind aKind)
|
||||
TraceWeakMappingChild(JS::CallbackTracer* aTrc, void** aThingp,
|
||||
JSGCTraceKind aKind)
|
||||
{
|
||||
MOZ_ASSERT(aTrc->callback == TraceWeakMappingChild);
|
||||
MOZ_ASSERT(aTrc->hasCallback(TraceWeakMappingChild));
|
||||
NoteWeakMapChildrenTracer* tracer =
|
||||
static_cast<NoteWeakMapChildrenTracer*>(aTrc);
|
||||
JS::GCCellPtr thing(*aThingp, aKind);
|
||||
|
@ -368,19 +371,21 @@ JSZoneParticipant::Traverse(void* aPtr, nsCycleCollectionTraversalCallback& aCb)
|
|||
}
|
||||
|
||||
static void
|
||||
NoteJSChildTracerShim(JSTracer* aTrc, void** aThingp, JSGCTraceKind aTraceKind);
|
||||
NoteJSChildTracerShim(JS::CallbackTracer* aTrc, void** aThingp,
|
||||
JSGCTraceKind aTraceKind);
|
||||
|
||||
struct TraversalTracer : public JSTracer
|
||||
struct TraversalTracer : public JS::CallbackTracer
|
||||
{
|
||||
TraversalTracer(JSRuntime* aRt, nsCycleCollectionTraversalCallback& aCb)
|
||||
: JSTracer(aRt, NoteJSChildTracerShim, DoNotTraceWeakMaps), mCb(aCb)
|
||||
: JS::CallbackTracer(aRt, NoteJSChildTracerShim, DoNotTraceWeakMaps),
|
||||
mCb(aCb)
|
||||
{
|
||||
}
|
||||
nsCycleCollectionTraversalCallback& mCb;
|
||||
};
|
||||
|
||||
static void
|
||||
NoteJSChild(JSTracer* aTrc, JS::GCCellPtr aThing)
|
||||
NoteJSChild(JS::CallbackTracer* aTrc, JS::GCCellPtr aThing)
|
||||
{
|
||||
TraversalTracer* tracer = static_cast<TraversalTracer*>(aTrc);
|
||||
|
||||
|
@ -427,7 +432,8 @@ NoteJSChild(JSTracer* aTrc, JS::GCCellPtr aThing)
|
|||
}
|
||||
|
||||
static void
|
||||
NoteJSChildTracerShim(JSTracer* aTrc, void** aThingp, JSGCTraceKind aTraceKind)
|
||||
NoteJSChildTracerShim(JS::CallbackTracer* aTrc, void** aThingp,
|
||||
JSGCTraceKind aTraceKind)
|
||||
{
|
||||
JS::GCCellPtr thing(*aThingp, aTraceKind);
|
||||
NoteJSChild(aTrc, thing);
|
||||
|
|
Загрузка…
Ссылка в новой задаче