bug 523688 - avoiding spurious OOM messages when on trace. r=brendan
authorIgor Bukanov <igor@mir2.org>
Fri, 23 Oct 2009 11:03:17 +0400
changeset 34329 5555bb22bcc24e03b685f1ac9ffc84d565e5f7ad
parent 34328 34be4f52a1df00a94b7b3c0a911dc92599582e31
child 34330 4c5a8237459599968d11a1bc93af17601e0051f5
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbrendan
bugs523688
milestone1.9.3a1pre
bug 523688 - avoiding spurious OOM messages when on trace. r=brendan
js/src/jsgc.cpp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -614,23 +614,32 @@ RemoveChunkFromList(JSRuntime *rt, JSGCC
     *ci->prevp = ci->next;
     if (ci->next) {
         JS_ASSERT(ci->next->prevp == &ci->next);
         ci->next->prevp = ci->prevp;
     }
 }
 
 static JSGCArenaInfo *
-NewGCArena(JSRuntime *rt)
+NewGCArena(JSContext *cx)
 {
     jsuword chunk;
     JSGCArenaInfo *a;
 
-    if (rt->gcBytes >= rt->gcMaxBytes)
-        return NULL;
+    JSRuntime *rt = cx->runtime;
+    if (rt->gcBytes >= rt->gcMaxBytes) {
+        /*
+         * FIXME bug 524051 We cannot run a last-ditch GC on trace for now, so
+         * as a workaround we allow to breach the max bytes limit here and
+         * schedule the GC later.
+         */
+        if (!JS_ON_TRACE(cx))
+            return NULL;
+        js_TriggerGC(cx, true);
+    }
 
     JSGCChunkInfo *ci;
     uint32 i;
     JSGCArenaInfo *aprev;
 
     ci = rt->gcChunkList;
     if (!ci) {
         chunk = NewGCChunk();
@@ -1438,17 +1447,17 @@ RefillFinalizableFreeList(JSContext *cx,
             JSGCThing *freeList = a->finalizable.freeList;
             if (freeList) {
                 a->finalizable.freeList = NULL;
                 JS_UNLOCK_GC(rt);
                 return freeList;
             }
         }
 
-        a = NewGCArena(rt);
+        a = NewGCArena(cx);
         if (a)
             break;
         if (!canGC) {
             METER(astats->fail++);
             JS_UNLOCK_GC(rt);
             return NULL;
         }
         doGC = true;
@@ -1662,17 +1671,17 @@ RefillDoubleFreeList(JSContext *cx)
             JS_ASSERT(!a->hasMarkedDoubles);
             rt->gcDoubleArenaList.cursor = a->prev;
             JS_UNLOCK_GC(rt);
             JSGCThing *list = TurnUsedArenaIntoDoubleList(a);
             if (list)
                 return list;
             JS_LOCK_GC(rt);
         }
-        a = NewGCArena(rt);
+        a = NewGCArena(cx);
         if (a)
             break;
         if (!canGC) {
             METER(rt->gcStats.doubleArenaStats.fail++);
             JS_UNLOCK_GC(rt);
 
             if (!JS_ON_TRACE(cx)) {
                 /* Trace code handle this on its own. */