2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <wtf/NumberOfCores.h>
31 #include <wtf/PageBlock.h>
33 #if OS(DARWIN) && ENABLE(PARALLEL_GC)
34 #include <sys/sysctl.h>
37 // Set to 1 to control the heuristics using environment variables.
38 #define ENABLE_RUN_TIME_HEURISTICS 0
40 #if ENABLE(RUN_TIME_HEURISTICS)
43 #include <wtf/StdLibExtras.h>
46 namespace JSC
{ namespace Options
{
50 unsigned maximumOptimizationCandidateInstructionCount
;
52 unsigned maximumFunctionForCallInlineCandidateInstructionCount
;
53 unsigned maximumFunctionForConstructInlineCandidateInstructionCount
;
55 unsigned maximumInliningDepth
;
57 int32_t thresholdForJITAfterWarmUp
;
58 int32_t thresholdForJITSoon
;
60 int32_t thresholdForOptimizeAfterWarmUp
;
61 int32_t thresholdForOptimizeAfterLongWarmUp
;
62 int32_t thresholdForOptimizeSoon
;
64 int32_t executionCounterIncrementForLoop
;
65 int32_t executionCounterIncrementForReturn
;
67 unsigned desiredSpeculativeSuccessFailRatio
;
69 double likelyToTakeSlowCaseThreshold
;
70 double couldTakeSlowCaseThreshold
;
71 unsigned likelyToTakeSlowCaseMinimumCount
;
72 unsigned couldTakeSlowCaseMinimumCount
;
74 double osrExitProminenceForFrequentExitSite
;
76 unsigned largeFailCountThresholdBase
;
77 unsigned largeFailCountThresholdBaseForLoop
;
78 unsigned forcedOSRExitCountForReoptimization
;
80 unsigned reoptimizationRetryCounterMax
;
81 unsigned reoptimizationRetryCounterStep
;
83 unsigned minimumOptimizationDelay
;
84 unsigned maximumOptimizationDelay
;
85 double desiredProfileLivenessRate
;
86 double desiredProfileFullnessRate
;
88 double doubleVoteRatioForDoubleFormat
;
90 unsigned minimumNumberOfScansBetweenRebalance
;
91 unsigned gcMarkStackSegmentSize
;
92 unsigned minimumNumberOfCellsToKeep
;
93 unsigned maximumNumberOfSharedSegments
;
94 unsigned sharedStackWakeupThreshold
;
95 unsigned numberOfGCMarkers
;
96 unsigned opaqueRootMergeThreshold
;
98 #if ENABLE(RUN_TIME_HEURISTICS)
99 static bool parse(const char* string
, bool& value
)
101 if (!strcasecmp(string
, "true") || !strcasecmp(string
, "yes") || !strcmp(string
, "1")) {
105 if (!strcasecmp(string
, "false") || !strcasecmp(string
, "no") || !strcmp(string
, "0")) {
112 static bool parse(const char* string
, int32_t& value
)
114 return sscanf(string
, "%d", &value
) == 1;
117 static bool parse(const char* string
, unsigned& value
)
119 return sscanf(string
, "%u", &value
) == 1;
122 static bool parse(const char* string
, double& value
)
124 return sscanf(string
, "%lf", &value
) == 1;
127 template<typename T
, typename U
>
128 void setHeuristic(T
& variable
, const char* name
, U value
)
130 const char* stringValue
= getenv(name
);
132 variable
= safeCast
<T
>(value
);
136 if (parse(stringValue
, variable
))
139 fprintf(stderr
, "WARNING: failed to parse %s=%s\n", name
, stringValue
);
140 variable
= safeCast
<T
>(value
);
143 #define SET(variable, value) setHeuristic(variable, "JSC_" #variable, value)
145 #define SET(variable, value) variable = value
148 void initializeOptions()
152 SET(maximumOptimizationCandidateInstructionCount
, 10000);
154 SET(maximumFunctionForCallInlineCandidateInstructionCount
, 180);
155 SET(maximumFunctionForConstructInlineCandidateInstructionCount
, 100);
157 SET(maximumInliningDepth
, 5);
159 SET(thresholdForJITAfterWarmUp
, 100);
160 SET(thresholdForJITSoon
, 100);
162 SET(thresholdForOptimizeAfterWarmUp
, 1000);
163 SET(thresholdForOptimizeAfterLongWarmUp
, 5000);
164 SET(thresholdForOptimizeSoon
, 1000);
166 SET(executionCounterIncrementForLoop
, 1);
167 SET(executionCounterIncrementForReturn
, 15);
169 SET(desiredSpeculativeSuccessFailRatio
, 6);
171 SET(likelyToTakeSlowCaseThreshold
, 0.15);
172 SET(couldTakeSlowCaseThreshold
, 0.05); // Shouldn't be zero because some ops will spuriously take slow case, for example for linking or caching.
173 SET(likelyToTakeSlowCaseMinimumCount
, 100);
174 SET(couldTakeSlowCaseMinimumCount
, 10);
176 SET(osrExitProminenceForFrequentExitSite
, 0.3);
178 SET(largeFailCountThresholdBase
, 20);
179 SET(largeFailCountThresholdBaseForLoop
, 1);
180 SET(forcedOSRExitCountForReoptimization
, 250);
182 SET(reoptimizationRetryCounterStep
, 1);
184 SET(minimumOptimizationDelay
, 1);
185 SET(maximumOptimizationDelay
, 5);
186 SET(desiredProfileLivenessRate
, 0.75);
187 SET(desiredProfileFullnessRate
, 0.35);
189 SET(doubleVoteRatioForDoubleFormat
, 2);
191 SET(minimumNumberOfScansBetweenRebalance
, 10000);
192 SET(gcMarkStackSegmentSize
, pageSize());
193 SET(minimumNumberOfCellsToKeep
, 10);
194 SET(maximumNumberOfSharedSegments
, 3);
195 SET(sharedStackWakeupThreshold
, 1);
196 SET(opaqueRootMergeThreshold
, 1000);
199 #if ENABLE(PARALLEL_GC)
200 cpusToUse
= WTF::numberOfProcessorCores();
202 // We don't scale so well beyond 4.
205 // Be paranoid, it is the OS we're dealing with, after all.
209 SET(numberOfGCMarkers
, cpusToUse
);
211 ASSERT(thresholdForOptimizeAfterLongWarmUp
>= thresholdForOptimizeAfterWarmUp
);
212 ASSERT(thresholdForOptimizeAfterWarmUp
>= thresholdForOptimizeSoon
);
213 ASSERT(thresholdForOptimizeAfterWarmUp
>= 0);
215 // Compute the maximum value of the reoptimization retry counter. This is simply
216 // the largest value at which we don't overflow the execute counter, when using it
217 // to left-shift the execution counter by this amount. Currently the value ends
218 // up being 18, so this loop is not so terrible; it probably takes up ~100 cycles
219 // total on a 32-bit processor.
220 reoptimizationRetryCounterMax
= 0;
221 while ((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp
) << (reoptimizationRetryCounterMax
+ 1)) <= static_cast<int64_t>(std::numeric_limits
<int32_t>::max()))
222 reoptimizationRetryCounterMax
++;
224 ASSERT((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp
) << reoptimizationRetryCounterMax
) > 0);
225 ASSERT((static_cast<int64_t>(thresholdForOptimizeAfterLongWarmUp
) << reoptimizationRetryCounterMax
) <= static_cast<int64_t>(std::numeric_limits
<int32_t>::max()));
228 } } // namespace JSC::Options