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