Fix from Gavin Reaney <gavin@picsel.com> for bug 362110, r=me.

This commit is contained in:
brendan%mozilla.org 2006-12-02 23:12:56 +00:00
parent f72d2b7f36
commit a3f20eeb8a

View File

@ -622,10 +622,13 @@ InsertPropertyTreeChild(JSRuntime *rt, JSScopeProperty *parent,
*/
JS_RUNTIME_METER(rt, duplicatePropTreeNodes);
}
chunk = NewPropTreeKidsChunk(rt);
if (!chunk)
return JS_FALSE;
if (sweptChunk) {
chunk = sweptChunk;
} else {
chunk = NewPropTreeKidsChunk(rt);
if (!chunk)
return JS_FALSE;
}
parent->kids = CHUNK_TO_KIDS(chunk);
chunk->kids[0] = sprop;
childp = &chunk->kids[1];
@ -640,7 +643,7 @@ InsertPropertyTreeChild(JSRuntime *rt, JSScopeProperty *parent,
}
/* NB: Called with the runtime lock held. */
static void
static PropTreeKidsChunk *
RemovePropertyTreeChild(JSRuntime *rt, JSScopeProperty *child)
{
JSPropertyTreeEntry *entry;
@ -691,9 +694,9 @@ RemovePropertyTreeChild(JSRuntime *rt, JSScopeProperty *child)
*chunkp = NULL;
if (!list)
parent->kids = NULL;
DestroyPropTreeKidsChunk(rt, lastChunk);
return lastChunk;
}
return;
return NULL;
}
}
@ -705,6 +708,7 @@ RemovePropertyTreeChild(JSRuntime *rt, JSScopeProperty *child)
parent->kids = NULL;
}
}
return NULL;
}
/*
@ -1490,7 +1494,7 @@ js_SweepScopeProperties(JSRuntime *rt)
JSArena **ap, *a;
JSScopeProperty *limit, *sprop, *parent, *kids, *kid;
uintN liveCount;
PropTreeKidsChunk *chunk, *nextChunk;
PropTreeKidsChunk *chunk, *nextChunk, *freeChunk;
uintN i;
#ifdef DUMP_SCOPE_STATS
@ -1553,7 +1557,7 @@ js_SweepScopeProperties(JSRuntime *rt)
}
/* Ok, sprop is garbage to collect: unlink it from its parent. */
RemovePropertyTreeChild(rt, sprop);
freeChunk = RemovePropertyTreeChild(rt, sprop);
/*
* Take care to reparent all sprop's kids to their grandparent.
@ -1569,11 +1573,16 @@ js_SweepScopeProperties(JSRuntime *rt)
* chunks to be reused by the grandparent, which removes the
* need for InsertPropertyTreeChild to malloc a new KidsChunk.
*
* If sprop does not have chunky kids, then we rely on the
* RemovePropertyTreeChild call above (which removed sprop from
* its parent) either leaving one free entry, or else returning
* the now-unused chunk to us so we can reuse it.
*
* We also require the grandparent to have either no kids or else
* chunky kids. A single non-chunky kid would force a new chunk to
* be malloced in some cases (if sprop had a single non-chunky
* kid, or a multiple of MAX_KIDS_PER_CHUNK kids). Note that
* RemovePropertyTreeChild never converts a single entry chunky
* RemovePropertyTreeChild never converts a single-entry chunky
* kid back to a non-chunky kid, so we are assured of correct
* behaviour.
*/
@ -1611,18 +1620,16 @@ js_SweepScopeProperties(JSRuntime *rt)
}
}
if (!chunk->kids[0]) {
/* The chunk wasn't reused so we can free it */
/* The chunk wasn't reused, so we must free it. */
DestroyPropTreeKidsChunk(rt, chunk);
}
} while ((chunk = nextChunk) != NULL);
} else {
kid = kids;
if (!InsertPropertyTreeChild(rt, parent, kid, NULL)) {
if (!InsertPropertyTreeChild(rt, parent, kid, freeChunk)) {
/*
* The removal of sprop should have left a free space
* for kid to be inserted into parent, unless the root
* hash table was shrunk. In this case we allow for
* failure only when parent is null.
* This can happen only if we failed to add an entry
* to the root property hash table.
*/
JS_ASSERT(!parent);
kid->parent = NULL;
@ -1630,6 +1637,11 @@ js_SweepScopeProperties(JSRuntime *rt)
}
}
if (freeChunk && !freeChunk->kids[0]) {
/* The chunk wasn't reused, so we must free it. */
DestroyPropTreeKidsChunk(rt, freeChunk);
}
/* Clear id so we know (above) that sprop is on the freelist. */
sprop->id = JSVAL_NULL;
FREENODE_INSERT(rt->propertyFreeList, sprop);