Bug 1374282 - ban Task.jsm during startup, r=Mossop, a=sheriffduty
authorFlorian Quèze <florian@queze.net>
Thu, 22 Jun 2017 12:51:43 +0200
changeset 414186 7a9536f89bc75b0672060f16ffbe6eb2c1ff3deb
parent 414185 05d686d3c53d0ab18cc2911296d380bc20d05300
child 414187 74a2ff180838c47f486e9c34a6cbfdc0705b495d
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMossop, sheriffduty
bugs1374282
milestone56.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 1374282 - ban Task.jsm during startup, r=Mossop, a=sheriffduty
browser/base/content/test/performance/browser_startup.js
toolkit/components/asyncshutdown/AsyncShutdown.jsm
toolkit/components/osfile/modules/osfile_async_front.jsm
toolkit/modules/Log.jsm
toolkit/modules/Sqlite.jsm
--- a/browser/base/content/test/performance/browser_startup.js
+++ b/browser/base/content/test/performance/browser_startup.js
@@ -88,16 +88,17 @@ const startupPhases = {
   }},
 
   // We are at this phase once we are ready to handle user events.
   // Anything loaded at this phase or before gets in the way of the user
   // interacting with the first browser window.
   "before handling user events": {blacklist: {
     modules: new Set([
       "resource://gre/modules/LoginManagerContextMenu.jsm",
+      "resource://gre/modules/Task.jsm",
     ]),
   }},
 };
 
 function test() {
   if (!AppConstants.NIGHTLY_BUILD && !AppConstants.DEBUG) {
     ok(!("@mozilla.org/test/startuprecorder;1" in Cc),
        "the startup recorder component shouldn't exist in this non-nightly non-debug build.");
--- a/toolkit/components/asyncshutdown/AsyncShutdown.jsm
+++ b/toolkit/components/asyncshutdown/AsyncShutdown.jsm
@@ -317,17 +317,22 @@ function getOrigin(topFrame, filename = 
     if (stack == null) {
       // Now build the rest of the stack as a string, using Task.jsm's rewriting
       // to ensure that we do not lose information at each call to `Task.spawn`.
       let frames = [];
       while (frame != null) {
         frames.push(frame.filename + ":" + frame.name + ":" + frame.lineNumber);
         frame = frame.caller;
       }
-      stack = Task.Debugging.generateReadableStack(frames.join("\n")).split("\n");
+      stack = frames.join("\n");
+      // Avoid loading Task.jsm if there's no task on the stack.
+      if (stack.includes("/Task.jsm:")) {
+        stack = Task.Debugging.generateReadableStack(stack);
+      }
+      stack = stack.split("\n");
     }
 
     return {
       filename,
       lineNumber,
       stack,
     };
   } catch (ex) {
--- a/toolkit/components/osfile/modules/osfile_async_front.jsm
+++ b/toolkit/components/osfile/modules/osfile_async_front.jsm
@@ -46,17 +46,18 @@ if (SharedAll.Constants.Win) {
 var OSError = SysAll.Error;
 var Type = SysAll.Type;
 
 var Path = {};
 Cu.import("resource://gre/modules/osfile/ospath.jsm", Path);
 
 // The library of promises.
 Cu.import("resource://gre/modules/Promise.jsm", this);
-Cu.import("resource://gre/modules/Task.jsm", this);
+XPCOMUtils.defineLazyModuleGetter(this, "Task",
+                                  "resource://gre/modules/Task.jsm");
 
 // The implementation of communications
 Cu.import("resource://gre/modules/PromiseWorker.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/TelemetryStopwatch.jsm", this);
 Cu.import("resource://gre/modules/AsyncShutdown.jsm", this);
 var Native = Cu.import("resource://gre/modules/osfile/osfile_native.jsm", {});
 
@@ -299,19 +300,21 @@ var Scheduler = this.Scheduler = {
           return null;
         }
 
         // Exit critical section
 
         let message = ["Meta_shutdown", [reset]];
 
         Scheduler.latestReceived = [];
-        Scheduler.latestSent = [Date.now(),
-          Task.Debugging.generateReadableStack(new Error().stack),
-          ...message];
+        let stack = new Error().stack;
+        // Avoid loading Task.jsm if there's no task on the stack.
+        if (stack.includes("/Task.jsm:"))
+          stack = Task.Debugging.generateReadableStack(stack);
+        Scheduler.latestSent = [Date.now(), stack, ...message];
 
         // Wait for result
         let resources;
         try {
           resources = await this._worker.post(...message);
 
           Scheduler.latestReceived = [Date.now(), message];
         } catch (ex) {
--- a/toolkit/modules/Log.jsm
+++ b/toolkit/modules/Log.jsm
@@ -186,17 +186,21 @@ this.Log = {
           output.push(str);
         }
         frame = frame.caller;
       }
       return "Stack trace: " + output.join(" < ");
     }
     // Standard JS exception
     if (e.stack) {
-      return "JS Stack trace: " + Task.Debugging.generateReadableStack(e.stack).trim()
+      let stack = e.stack;
+      // Avoid loading Task.jsm if there's no task on the stack.
+      if (stack.includes("/Task.jsm:"))
+        stack = Task.Debugging.generateReadableStack(stack);
+      return "JS Stack trace: " + stack.trim()
         .replace(/\n/g, " < ").replace(/@[^@]*?([^\/\.]+\.\w+:)/g, "@$1");
     }
 
     return "No traceback available";
   }
 };
 
 /*
--- a/toolkit/modules/Sqlite.jsm
+++ b/toolkit/modules/Sqlite.jsm
@@ -586,17 +586,21 @@ ConnectionData.prototype = Object.freeze
               throw ex;
             }
           }
 
           let result;
           try {
             // Keep Task.spawn here to preserve API compat; unfortunately
             // func was a generator rather than a task here.
-            result = await Task.spawn(func); // eslint-disable-line mozilla/no-task
+            result = func();
+            if (Object.prototype.toString.call(result) == "[object Generator]")
+              result = await Task.spawn(func); // eslint-disable-line mozilla/no-task
+            else
+              result = await result;
           } catch (ex) {
             // It's possible that the exception has been caused by trying to
             // close the connection in the middle of a transaction.
             if (this._closeRequested) {
               this._log.warn("Connection closed while performing a transaction", ex);
             } else {
               this._log.warn("Error during transaction. Rolling back", ex);
               // If we began a transaction, we must rollback it.