Bug 1146696 - Don't assume there are no arenas available after last ditch GC r=terrence a=sylvestre
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 30 Mar 2015 11:03:35 +0100
changeset 258318 484a6aef6a4f
parent 258317 0c29ab096b90
child 258319 589aafc2bb13
push id4644
push userjcoppeard@mozilla.com
push date2015-04-07 14:42 +0000
treeherdermozilla-beta@484a6aef6a4f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence, sylvestre
bugs1146696
milestone38.0
Bug 1146696 - Don't assume there are no arenas available after last ditch GC r=terrence a=sylvestre
js/src/jit-test/tests/gc/bug-1146696.js
js/src/jsgc.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1146696.js
@@ -0,0 +1,21 @@
+// |jit-test| --no-ggc; allow-oom
+gc();
+dbg1 = new Debugger();
+root2 = newGlobal();
+dbg1.memory.onGarbageCollection = function(){}
+dbg1.addDebuggee(root2);
+for (var j = 0; j < 9999; ++j) {
+    try {
+        a
+    } catch (e) {}
+}
+gcparam("maxBytes", gcparam("gcBytes") + 8000);
+function g(i) {
+    if (i == 0)
+        return;
+    var x = "";
+    function f() {}
+    eval('');
+    g(i - 1);
+}
+g(100);
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2971,17 +2971,21 @@ GCRuntime::refillFreeListFromMainThread(
             return nullptr;
 
         JS::PrepareForFullGC(rt);
         AutoKeepAtoms keepAtoms(cx->perThreadData);
         rt->gc.gc(GC_SHRINK, JS::gcreason::LAST_DITCH);
     }
 
     // Retry the allocation after the last-ditch GC.
-    thing = tryRefillFreeListFromMainThread(cx, thingKind);
+    // Note that due to GC callbacks we might already have allocated an arena
+    // for this thing kind!
+    thing = cx->arenas()->allocateFromFreeList(thingKind, Arena::thingSize(thingKind));
+    if (!thing)
+        thing = tryRefillFreeListFromMainThread(cx, thingKind);
     if (thing)
         return thing;
 
     // We are really just totally out of memory.
     MOZ_ASSERT(allowGC, "A fallible allocation must not report OOM on failure.");
     js_ReportOutOfMemory(cx);
     return nullptr;
 }