LCOV - code coverage report
Current view: top level - js/src/jit - JitOptions.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 69 122 56.6 %
Date: 2017-07-14 16:53:18 Functions: 6 11 54.5 %
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/JitOptions.h"
       8             : #include "mozilla/TypeTraits.h"
       9             : 
      10             : #include <cstdlib>
      11             : #include "jsfun.h"
      12             : using namespace js;
      13             : using namespace js::jit;
      14             : 
      15             : using mozilla::Maybe;
      16             : 
      17             : namespace js {
      18             : namespace jit {
      19             : 
      20           3 : DefaultJitOptions JitOptions;
      21             : 
      22           0 : static void Warn(const char* env, const char* value)
      23             : {
      24           0 :     fprintf(stderr, "Warning: I didn't understand %s=\"%s\"\n", env, value);
      25           0 : }
      26             : 
      27             : template<typename T> struct IsBool : mozilla::FalseType {};
      28             : template<> struct IsBool<bool> : mozilla::TrueType {};
      29             : 
      30             : static Maybe<int>
      31           0 : ParseInt(const char* str)
      32             : {
      33             :     char* endp;
      34           0 :     int retval = strtol(str, &endp, 0);
      35           0 :     if (*endp == '\0')
      36           0 :         return mozilla::Some(retval);
      37           0 :     return mozilla::Nothing();
      38             : }
      39             : 
      40             : template<typename T>
      41         300 : T overrideDefault(const char* param, T dflt) {
      42         300 :     char* str = getenv(param);
      43         300 :     if (!str)
      44         300 :         return dflt;
      45             :     if (IsBool<T>::value) {
      46           0 :         if (strcmp(str, "true") == 0 || strcmp(str, "yes") == 0)
      47           0 :             return true;
      48           0 :         if (strcmp(str, "false") == 0 || strcmp(str, "no") == 0)
      49           0 :             return false;
      50           0 :         Warn(param, str);
      51             :     } else {
      52           0 :         Maybe<int> value = ParseInt(str);
      53           0 :         if (value.isSome())
      54           0 :             return value.ref();
      55           0 :         Warn(param, str);
      56             :     }
      57           0 :     return dflt;
      58             : }
      59             : 
      60             : #define SET_DEFAULT(var, dflt) var = overrideDefault("JIT_OPTION_" #var, dflt)
      61           6 : DefaultJitOptions::DefaultJitOptions()
      62             : {
      63             :     // Whether to perform expensive graph-consistency DEBUG-only assertions.
      64             :     // It can be useful to disable this to reduce DEBUG-compile time of large
      65             :     // wasm programs.
      66           6 :     SET_DEFAULT(checkGraphConsistency, true);
      67             : 
      68             : #ifdef CHECK_OSIPOINT_REGISTERS
      69             :     // Emit extra code to verify live regs at the start of a VM call
      70             :     // are not modified before its OsiPoint.
      71           6 :     SET_DEFAULT(checkOsiPointRegisters, false);
      72             : #endif
      73             : 
      74             :     // Whether to enable extra code to perform dynamic validation of
      75             :     // RangeAnalysis results.
      76           6 :     SET_DEFAULT(checkRangeAnalysis, false);
      77             : 
      78             :     // Toggles whether IonBuilder fallbacks to a call if we fail to inline.
      79           6 :     SET_DEFAULT(disableInlineBacktracking, false);
      80             : 
      81             :     // Toggles whether Alignment Mask Analysis is globally disabled.
      82           6 :     SET_DEFAULT(disableAma, false);
      83             : 
      84             :     // Toggles whether Effective Address Analysis is globally disabled.
      85           6 :     SET_DEFAULT(disableEaa, false);
      86             : 
      87             :     // Toggle whether eager simd unboxing is globally disabled.
      88           6 :     SET_DEFAULT(disableEagerSimdUnbox, false);
      89             : 
      90             :     // Toggles whether Edge Case Analysis is gobally disabled.
      91           6 :     SET_DEFAULT(disableEdgeCaseAnalysis, false);
      92             : 
      93             :     // Toggles whether to use flow sensitive Alias Analysis.
      94           6 :     SET_DEFAULT(disableFlowAA, true);
      95             : 
      96             :     // Toggle whether global value numbering is globally disabled.
      97           6 :     SET_DEFAULT(disableGvn, false);
      98             : 
      99             :     // Toggles whether inlining is globally disabled.
     100           6 :     SET_DEFAULT(disableInlining, false);
     101             : 
     102             :     // Toggles whether loop invariant code motion is globally disabled.
     103           6 :     SET_DEFAULT(disableLicm, false);
     104             : 
     105             :     // Toggles whether Loop Unrolling is globally disabled.
     106           6 :     SET_DEFAULT(disableLoopUnrolling, true);
     107             : 
     108             :     // Toggles wheter optimization tracking is globally disabled.
     109           6 :     SET_DEFAULT(disableOptimizationTracking, true);
     110             : 
     111             :     // Toggle whether Profile Guided Optimization is globally disabled.
     112           6 :     SET_DEFAULT(disablePgo, false);
     113             : 
     114             :     // Toggles whether instruction reordering is globally disabled.
     115           6 :     SET_DEFAULT(disableInstructionReordering, false);
     116             : 
     117             :     // Toggles whether Range Analysis is globally disabled.
     118           6 :     SET_DEFAULT(disableRangeAnalysis, false);
     119             : 
     120             :     // Toggles wheter Recover instructions is globally disabled.
     121           6 :     SET_DEFAULT(disableRecoverIns, false);
     122             : 
     123             :     // Toggle whether eager scalar replacement is globally disabled.
     124           6 :     SET_DEFAULT(disableScalarReplacement, false);
     125             : 
     126             :     // Toggles whether CacheIR stubs are used.
     127           6 :     SET_DEFAULT(disableCacheIR, false);
     128             : 
     129             :     // Toggles whether shared stubs are used in Ionmonkey.
     130           6 :     SET_DEFAULT(disableSharedStubs, false);
     131             : 
     132             :     // Toggles whether sincos optimization is globally disabled.
     133             :     // See bug984018: The MacOS is the only one that has the sincos fast.
     134             :     #if defined(XP_MACOSX)
     135             :         SET_DEFAULT(disableSincos, false);
     136             :     #else
     137           6 :         SET_DEFAULT(disableSincos, true);
     138             :     #endif
     139             : 
     140             :     // Toggles whether sink code motion is globally disabled.
     141           6 :     SET_DEFAULT(disableSink, true);
     142             : 
     143             :     // Whether functions are compiled immediately.
     144           6 :     SET_DEFAULT(eagerCompilation, false);
     145             : 
     146             :     // Whether IonBuilder should prefer IC generation above specialized MIR.
     147           6 :     SET_DEFAULT(forceInlineCaches, false);
     148             : 
     149             :     // Toggles whether large scripts are rejected.
     150           6 :     SET_DEFAULT(limitScriptSize, true);
     151             : 
     152             :     // Toggles whether functions may be entered at loop headers.
     153           6 :     SET_DEFAULT(osr, true);
     154             : 
     155             :     // Whether to enable extra code to perform dynamic validations.
     156           6 :     SET_DEFAULT(runExtraChecks, false);
     157             : 
     158             :     // How many invocations or loop iterations are needed before functions
     159             :     // are compiled with the baseline compiler.
     160           6 :     SET_DEFAULT(baselineWarmUpThreshold, 10);
     161             : 
     162             :     // Number of exception bailouts (resuming into catch/finally block) before
     163             :     // we invalidate and forbid Ion compilation.
     164           6 :     SET_DEFAULT(exceptionBailoutThreshold, 10);
     165             : 
     166             :     // Number of bailouts without invalidation before we set
     167             :     // JSScript::hadFrequentBailouts and invalidate.
     168           6 :     SET_DEFAULT(frequentBailoutThreshold, 10);
     169             : 
     170             :     // Whether to run all debug checks in debug builds.
     171             :     // Disabling might make it more enjoyable to run JS in debug builds.
     172           6 :     SET_DEFAULT(fullDebugChecks, true);
     173             : 
     174             :     // How many actual arguments are accepted on the C stack.
     175           6 :     SET_DEFAULT(maxStackArgs, 4096);
     176             : 
     177             :     // How many times we will try to enter a script via OSR before
     178             :     // invalidating the script.
     179           6 :     SET_DEFAULT(osrPcMismatchesBeforeRecompile, 6000);
     180             : 
     181             :     // The bytecode length limit for small function.
     182           6 :     SET_DEFAULT(smallFunctionMaxBytecodeLength_, 130);
     183             : 
     184             :     // An artificial testing limit for the maximum supported offset of
     185             :     // pc-relative jump and call instructions.
     186           6 :     SET_DEFAULT(jumpThreshold, UINT32_MAX);
     187             : 
     188             :     // Whether the (ARM) simulators should always interrupt before executing any
     189             :     // instruction.
     190           6 :     SET_DEFAULT(simulatorAlwaysInterrupt, false);
     191             : 
     192             :     // Branch pruning heuristic is based on a scoring system, which is look at
     193             :     // different metrics and provide a score. The score is computed as a
     194             :     // projection where each factor defines the weight of each metric. Then this
     195             :     // score is compared against a threshold to prevent a branch from being
     196             :     // removed.
     197           6 :     SET_DEFAULT(branchPruningHitCountFactor, 1);
     198           6 :     SET_DEFAULT(branchPruningInstFactor, 10);
     199           6 :     SET_DEFAULT(branchPruningBlockSpanFactor, 100);
     200           6 :     SET_DEFAULT(branchPruningEffectfulInstFactor, 3500);
     201           6 :     SET_DEFAULT(branchPruningThreshold, 4000);
     202             : 
     203             :     // Force how many invocation or loop iterations are needed before compiling
     204             :     // a function with the highest ionmonkey optimization level.
     205             :     // (i.e. OptimizationLevel_Normal)
     206           6 :     const char* forcedDefaultIonWarmUpThresholdEnv = "JIT_OPTION_forcedDefaultIonWarmUpThreshold";
     207           6 :     if (const char* env = getenv(forcedDefaultIonWarmUpThresholdEnv)) {
     208           0 :         Maybe<int> value = ParseInt(env);
     209           0 :         if (value.isSome())
     210           0 :             forcedDefaultIonWarmUpThreshold.emplace(value.ref());
     211             :         else
     212           0 :             Warn(forcedDefaultIonWarmUpThresholdEnv, env);
     213             :     }
     214             : 
     215             :     // Same but for compiling small functions.
     216             :     const char* forcedDefaultIonSmallFunctionWarmUpThresholdEnv =
     217           6 :         "JIT_OPTION_forcedDefaultIonSmallFunctionWarmUpThreshold";
     218           6 :     if (const char* env = getenv(forcedDefaultIonSmallFunctionWarmUpThresholdEnv)) {
     219           0 :         Maybe<int> value = ParseInt(env);
     220           0 :         if (value.isSome())
     221           0 :             forcedDefaultIonSmallFunctionWarmUpThreshold.emplace(value.ref());
     222             :         else
     223           0 :             Warn(forcedDefaultIonSmallFunctionWarmUpThresholdEnv, env);
     224             :     }
     225             : 
     226             :     // Force the used register allocator instead of letting the optimization
     227             :     // pass decide.
     228           6 :     const char* forcedRegisterAllocatorEnv = "JIT_OPTION_forcedRegisterAllocator";
     229           6 :     if (const char* env = getenv(forcedRegisterAllocatorEnv)) {
     230           0 :         forcedRegisterAllocator = LookupRegisterAllocator(env);
     231           0 :         if (!forcedRegisterAllocator.isSome())
     232           0 :             Warn(forcedRegisterAllocatorEnv, env);
     233             :     }
     234             : 
     235             :     // Toggles whether unboxed plain objects can be created by the VM.
     236           6 :     SET_DEFAULT(disableUnboxedObjects, false);
     237             : 
     238             :     // Test whether Atomics are allowed in asm.js code.
     239           6 :     SET_DEFAULT(asmJSAtomicsEnable, false);
     240             : 
     241             :     // Test whether wasm int64 / double NaN bits testing is enabled.
     242           6 :     SET_DEFAULT(wasmTestMode, false);
     243             : 
     244             :     // Test whether wasm bounds check should always be generated.
     245           6 :     SET_DEFAULT(wasmAlwaysCheckBounds, false);
     246             : 
     247             :     // Toggles the optimization whereby offsets are folded into loads and not
     248             :     // included in the bounds check.
     249           6 :     SET_DEFAULT(wasmFoldOffsets, true);
     250             : 
     251             :     // Until which wasm bytecode size should we accumulate functions, in order
     252             :     // to compile efficiently on helper threads. Baseline code compiles much
     253             :     // faster than Ion code so use scaled thresholds (see also bug 1320374).
     254           6 :     SET_DEFAULT(wasmBatchBaselineThreshold, 10000);
     255           6 :     SET_DEFAULT(wasmBatchIonThreshold, 1100);
     256             : 
     257             :     // Determines whether we suppress using signal handlers
     258             :     // for interrupting jit-ed code. This is used only for testing.
     259           6 :     SET_DEFAULT(ionInterruptWithoutSignals, false);
     260           6 : }
     261             : 
     262             : bool
     263        7905 : DefaultJitOptions::isSmallFunction(JSScript* script) const
     264             : {
     265        7905 :     return script->length() <= smallFunctionMaxBytecodeLength_;
     266             : }
     267             : 
     268             : void
     269           0 : DefaultJitOptions::enableGvn(bool enable)
     270             : {
     271           0 :     disableGvn = !enable;
     272           0 : }
     273             : 
     274             : void
     275           0 : DefaultJitOptions::setEagerCompilation()
     276             : {
     277           0 :     eagerCompilation = true;
     278           0 :     baselineWarmUpThreshold = 0;
     279           0 :     forcedDefaultIonWarmUpThreshold.reset();
     280           0 :     forcedDefaultIonWarmUpThreshold.emplace(0);
     281           0 :     forcedDefaultIonSmallFunctionWarmUpThreshold.reset();
     282           0 :     forcedDefaultIonSmallFunctionWarmUpThreshold.emplace(0);
     283           0 : }
     284             : 
     285             : void
     286           0 : DefaultJitOptions::setCompilerWarmUpThreshold(uint32_t warmUpThreshold)
     287             : {
     288           0 :     forcedDefaultIonWarmUpThreshold.reset();
     289           0 :     forcedDefaultIonWarmUpThreshold.emplace(warmUpThreshold);
     290           0 :     forcedDefaultIonSmallFunctionWarmUpThreshold.reset();
     291           0 :     forcedDefaultIonSmallFunctionWarmUpThreshold.emplace(warmUpThreshold);
     292             : 
     293             :     // Undo eager compilation
     294           0 :     if (eagerCompilation && warmUpThreshold != 0) {
     295           0 :         jit::DefaultJitOptions defaultValues;
     296           0 :         eagerCompilation = false;
     297           0 :         baselineWarmUpThreshold = defaultValues.baselineWarmUpThreshold;
     298             :     }
     299           0 : }
     300             : 
     301             : void
     302           3 : DefaultJitOptions::resetCompilerWarmUpThreshold()
     303             : {
     304           3 :     forcedDefaultIonWarmUpThreshold.reset();
     305             : 
     306             :     // Undo eager compilation
     307           3 :     if (eagerCompilation) {
     308           0 :         jit::DefaultJitOptions defaultValues;
     309           0 :         eagerCompilation = false;
     310           0 :         baselineWarmUpThreshold = defaultValues.baselineWarmUpThreshold;
     311             :     }
     312           3 : }
     313             : 
     314             : } // namespace jit
     315             : } // namespace js

Generated by: LCOV version 1.13