LCOV - code coverage report
Current view: top level - js/src/jit - IonOptimizationLevels.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 84 91 92.3 %
Date: 2017-07-14 16:53:18 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       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/. */
       6             : 
       7             : #include "jit/IonOptimizationLevels.h"
       8             : 
       9             : #include "jsscript.h"
      10             : 
      11             : #include "jit/Ion.h"
      12             : 
      13             : using namespace js;
      14             : using namespace js::jit;
      15             : 
      16             : namespace js {
      17             : namespace jit {
      18             : 
      19           3 : OptimizationLevelInfo IonOptimizations;
      20             : 
      21             : void
      22           6 : OptimizationInfo::initNormalOptimizationInfo()
      23             : {
      24           6 :     level_ = OptimizationLevel::Normal;
      25             : 
      26           6 :     autoTruncate_ = true;
      27           6 :     eaa_ = true;
      28           6 :     eagerSimdUnbox_ = true;
      29           6 :     edgeCaseAnalysis_ = true;
      30           6 :     eliminateRedundantChecks_ = true;
      31           6 :     inlineInterpreted_ = true;
      32           6 :     inlineNative_ = true;
      33           6 :     licm_ = true;
      34           6 :     loopUnrolling_ = true;
      35           6 :     gvn_ = true;
      36           6 :     rangeAnalysis_ = true;
      37           6 :     reordering_ = true;
      38           6 :     sincos_ = true;
      39           6 :     sink_ = true;
      40             : 
      41           6 :     registerAllocator_ = RegisterAllocator_Backtracking;
      42             : 
      43           6 :     inlineMaxBytecodePerCallSiteActiveCooperatingThread_ = 550;
      44           6 :     inlineMaxBytecodePerCallSiteHelperThread_ = 1100;
      45           6 :     inlineMaxCalleeInlinedBytecodeLength_ = 3550;
      46           6 :     inlineMaxTotalBytecodeLength_ = 85000;
      47           6 :     inliningMaxCallerBytecodeLength_ = 1600;
      48           6 :     maxInlineDepth_ = 3;
      49           6 :     scalarReplacement_ = true;
      50           6 :     smallFunctionMaxInlineDepth_ = 10;
      51           6 :     compilerWarmUpThreshold_ = CompilerWarmupThreshold;
      52           6 :     compilerSmallFunctionWarmUpThreshold_ = CompilerSmallFunctionWarmupThreshold;
      53           6 :     inliningWarmUpThresholdFactor_ = 0.125;
      54           6 :     inliningRecompileThresholdFactor_ = 4;
      55           6 : }
      56             : 
      57             : void
      58           3 : OptimizationInfo::initWasmOptimizationInfo()
      59             : {
      60             :     // The Wasm optimization level
      61             :     // Disables some passes that don't work well with wasm.
      62             : 
      63             :     // Take normal option values for not specified values.
      64           3 :     initNormalOptimizationInfo();
      65             : 
      66           3 :     level_ = OptimizationLevel::Wasm;
      67             : 
      68           3 :     ama_ = true;
      69           3 :     autoTruncate_ = false;
      70           3 :     eagerSimdUnbox_ = false;           // wasm has no boxing / unboxing.
      71           3 :     edgeCaseAnalysis_ = false;
      72           3 :     eliminateRedundantChecks_ = false;
      73           3 :     scalarReplacement_ = false;        // wasm has no objects.
      74           3 :     sincos_ = false;
      75           3 :     sink_ = false;
      76           3 : }
      77             : 
      78             : uint32_t
      79        7872 : OptimizationInfo::compilerWarmUpThreshold(JSScript* script, jsbytecode* pc) const
      80             : {
      81        7872 :     MOZ_ASSERT(pc == nullptr || pc == script->code() || JSOp(*pc) == JSOP_LOOPENTRY);
      82             : 
      83        7872 :     if (pc == script->code())
      84         620 :         pc = nullptr;
      85             : 
      86        7872 :     uint32_t warmUpThreshold = compilerWarmUpThreshold_;
      87        7872 :     if (JitOptions.forcedDefaultIonWarmUpThreshold.isSome())
      88           0 :         warmUpThreshold = JitOptions.forcedDefaultIonWarmUpThreshold.ref();
      89             : 
      90        7872 :     if (JitOptions.isSmallFunction(script)) {
      91        3748 :         warmUpThreshold = compilerSmallFunctionWarmUpThreshold_;
      92        3748 :         if (JitOptions.forcedDefaultIonSmallFunctionWarmUpThreshold.isSome())
      93           0 :             warmUpThreshold = JitOptions.forcedDefaultIonSmallFunctionWarmUpThreshold.ref();
      94             :     }
      95             : 
      96             :     // If the script is too large to compile on the active thread, we can still
      97             :     // compile it off thread. In these cases, increase the warm-up counter
      98             :     // threshold to improve the compilation's type information and hopefully
      99             :     // avoid later recompilation.
     100             : 
     101        7872 :     if (script->length() > MAX_ACTIVE_THREAD_SCRIPT_SIZE)
     102          40 :         warmUpThreshold *= (script->length() / (double) MAX_ACTIVE_THREAD_SCRIPT_SIZE);
     103             : 
     104        7872 :     uint32_t numLocalsAndArgs = NumLocalsAndArgs(script);
     105        7872 :     if (numLocalsAndArgs > MAX_ACTIVE_THREAD_LOCALS_AND_ARGS)
     106           0 :         warmUpThreshold *= (numLocalsAndArgs / (double) MAX_ACTIVE_THREAD_LOCALS_AND_ARGS);
     107             : 
     108        7872 :     if (!pc || JitOptions.eagerCompilation)
     109        7622 :         return warmUpThreshold;
     110             : 
     111             :     // It's more efficient to enter outer loops, rather than inner loops, via OSR.
     112             :     // To accomplish this, we use a slightly higher threshold for inner loops.
     113             :     // Note that the loop depth is always > 0 so we will prefer non-OSR over OSR.
     114         250 :     uint32_t loopDepth = LoopEntryDepthHint(pc);
     115         250 :     MOZ_ASSERT(loopDepth > 0);
     116         250 :     return warmUpThreshold + loopDepth * 100;
     117             : }
     118             : 
     119           3 : OptimizationLevelInfo::OptimizationLevelInfo()
     120             : {
     121           3 :     infos_[OptimizationLevel::Normal].initNormalOptimizationInfo();
     122           3 :     infos_[OptimizationLevel::Wasm].initWasmOptimizationInfo();
     123             : 
     124             : #ifdef DEBUG
     125           3 :     OptimizationLevel level = firstLevel();
     126           3 :     while (!isLastLevel(level)) {
     127           0 :         OptimizationLevel next = nextLevel(level);
     128           0 :         MOZ_ASSERT_IF(level != OptimizationLevel::DontCompile, level < next);
     129           0 :         level = next;
     130             :     }
     131             : #endif
     132           3 : }
     133             : 
     134             : OptimizationLevel
     135        7875 : OptimizationLevelInfo::nextLevel(OptimizationLevel level) const
     136             : {
     137        7875 :     MOZ_ASSERT(!isLastLevel(level));
     138        7875 :     switch (level) {
     139             :       case OptimizationLevel::DontCompile:
     140       15750 :         return OptimizationLevel::Normal;
     141             :       case OptimizationLevel::Normal:
     142             :       case OptimizationLevel::Wasm:
     143             :       case OptimizationLevel::Count:;
     144             :     }
     145           0 :     MOZ_CRASH("Unknown optimization level.");
     146             : }
     147             : 
     148             : OptimizationLevel
     149         868 : OptimizationLevelInfo::firstLevel() const
     150             : {
     151         868 :     return nextLevel(OptimizationLevel::DontCompile);
     152             : }
     153             : 
     154             : bool
     155       15232 : OptimizationLevelInfo::isLastLevel(OptimizationLevel level) const
     156             : {
     157       15232 :     return level == OptimizationLevel::Normal;
     158             : }
     159             : 
     160             : OptimizationLevel
     161        7007 : OptimizationLevelInfo::levelForScript(JSScript* script, jsbytecode* pc) const
     162             : {
     163        7007 :     OptimizationLevel prev = OptimizationLevel::DontCompile;
     164             : 
     165        7105 :     while (!isLastLevel(prev)) {
     166        7007 :         OptimizationLevel level = nextLevel(prev);
     167        7007 :         const OptimizationInfo* info = get(level);
     168        7007 :         if (script->getWarmUpCount() < info->compilerWarmUpThreshold(script, pc))
     169        6958 :             return prev;
     170             : 
     171          49 :         prev = level;
     172             :     }
     173             : 
     174          49 :     return prev;
     175             : }
     176             : 
     177             : } // namespace jit
     178             : } // namespace js

Generated by: LCOV version 1.13