mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-03 23:30:46 +00:00
Fix from Gavin Reaney <gavin@picsel.com> for bug 362110, r=me.
This commit is contained in:
parent
f72d2b7f36
commit
a3f20eeb8a
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user