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; } JSDumpingTracer;
static void static void
DumpNotify(JSTracer *trc, void *thing, JSGCTraceKind kind) DumpNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{ {
void *thing = *thingp;
JSDumpingTracer *dtrc; JSDumpingTracer *dtrc;
JSContext *cx; JSContext *cx;
JSDHashEntryStub *entry; JSDHashEntryStub *entry;

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

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

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

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

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

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

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

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

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

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

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

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

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

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