Bug 1266676 - IonMonkey: Compile smaller functions faster, r=jandem
☠☠ backed out by 3ae9a6bb0821 ☠ ☠
authorHannes Verschore <hv1989@gmail.com>
Fri, 22 Apr 2016 11:34:00 -0400
changeset 332434 c23b44faa96925d311e0844b14c8dc468f584f14
parent 332433 bd10c1a7ea1e7783fe136c1fd8ca561d29582dc5
child 332435 ebf23fb059f5ab37598ed92ba7901aac9023d708
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1266676
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1266676 - IonMonkey: Compile smaller functions faster, r=jandem
js/src/jit/IonOptimizationLevels.cpp
js/src/jit/IonOptimizationLevels.h
js/src/jit/JitOptions.cpp
js/src/jit/JitOptions.h
--- a/js/src/jit/IonOptimizationLevels.cpp
+++ b/js/src/jit/IonOptimizationLevels.cpp
@@ -44,16 +44,17 @@ OptimizationInfo::initNormalOptimization
     inlineMaxBytecodePerCallSiteOffThread_ = 1000;
     inlineMaxCalleeInlinedBytecodeLength_ = 3350;
     inlineMaxTotalBytecodeLength_ = 80000;
     inliningMaxCallerBytecodeLength_ = 1500;
     maxInlineDepth_ = 3;
     scalarReplacement_ = true;
     smallFunctionMaxInlineDepth_ = 10;
     compilerWarmUpThreshold_ = CompilerWarmupThreshold;
+    compilerSmallFunctionWarmUpThreshold_ = CompilerSmallFunctionWarmupThreshold;
     inliningWarmUpThresholdFactor_ = 0.125;
     inliningRecompileThresholdFactor_ = 4;
 }
 
 void
 OptimizationInfo::initAsmjsOptimizationInfo()
 {
     // The AsmJS optimization level
@@ -81,16 +82,22 @@ OptimizationInfo::compilerWarmUpThreshol
 
     if (pc == script->code())
         pc = nullptr;
 
     uint32_t warmUpThreshold = compilerWarmUpThreshold_;
     if (JitOptions.forcedDefaultIonWarmUpThreshold.isSome())
         warmUpThreshold = JitOptions.forcedDefaultIonWarmUpThreshold.ref();
 
+    if (JitOptions.isSmallFunction(script)) {
+        warmUpThreshold = compilerSmallFunctionWarmUpThreshold_;
+        if (JitOptions.forcedDefaultIonSmallFunctionWarmUpThreshold.isSome())
+            warmUpThreshold = JitOptions.forcedDefaultIonSmallFunctionWarmUpThreshold.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);
 
--- a/js/src/jit/IonOptimizationLevels.h
+++ b/js/src/jit/IonOptimizationLevels.h
@@ -129,16 +129,23 @@ class OptimizationInfo
 
     // How many invocations or loop iterations are needed before functions
     // are compiled.
     uint32_t compilerWarmUpThreshold_;
 
     // Default compiler warmup threshold, unless it is overridden.
     static const uint32_t CompilerWarmupThreshold = 1000;
 
+    // How many invocations or loop iterations are needed before small functions
+    // are compiled.
+    uint32_t compilerSmallFunctionWarmUpThreshold_;
+
+    // Default small function compiler warmup threshold, unless it is overridden.
+    static const uint32_t CompilerSmallFunctionWarmupThreshold = 100;
+
     // How many invocations or loop iterations are needed before calls
     // are inlined, as a fraction of compilerWarmUpThreshold.
     double inliningWarmUpThresholdFactor_;
 
     // How many invocations or loop iterations are needed before a function
     // is hot enough to recompile the outerScript to inline that function,
     // as a multiplication of inliningWarmUpThreshold.
     uint32_t inliningRecompileThresholdFactor_;
--- a/js/src/jit/JitOptions.cpp
+++ b/js/src/jit/JitOptions.cpp
@@ -173,16 +173,27 @@ DefaultJitOptions::DefaultJitOptions()
     if (const char* env = getenv(forcedDefaultIonWarmUpThresholdEnv)) {
         Maybe<int> value = ParseInt(env);
         if (value.isSome())
             forcedDefaultIonWarmUpThreshold.emplace(value.ref());
         else
             Warn(forcedDefaultIonWarmUpThresholdEnv, env);
     }
 
+    // Same but for compiling small functions.
+    const char* forcedDefaultIonSmallFunctionWarmUpThresholdEnv =
+        "JIT_OPTION_forcedDefaultIonSmallFunctionWarmUpThreshold";
+    if (const char* env = getenv(forcedDefaultIonSmallFunctionWarmUpThresholdEnv)) {
+        Maybe<int> value = ParseInt(env);
+        if (value.isSome())
+            forcedDefaultIonSmallFunctionWarmUpThreshold.emplace(value.ref());
+        else
+            Warn(forcedDefaultIonSmallFunctionWarmUpThresholdEnv, env);
+    }
+
     // Force the used register allocator instead of letting the optimization
     // pass decide.
     const char* forcedRegisterAllocatorEnv = "JIT_OPTION_forcedRegisterAllocator";
     if (const char* env = getenv(forcedRegisterAllocatorEnv)) {
         forcedRegisterAllocator = LookupRegisterAllocator(env);
         if (!forcedRegisterAllocator.isSome())
             Warn(forcedRegisterAllocatorEnv, env);
     }
@@ -208,23 +219,27 @@ DefaultJitOptions::enableGvn(bool enable
 
 void
 DefaultJitOptions::setEagerCompilation()
 {
     eagerCompilation = true;
     baselineWarmUpThreshold = 0;
     forcedDefaultIonWarmUpThreshold.reset();
     forcedDefaultIonWarmUpThreshold.emplace(0);
+    forcedDefaultIonSmallFunctionWarmUpThreshold.reset();
+    forcedDefaultIonSmallFunctionWarmUpThreshold.emplace(0);
 }
 
 void
 DefaultJitOptions::setCompilerWarmUpThreshold(uint32_t warmUpThreshold)
 {
     forcedDefaultIonWarmUpThreshold.reset();
     forcedDefaultIonWarmUpThreshold.emplace(warmUpThreshold);
+    forcedDefaultIonSmallFunctionWarmUpThreshold.reset();
+    forcedDefaultIonSmallFunctionWarmUpThreshold.emplace(warmUpThreshold);
 
     // Undo eager compilation
     if (eagerCompilation && warmUpThreshold != 0) {
         jit::DefaultJitOptions defaultValues;
         eagerCompilation = false;
         baselineWarmUpThreshold = defaultValues.baselineWarmUpThreshold;
     }
 }
--- a/js/src/jit/JitOptions.h
+++ b/js/src/jit/JitOptions.h
@@ -70,16 +70,17 @@ struct DefaultJitOptions
     uint32_t baselineWarmUpThreshold;
     uint32_t exceptionBailoutThreshold;
     uint32_t frequentBailoutThreshold;
     uint32_t maxStackArgs;
     uint32_t osrPcMismatchesBeforeRecompile;
     uint32_t smallFunctionMaxBytecodeLength_;
     uint32_t jumpThreshold;
     mozilla::Maybe<uint32_t> forcedDefaultIonWarmUpThreshold;
+    mozilla::Maybe<uint32_t> forcedDefaultIonSmallFunctionWarmUpThreshold;
     mozilla::Maybe<IonRegisterAllocator> forcedRegisterAllocator;
 
     // The options below affect the rest of the VM, and not just the JIT.
     bool disableUnboxedObjects;
 
     DefaultJitOptions();
     bool isSmallFunction(JSScript* script) const;
     void setEagerCompilation();