mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-09-28 05:55:58 +00:00
169 lines
4.9 KiB
C++
169 lines
4.9 KiB
C++
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||
|
|
||
|
#include "jit/IonOptimizationLevels.h"
|
||
|
|
||
|
#include "jsscript.h"
|
||
|
|
||
|
#include "jit/Ion.h"
|
||
|
|
||
|
using namespace js;
|
||
|
using namespace js::jit;
|
||
|
|
||
|
namespace js {
|
||
|
namespace jit {
|
||
|
|
||
|
OptimizationInfos IonOptimizations;
|
||
|
|
||
|
void
|
||
|
OptimizationInfo::initNormalOptimizationInfo()
|
||
|
{
|
||
|
level_ = Optimization_Normal;
|
||
|
|
||
|
eaa_ = true;
|
||
|
edgeCaseAnalysis_ = true;
|
||
|
eliminateRedundantChecks_ = true;
|
||
|
inlineInterpreted_ = true;
|
||
|
inlineNative_ = true;
|
||
|
eagerSimdUnbox_ = true;
|
||
|
gvn_ = true;
|
||
|
licm_ = true;
|
||
|
rangeAnalysis_ = true;
|
||
|
loopUnrolling_ = true;
|
||
|
reordering_ = true;
|
||
|
autoTruncate_ = true;
|
||
|
sincos_ = true;
|
||
|
sink_ = true;
|
||
|
registerAllocator_ = RegisterAllocator_Backtracking;
|
||
|
|
||
|
inlineMaxBytecodePerCallSiteMainThread_ = 500;
|
||
|
inlineMaxBytecodePerCallSiteOffThread_ = 1000;
|
||
|
inlineMaxCalleeInlinedBytecodeLength_ = 3350;
|
||
|
inlineMaxTotalBytecodeLength_ = 80000;
|
||
|
inliningMaxCallerBytecodeLength_ = 1500;
|
||
|
maxInlineDepth_ = 3;
|
||
|
scalarReplacement_ = true;
|
||
|
smallFunctionMaxInlineDepth_ = 13;
|
||
|
compilerWarmUpThreshold_ = CompilerWarmupThreshold;
|
||
|
inliningWarmUpThresholdFactor_ = 0.125;
|
||
|
inliningRecompileThresholdFactor_ = 4;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
OptimizationInfo::initAsmjsOptimizationInfo()
|
||
|
{
|
||
|
// The AsmJS optimization level
|
||
|
// Disables some passes that don't work well with asmjs.
|
||
|
|
||
|
// Take normal option values for not specified values.
|
||
|
initNormalOptimizationInfo();
|
||
|
|
||
|
ama_ = true;
|
||
|
level_ = Optimization_AsmJS;
|
||
|
eagerSimdUnbox_ = false; // AsmJS has no boxing / unboxing.
|
||
|
edgeCaseAnalysis_ = false;
|
||
|
eliminateRedundantChecks_ = false;
|
||
|
autoTruncate_ = false;
|
||
|
sincos_ = false;
|
||
|
sink_ = false;
|
||
|
registerAllocator_ = RegisterAllocator_Backtracking;
|
||
|
scalarReplacement_ = false; // AsmJS has no objects.
|
||
|
}
|
||
|
|
||
|
uint32_t
|
||
|
OptimizationInfo::compilerWarmUpThreshold(JSScript* script, jsbytecode* pc) const
|
||
|
{
|
||
|
MOZ_ASSERT(pc == nullptr || pc == script->code() || JSOp(*pc) == JSOP_LOOPENTRY);
|
||
|
|
||
|
if (pc == script->code())
|
||
|
pc = nullptr;
|
||
|
|
||
|
uint32_t warmUpThreshold = compilerWarmUpThreshold_;
|
||
|
if (JitOptions.forcedDefaultIonWarmUpThreshold.isSome())
|
||
|
warmUpThreshold = JitOptions.forcedDefaultIonWarmUpThreshold.ref();
|
||
|
|
||
|
// If the script is too large to compile on the main thread, we can still
|
||
|
// compile it off thread. In these cases, increase the warm-up counter
|
||
|
// threshold to improve the compilation's type information and hopefully
|
||
|
// avoid later recompilation.
|
||
|
|
||
|
if (script->length() > MAX_MAIN_THREAD_SCRIPT_SIZE)
|
||
|
warmUpThreshold *= (script->length() / (double) MAX_MAIN_THREAD_SCRIPT_SIZE);
|
||
|
|
||
|
uint32_t numLocalsAndArgs = NumLocalsAndArgs(script);
|
||
|
if (numLocalsAndArgs > MAX_MAIN_THREAD_LOCALS_AND_ARGS)
|
||
|
warmUpThreshold *= (numLocalsAndArgs / (double) MAX_MAIN_THREAD_LOCALS_AND_ARGS);
|
||
|
|
||
|
if (!pc || JitOptions.eagerCompilation)
|
||
|
return warmUpThreshold;
|
||
|
|
||
|
// It's more efficient to enter outer loops, rather than inner loops, via OSR.
|
||
|
// To accomplish this, we use a slightly higher threshold for inner loops.
|
||
|
// Note that the loop depth is always > 0 so we will prefer non-OSR over OSR.
|
||
|
uint32_t loopDepth = LoopEntryDepthHint(pc);
|
||
|
MOZ_ASSERT(loopDepth > 0);
|
||
|
return warmUpThreshold + loopDepth * 100;
|
||
|
}
|
||
|
|
||
|
OptimizationInfos::OptimizationInfos()
|
||
|
{
|
||
|
infos_[Optimization_Normal - 1].initNormalOptimizationInfo();
|
||
|
infos_[Optimization_AsmJS - 1].initAsmjsOptimizationInfo();
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
OptimizationLevel level = firstLevel();
|
||
|
while (!isLastLevel(level)) {
|
||
|
OptimizationLevel next = nextLevel(level);
|
||
|
MOZ_ASSERT(level < next);
|
||
|
level = next;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
OptimizationLevel
|
||
|
OptimizationInfos::nextLevel(OptimizationLevel level) const
|
||
|
{
|
||
|
MOZ_ASSERT(!isLastLevel(level));
|
||
|
switch (level) {
|
||
|
case Optimization_DontCompile:
|
||
|
return Optimization_Normal;
|
||
|
default:
|
||
|
MOZ_CRASH("Unknown optimization level.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
OptimizationLevel
|
||
|
OptimizationInfos::firstLevel() const
|
||
|
{
|
||
|
return nextLevel(Optimization_DontCompile);
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
OptimizationInfos::isLastLevel(OptimizationLevel level) const
|
||
|
{
|
||
|
return level == Optimization_Normal;
|
||
|
}
|
||
|
|
||
|
OptimizationLevel
|
||
|
OptimizationInfos::levelForScript(JSScript* script, jsbytecode* pc) const
|
||
|
{
|
||
|
OptimizationLevel prev = Optimization_DontCompile;
|
||
|
|
||
|
while (!isLastLevel(prev)) {
|
||
|
OptimizationLevel level = nextLevel(prev);
|
||
|
const OptimizationInfo* info = get(level);
|
||
|
if (script->getWarmUpCount() < info->compilerWarmUpThreshold(script, pc))
|
||
|
return prev;
|
||
|
|
||
|
prev = level;
|
||
|
}
|
||
|
|
||
|
return prev;
|
||
|
}
|
||
|
|
||
|
} // namespace jit
|
||
|
} // namespace js
|