Bug 730148 - Handle OOM better in ValidateIncrementalMarking (r=igor)

This commit is contained in:
Bill McCloskey 2012-02-24 10:46:31 -08:00
parent 9ec0e5d3d9
commit ea6ab27298

View File

@ -3069,9 +3069,32 @@ EndMarkPhase(JSContext *cx)
static void
ValidateIncrementalMarking(JSContext *cx)
{
typedef HashMap<Chunk *, uintptr_t *, GCChunkHasher, SystemAllocPolicy> BitmapMap;
BitmapMap map;
if (!map.init())
return;
JSRuntime *rt = cx->runtime;
FullGCMarker *gcmarker = &rt->gcMarker;
/* Save existing mark bits */
for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
ChunkBitmap *bitmap = &r.front()->bitmap;
uintptr_t *entry = (uintptr_t *)js_malloc(sizeof(bitmap->bitmap));
if (!entry)
return;
memcpy(entry, bitmap->bitmap, sizeof(bitmap->bitmap));
if (!map.putNew(r.front(), entry))
return;
}
/*
* After this point, the function should run to completion, so we shouldn't
* do anything fallible.
*/
/* Re-do all the marking, but non-incrementally. */
js::gc::State state = rt->gcIncrementalState;
rt->gcIncrementalState = NO_INCREMENTAL;
@ -3081,18 +3104,6 @@ ValidateIncrementalMarking(JSContext *cx)
JS_ASSERT(gcmarker->isDrained());
gcmarker->reset();
typedef HashMap<Chunk *, uintptr_t *> BitmapMap;
BitmapMap map(cx);
map.init();
for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
ChunkBitmap *bitmap = &r.front()->bitmap;
uintptr_t *entry = (uintptr_t *)js_malloc(sizeof(bitmap->bitmap));
if (entry)
memcpy(entry, bitmap->bitmap, sizeof(bitmap->bitmap));
map.putNew(r.front(), entry);
}
for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront())
r.front()->bitmap.clear();
@ -3101,15 +3112,13 @@ ValidateIncrementalMarking(JSContext *cx)
rt->gcMarker.drainMarkStack(budget);
MarkGrayAndWeak(cx);
/* Now verify that we have the same mark bits as before. */
for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
Chunk *chunk = r.front();
ChunkBitmap *bitmap = &chunk->bitmap;
uintptr_t *entry = map.lookup(r.front())->value;
ChunkBitmap incBitmap;
if (!entry)
continue;
memcpy(incBitmap.bitmap, entry, sizeof(incBitmap.bitmap));
js_free(entry);