[INFER] Sweep cloned type sets in call ICs before destroying the objects they reference,
bug 641491.
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug641491.js
@@ -0,0 +1,19 @@
+function f1() {
+}
+function f2() {
+}
+function f3(o) {
+ f2 = XML.prototype;
+}
+var key = Object.getOwnPropertyNames(f1)[30];
+if(key) {
+ f3 = f1[key];
+}
+gc();
+gc();
+try {
+for(var i=0; i<10; i++) {
+ delete f2[1];
+ f3(function() {});
+}
+} catch (e) {}
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -518,43 +518,16 @@ JSCompartment::sweep(JSContext *cx, uint
*/
for (JSCList *cursor = scripts.next; cursor != &scripts; cursor = cursor->next) {
JSScript *script = reinterpret_cast<JSScript *>(cursor);
if (script->hasJITCode())
mjit::ic::PurgePICs(cx, script);
}
# endif
- if (!types.inferenceDepth && types.inferenceEnabled) {
- for (JSCList *cursor = scripts.next; cursor != &scripts; cursor = cursor->next) {
- JSScript *script = reinterpret_cast<JSScript *>(cursor);
- script->condenseTypes(cx);
- }
-
- types.condense(cx);
- }
-
- types.sweep(cx);
-
- for (JSCList *cursor = scripts.next; cursor != &scripts; cursor = cursor->next) {
- JSScript *script = reinterpret_cast<JSScript *>(cursor);
- script->sweepTypes(cx);
- }
-
- if (!types.inferenceDepth) {
- /* Reset the inference pool, releasing all intermediate type data. */
- JS_FinishArenaPool(&types.pool);
-
- /*
- * Destroy eval'ed scripts, now that any type inference information referring
- * to eval scripts has been removed.
- */
- js_DestroyScriptsToGC(cx, this);
- }
-
#if defined JS_METHODJIT && defined JS_MONOIC
/*
* The release interval is the frequency with which we should try to destroy
* executable pools by releasing all JIT code in them, zero to never destroy pools.
* Initialize counter so that the first pool will be destroyed, and eventually drive
* the amount of JIT code in never-used compartments to zero. Don't discard anything
* for compartments which currently have active stack frames.
@@ -578,16 +551,43 @@ JSCompartment::sweep(JSContext *cx, uint
mjit::ReleaseScriptCode(cx, script);
}
}
}
}
#endif
+ if (!types.inferenceDepth && types.inferenceEnabled) {
+ for (JSCList *cursor = scripts.next; cursor != &scripts; cursor = cursor->next) {
+ JSScript *script = reinterpret_cast<JSScript *>(cursor);
+ script->condenseTypes(cx);
+ }
+
+ types.condense(cx);
+ }
+
+ types.sweep(cx);
+
+ for (JSCList *cursor = scripts.next; cursor != &scripts; cursor = cursor->next) {
+ JSScript *script = reinterpret_cast<JSScript *>(cursor);
+ script->sweepTypes(cx);
+ }
+
+ if (!types.inferenceDepth) {
+ /* Reset the inference pool, releasing all intermediate type data. */
+ JS_FinishArenaPool(&types.pool);
+
+ /*
+ * Destroy eval'ed scripts, now that any type inference information referring
+ * to eval scripts has been removed.
+ */
+ js_DestroyScriptsToGC(cx, this);
+ }
+
active = false;
}
void
JSCompartment::purge(JSContext *cx)
{
freeLists.purge();
dtoaCache.purge();