X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/1df5f87f1309a8daa30dabdee855f48ae40d14ab..6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174:/runtime/Options.cpp?ds=sidebyside diff --git a/runtime/Options.cpp b/runtime/Options.cpp new file mode 100644 index 0000000..8f5a050 --- /dev/null +++ b/runtime/Options.cpp @@ -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 +#include +#include + +#if OS(DARWIN) && ENABLE(PARALLEL_GC) +#include +#endif + +// Set to 1 to control the heuristics using environment variables. +#define ENABLE_RUN_TIME_HEURISTICS 0 + +#if ENABLE(RUN_TIME_HEURISTICS) +#include +#include +#include +#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 +void setHeuristic(T& variable, const char* name, U value) +{ + const char* stringValue = getenv(name); + if (!stringValue) { + variable = safeCast(value); + return; + } + + if (parse(stringValue, variable)) + return; + + fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue); + variable = safeCast(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(thresholdForOptimizeAfterLongWarmUp) << (reoptimizationRetryCounterMax + 1)) <= static_cast(std::numeric_limits::max())) + reoptimizationRetryCounterMax++; + + ASSERT((static_cast(thresholdForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) > 0); + ASSERT((static_cast(thresholdForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) <= static_cast(std::numeric_limits::max())); +} + +} } // namespace JSC::Options + +