Bug 1271854 - Part 1: Allow specifying multiple GC zeal levels; r=terrence
authorEhsan Akhgari <ehsan@mozilla.com>
Thu, 12 May 2016 10:19:52 -0400
changeset 297456 e04dd37f479920a8440cbdea4463a9a05119fa9d
parent 297455 6bab48d2528b459f7e0cb322ddccada8c72fd95d
child 297457 13670b4bb7af9c584cc5139ec1f5500d69b25cf3
push id19225
push userphilringnalda@gmail.com
push dateSat, 14 May 2016 20:07:57 +0000
treeherderfx-team@403912ca555e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1271854
milestone49.0a1
Bug 1271854 - Part 1: Allow specifying multiple GC zeal levels; r=terrence This affects both the environment variable JS_GC_ZEAL, and the --gc-zeal argument to the JS shell.
js/src/jsgc.cpp
js/src/shell/js.cpp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1185,17 +1185,17 @@ GCRuntime::getZealBits(uint32_t* zealBit
 {
     *zealBits = zealModeBits;
     *frequency = zealFrequency;
     *scheduled = nextScheduled;
 }
 
 const char* gc::ZealModeHelpText =
     "  Specifies how zealous the garbage collector should be. Some of these modes can\n"
-    "  be set simultaneously, e.g. in the shell, gczeal(2); gczeal(4); will activate\n"
+    "  be set simultaneously, by passing multiple level options, e.g. \"2;4\" will activate\n"
     "  both modes 2 and 4.\n"
     "  \n"
     "  Values:\n"
     "    0: Normal amount of collection (resets all modes)\n"
     "    1: Collect when roots are added or removed\n"
     "    2: Collect when every N allocations (default: 100)\n"
     "    3: Collect when the window paints (browser only)\n"
     "    4: Verify pre write barriers between instructions\n"
@@ -1250,36 +1250,51 @@ void
 GCRuntime::setNextScheduled(uint32_t count)
 {
     nextScheduled = count;
 }
 
 bool
 GCRuntime::parseAndSetZeal(const char* str)
 {
-    int zeal = -1;
     int frequency = -1;
-
-    if (isdigit(str[0])) {
-        zeal = atoi(str);
-
-        const char* p = strchr(str, ',');
-        if (!p)
-            frequency = JS_DEFAULT_ZEAL_FREQ;
-        else
-            frequency = atoi(p + 1);
-    }
-
-    if (zeal < 0 || zeal > int(ZealMode::Limit) || frequency <= 0) {
-        fprintf(stderr, "Format: JS_GC_ZEAL=level[,N]\n");
-        fputs(ZealModeHelpText, stderr);
-        return false;
-    }
-
-    setZeal(zeal, frequency);
+    bool foundFrequency = false;
+    mozilla::Vector<int> zeals;
+
+    do {
+        int zeal = -1;
+
+        if (isdigit(str[0])) {
+            zeal = atoi(str);
+
+            size_t offset = strspn(str, "0123456789");
+            const char* p = str + offset;
+            if (!*p || *p == ';') {
+                frequency = JS_DEFAULT_ZEAL_FREQ;
+            } else if (*p == ',') {
+                frequency = atoi(p + 1);
+                foundFrequency = true;
+            }
+        }
+
+        if (zeal < 0 || zeal > int(ZealMode::Limit) || frequency <= 0) {
+            fprintf(stderr, "Format: JS_GC_ZEAL=level(;level)*[,N]\n");
+            fputs(ZealModeHelpText, stderr);
+            return false;
+        }
+
+        if (!zeals.emplaceBack(zeal)) {
+            return false;
+        }
+    } while (!foundFrequency &&
+             (str = strchr(str, ';')) != nullptr &&
+             str++);
+
+    for (auto z : zeals)
+        setZeal(z, frequency);
     return true;
 }
 
 #endif
 
 /*
  * Lifetime in number of major GCs for type sets attached to scripts containing
  * observed types.
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -7317,17 +7317,17 @@ main(int argc, char** argv, char** envp)
 #elif defined(JS_SIMULATOR_MIPS32) || defined(JS_SIMULATOR_MIPS64)
 	|| !op.addBoolOption('\0', "mips-sim-icache-checks", "Enable icache flush checks in the MIPS "
                              "simulator.")
         || !op.addIntOption('\0', "mips-sim-stop-at", "NUMBER", "Stop the MIPS simulator after the given "
                             "NUMBER of instructions.", -1)
 #endif
         || !op.addIntOption('\0', "nursery-size", "SIZE-MB", "Set the maximum nursery size in MB", 16)
 #ifdef JS_GC_ZEAL
-        || !op.addStringOption('z', "gc-zeal", "LEVEL[,N]", gc::ZealModeHelpText)
+        || !op.addStringOption('z', "gc-zeal", "LEVEL(;LEVEL)*[,N]", gc::ZealModeHelpText)
 #endif
         || !op.addStringOption('\0', "module-load-path", "DIR", "Set directory to load modules from")
     )
     {
         return EXIT_FAILURE;
     }
 
     op.setArgTerminatesOptions("script", true);