diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 3b54d5988e36..b1e318db970b 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -758,16 +758,25 @@ CreateLazyScriptsForCompartment(JSContext* cx) // clones. See bug 1105306. for (gc::ZoneCellIter i(cx->zone(), JSFunction::FinalizeKind); !i.done(); i.next()) { JSObject* obj = i.get(); - if (obj->compartment() == cx->compartment() && obj->is()) { - JSFunction* fun = &obj->as(); - if (fun->isInterpretedLazy()) { - LazyScript* lazy = fun->lazyScriptOrNull(); - if (lazy && lazy->sourceObject() && !lazy->maybeScript() && - !lazy->hasUncompiledEnclosingScript()) - { - if (!lazyFunctions.append(fun)) - return false; - } + + // Sweeping is incremental; take care to not delazify functions that + // are about to be finalized. GC things referenced by objects that are + // about to be finalized (e.g., in slots) may already be freed. + if (gc::IsAboutToBeFinalizedUnbarriered(&obj) || + obj->compartment() != cx->compartment() || + !obj->is()) + { + continue; + } + + JSFunction* fun = &obj->as(); + if (fun->isInterpretedLazy()) { + LazyScript* lazy = fun->lazyScriptOrNull(); + if (lazy && lazy->sourceObject() && !lazy->maybeScript() && + !lazy->hasUncompiledEnclosingScript()) + { + if (!lazyFunctions.append(fun)) + return false; } } }