1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "jit/IonOptimizationLevels.h"
10 #include "vm/JSScript.h"
12 #include "vm/JSScript-inl.h"
15 using namespace js::jit
;
20 const OptimizationLevelInfo IonOptimizations
;
22 void OptimizationInfo::initNormalOptimizationInfo() {
23 level_
= OptimizationLevel::Normal
;
27 edgeCaseAnalysis_
= true;
28 eliminateRedundantChecks_
= true;
29 eliminateRedundantShapeGuards_
= true;
30 eliminateRedundantGCBarriers_
= true;
31 inlineInterpreted_
= true;
35 rangeAnalysis_
= true;
37 scalarReplacement_
= true;
40 registerAllocator_
= RegisterAllocator_Backtracking
;
43 void OptimizationInfo::initWasmOptimizationInfo() {
44 // The Wasm optimization level
45 // Disables some passes that don't work well with wasm.
47 // Take normal option values for not specified values.
48 initNormalOptimizationInfo();
50 level_
= OptimizationLevel::Wasm
;
53 autoTruncate_
= false;
54 edgeCaseAnalysis_
= false;
55 eliminateRedundantChecks_
= false;
56 eliminateRedundantShapeGuards_
= false;
57 eliminateRedundantGCBarriers_
= false;
58 scalarReplacement_
= false; // wasm has no objects.
62 uint32_t OptimizationInfo::compilerWarmUpThreshold(JSScript
* script
,
63 jsbytecode
* pc
) const {
64 MOZ_ASSERT(pc
== nullptr || pc
== script
->code() ||
65 JSOp(*pc
) == JSOp::LoopHead
);
67 // The script must not start with a LoopHead op or the code below would be
68 // wrong. See bug 1602681.
69 MOZ_ASSERT_IF(pc
&& JSOp(*pc
) == JSOp::LoopHead
, pc
> script
->code());
71 if (pc
== script
->code()) {
75 uint32_t warmUpThreshold
= baseCompilerWarmUpThreshold();
77 // If the script is too large to compile on the main thread, we can still
78 // compile it off thread. In these cases, increase the warm-up counter
79 // threshold to improve the compilation's type information and hopefully
80 // avoid later recompilation.
82 if (script
->length() > JitOptions
.ionMaxScriptSizeMainThread
) {
84 (script
->length() / double(JitOptions
.ionMaxScriptSizeMainThread
));
87 uint32_t numLocalsAndArgs
= NumLocalsAndArgs(script
);
88 if (numLocalsAndArgs
> JitOptions
.ionMaxLocalsAndArgsMainThread
) {
90 (numLocalsAndArgs
/ double(JitOptions
.ionMaxLocalsAndArgsMainThread
));
93 if (!pc
|| JitOptions
.eagerIonCompilation()) {
94 return warmUpThreshold
;
97 // It's more efficient to enter outer loops, rather than inner loops, via OSR.
98 // To accomplish this, we use a slightly higher threshold for inner loops.
99 // Note that the loop depth is always > 0 so we will prefer non-OSR over OSR.
100 uint32_t loopDepth
= LoopHeadDepthHint(pc
);
101 MOZ_ASSERT(loopDepth
> 0);
102 return warmUpThreshold
+ loopDepth
* (baseCompilerWarmUpThreshold() / 10);
105 uint32_t OptimizationInfo::recompileWarmUpThreshold(JSScript
* script
,
106 jsbytecode
* pc
) const {
107 MOZ_ASSERT(pc
== script
->code() || JSOp(*pc
) == JSOp::LoopHead
);
109 uint32_t threshold
= compilerWarmUpThreshold(script
, pc
);
110 if (JSOp(*pc
) != JSOp::LoopHead
|| JitOptions
.eagerIonCompilation()) {
114 // If we're stuck in a long-running loop at a low optimization level, we have
115 // to invalidate to be able to tier up. This is worse than recompiling at
116 // function entry (because in that case we can use the lazy link mechanism and
117 // avoid invalidation completely). Use a very high recompilation threshold for
118 // loop edges so that this only affects very long-running loops.
120 uint32_t loopDepth
= LoopHeadDepthHint(pc
);
121 MOZ_ASSERT(loopDepth
> 0);
122 return threshold
+ loopDepth
* (baseCompilerWarmUpThreshold() / 10);
125 OptimizationLevelInfo::OptimizationLevelInfo() {
126 infos_
[OptimizationLevel::Normal
].initNormalOptimizationInfo();
127 infos_
[OptimizationLevel::Wasm
].initWasmOptimizationInfo();
130 OptimizationLevel
OptimizationLevelInfo::levelForScript(JSScript
* script
,
131 jsbytecode
* pc
) const {
132 const OptimizationInfo
* info
= get(OptimizationLevel::Normal
);
133 if (script
->getWarmUpCount() < info
->compilerWarmUpThreshold(script
, pc
)) {
134 return OptimizationLevel::DontCompile
;
137 return OptimizationLevel::Normal
;