[Bug 592007] TM: New Scope patch changes GC behavior in browser r=gal (CLOSED TREE)
authorGregor Wagner <anygregor@gmail.com>
Tue, 31 Aug 2010 08:37:16 -0700
changeset 52512 007b92be0804
parent 52511 e8ee411dca70
child 52513 e80892986b11
push id15660
push userrsayre@mozilla.com
push date2010-09-11 19:16 +0000
treeherdermozilla-central@f1bd314e64ac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgal
bugs592007
milestone2.0b5pre
[Bug 592007] TM: New Scope patch changes GC behavior in browser r=gal (CLOSED TREE)
js/src/jscntxt.h
js/src/jsgc.cpp
js/src/jsgc.h
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1315,16 +1315,17 @@ struct JSRuntime {
     JSGCArenaList       gcArenaList[FINALIZE_LIMIT];
     js::RootedValueMap  gcRootsHash;
     js::GCLocks         gcLocksHash;
     jsrefcount          gcKeepAtoms;
     size_t              gcBytes;
     size_t              gcLastBytes;
     size_t              gcMaxBytes;
     size_t              gcMaxMallocBytes;
+    size_t              gcNewArenaTriggerBytes;
     uint32              gcEmptyArenaPoolLifespan;
     uint32              gcNumber;
     js::GCMarker        *gcMarkingTracer;
     uint32              gcTriggerFactor;
     size_t              gcTriggerBytes;
     volatile JSBool     gcIsNeeded;
     volatile JSBool     gcFlushCodeCaches;
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -628,17 +628,19 @@ ReleaseGCChunk(JSRuntime *rt, jsuword ch
     METER(rt->gcStats.nchunks--);
     rt->gcChunkAllocator->free(p);
 }
 
 static JSGCArena *
 NewGCArena(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
-    if (!JS_THREAD_DATA(cx)->waiveGCQuota && rt->gcBytes >= rt->gcMaxBytes) {
+    if (!JS_THREAD_DATA(cx)->waiveGCQuota && 
+        (rt->gcBytes >= rt->gcMaxBytes || 
+        rt->gcBytes > GC_HEAP_GROWTH_FACTOR * rt->gcNewArenaTriggerBytes)) {
         /*
          * FIXME bug 524051 We cannot run a last-ditch GC on trace for now, so
          * just pretend we are out of memory which will throw us off trace and
          * we will re-try this code path from the interpreter.
          */
         if (!JS_ON_TRACE(cx))
             return NULL;
         js_TriggerGC(cx, true);
@@ -947,16 +949,17 @@ js_InitGC(JSRuntime *rt, uint32 maxbytes
      */
     rt->setGCTriggerFactor((uint32) -1);
 
     /*
      * The assigned value prevents GC from running when GC memory is too low
      * (during JS engine start).
      */
     rt->setGCLastBytes(8192);
+    rt->gcNewArenaTriggerBytes = GC_ARENA_ALLOCATION_TRIGGER;
 
     METER(PodZero(&rt->gcStats));
     return true;
 }
 
 namespace js {
 
 /*
@@ -2761,16 +2764,21 @@ GC(JSContext *cx  GCTIMER_PARAM)
 
     FinalizeArenaList<JSShortString, FinalizeShortString>(cx, FINALIZE_SHORT_STRING);
     FinalizeArenaList<JSString, FinalizeString>(cx, FINALIZE_STRING);
     for (unsigned i = FINALIZE_EXTERNAL_STRING0;
          i <= FINALIZE_EXTERNAL_STRING_LAST;
          ++i) {
         FinalizeArenaList<JSString, FinalizeExternalString>(cx, i);
     }
+    
+    rt->gcNewArenaTriggerBytes = rt->gcBytes < GC_ARENA_ALLOCATION_TRIGGER ?
+                                 GC_ARENA_ALLOCATION_TRIGGER :
+                                 rt->gcBytes;
+
     TIMESTAMP(sweepStringEnd);
 
     SweepCompartments(cx);
 
     /*
      * Sweep the runtime's property trees after finalizing objects, in case any
      * had watchpoints referencing tree nodes.
      */
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -60,16 +60,28 @@
 
 #define JSTRACE_XML         2
 
 /*
  * One past the maximum trace kind.
  */
 #define JSTRACE_LIMIT       3
 
+/*
+ * Lower limit after which we limit the heap growth
+ */
+const size_t GC_ARENA_ALLOCATION_TRIGGER = 25 * js::GC_CHUNK_SIZE;
+
+/*
+ * A GC is triggered once the number of newly allocated arenas 
+ * is 1.5 times the number of live arenas after the last GC.
+ * (Starting after the lower limit of GC_ARENA_ALLOCATION_TRIGGER)
+ */
+const float GC_HEAP_GROWTH_FACTOR = 1.5;
+
 const uintN JS_EXTERNAL_STRING_LIMIT = 8;
 
 /*
  * Get the type of the external string or -1 if the string was not created
  * with JS_NewExternalString.
  */
 extern intN
 js_GetExternalStringGCType(JSString *str);