Delay Ion compilation until a function is hot (bug 683039, r=bhackett).
authorDavid Anderson <danderson@mozilla.com>
Mon, 29 Aug 2011 19:03:02 -0700
changeset 105220 4ceb3e9961e4e1d15a90a63aaddb74621d577582
parent 105219 1ec61b5ec88b252f36465f18a73d39df71837826
child 105221 a8ca429e2cce54a2e8d029c9a7cccd12ee712676
push id14706
push usereakhgari@mozilla.com
push dateTue, 11 Sep 2012 20:39:52 +0000
treeherdermozilla-inbound@d50bf1edaabe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs683039
milestone8.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
Delay Ion compilation until a function is hot (bug 683039, r=bhackett).
js/src/ion/Ion.cpp
js/src/ion/Ion.h
js/src/shell/js.cpp
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -547,16 +547,19 @@ ion::Compile(JSContext *cx, JSScript *sc
 
     if (script->ion) {
         if (script->ion == ION_DISABLED_SCRIPT || !script->ion->method())
             return Method_CantCompile;
 
         return Method_Compiled;
     }
 
+    if (script->incUseCount() <= js_IonOptions.invokesBeforeCompile)
+        return Method_Skipped;
+
     if (!IonCompile(cx, script, fp)) {
         script->ion = ION_DISABLED_SCRIPT;
         return Method_CantCompile;
     }
 
     return Method_Compiled;
 }
 
--- a/js/src/ion/Ion.h
+++ b/js/src/ion/Ion.h
@@ -74,28 +74,40 @@ struct IonOptions
     bool licm;
 
     // Toggles whether Linear Scan Register Allocation is used. If LSRA is not
     // used, then Greedy Register Allocation is used instead.
     //
     // Default: true
     bool lsra;
 
+    // How many invocations of a function are needed before the Ion compiler
+    // kicks in.
+    //
+    // Default: 40.
+    uint32 invokesBeforeCompile;
+
+    void setEagerCompilation() {
+        invokesBeforeCompile = 0;
+    }
+
     IonOptions()
       : enabled(false),
         gvn(true),
         gvnIsOptimistic(true),
         licm(true),
-        lsra(true)
+        lsra(true),
+        invokesBeforeCompile(40)
     { }
 };
 
 enum MethodStatus
 {
     Method_CantCompile,
+    Method_Skipped,
     Method_Compiled
 };
 
 // An Ion context is needed to enter into either an Ion method or an instance
 // of the Ion compiler. It points to a temporary allocator and the active
 // JSContext.
 class IonContext
 {
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -5366,16 +5366,19 @@ ProcessArgs(JSContext *cx, JSObject *obj
     if (const char *str = op->getStringOption("ion-regalloc")) {
         if (strcmp(str, "lsra") == 0)
             ion::js_IonOptions.lsra = true;
         else if (strcmp(str, "greedy") == 0)
             ion::js_IonOptions.lsra = false;
         else
             return OptionFailure("ion-regalloc", str);
     }
+
+    if (op->getBoolOption("ion-eager"))
+        ion::js_IonOptions.setEagerCompilation();
 #endif
 
     /* |scriptArgs| gets bound on the global before any code is run. */
     if (!BindScriptArgs(cx, obj, op))
         return EXIT_FAILURE;
 
     MultiStringRange filePaths = op->getMultiStringOption('f');
     MultiStringRange codeChunks = op->getMultiStringOption('e');
@@ -5653,16 +5656,17 @@ main(int argc, char **argv, char **envp)
                                "  pessimistic: use pessimistic GVN\n"
                                "  optimistic: (default) use optimistic GVN")
         || !op.addStringOption('\0', "ion-licm", "on/off",
                                "Loop invariant code motion (default: on, off to disable)")
         || !op.addStringOption('\0', "ion-regalloc", "[mode]",
                                "Specify Ion register allocation:\n"
                                "  greedy: Greedy register allocation\n"
                                "  lsra: Linear Scan register allocation (default)")
+        || !op.addBoolOption('\0', "ion-eager", "Always compile methods")
 #endif
     )
     {
         return EXIT_FAILURE;
     }
 
     switch (op.parseArgs(argc, argv)) {
       case OptionParser::ParseHelp: