Re-enable parallel GC on Mac
[WebKit-https.git] / Source / JavaScriptCore / 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 unsigned maximumOptimizationCandidateInstructionCount;
49
50 unsigned maximumFunctionForCallInlineCandidateInstructionCount;
51 unsigned maximumFunctionForConstructInlineCandidateInstructionCount;
52
53 unsigned maximumInliningDepth;
54
55 int32_t executionCounterValueForJITAfterWarmUp;
56 int32_t executionCounterValueForDontJITAnytimeSoon;
57 int32_t executionCounterValueForJITSoon;
58
59 int32_t executionCounterValueForOptimizeAfterWarmUp;
60 int32_t executionCounterValueForOptimizeAfterLongWarmUp;
61 int32_t executionCounterValueForDontOptimizeAnytimeSoon;
62 int32_t executionCounterValueForOptimizeSoon;
63 int32_t executionCounterValueForOptimizeNextInvocation;
64
65 int32_t executionCounterIncrementForLoop;
66 int32_t executionCounterIncrementForReturn;
67
68 unsigned desiredSpeculativeSuccessFailRatio;
69
70 double likelyToTakeSlowCaseThreshold;
71 double couldTakeSlowCaseThreshold;
72 unsigned likelyToTakeSlowCaseMinimumCount;
73 unsigned couldTakeSlowCaseMinimumCount;
74
75 double osrExitProminenceForFrequentExitSite;
76
77 unsigned largeFailCountThresholdBase;
78 unsigned largeFailCountThresholdBaseForLoop;
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, int32_t& value)
100 {
101     return sscanf(string, "%d", &value) == 1;
102 }
103
104 static bool parse(const char* string, unsigned& value)
105 {
106     return sscanf(string, "%u", &value) == 1;
107 }
108
109 static bool parse(const char* string, double& value)
110 {
111     return sscanf(string, "%lf", &value) == 1;
112 }
113
114 template<typename T, typename U>
115 void setHeuristic(T& variable, const char* name, U value)
116 {
117     const char* stringValue = getenv(name);
118     if (!stringValue) {
119         variable = safeCast<T>(value);
120         return;
121     }
122     
123     if (parse(stringValue, variable))
124         return;
125     
126     fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue);
127     variable = safeCast<T>(value);
128 }
129
130 #define SET(variable, value) setHeuristic(variable, "JSC_" #variable, value)
131 #else
132 #define SET(variable, value) variable = value
133 #endif
134
135 void initializeOptions()
136 {
137     SET(maximumOptimizationCandidateInstructionCount, 1100);
138     
139     SET(maximumFunctionForCallInlineCandidateInstructionCount, 180);
140     SET(maximumFunctionForConstructInlineCandidateInstructionCount, 100);
141     
142     SET(maximumInliningDepth, 5);
143
144     SET(executionCounterValueForJITAfterWarmUp,     -100);
145     SET(executionCounterValueForDontJITAnytimeSoon, std::numeric_limits<int32_t>::min());
146     SET(executionCounterValueForJITSoon,            -100);
147
148     SET(executionCounterValueForOptimizeAfterWarmUp,     -1000);
149     SET(executionCounterValueForOptimizeAfterLongWarmUp, -5000);
150     SET(executionCounterValueForDontOptimizeAnytimeSoon, std::numeric_limits<int32_t>::min());
151     SET(executionCounterValueForOptimizeSoon,            -1000);
152     SET(executionCounterValueForOptimizeNextInvocation,  0);
153
154     SET(executionCounterIncrementForLoop,   1);
155     SET(executionCounterIncrementForReturn, 15);
156
157     SET(desiredSpeculativeSuccessFailRatio, 6);
158     
159     SET(likelyToTakeSlowCaseThreshold,    0.15);
160     SET(couldTakeSlowCaseThreshold,       0.05); // Shouldn't be zero because some ops will spuriously take slow case, for example for linking or caching.
161     SET(likelyToTakeSlowCaseMinimumCount, 100);
162     SET(couldTakeSlowCaseMinimumCount,    10);
163     
164     SET(osrExitProminenceForFrequentExitSite, 0.3);
165
166     SET(largeFailCountThresholdBase,        20);
167     SET(largeFailCountThresholdBaseForLoop, 1);
168
169     SET(reoptimizationRetryCounterStep, 1);
170
171     SET(minimumOptimizationDelay,   1);
172     SET(maximumOptimizationDelay,   5);
173     SET(desiredProfileLivenessRate, 0.75);
174     SET(desiredProfileFullnessRate, 0.35);
175     
176     SET(doubleVoteRatioForDoubleFormat, 2);
177     
178     SET(minimumNumberOfScansBetweenRebalance, 10000);
179     SET(gcMarkStackSegmentSize,               pageSize());
180     SET(minimumNumberOfCellsToKeep,           10);
181     SET(maximumNumberOfSharedSegments,        3);
182     SET(sharedStackWakeupThreshold,           1);
183     SET(opaqueRootMergeThreshold,             1000);
184
185     int cpusToUse = 1;
186 #if ENABLE(PARALLEL_GC)
187     cpusToUse = WTF::numberOfProcessorCores();
188 #endif
189     // We don't scale so well beyond 4.
190     if (cpusToUse > 4)
191         cpusToUse = 4;
192     // Be paranoid, it is the OS we're dealing with, after all.
193     if (cpusToUse < 1)
194         cpusToUse = 1;
195     
196     SET(numberOfGCMarkers, cpusToUse);
197
198     ASSERT(executionCounterValueForDontOptimizeAnytimeSoon <= executionCounterValueForOptimizeAfterLongWarmUp);
199     ASSERT(executionCounterValueForOptimizeAfterLongWarmUp <= executionCounterValueForOptimizeAfterWarmUp);
200     ASSERT(executionCounterValueForOptimizeAfterWarmUp <= executionCounterValueForOptimizeSoon);
201     ASSERT(executionCounterValueForOptimizeAfterWarmUp < 0);
202     ASSERT(executionCounterValueForOptimizeSoon <= executionCounterValueForOptimizeNextInvocation);
203     
204     // Compute the maximum value of the reoptimization retry counter. This is simply
205     // the largest value at which we don't overflow the execute counter, when using it
206     // to left-shift the execution counter by this amount. Currently the value ends
207     // up being 18, so this loop is not so terrible; it probably takes up ~100 cycles
208     // total on a 32-bit processor.
209     reoptimizationRetryCounterMax = 0;
210     while ((static_cast<int64_t>(executionCounterValueForOptimizeAfterLongWarmUp) << (reoptimizationRetryCounterMax + 1)) >= static_cast<int64_t>(std::numeric_limits<int32_t>::min()))
211         reoptimizationRetryCounterMax++;
212     
213     ASSERT((static_cast<int64_t>(executionCounterValueForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) < 0);
214     ASSERT((static_cast<int64_t>(executionCounterValueForOptimizeAfterLongWarmUp) << reoptimizationRetryCounterMax) >= static_cast<int64_t>(std::numeric_limits<int32_t>::min()));
215 }
216
217 } } // namespace JSC::Options
218
219