Bug 1383100 - Use StructuredCloneHolder instead of cloneInto to log objects because of performance regression for big objects.
MozReview-Commit-ID: FIpz017Y8mw
--- 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") {