]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/Options.cpp
JavaScriptCore-1097.13.tar.gz
[apple/javascriptcore.git] / runtime / Options.cpp
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