Bug 887652 - Limit number of empty chunks after a GC. r=terrence. a=leo+
authorGregor Wagner <anygregor@gmail.com>
Tue, 09 Jul 2013 16:41:22 -0700
changeset 119767 5b34e0cda635d4bd3b33da97409b48fc8bfed0fc
parent 119765 f917f3fb17ab9fae8f26d2112e6800ee839a43c3
child 119768 9cd44200f74bf52b07884d525f754dce19121649
push id40
push userryanvm@gmail.com
push dateWed, 10 Jul 2013 19:07:54 +0000
reviewersterrence, leo
bugs887652
milestone18.1
Bug 887652 - Limit number of empty chunks after a GC. r=terrence. a=leo+
js/src/jsgc.cpp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -117,16 +117,22 @@ namespace js {
 namespace gc {
 
 /* Perform a Full GC every 20 seconds if MaybeGC is called */
 static const uint64_t GC_IDLE_FULL_SPAN = 20 * 1000 * 1000;
 
 /* Increase the IGC marking slice time if we are in highFrequencyGC mode. */
 const int IGC_MARK_SLICE_MULTIPLIER = 2;
 
+#if defined(ANDROID) || defined(MOZ_B2G)
+static const int MAX_EMPTY_CHUNK_COUNT = 2;
+#else
+static const int MAX_EMPTY_CHUNK_COUNT = 30;
+#endif
+
 #ifdef JS_GC_ZEAL
 static void
 StartVerifyPreBarriers(JSRuntime *rt);
 
 static void
 EndVerifyPreBarriers(JSRuntime *rt);
 
 static void
@@ -551,23 +557,26 @@ ChunkPool::expire(JSRuntime *rt, bool re
 
     /*
      * Return old empty chunks to the system while preserving the order of
      * other chunks in the list. This way, if the GC runs several times
      * without emptying the list, the older chunks will stay at the tail
      * and are more likely to reach the max age.
      */
     Chunk *freeList = NULL;
+    int freeChunkCount = 0;
     for (Chunk **chunkp = &emptyChunkListHead; *chunkp; ) {
         JS_ASSERT(emptyCount);
         Chunk *chunk = *chunkp;
         JS_ASSERT(chunk->unused());
         JS_ASSERT(!rt->gcChunkSet.has(chunk));
         JS_ASSERT(chunk->info.age <= MAX_EMPTY_CHUNK_AGE);
-        if (releaseAll || chunk->info.age == MAX_EMPTY_CHUNK_AGE) {
+        if (releaseAll || chunk->info.age == MAX_EMPTY_CHUNK_AGE ||
+            freeChunkCount++ > MAX_EMPTY_CHUNK_COUNT)
+        {
             *chunkp = chunk->info.next;
             --emptyCount;
             chunk->prepareToBeFreed(rt);
             chunk->info.next = freeList;
             freeList = chunk;
         } else {
             /* Keep the chunk but increase its age. */
             ++chunk->info.age;