зеркало из https://github.com/mozilla/gecko-dev.git
Bulk clear GC bitmaps when GC starts instead of after the GC ends (565229, r=gregor).
This commit is contained in:
Родитель
47c15f7d65
Коммит
69b4feafd6
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче