Bug 726115 - Make the tracer callback take an indirect pointer; r=billm

This will be required for a tracer to move objects.  This patch only
updates the tracer interface and users of the interface.

--HG--
extra : rebase_source : 844d819a80cf6cb1dba0d07ea97f647802c66d40
This commit is contained in:
Terrence Cole 2012-02-15 16:28:41 -08:00
Родитель 8a802480e1
Коммит 1bca8b91f0
8 изменённых файлов: 37 добавлений и 30 удалений

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

@ -2642,8 +2642,9 @@ typedef struct JSDumpingTracer {
} JSDumpingTracer;
static void
DumpNotify(JSTracer *trc, void *thing, JSGCTraceKind kind)
DumpNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
void *thing = *thingp;
JSDumpingTracer *dtrc;
JSContext *cx;
JSDHashEntryStub *entry;

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

@ -3098,7 +3098,7 @@ JSVAL_TRACE_KIND(jsval v)
* wants to use the existing liveness of entries.
*/
typedef void
(* JSTraceCallback)(JSTracer *trc, void *thing, JSGCTraceKind kind);
(* JSTraceCallback)(JSTracer *trc, void **thingp, JSGCTraceKind kind);
struct JSTracer {
JSRuntime *runtime;

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

@ -483,13 +483,14 @@ struct JSDumpHeapTracer : public JSTracer {
};
static void
DumpHeapVisitChild(JSTracer *trc, void *thing, JSGCTraceKind kind);
DumpHeapVisitChild(JSTracer *trc, void **thingp, JSGCTraceKind kind);
static void
DumpHeapPushIfNew(JSTracer *trc, void *thing, JSGCTraceKind kind)
DumpHeapPushIfNew(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
JS_ASSERT(trc->callback == DumpHeapPushIfNew ||
trc->callback == DumpHeapVisitChild);
void *thing = *thingp;
JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(trc);
/*
@ -509,13 +510,13 @@ DumpHeapPushIfNew(JSTracer *trc, void *thing, JSGCTraceKind kind)
}
static void
DumpHeapVisitChild(JSTracer *trc, void *thing, JSGCTraceKind kind)
DumpHeapVisitChild(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
JS_ASSERT(trc->callback == DumpHeapVisitChild);
JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(trc);
const char *edgeName = JS_GetTraceEdgeName(dtrc, dtrc->buffer, sizeof(dtrc->buffer));
fprintf(dtrc->output, "> %p %s\n", (void *)thing, edgeName);
DumpHeapPushIfNew(dtrc, thing, kind);
fprintf(dtrc->output, "> %p %s\n", *thingp, edgeName);
DumpHeapPushIfNew(dtrc, thingp, kind);
}
void

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

@ -1815,7 +1815,7 @@ GCMarker::markDelayedChildren()
#ifdef DEBUG
static void
EmptyMarkCallback(JSTracer *trc, void *thing, JSGCTraceKind kind)
EmptyMarkCallback(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
}
#endif
@ -3393,7 +3393,7 @@ struct VerifyTracer : JSTracer {
* node.
*/
static void
AccumulateEdge(JSTracer *jstrc, void *thing, JSGCTraceKind kind)
AccumulateEdge(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
{
VerifyTracer *trc = (VerifyTracer *)jstrc;
@ -3406,7 +3406,7 @@ AccumulateEdge(JSTracer *jstrc, void *thing, JSGCTraceKind kind)
VerifyNode *node = trc->curnode;
uint32_t i = node->count;
node->edges[i].thing = thing;
node->edges[i].thing = *thingp;
node->edges[i].kind = kind;
node->edges[i].label = trc->debugPrinter ? NULL : (char *)trc->debugPrintArg;
node->count++;
@ -3547,9 +3547,9 @@ oom:
}
static void
CheckAutorooter(JSTracer *jstrc, void *thing, JSGCTraceKind kind)
CheckAutorooter(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
{
static_cast<Cell *>(thing)->markIfUnmarked();
static_cast<Cell *>(*thingp)->markIfUnmarked();
}
/*
@ -3560,13 +3560,13 @@ CheckAutorooter(JSTracer *jstrc, void *thing, JSGCTraceKind kind)
* modified) must point to marked objects.
*/
static void
CheckEdge(JSTracer *jstrc, void *thing, JSGCTraceKind kind)
CheckEdge(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
{
VerifyTracer *trc = (VerifyTracer *)jstrc;
VerifyNode *node = trc->curnode;
for (uint32_t i = 0; i < node->count; i++) {
if (node->edges[i].thing == thing) {
if (node->edges[i].thing == *thingp) {
JS_ASSERT(node->edges[i].kind == kind);
node->edges[i].thing = NULL;
return;

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

@ -106,10 +106,13 @@ MarkInternal(JSTracer *trc, T *thing)
* GC.
*/
if (!rt->gcCurrentCompartment || thing->compartment() == rt->gcCurrentCompartment) {
if (IS_GC_MARKING_TRACER(trc))
if (IS_GC_MARKING_TRACER(trc)) {
PushMarkStack(static_cast<GCMarker *>(trc), thing);
else
trc->callback(trc, (void *)thing, GetGCThingTraceKind(thing));
} else {
void *tmp = (void *)thing;
trc->callback(trc, &tmp, GetGCThingTraceKind(thing));
JS_ASSERT(tmp == thing);
}
}
#ifdef DEBUG

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

@ -1446,11 +1446,12 @@ typedef struct JSCountHeapTracer {
} JSCountHeapTracer;
static void
CountHeapNotify(JSTracer *trc, void *thing, JSGCTraceKind kind)
CountHeapNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
JSCountHeapTracer *countTracer;
JSDHashEntryStub *entry;
JSCountHeapNode *node;
void *thing = *thingp;
JS_ASSERT(trc->callback == CountHeapNotify);
countTracer = (JSCountHeapTracer *)trc;

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

@ -232,7 +232,7 @@ class HeapReverser : public JSTracer {
* A stack of work items. We represent the stack explicitly to avoid
* overflowing the C++ stack when traversing long chains of objects.
*/
Vector<Child> work;
Vector<Child> work;
/* When traverseEdge is called, the Cell and kind at which the edge originated. */
void *parent;
@ -249,19 +249,17 @@ class HeapReverser : public JSTracer {
bool traversalStatus;
/* Static member function wrapping 'traverseEdge'. */
static void traverseEdgeWithThis(JSTracer *tracer, void *cell, JSGCTraceKind kind) {
static void traverseEdgeWithThis(JSTracer *tracer, void **thingp, JSGCTraceKind kind) {
HeapReverser *reverser = static_cast<HeapReverser *>(tracer);
reverser->traversalStatus = reverser->traverseEdge(cell, kind);
reverser->traversalStatus = reverser->traverseEdge(*thingp, kind);
}
/* Return a jsval representing a node, if possible; otherwise, return JSVAL_VOID. */
jsval nodeToValue(void *cell, int kind) {
if (kind == JSTRACE_OBJECT) {
JSObject *object = static_cast<JSObject *>(cell);
return OBJECT_TO_JSVAL(object);
} else {
if (kind != JSTRACE_OBJECT)
return JSVAL_VOID;
}
JSObject *object = static_cast<JSObject *>(cell);
return OBJECT_TO_JSVAL(object);
}
};

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

@ -480,9 +480,10 @@ struct NoteWeakMapChildrenTracer : public JSTracer
};
static void
TraceWeakMappingChild(JSTracer *trc, void *thing, JSGCTraceKind kind)
TraceWeakMappingChild(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
MOZ_ASSERT(trc->callback == TraceWeakMappingChild);
void *thing = *thingp;
NoteWeakMapChildrenTracer *tracer =
static_cast<NoteWeakMapChildrenTracer *>(trc);
if (kind == JSTRACE_STRING)
@ -721,8 +722,9 @@ xpc_GCThingIsGrayCCThing(void *thing)
* re-coloring.
*/
static void
UnmarkGrayChildren(JSTracer *trc, void *thing, JSGCTraceKind kind)
UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
void *thing = *thingp;
int stackDummy;
if (!JS_CHECK_STACK_SIZE(js::GetContextStackLimit(trc->context), &stackDummy)) {
/*
@ -776,9 +778,10 @@ struct TraversalTracer : public JSTracer
};
static void
NoteJSChild(JSTracer *trc, void *thing, JSGCTraceKind kind)
NoteJSChild(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
TraversalTracer *tracer = static_cast<TraversalTracer*>(trc);
void *thing = *thingp;
// Don't traverse non-gray objects, unless we want all traces.
if (!xpc_IsGrayGCThing(thing) && !tracer->cb.WantAllTraces())
@ -1166,7 +1169,7 @@ struct VerifyTraceXPCGlobalCalledTracer
};
static void
VerifyTraceXPCGlobalCalled(JSTracer *trc, void *thing, JSGCTraceKind kind)
VerifyTraceXPCGlobalCalled(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
// We don't do anything here, we only want to verify that TraceXPCGlobal
// was called.