Bulk clear GC bitmaps when GC starts instead of after the GC ends (565229, r=gregor).

This commit is contained in:
Andreas Gal 2010-05-18 03:01:33 -07:00
Родитель 47c15f7d65
Коммит 69b4feafd6
1 изменённых файлов: 21 добавлений и 37 удалений

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

@ -275,9 +275,6 @@ struct JSGCArenaInfo {
JSGCThing *freeList; JSGCThing *freeList;
/* The arena has marked doubles. */
bool hasMarkedDoubles;
static inline JSGCArenaInfo *fromGCThing(void* thing); static inline JSGCArenaInfo *fromGCThing(void* thing);
}; };
@ -316,8 +313,6 @@ struct JSGCArena {
inline JSGCMarkingDelay *getMarkingDelay(); inline JSGCMarkingDelay *getMarkingDelay();
inline jsbitmap *getMarkBitmap(); inline jsbitmap *getMarkBitmap();
inline void clearMarkBitmap();
}; };
struct JSGCChunkInfo { struct JSGCChunkInfo {
@ -331,6 +326,8 @@ struct JSGCChunkInfo {
inline jsuword getChunk(); inline jsuword getChunk();
inline void clearMarkBitmap();
static inline JSGCChunkInfo *fromChunk(jsuword chunk); static inline JSGCChunkInfo *fromChunk(jsuword chunk);
}; };
@ -387,6 +384,13 @@ JSGCChunkInfo::getChunk() {
return chunk; return chunk;
} }
inline void
JSGCChunkInfo::clearMarkBitmap()
{
PodZero(reinterpret_cast<jsbitmap *>(getChunk() + GC_MARK_BITMAP_ARRAY_OFFSET),
GC_MARK_BITMAP_WORDS * GC_ARENAS_PER_CHUNK);
}
/* static */ /* static */
inline JSGCChunkInfo * inline JSGCChunkInfo *
JSGCChunkInfo::fromChunk(jsuword chunk) { JSGCChunkInfo::fromChunk(jsuword chunk) {
@ -488,12 +492,6 @@ JSGCArena::getMarkBitmap()
return reinterpret_cast<jsbitmap *>(chunk | offset); return reinterpret_cast<jsbitmap *>(chunk | offset);
} }
inline void
JSGCArena::clearMarkBitmap()
{
PodZero(getMarkBitmap(), GC_MARK_BITMAP_WORDS);
}
/* /*
* Helpers for GC-thing operations. * Helpers for GC-thing operations.
*/ */
@ -883,16 +881,6 @@ js_IsAboutToBeFinalized(void *thing)
if (JSString::isStatic(thing)) if (JSString::isStatic(thing))
return false; return false;
JSGCArenaInfo *ainfo = JSGCArenaInfo::fromGCThing(thing);
if (!ainfo->list) {
/*
* Check if arena has no marked doubles. In that case the bitmap with
* the mark flags contains all garbage as it is initialized only when
* marking the first double in the arena.
*/
if (!ainfo->hasMarkedDoubles)
return true;
}
return !IsMarkedGCThing(thing); return !IsMarkedGCThing(thing);
} }
@ -1485,7 +1473,6 @@ RefillFinalizableFreeList(JSContext *cx, unsigned thingKind)
arenaList->head = a; arenaList->head = a;
} }
a->clearMarkBitmap();
JSGCMarkingDelay *markingDelay = a->getMarkingDelay(); JSGCMarkingDelay *markingDelay = a->getMarkingDelay();
markingDelay->link = NULL; markingDelay->link = NULL;
markingDelay->unmarkedChildren = 0; markingDelay->unmarkedChildren = 0;
@ -1699,7 +1686,6 @@ RefillDoubleFreeList(JSContext *cx)
rt->gcDoubleArenaList.head = a; rt->gcDoubleArenaList.head = a;
JS_UNLOCK_GC(rt); JS_UNLOCK_GC(rt);
ainfo->hasMarkedDoubles = false;
return MakeNewArenaFreeList(a, sizeof(jsdouble)); return MakeNewArenaFreeList(a, sizeof(jsdouble));
} }
@ -2052,12 +2038,6 @@ js_CallGCMarker(JSTracer *trc, void *thing, uint32 kind)
*/ */
switch (kind) { switch (kind) {
case JSTRACE_DOUBLE: { case JSTRACE_DOUBLE: {
JSGCArenaInfo *ainfo = JSGCArenaInfo::fromGCThing(thing);
JS_ASSERT(!ainfo->list);
if (!ainfo->hasMarkedDoubles) {
ainfo->hasMarkedDoubles = true;
JSGCArena::fromGCThing(thing)->clearMarkBitmap();
}
MarkIfUnmarkedGCThing(thing); MarkIfUnmarkedGCThing(thing);
goto out; goto out;
} }
@ -2632,7 +2612,6 @@ FinalizeArenaList(JSContext *cx, unsigned thingKind)
METER(nkilledarenas++); METER(nkilledarenas++);
} else { } else {
JS_ASSERT(nfree < ThingsPerArena(sizeof(T))); JS_ASSERT(nfree < ThingsPerArena(sizeof(T)));
a->clearMarkBitmap();
*tailp = NULL; *tailp = NULL;
ainfo->freeList = freeList; ainfo->freeList = freeList;
ap = &ainfo->prev; ap = &ainfo->prev;
@ -2730,6 +2709,15 @@ struct GCTimer {
# define GCTIMER_END(last) ((void) 0) # define GCTIMER_END(last) ((void) 0)
#endif #endif
static inline bool
HasMarkedDoubles(JSGCArena *a)
{
JS_STATIC_ASSERT(GC_MARK_BITMAP_SIZE == 8 * sizeof(uint64));
uint64 *markBitmap = (uint64 *) a->getMarkBitmap();
return !!(markBitmap[0] | markBitmap[1] | markBitmap[2] | markBitmap[3] |
markBitmap[4] | markBitmap[5] | markBitmap[6] | markBitmap[7]);
}
static void static void
SweepDoubles(JSRuntime *rt) SweepDoubles(JSRuntime *rt)
{ {
@ -2739,7 +2727,7 @@ SweepDoubles(JSRuntime *rt)
JSGCArena **ap = &rt->gcDoubleArenaList.head; JSGCArena **ap = &rt->gcDoubleArenaList.head;
while (JSGCArena *a = *ap) { while (JSGCArena *a = *ap) {
JSGCArenaInfo *ainfo = a->getInfo(); JSGCArenaInfo *ainfo = a->getInfo();
if (!ainfo->hasMarkedDoubles) { if (!HasMarkedDoubles(a)) {
/* No marked double values in the arena. */ /* No marked double values in the arena. */
*ap = ainfo->prev; *ap = ainfo->prev;
ReleaseGCArena(rt, a); ReleaseGCArena(rt, a);
@ -2754,7 +2742,6 @@ SweepDoubles(JSRuntime *rt)
} }
METER(nlivearenas++); METER(nlivearenas++);
#endif #endif
ainfo->hasMarkedDoubles = false;
ap = &ainfo->prev; ap = &ainfo->prev;
} }
} }
@ -2877,11 +2864,8 @@ GC(JSContext *cx GCTIMER_PARAM)
rt->gcMarkingTracer = &trc; rt->gcMarkingTracer = &trc;
JS_ASSERT(IS_GC_MARKING_TRACER(&trc)); JS_ASSERT(IS_GC_MARKING_TRACER(&trc));
for (JSGCArena *a = rt->gcDoubleArenaList.head; a;) { for (JSGCChunkInfo **i = rt->gcChunks.begin(); i != rt->gcChunks.end(); ++i)
JSGCArenaInfo *ainfo = a->getInfo(); (*i)->clearMarkBitmap();
JS_ASSERT(!ainfo->hasMarkedDoubles);
a = ainfo->prev;
}
js_TraceRuntime(&trc); js_TraceRuntime(&trc);
js_MarkScriptFilenames(rt); js_MarkScriptFilenames(rt);