Bug 1383100 - Use StructuredCloneHolder instead of cloneInto to log objects because of performance regression for big objects. draft
authorJulien Wajsberg <felash@gmail.com>
Thu, 20 Jul 2017 16:04:15 +0200
changeset 621015 96d85f3c7d2b0431598470500260c9694b72eba8
parent 620862 32083f24a1bb2c33050b4c972783f066432194eb
child 640871 6470999082e2abe5e796057a291045205634ab44
push id72227
push userbmo:felash@gmail.com
push dateFri, 04 Aug 2017 07:08:58 +0000
bugs1383100
milestone57.0a1
Bug 1383100 - Use StructuredCloneHolder instead of cloneInto to log objects because of performance regression for big objects. MozReview-Commit-ID: FIpz017Y8mw
devtools/server/actors/webconsole.js
toolkit/components/processsingleton/ContentProcessSingleton.js
--- a/devtools/server/actors/webconsole.js
+++ b/devtools/server/actors/webconsole.js
@@ -10,16 +10,17 @@
 
 const Services = require("Services");
 const { Cc, Ci, Cu } = require("chrome");
 const { DebuggerServer, ActorPool } = require("devtools/server/main");
 const { ThreadActor } = require("devtools/server/actors/script");
 const { ObjectActor, LongStringActor, createValueGrip, stringIsLong } = require("devtools/server/actors/object");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 const ErrorDocs = require("devtools/server/actors/errordocs");
+const { StructuredCloneHolder } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 loader.lazyRequireGetter(this, "NetworkMonitor", "devtools/shared/webconsole/network-monitor", true);
 loader.lazyRequireGetter(this, "NetworkMonitorChild", "devtools/shared/webconsole/network-monitor", true);
 loader.lazyRequireGetter(this, "ConsoleProgressListener", "devtools/shared/webconsole/network-monitor", true);
 loader.lazyRequireGetter(this, "StackTraceCollector", "devtools/shared/webconsole/network-monitor", true);
 loader.lazyRequireGetter(this, "events", "sdk/event/core");
 loader.lazyRequireGetter(this, "ServerLoggingListener", "devtools/shared/webconsole/server-logger", true);
 loader.lazyRequireGetter(this, "JSPropertyProvider", "devtools/shared/webconsole/js-property-provider", true);
@@ -433,16 +434,21 @@ WebConsoleActor.prototype =
    *        The value you want to get a debuggee value for.
    * @param boolean useObjectGlobal
    *        If |true| the object global is determined and added as a debuggee,
    *        otherwise |this.window| is used when makeDebuggeeValue() is invoked.
    * @return object
    *         Debuggee value for |value|.
    */
   makeDebuggeeValue: function (value, useObjectGlobal) {
+    if (value instanceof StructuredCloneHolder) {
+      // When logging an object from an OOP extension we use a StructuredCloneHolder
+      // Let's unwrap it.
+      value = value.deserialize(this.window);
+    }
     if (useObjectGlobal && typeof value == "object") {
       try {
         let global = Cu.getGlobalForObject(value);
         let dbgGlobal = this.dbg.makeGlobalObjectReference(global);
         return dbgGlobal.makeDebuggeeValue(value);
       } catch (ex) {
         // The above can throw an exception if value is not an actual object
         // or 'Object in compartment marked as invisible to Debugger'
--- a/toolkit/components/processsingleton/ContentProcessSingleton.js
+++ b/toolkit/components/processsingleton/ContentProcessSingleton.js
@@ -83,17 +83,17 @@ ContentProcessSingleton.prototype = {
             arg !== null) {
           if (Services.appinfo.remoteType === E10SUtils.EXTENSION_REMOTE_TYPE) {
             // For OOP extensions: we want the developer to be able to see the
             // logs in the Browser Console. When the Addon Toolbox will be more
             // prominent we can revisit.
             try {
               // If the argument is clonable, then send it as-is. If
               // cloning fails, fall back to the unavailable string.
-              arg = Cu.cloneInto(arg, {});
+              arg = new StructuredCloneHolder(arg);
             } catch (e) {
               arg = unavailString;
             }
           } else {
             arg = unavailString;
           }
           totalArgLength += unavailStringLength;
         } else if (typeof arg == "string") {