bug 667507 - r=gal

This commit is contained in:
Igor Bukanov 2011-07-14 21:47:36 +02:00
parent ac29c887f8
commit 2d1c8c12b5
2 changed files with 34 additions and 13 deletions

View File

@ -0,0 +1,6 @@
for (i = 0; i < 10; i++) {
Object.defineProperty({}, "", {
get: function() {}
})
gc()
}

View File

@ -2881,15 +2881,8 @@ TraceMonitor::flush()
}
static bool
HasUnreachableGCThingsImpl(JSContext *cx, TreeFragment *f)
HasUnreachableGCThings(JSContext *cx, TreeFragment *f)
{
if (f->visiting)
return false;
f->visiting = true;
if (!f->code())
return false;
/*
* We do not check here for dead scripts as JSScript is not a GC thing.
* Instead PurgeScriptFragments is used to remove dead script fragments.
@ -2911,17 +2904,33 @@ HasUnreachableGCThingsImpl(JSContext *cx, TreeFragment *f)
return true;
}
return false;
}
static bool
ContainsUnrechableGCThingImpl(JSContext *cx, TreeFragment *f)
{
if (f->visiting)
return false;
f->visiting = true;
if (!f->code())
return false;
if (HasUnreachableGCThings(cx, f))
return true;
TreeFragment** data = f->dependentTrees.data();
unsigned length = f->dependentTrees.length();
for (unsigned n = 0; n < length; ++n) {
if (HasUnreachableGCThingsImpl(cx, data[n]))
if (ContainsUnrechableGCThingImpl(cx, data[n]))
return true;
}
data = f->linkedTrees.data();
length = f->linkedTrees.length();
for (unsigned n = 0; n < length; ++n) {
if (HasUnreachableGCThingsImpl(cx, data[n]))
if (ContainsUnrechableGCThingImpl(cx, data[n]))
return true;
}
@ -2948,10 +2957,16 @@ ClearVisitingFlag(TreeFragment *f)
ClearVisitingFlag(data[n]);
}
/*
* Recursively check if the fragment and its dependent and linked trees has
* dead GC things. As the trees can point to each other we use the visiting
* flag to detect already visited fragments. The flag is cleared after we
* walked the whole graph in the separated ClearVisitingFlag function.
*/
static bool
HasUnreachableGCThings(JSContext *cx, TreeFragment *f)
ContainsUnrechableGCThing(JSContext *cx, TreeFragment *f)
{
bool hasUnrechable = HasUnreachableGCThingsImpl(cx, f);
bool hasUnrechable = ContainsUnrechableGCThingImpl(cx, f);
ClearVisitingFlag(f);
return hasUnrechable;
}
@ -2974,7 +2989,7 @@ TraceMonitor::sweep(JSContext *cx)
while (TreeFragment* frag = *fragp) {
TreeFragment* peer = frag;
do {
if (peer->code() && HasUnreachableGCThings(cx, peer))
if (peer->code() && ContainsUnrechableGCThing(cx, peer))
break;
peer = peer->peer;
} while (peer);