mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 723971 - unmark gray for shapes. r=billm
This commit is contained in:
parent
ac1fbc4a6a
commit
7f86c54ec3
@ -699,6 +699,18 @@ xpc_GCThingIsGrayCCThing(void *thing)
|
|||||||
xpc_IsGrayGCThing(thing);
|
xpc_IsGrayGCThing(thing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct UnmarkGrayTracer : public JSTracer
|
||||||
|
{
|
||||||
|
UnmarkGrayTracer() : mTracingShape(false), mPreviousShape(nsnull) {}
|
||||||
|
UnmarkGrayTracer(JSTracer *trc, bool aTracingShape)
|
||||||
|
: mTracingShape(aTracingShape), mPreviousShape(nsnull)
|
||||||
|
{
|
||||||
|
JS_TracerInit(this, trc->runtime, trc->callback);
|
||||||
|
}
|
||||||
|
bool mTracingShape; // true iff we are tracing the immediate children of a shape
|
||||||
|
void *mPreviousShape; // If mTracingShape, shape child or NULL. Otherwise, NULL.
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The GC and CC are run independently. Consequently, the following sequence of
|
* The GC and CC are run independently. Consequently, the following sequence of
|
||||||
* events can occur:
|
* events can occur:
|
||||||
@ -729,15 +741,38 @@ UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this thing is not a CC-kind or already non-gray then we're done.
|
if (!xpc_IsGrayGCThing(thing))
|
||||||
if (!AddToCCKind(kind) || !xpc_IsGrayGCThing(thing))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Unmark.
|
|
||||||
static_cast<js::gc::Cell *>(thing)->unmark(js::gc::GRAY);
|
static_cast<js::gc::Cell *>(thing)->unmark(js::gc::GRAY);
|
||||||
|
|
||||||
// Trace children.
|
/*
|
||||||
JS_TraceChildren(trc, thing, kind);
|
* Trace children of |thing|. If |thing| and its parent are both shapes, |thing| will
|
||||||
|
* get saved to mPreviousShape without being traced. The parent will later
|
||||||
|
* trace |thing|. This is done to avoid increasing the stack depth during shape
|
||||||
|
* tracing. It is safe to do because a shape can only have one child that is a shape.
|
||||||
|
*/
|
||||||
|
UnmarkGrayTracer *tracer = static_cast<UnmarkGrayTracer*>(trc);
|
||||||
|
UnmarkGrayTracer childTracer(tracer, kind == JSTRACE_SHAPE);
|
||||||
|
|
||||||
|
if (kind != JSTRACE_SHAPE) {
|
||||||
|
JS_TraceChildren(&childTracer, thing, kind);
|
||||||
|
MOZ_ASSERT(!childTracer.mPreviousShape);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tracer->mTracingShape) {
|
||||||
|
MOZ_ASSERT(!tracer->mPreviousShape);
|
||||||
|
tracer->mPreviousShape = thing;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
MOZ_ASSERT(!xpc_IsGrayGCThing(thing));
|
||||||
|
JS_TraceChildren(&childTracer, thing, JSTRACE_SHAPE);
|
||||||
|
thing = childTracer.mPreviousShape;
|
||||||
|
childTracer.mPreviousShape = nsnull;
|
||||||
|
} while (thing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -749,7 +784,7 @@ xpc_UnmarkGrayObjectRecursive(JSObject *obj)
|
|||||||
js::gc::AsCell(obj)->unmark(js::gc::GRAY);
|
js::gc::AsCell(obj)->unmark(js::gc::GRAY);
|
||||||
|
|
||||||
// Trace children.
|
// Trace children.
|
||||||
JSTracer trc;
|
UnmarkGrayTracer trc;
|
||||||
JS_TracerInit(&trc, JS_GetObjectRuntime(obj), UnmarkGrayChildren);
|
JS_TracerInit(&trc, JS_GetObjectRuntime(obj), UnmarkGrayChildren);
|
||||||
JS_TraceChildren(&trc, obj, JSTRACE_OBJECT);
|
JS_TraceChildren(&trc, obj, JSTRACE_OBJECT);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user