Bug 1101602 - Add --gc-zeal option to JS shell r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 20 Nov 2014 10:19:31 +0000
changeset 240939 03c6a758c9e8da0dfcad48788a8eabb6f9d899d2
parent 240938 70ffdede9e2bba10442df671fa8ae10938508162
child 240940 beb6d3e078d0eb1802922431af4e63e0fc85d0b5
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1101602
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1101602 - Add --gc-zeal option to JS shell r=sfink
js/src/gc/GCRuntime.h
js/src/jsgc.cpp
js/src/shell/js.cpp
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -319,16 +319,17 @@ class GCRuntime
     void notifyDidPaint();
     void shrinkBuffers();
     void onOutOfMallocMemory();
     void onOutOfMallocMemory(const AutoLockGC &lock);
 
 #ifdef JS_GC_ZEAL
     const void *addressOfZealMode() { return &zealMode; }
     void setZeal(uint8_t zeal, uint32_t frequency);
+    bool parseAndSetZeal(const char *str);
     void setNextScheduled(uint32_t count);
     void verifyPreBarriers();
     void verifyPostBarriers();
     void maybeVerifyPreBarriers(bool always);
     void maybeVerifyPostBarriers(bool always);
     bool selectForMarking(JSObject *object);
     void clearSelectedForMarking();
     void setDeterministic(bool enable);
@@ -527,17 +528,16 @@ class GCRuntime
     void prepareToFreeChunk(ChunkInfo &info);
     void releaseChunk(Chunk *chunk);
 
     friend class BackgroundAllocTask;
     friend class AutoMaybeStartBackgroundAllocation;
     inline bool wantBackgroundAllocation(const AutoLockGC &lock) const;
     void startBackgroundAllocTaskIfIdle();
 
-    bool initZeal();
     void requestMajorGC(JS::gcreason::Reason reason);
     void collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
                  JS::gcreason::Reason reason);
     bool gcCycle(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
                  JS::gcreason::Reason reason);
     gcstats::ZoneGCStats scanZonesBeforeGC();
     void budgetIncrementalGC(SliceBudget &budget);
     void resetIncrementalGC(const char *reason);
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -184,16 +184,17 @@
 #include "jsgcinlines.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/MacroForEach.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Move.h"
 
+#include <ctype.h>
 #include <string.h>
 #ifndef XP_WIN
 # include <sys/mman.h>
 # include <unistd.h>
 #endif
 
 #include "jsapi.h"
 #include "jsatom.h"
@@ -1280,32 +1281,32 @@ GCRuntime::setZeal(uint8_t zeal, uint32_
 
 void
 GCRuntime::setNextScheduled(uint32_t count)
 {
     nextScheduled = count;
 }
 
 bool
-GCRuntime::initZeal()
-{
-    const char *env = getenv("JS_GC_ZEAL");
-    if (!env)
-        return true;
-
+GCRuntime::parseAndSetZeal(const char *str)
+{
     int zeal = -1;
-    int frequency = JS_DEFAULT_ZEAL_FREQ;
-    if (strcmp(env, "help") != 0) {
-        zeal = atoi(env);
-        const char *p = strchr(env, ',');
-        if (p)
+    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 > ZealLimit || frequency < 0) {
+    if (zeal < 0 || zeal > ZealLimit || frequency <= 0) {
         fprintf(stderr, "Format: JS_GC_ZEAL=level[,N]\n");
         fputs(ZealModeHelpText, stderr);
         return false;
     }
 
     setZeal(zeal, frequency);
     return true;
 }
@@ -1355,17 +1356,18 @@ GCRuntime::init(uint32_t maxbytes, uint3
     } else {
         MOZ_ASSERT(nursery.nurserySize() > 0);
         if (!storeBuffer.enable())
             return false;
     }
 #endif
 
 #ifdef JS_GC_ZEAL
-    if (!initZeal())
+    const char *zealSpec = getenv("JS_GC_ZEAL");
+    if (zealSpec && zealSpec[0] && !parseAndSetZeal(zealSpec))
         return false;
 #endif
 
     if (!InitTrace(*this))
         return false;
 
     if (!marker.init(mode))
         return false;
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -5607,16 +5607,22 @@ SetRuntimeOptions(JSRuntime *rt, const O
             jsCacheDir = JS_strdup(rt, jsCacheDir);
         jsCacheAsmJSPath = JS_smprintf("%s/asmjs.cache", jsCacheDir);
     }
 
 #ifdef DEBUG
     dumpEntrainedVariables = op.getBoolOption("dump-entrained-variables");
 #endif
 
+#ifdef JS_GC_ZEAL
+    const char *zealStr = op.getStringOption("gc-zeal");
+    if (zealStr && !rt->gc.parseAndSetZeal(zealStr))
+        return false;
+#endif
+
     return true;
 }
 
 static int
 Shell(JSContext *cx, OptionParser *op, char **envp)
 {
     JSAutoRequest ar(cx);
 
@@ -5839,16 +5845,21 @@ main(int argc, char **argv, char **envp)
 	|| !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
 #ifdef JSGC_GENERATIONAL
         || !op.addIntOption('\0', "nursery-size", "SIZE-MB", "Set the maximum nursery size in MB", 16)
 #endif
+#ifdef JS_GC_ZEAL
+        || !op.addStringOption('z', "gc-zeal", "LEVEL[,N]",
+                               "Specifies zealous garbage collection, overriding the environement "
+                               "variable JS_GC_ZEAL.")
+#endif
     )
     {
         return EXIT_FAILURE;
     }
 
     op.setArgTerminatesOptions("script", true);
     op.setArgCapturesRest("scriptArgs");