Bug 730961 - Make internal marking interface indirect; r=billm

Now that all of the marking interface users use indirect marking, we can pass
through the indirection internally and stop passing every object through the
stack.
This commit is contained in:
Terrence Cole 2012-03-14 14:07:16 -07:00
parent a3c1ab17a1
commit 7f9923f96d
3 changed files with 51 additions and 35 deletions

View File

@ -1084,7 +1084,9 @@ MarkIfGCThingWord(JSTracer *trc, uintptr_t w)
JS_snprintf(nameBuf, sizeof(nameBuf), pattern, thing);
JS_SET_TRACING_NAME(trc, nameBuf);
#endif
MarkKind(trc, thing, traceKind);
void *tmp = thing;
MarkKind(trc, &tmp, traceKind);
JS_ASSERT(tmp == thing);
#ifdef DEBUG
if (trc->runtime->gcIncrementalState == MARK_ROOTS)
@ -1130,7 +1132,7 @@ MarkConservativeStackRoots(JSTracer *trc, bool useSavedRoots)
root++)
{
JS_SET_TRACING_NAME(trc, "cstack");
MarkKind(trc, root->thing, root->kind);
MarkKind(trc, &root->thing, root->kind);
}
return;
}
@ -2057,7 +2059,9 @@ GCMarker::markBufferedGrayRoots()
debugPrintArg = elem->debugPrintArg;
debugPrintIndex = elem->debugPrintIndex;
#endif
MarkKind(this, elem->thing, elem->kind);
void *tmp = elem->thing;
MarkKind(this, &tmp, elem->kind);
JS_ASSERT(tmp == elem->thing);
}
grayRoots.clearAndFree();
@ -2147,7 +2151,7 @@ gc_root_traversal(JSTracer *trc, const RootEntry &entry)
#endif
const char *name = entry.value.name ? entry.value.name : "root";
if (entry.value.type == JS_GC_ROOT_GCTHING_PTR)
MarkGCThingRoot(trc, *reinterpret_cast<void **>(entry.key), name);
MarkGCThingRoot(trc, reinterpret_cast<void **>(entry.key), name);
else
MarkValueRoot(trc, reinterpret_cast<Value *>(entry.key), name);
}
@ -2156,7 +2160,9 @@ static void
gc_lock_traversal(const GCLocks::Entry &entry, JSTracer *trc)
{
JS_ASSERT(entry.value >= 1);
MarkGCThingRoot(trc, entry.key, "locked object");
void *tmp = entry.key;
MarkGCThingRoot(trc, &tmp, "locked object");
JS_ASSERT(tmp == entry.key);
}
namespace js {

View File

@ -88,8 +88,11 @@ CheckMarkedThing(JSTracer *trc, T *thing)
template<typename T>
void
MarkInternal(JSTracer *trc, T *thing)
MarkInternal(JSTracer *trc, T **thingp)
{
JS_ASSERT(thingp);
T *thing = *thingp;
CheckMarkedThing(trc, thing);
JSRuntime *rt = trc->runtime;
@ -106,9 +109,7 @@ MarkInternal(JSTracer *trc, T *thing)
if (!trc->callback) {
PushMarkStack(static_cast<GCMarker *>(trc), thing);
} else {
void *tmp = (void *)thing;
trc->callback(trc, &tmp, GetGCThingTraceKind(thing));
JS_ASSERT(tmp == thing);
trc->callback(trc, (void **)thingp, GetGCThingTraceKind(thing));
}
}
@ -129,7 +130,7 @@ static void
MarkUnbarriered(JSTracer *trc, T **thingp, const char *name)
{
JS_SET_TRACING_NAME(trc, name);
MarkInternal(trc, *thingp);
MarkInternal(trc, thingp);
}
template <typename T>
@ -137,7 +138,7 @@ static void
Mark(JSTracer *trc, HeapPtr<T> *thing, const char *name)
{
JS_SET_TRACING_NAME(trc, name);
MarkInternal(trc, thing->get());
MarkInternal(trc, thing->unsafeGet());
}
template <typename T>
@ -146,7 +147,7 @@ MarkRoot(JSTracer *trc, T **thingp, const char *name)
{
JS_ROOT_MARKING_ASSERT(trc);
JS_SET_TRACING_NAME(trc, name);
MarkInternal(trc, *thingp);
MarkInternal(trc, thingp);
}
template <typename T>
@ -154,9 +155,9 @@ static void
MarkRange(JSTracer *trc, size_t len, HeapPtr<T> *vec, const char *name)
{
for (size_t i = 0; i < len; ++i) {
if (T *obj = vec[i]) {
if (vec[i].get()) {
JS_SET_TRACING_INDEX(trc, name, i);
MarkInternal(trc, obj);
MarkInternal(trc, vec[i].unsafeGet());
}
}
}
@ -168,7 +169,7 @@ MarkRootRange(JSTracer *trc, size_t len, T **vec, const char *name)
JS_ROOT_MARKING_ASSERT(trc);
for (size_t i = 0; i < len; ++i) {
JS_SET_TRACING_INDEX(trc, name, i);
MarkInternal(trc, vec[i]);
MarkInternal(trc, &vec[i]);
}
}
@ -221,45 +222,47 @@ DeclMarkerImpl(XML, JSXML)
/*** Externally Typed Marking ***/
void
MarkKind(JSTracer *trc, void *thing, JSGCTraceKind kind)
MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
JS_ASSERT(thing);
JS_ASSERT(kind == GetGCThingTraceKind(thing));
JS_ASSERT(thingp);
JS_ASSERT(*thingp);
JS_ASSERT(kind == GetGCThingTraceKind(*thingp));
switch (kind) {
case JSTRACE_OBJECT:
MarkInternal(trc, reinterpret_cast<JSObject *>(thing));
MarkInternal(trc, reinterpret_cast<JSObject **>(thingp));
break;
case JSTRACE_STRING:
MarkInternal(trc, reinterpret_cast<JSString *>(thing));
MarkInternal(trc, reinterpret_cast<JSString **>(thingp));
break;
case JSTRACE_SCRIPT:
MarkInternal(trc, static_cast<JSScript *>(thing));
MarkInternal(trc, reinterpret_cast<JSScript **>(thingp));
break;
case JSTRACE_SHAPE:
MarkInternal(trc, reinterpret_cast<Shape *>(thing));
MarkInternal(trc, reinterpret_cast<Shape **>(thingp));
break;
case JSTRACE_BASE_SHAPE:
MarkInternal(trc, reinterpret_cast<BaseShape *>(thing));
MarkInternal(trc, reinterpret_cast<BaseShape **>(thingp));
break;
case JSTRACE_TYPE_OBJECT:
MarkInternal(trc, reinterpret_cast<types::TypeObject *>(thing));
MarkInternal(trc, reinterpret_cast<types::TypeObject **>(thingp));
break;
#if JS_HAS_XML_SUPPORT
case JSTRACE_XML:
MarkInternal(trc, static_cast<JSXML *>(thing));
MarkInternal(trc, reinterpret_cast<JSXML **>(thingp));
break;
#endif
}
}
void
MarkGCThingRoot(JSTracer *trc, void *thing, const char *name)
MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name)
{
JS_ROOT_MARKING_ASSERT(trc);
JS_SET_TRACING_NAME(trc, name);
if (!thing)
JS_ASSERT(thingp);
if (!*thingp)
return;
MarkKind(trc, thing, GetGCThingTraceKind(thing));
MarkKind(trc, thingp, GetGCThingTraceKind(*thingp));
}
/*** ID Marking ***/
@ -269,11 +272,11 @@ MarkIdInternal(JSTracer *trc, jsid *id)
{
if (JSID_IS_STRING(*id)) {
JSString *str = JSID_TO_STRING(*id);
MarkInternal(trc, str);
MarkInternal(trc, &str);
*id = ATOM_TO_JSID(reinterpret_cast<JSAtom *>(str));
} else if (JS_UNLIKELY(JSID_IS_OBJECT(*id))) {
JSObject *obj = JSID_TO_OBJECT(*id);
MarkInternal(trc, obj);
MarkInternal(trc, &obj);
*id = OBJECT_TO_JSID(obj);
}
}
@ -319,7 +322,12 @@ MarkValueInternal(JSTracer *trc, Value *v)
{
if (v->isMarkable()) {
JS_ASSERT(v->toGCThing());
return MarkKind(trc, v->toGCThing(), v->gcKind());
void *thing = v->toGCThing();
MarkKind(trc, &thing, v->gcKind());
if (v->isString())
v->setString((JSString *)thing);
else
v->setObjectOrNull((JSObject *)thing);
}
}
@ -408,7 +416,7 @@ void
MarkObject(JSTracer *trc, HeapPtr<GlobalObject, JSScript *> *thingp, const char *name)
{
JS_SET_TRACING_NAME(trc, name);
MarkInternal(trc, thingp->get());
MarkInternal(trc, thingp->unsafeGet());
}
void
@ -1172,7 +1180,9 @@ void
CallTracer(JSTracer *trc, void *thing, JSGCTraceKind kind)
{
JS_ASSERT(thing);
MarkKind(trc, thing, kind);
void *tmp = thing;
MarkKind(trc, &tmp, kind);
JS_ASSERT(tmp == thing);
}
} /* namespace js */

View File

@ -76,10 +76,10 @@ DeclMarker(XML, JSXML)
* after we transition to exact rooting.
*/
void
MarkKind(JSTracer *trc, void *thing, JSGCTraceKind kind);
MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind);
void
MarkGCThingRoot(JSTracer *trc, void *thing, const char *name);
MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name);
/*** ID Marking ***/