]>
Commit | Line | Data |
---|---|---|
6fe7ccc8 A |
1 | /* |
2 | * Copyright (C) 2011 Apple Inc. All rights reserved. | |
3 | * | |
4 | * Redistribution and use in source and binary forms, with or without | |
5 | * modification, are permitted provided that the following conditions | |
6 | * are met: | |
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. | |
12 | * | |
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. | |
24 | */ | |
25 | ||
26 | #include "config.h" | |
27 | #include "Options.h" | |
28 | ||
29 | #include <limits> | |
30 | #include <wtf/NumberOfCores.h> | |
31 | #include <wtf/PageBlock.h> | |
32 | ||
33 | #if OS(DARWIN) && ENABLE(PARALLEL_GC) | |
34 | #include <sys/sysctl.h> | |
35 | #endif | |
36 | ||
37 | // Set to 1 to control the heuristics using environment variables. | |
38 | #define ENABLE_RUN_TIME_HEURISTICS 0 | |
39 | ||
40 | #if ENABLE(RUN_TIME_HEURISTICS) | |
41 | #include <stdio.h> | |
42 | #include <stdlib.h> | |
43 | #include <wtf/StdLibExtras.h> | |
44 | #endif | |
45 | ||
46 | namespace JSC { namespace Options { | |
47 | ||
48 | bool useJIT; | |
49 | ||
50 | unsigned maximumOptimizationCandidateInstructionCount; | |
51 | ||
52 | unsigned maximumFunctionForCallInlineCandidateInstructionCount; | |
53 | unsigned maximumFunctionForConstructInlineCandidateInstructionCount; | |
54 | ||
55 | unsigned maximumInliningDepth; | |
56 | ||
57 | int32_t thresholdForJITAfterWarmUp; | |
58 | int32_t thresholdForJITSoon; | |
59 | ||
60 | int32_t thresholdForOptimizeAfterWarmUp; | |
61 | int32_t thresholdForOptimizeAfterLongWarmUp; | |
62 | int32_t thresholdForOptimizeSoon; | |
63 | ||
64 | int32_t executionCounterIncrementForLoop; | |
65 | int32_t executionCounterIncrementForReturn; | |
66 | ||
67 | unsigned desiredSpeculativeSuccessFailRatio; | |
68 | ||
69 | double likelyToTakeSlowCaseThreshold; | |
70 | double couldTakeSlowCaseThreshold; | |
71 | unsigned likelyToTakeSlowCaseMinimumCount; | |
72 | unsigned couldTakeSlowCaseMinimumCount; | |
73 | ||
74 | double osrExitProminenceForFrequentExitSite; | |
75 | ||
76 | unsigned largeFailCountThresholdBase; | |
77 | unsigned largeFailCountThresholdBaseForLoop; | |
78 | unsigned forcedOSRExitCountForReoptimization; | |
79 | ||
80 | unsigned reoptimizationRetryCounterMax; | |
81 | unsigned reoptimizationRetryCounterStep; | |
82 | ||
83 | unsigned minimumOptimizationDelay; | |
84 | unsigned maximumOptimizationDelay; | |
85 | double desiredProfileLivenessRate; | |
86 | double desiredProfileFullnessRate; | |
87 | ||
88 | double doubleVoteRatioForDoubleFormat; | |
89 | ||
90 | unsigned minimumNumberOfScansBetweenRebalance; | |
91 | unsigned gcMarkStackSegmentSize; | |
92 | unsigned minimumNumberOfCellsToKeep; | |
93 | unsigned maximumNumberOfSharedSegments; | |
94 | unsigned sharedStackWakeupThreshold; | |
95 | unsigned numberOfGCMarkers; | |
96 | unsigned opaqueRootMergeThreshold; | |
97 | ||
98 | #if ENABLE(RUN_TIME_HEURISTICS) | |
99 | static bool parse(const char* string, bool& value) | |
100 | { | |
101 | if (!strcasecmp(string, "true") || !strcasecmp(string, "yes") || !strcmp(string, "1")) { | |
102 | value = true; | |
103 | return true; | |
104 | } | |
105 | if (!strcasecmp(string, "false") || !strcasecmp(string, "no") || !strcmp(string, "0")) { | |
106 | value = false; | |
107 | return true; | |
108 | } | |
109 | return false; | |
110 | } | |
111 | ||
112 | static bool parse(const char* string, int32_t& value) | |
113 | { | |
114 | return sscanf(string, "%d", &value) == 1; | |
115 | } | |
116 | ||
117 | static bool parse(const char* string, unsigned& value) | |
118 | { | |
119 | return sscanf(string, "%u", &value) == 1; | |
120 | } | |
121 | ||
122 | static bool parse(const char* string, double& value) | |
123 | { | |
124 | return sscanf(string, "%lf", &value) == 1; | |
125 | } | |
126 | ||
127 | template<typename T, typename U> | |
128 | void setHeuristic(T& variable, const char* name, U value) | |
129 | { | |
130 | const char* stringValue = getenv(name); | |
131 | if (!stringValue) { | |
132 | variable = safeCast<T>(value); | |
133 | return; | |
134 | } | |
135 | ||
136 | if (parse(stringValue, variable)) | |
137 | return; | |
138 | ||
139 | fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue); | |
140 | variable = safeCast<T>(value); | |
141 | } | |
142 | ||
143 | #define SET(variable, value) setHeuristic(variable, "JSC_" #variable, value) | |
144 | #else | |
145 | #define SET(variable, value) variable = value | |
146 | #endif | |
147 | ||
148 | void initializeOptions() | |
149 | { | |
150 | SET(useJIT, true); | |
151 | ||
152 | SET(maximumOptimizationCandidateInstructionCount, 10000); | |
153 | ||
154 | SET(maximumFunctionForCallInlineCandidateInstructionCount, 180); | |
155 | SET(maximumFunctionForConstructInlineCandidateInstructionCount, 100); | |
156 | ||
157 | SET(maximumInliningDepth, 5); | |
158 | ||
159 | SET(thresholdForJITAfterWarmUp, 100); | |
160 | SET(thresholdForJITSoon, 100); | |
161 | ||
162 | SET(thresholdForOptimizeAfterWarmUp, 1000); | |
163 | SET(thresholdForOptimizeAfterLongWarmUp, 5000); | |
164 | SET(thresholdForOptimizeSoon, 1000); | |
165 | ||
166 | SET(executionCounterIncrementForLoop, 1); | |
167 | SET(executionCounterIncrementForReturn, 15); | |
168 | ||
169 | SET(desiredSpeculativeSuccessFailRatio, 6); | |
170 | ||
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); | |
175 | ||
176 | SET(osrExitProminenceForFrequentExitSite, 0.3); | |
177 | ||
178 | SET(largeFailCountThresholdBase, 20); | |
179 | SET(largeFailCountThresholdBaseForLoop, 1); | |
180 | SET(forcedOSRExitCountForReoptimization, 250); | |
181 | ||
182 | SET(reoptimizationRetryCounterStep, 1); | |
183 | ||
184 | SET(minimumOptimizationDelay, 1); | |
185 | SET(maximumOptimizationDelay, 5); | |
186 | SET(desiredProfileLivenessRate, 0.75); | |
187 | SET(desiredProfileFullnessRate, 0.35); | |
188 | ||
189 | SET(doubleVoteRatioForDoubleFormat, 2); | |
190 | ||
191 | SET(minimumNumberOfScansBetweenRebalance, 10000); | |
192 | SET(gcMarkStackSegmentSize, pageSize()); | |
193 | SET(minimumNumberOfCellsToKeep, 10); | |
194 | SET(maximumNumberOfSharedSegments, 3); | |
195 | SET(sharedStackWakeupThreshold, 1); | |
196 | SET(opaqueRootMergeThreshold, 1000); | |
197 | ||
198 | int cpusToUse = 1; | |
199 | #if ENABLE(PARALLEL_GC) | |
200 | cpusToUse = WTF::numberOfProcessorCores(); | |
201 | #endif | |
202 | // We don't scale so well beyond 4. | |
203 | if (cpusToUse > 4) | |
204 | cpusToUse = 4; | |
205 | // Be paranoid, it is the OS we're dealing with, after all. | |
206 | if (cpusToUse < 1) | |
207 | cpusToUse = 1; | |
208 | ||
209 | SET(numberOfGCMarkers, cpusToUse); | |
210 | ||
211 | ASSERT(thresholdForOptimizeAfterLongWarmUp >= thresholdForOptimizeAfterWarmUp); | |
212 | ASSERT(thresholdForOptimizeAfterWarmUp >= thresholdForOptimizeSoon); | |
213 | ASSERT(thresholdForOptimizeAfterWarmUp >= 0); | |
214 | ||
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++; | |
223 | ||
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())); | |
226 | } | |
227 | ||
228 | } } // namespace JSC::Options | |
229 | ||
230 |