]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/Options.cpp
JavaScriptCore-7600.1.4.16.1.tar.gz
[apple/javascriptcore.git] / runtime / Options.cpp
index 40711bfa30fae2a796fd962041d0feba108bd1a6..f0ddf98e745e606b15db48f47f03678c96534522 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,9 +29,9 @@
 #include "HeapStatistics.h"
 #include <algorithm>
 #include <limits>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <wtf/DataLog.h>
 #include <wtf/NumberOfCores.h>
 #include <wtf/PageBlock.h>
 #include <wtf/StdLibExtras.h>
@@ -76,37 +76,73 @@ static bool parse(const char* string, OptionRange& value)
     return value.init(string);
 }
 
+static bool parse(const char* string, const char*& value)
+{
+    value = string;
+    return true;
+}
+
+static bool parse(const char* string, GCLogging::Level& value)
+{
+    if (!strcasecmp(string, "none") || !strcasecmp(string, "no") || !strcasecmp(string, "false") || !strcmp(string, "0")) {
+        value = GCLogging::None;
+        return true;
+    }
+
+    if (!strcasecmp(string, "basic") || !strcasecmp(string, "yes") || !strcasecmp(string, "true") || !strcmp(string, "1")) {
+        value = GCLogging::Basic;
+        return true;
+    }
+
+    if (!strcasecmp(string, "verbose") || !strcmp(string, "2")) {
+        value = GCLogging::Verbose;
+        return true;
+    }
+
+    return false;
+}
+
 template<typename T>
-void overrideOptionWithHeuristic(T& variable, const char* name)
+bool overrideOptionWithHeuristic(T& variable, const char* name)
 {
 #if !OS(WINCE)
     const char* stringValue = getenv(name);
     if (!stringValue)
-        return;
+        return false;
     
     if (parse(stringValue, variable))
-        return;
+        return true;
     
     fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue);
 #endif
+    return false;
 }
 
-static unsigned computeNumberOfGCMarkers(int maxNumberOfGCMarkers)
+static unsigned computeNumberOfWorkerThreads(int maxNumberOfWorkerThreads, int minimum = 1)
 {
-    int cpusToUse = 1;
-
-#if ENABLE(PARALLEL_GC)
-    cpusToUse = std::min(WTF::numberOfProcessorCores(), maxNumberOfGCMarkers);
+    int cpusToUse = std::min(WTF::numberOfProcessorCores(), maxNumberOfWorkerThreads);
 
     // Be paranoid, it is the OS we're dealing with, after all.
     ASSERT(cpusToUse >= 1);
-    if (cpusToUse < 1)
-        cpusToUse = 1;
+    return std::max(cpusToUse, minimum);
+}
+
+static int32_t computePriorityDeltaOfWorkerThreads(int32_t twoCorePriorityDelta, int32_t multiCorePriorityDelta)
+{
+    if (WTF::numberOfProcessorCores() <= 2)
+        return twoCorePriorityDelta;
+
+    return multiCorePriorityDelta;
+}
+
+static unsigned computeNumberOfGCMarkers(unsigned maxNumberOfGCMarkers)
+{
+#if ENABLE(PARALLEL_GC)
+    return computeNumberOfWorkerThreads(maxNumberOfGCMarkers);
 #else
     UNUSED_PARAM(maxNumberOfGCMarkers);
+    return 1;
 #endif
-
-    return cpusToUse;
 }
 
 bool OptionRange::init(const char* rangeString)
@@ -172,6 +208,59 @@ const Options::EntryInfo Options::s_optionsInfo[Options::numberOfOptions] = {
 #undef FOR_EACH_OPTION
 };
 
+static void recomputeDependentOptions()
+{
+#if !ENABLE(JIT)
+    Options::useLLInt() = true;
+    Options::useJIT() = false;
+    Options::useDFGJIT() = false;
+    Options::useFTLJIT() = false;
+#endif
+#if !ENABLE(YARR_JIT)
+    Options::useRegExpJIT() = false;
+#endif
+#if !ENABLE(CONCURRENT_JIT)
+    Options::enableConcurrentJIT() = false;
+#endif
+#if !ENABLE(DFG_JIT)
+    Options::useDFGJIT() = false;
+    Options::useFTLJIT() = false;
+#endif
+#if !ENABLE(FTL_JIT)
+    Options::useFTLJIT() = false;
+#endif
+
+    if (Options::showDisassembly()
+        || Options::showDFGDisassembly()
+        || Options::showFTLDisassembly()
+        || Options::dumpBytecodeAtDFGTime()
+        || Options::dumpGraphAtEachPhase()
+        || Options::verboseCompilation()
+        || Options::verboseFTLCompilation()
+        || Options::logCompilationChanges()
+        || Options::validateGraph()
+        || Options::validateGraphAtEachPhase()
+        || Options::verboseOSR()
+        || Options::verboseCompilationQueue()
+        || Options::reportCompileTimes()
+        || Options::reportFTLCompileTimes()
+        || Options::verboseCFA()
+        || Options::verboseFTLFailure())
+        Options::alwaysComputeHash() = true;
+    
+    // Compute the maximum value of the reoptimization retry counter. This is simply
+    // the largest value at which we don't overflow the execute counter, when using it
+    // to left-shift the execution counter by this amount. Currently the value ends
+    // up being 18, so this loop is not so terrible; it probably takes up ~100 cycles
+    // total on a 32-bit processor.
+    Options::reoptimizationRetryCounterMax() = 0;
+    while ((static_cast<int64_t>(Options::thresholdForOptimizeAfterLongWarmUp()) << (Options::reoptimizationRetryCounterMax() + 1)) <= static_cast<int64_t>(std::numeric_limits<int32_t>::max()))
+        Options::reoptimizationRetryCounterMax()++;
+
+    ASSERT((static_cast<int64_t>(Options::thresholdForOptimizeAfterLongWarmUp()) << Options::reoptimizationRetryCounterMax()) > 0);
+    ASSERT((static_cast<int64_t>(Options::thresholdForOptimizeAfterLongWarmUp()) << Options::reoptimizationRetryCounterMax()) <= static_cast<int64_t>(std::numeric_limits<int32_t>::max()));
+}
+
 void Options::initialize()
 {
     // Initialize each of the options with their default values:
@@ -180,20 +269,12 @@ void Options::initialize()
     JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
         
-#if USE(CF) || OS(UNIX)
-    objectsAreImmortal() = !!getenv("JSImmortalZombieEnabled");
-    useZombieMode() = !!getenv("JSImmortalZombieEnabled") || !!getenv("JSZombieEnabled");
-
-    gcMaxHeapSize() = getenv("GCMaxHeapSize") ? HeapStatistics::parseMemoryAmount(getenv("GCMaxHeapSize")) : 0;
-    recordGCPauseTimes() = !!getenv("JSRecordGCPauseTimes");
-    logHeapStatisticsAtExit() = gcMaxHeapSize() || recordGCPauseTimes();
-#endif
-
     // Allow environment vars to override options if applicable.
     // The evn var should be the name of the option prefixed with
     // "JSC_".
 #define FOR_EACH_OPTION(type_, name_, defaultValue_) \
-    overrideOptionWithHeuristic(name_(), "JSC_" #name_);
+    if (overrideOptionWithHeuristic(name_(), "JSC_" #name_)) \
+        s_options[OPT_##name_].didOverride = true;
     JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
 
@@ -201,30 +282,12 @@ void Options::initialize()
     ; // Deconfuse editors that do auto indentation
 #endif
     
-#if !ENABLE(JIT)
-    useJIT() = false;
-    useDFGJIT() = false;
-#endif
-#if !ENABLE(YARR_JIT)
-    useRegExpJIT() = false;
-#endif
-    
-    // Do range checks where needed and make corrections to the options:
-    ASSERT(thresholdForOptimizeAfterLongWarmUp() >= thresholdForOptimizeAfterWarmUp());
-    ASSERT(thresholdForOptimizeAfterWarmUp() >= thresholdForOptimizeSoon());
-    ASSERT(thresholdForOptimizeAfterWarmUp() >= 0);
+    recomputeDependentOptions();
 
-    // Compute the maximum value of the reoptimization retry counter. This is simply
-    // the largest value at which we don't overflow the execute counter, when using it
-    // to left-shift the execution counter by this amount. Currently the value ends
-    // up being 18, so this loop is not so terrible; it probably takes up ~100 cycles
-    // total on a 32-bit processor.
-    reoptimizationRetryCounterMax() = 0;
-    while ((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp()) << (reoptimizationRetryCounterMax() + 1)) <= static_cast<int64_t>(std::numeric_limits<int32>::max()))
-        reoptimizationRetryCounterMax()++;
-
-    ASSERT((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp()) << reoptimizationRetryCounterMax()) > 0);
-    ASSERT((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp()) << reoptimizationRetryCounterMax()) <= static_cast<int64_t>(std::numeric_limits<int32>::max()));
+    // Do range checks where needed and make corrections to the options:
+    ASSERT(Options::thresholdForOptimizeAfterLongWarmUp() >= Options::thresholdForOptimizeAfterWarmUp());
+    ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= Options::thresholdForOptimizeSoon());
+    ASSERT(Options::thresholdForOptimizeAfterWarmUp() >= 0);
 }
 
 // Parses a single command line option in the format "<optionName>=<value>"
@@ -244,10 +307,12 @@ bool Options::setOption(const char* arg)
 #define FOR_EACH_OPTION(type_, name_, defaultValue_)    \
     if (!strncmp(arg, #name_, equalStr - arg)) {        \
         type_ value;                                    \
-        value = 0;                                      \
+        value = (defaultValue_);                        \
         bool success = parse(valueStr, value);          \
         if (success) {                                  \
             name_() = value;                            \
+            s_options[OPT_##name_].didOverride = true;  \
+            recomputeDependentOptions();                \
             return true;                                \
         }                                               \
         return false;                                   \
@@ -256,7 +321,7 @@ bool Options::setOption(const char* arg)
     JSC_OPTIONS(FOR_EACH_OPTION)
 #undef FOR_EACH_OPTION
 
-        return false; // No option matched.
+    return false; // No option matched.
 }
 
 void Options::dumpAllOptions(FILE* stream)
@@ -288,6 +353,17 @@ void Options::dumpOption(OptionID id, FILE* stream, const char* header, const ch
     case optionRangeType:
         fprintf(stream, "%s", s_options[id].u.optionRangeVal.rangeString());
         break;
+    case optionStringType: {
+        const char* option = s_options[id].u.optionStringVal;
+        if (!option)
+            option = "";
+        fprintf(stream, "%s", option);
+        break;
+    }
+    case gcLogLevelType: {
+        fprintf(stream, "%s", GCLogging::levelAsString(s_options[id].u.gcLogLevelVal));
+        break;
+    }
     }
     fprintf(stream, "%s", footer);
 }