]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/Options.cpp
JavaScriptCore-1097.3.tar.gz
[apple/javascriptcore.git] / runtime / Options.cpp
diff --git a/runtime/Options.cpp b/runtime/Options.cpp
new file mode 100644 (file)
index 0000000..8f5a050
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "Options.h"
+
+#include <limits>
+#include <wtf/NumberOfCores.h>
+#include <wtf/PageBlock.h>
+
+#if OS(DARWIN) && ENABLE(PARALLEL_GC)
+#include <sys/sysctl.h>
+#endif
+
+// Set to 1 to control the heuristics using environment variables.
+#define ENABLE_RUN_TIME_HEURISTICS 0
+
+#if ENABLE(RUN_TIME_HEURISTICS)
+#include <stdio.h>
+#include <stdlib.h>
+#include <wtf/StdLibExtras.h>
+#endif
+
+namespace JSC { namespace Options {
+
+bool useJIT;
+
+unsigned maximumOptimizationCandidateInstructionCount;
+
+unsigned maximumFunctionForCallInlineCandidateInstructionCount;
+unsigned maximumFunctionForConstructInlineCandidateInstructionCount;
+
+unsigned maximumInliningDepth;
+
+int32_t thresholdForJITAfterWarmUp;
+int32_t thresholdForJITSoon;
+
+int32_t thresholdForOptimizeAfterWarmUp;
+int32_t thresholdForOptimizeAfterLongWarmUp;
+int32_t thresholdForOptimizeSoon;
+
+int32_t executionCounterIncrementForLoop;
+int32_t executionCounterIncrementForReturn;
+
+unsigned desiredSpeculativeSuccessFailRatio;
+
+double likelyToTakeSlowCaseThreshold;
+double couldTakeSlowCaseThreshold;
+unsigned likelyToTakeSlowCaseMinimumCount;
+unsigned couldTakeSlowCaseMinimumCount;
+
+double osrExitProminenceForFrequentExitSite;
+
+unsigned largeFailCountThresholdBase;
+unsigned largeFailCountThresholdBaseForLoop;
+unsigned forcedOSRExitCountForReoptimization;
+
+unsigned reoptimizationRetryCounterMax;
+unsigned reoptimizationRetryCounterStep;
+
+unsigned minimumOptimizationDelay;
+unsigned maximumOptimizationDelay;
+double desiredProfileLivenessRate;
+double desiredProfileFullnessRate;
+
+double doubleVoteRatioForDoubleFormat;
+
+unsigned minimumNumberOfScansBetweenRebalance;
+unsigned gcMarkStackSegmentSize;
+unsigned minimumNumberOfCellsToKeep;
+unsigned maximumNumberOfSharedSegments;
+unsigned sharedStackWakeupThreshold;
+unsigned numberOfGCMarkers;
+unsigned opaqueRootMergeThreshold;
+
+#if ENABLE(RUN_TIME_HEURISTICS)
+static bool parse(const char* string, bool& value)
+{
+    if (!strcasecmp(string, "true") || !strcasecmp(string, "yes") || !strcmp(string, "1")) {
+        value = true;
+        return true;
+    }
+    if (!strcasecmp(string, "false") || !strcasecmp(string, "no") || !strcmp(string, "0")) {
+        value = false;
+        return true;
+    }
+    return false;
+}
+
+static bool parse(const char* string, int32_t& value)
+{
+    return sscanf(string, "%d", &value) == 1;
+}
+
+static bool parse(const char* string, unsigned& value)
+{
+    return sscanf(string, "%u", &value) == 1;
+}
+
+static bool parse(const char* string, double& value)
+{
+    return sscanf(string, "%lf", &value) == 1;
+}
+
+template<typename T, typename U>
+void setHeuristic(T& variable, const char* name, U value)
+{
+    const char* stringValue = getenv(name);
+    if (!stringValue) {
+        variable = safeCast<T>(value);
+        return;
+    }
+    
+    if (parse(stringValue, variable))
+        return;
+    
+    fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue);
+    variable = safeCast<T>(value);
+}
+
+#define SET(variable, value) setHeuristic(variable, "JSC_" #variable, value)
+#else
+#define SET(variable, value) variable = value
+#endif
+
+void initializeOptions()
+{
+    SET(useJIT, true);
+    
+    SET(maximumOptimizationCandidateInstructionCount, 10000);
+    
+    SET(maximumFunctionForCallInlineCandidateInstructionCount, 180);
+    SET(maximumFunctionForConstructInlineCandidateInstructionCount, 100);
+    
+    SET(maximumInliningDepth, 5);
+
+    SET(thresholdForJITAfterWarmUp,     100);
+    SET(thresholdForJITSoon,            100);
+
+    SET(thresholdForOptimizeAfterWarmUp,     1000);
+    SET(thresholdForOptimizeAfterLongWarmUp, 5000);
+    SET(thresholdForOptimizeSoon,            1000);
+
+    SET(executionCounterIncrementForLoop,   1);
+    SET(executionCounterIncrementForReturn, 15);
+
+    SET(desiredSpeculativeSuccessFailRatio, 6);
+    
+    SET(likelyToTakeSlowCaseThreshold,    0.15);
+    SET(couldTakeSlowCaseThreshold,       0.05); // Shouldn't be zero because some ops will spuriously take slow case, for example for linking or caching.
+    SET(likelyToTakeSlowCaseMinimumCount, 100);
+    SET(couldTakeSlowCaseMinimumCount,    10);
+    
+    SET(osrExitProminenceForFrequentExitSite, 0.3);
+
+    SET(largeFailCountThresholdBase,         20);
+    SET(largeFailCountThresholdBaseForLoop,  1);
+    SET(forcedOSRExitCountForReoptimization, 250);
+
+    SET(reoptimizationRetryCounterStep, 1);
+
+    SET(minimumOptimizationDelay,   1);
+    SET(maximumOptimizationDelay,   5);
+    SET(desiredProfileLivenessRate, 0.75);
+    SET(desiredProfileFullnessRate, 0.35);
+    
+    SET(doubleVoteRatioForDoubleFormat, 2);
+    
+    SET(minimumNumberOfScansBetweenRebalance, 10000);
+    SET(gcMarkStackSegmentSize,               pageSize());
+    SET(minimumNumberOfCellsToKeep,           10);
+    SET(maximumNumberOfSharedSegments,        3);
+    SET(sharedStackWakeupThreshold,           1);
+    SET(opaqueRootMergeThreshold,             1000);
+
+    int cpusToUse = 1;
+#if ENABLE(PARALLEL_GC)
+    cpusToUse = WTF::numberOfProcessorCores();
+#endif
+    // We don't scale so well beyond 4.
+    if (cpusToUse > 4)
+        cpusToUse = 4;
+    // Be paranoid, it is the OS we're dealing with, after all.
+    if (cpusToUse < 1)
+        cpusToUse = 1;
+    
+    SET(numberOfGCMarkers, cpusToUse);
+
+    ASSERT(thresholdForOptimizeAfterLongWarmUp >= thresholdForOptimizeAfterWarmUp);
+    ASSERT(thresholdForOptimizeAfterWarmUp >= thresholdForOptimizeSoon);
+    ASSERT(thresholdForOptimizeAfterWarmUp >= 0);
+    
+    // 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_t>::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_t>::max()));
+}
+
+} } // namespace JSC::Options
+
+