author | Miriam <bmiriam1230@gmail.com> |
Fri, 06 Sep 2019 18:12:06 +0000 | |
changeset 492059 | b0a5b50962e7774af1c0500098a7a14170397961 |
parent 492058 | 3182a1d6debb009c402ad74fba1c03a1a19966bf |
child 492060 | 3bcc094e0863013bd86996c7665260594d6413e1 |
push id | 36543 |
push user | ncsoregi@mozilla.com |
push date | Sat, 07 Sep 2019 09:40:21 +0000 |
treeherder | mozilla-central@de62729b366c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jlast |
bugs | 1574190 |
milestone | 71.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
|
devtools/server/actors/object.js | file | annotate | diff | comparison | revisions | |
devtools/server/actors/root.js | file | annotate | diff | comparison | revisions |
--- a/devtools/server/actors/object.js +++ b/devtools/server/actors/object.js @@ -103,27 +103,30 @@ const proto = { this._originalDescriptors = new Map(); }, rawValue: function() { return this.obj.unsafeDereference(); }, addWatchpoint(property, label, watchpointType) { + // We promote the object actor to the thread pool + // so that it lives for the lifetime of the watchpoint. + this.thread.threadObjectGrip(this); + if (this._originalDescriptors.has(property)) { return; } const desc = this.obj.getOwnPropertyDescriptor(property); - //If there is already a setter or getter, don't add watchpoint. if (desc.set || desc.get) { return; } - this._originalDescriptors.set(property, desc); + this._originalDescriptors.set(property, { desc, watchpointType }); const pauseAndRespond = () => { const frame = this.thread.dbg.getNewestFrame(); this.thread._pauseAndRespond(frame, { type: "watchpoint", message: label, }); }; @@ -132,42 +135,52 @@ const proto = { this.obj.defineProperty(property, { configurable: desc.configurable, enumerable: desc.enumerable, set: this.obj.makeDebuggeeValue(v => { desc.value = v; }), get: this.obj.makeDebuggeeValue(() => { pauseAndRespond(); + return desc.value; }), }); } if (watchpointType === "set") { this.obj.defineProperty(property, { configurable: desc.configurable, enumerable: desc.enumerable, set: this.obj.makeDebuggeeValue(v => { + pauseAndRespond(); desc.value = v; - pauseAndRespond(); + }), + get: this.obj.makeDebuggeeValue(v => { + return desc.value; }), }); } }, removeWatchpoint(property) { if (!this._originalDescriptors.has(property)) { return; } - const desc = this._originalDescriptors.get(property); + const desc = this._originalDescriptors.get(property).desc; this._originalDescriptors.delete(property); this.obj.defineProperty(property, desc); }, + removeWatchpoints() { + this._originalDescriptors.forEach(property => + this.removeWatchpoint(property) + ); + }, + /** * Returns a grip for this actor for returning in a protocol message. */ form: function() { const g = { type: "object", actor: this.actorID, }; @@ -776,18 +789,20 @@ const proto = { configurable: desc.configurable, enumerable: desc.enumerable, }; if ("value" in desc) { retval.writable = desc.writable; retval.value = this.hooks.createValueGrip(desc.value); } else if (this._originalDescriptors.has(name)) { - const value = this._originalDescriptors.get(name).value; - retval.value = this.hooks.createValueGrip(value); + const watchpointType = this._originalDescriptors.get(name).watchpointType; + desc = this._originalDescriptors.get(name).desc; + retval.value = this.hooks.createValueGrip(desc.value); + retval.watchpoint = watchpointType; } else { if ("get" in desc) { retval.get = this.hooks.createValueGrip(desc.get); } if ("set" in desc) { retval.set = this.hooks.createValueGrip(desc.set); } @@ -1011,13 +1026,15 @@ const proto = { proxyHandler: this.hooks.createValueGrip(this.obj.proxyHandler), }; }, /** * Release the actor, when it isn't needed anymore. * Protocol.js uses this release method to call the destroy method. */ - release: function() {}, + release: function() { + this.removeWatchpoints(); + }, }; exports.ObjectActor = protocol.ActorClassWithSpec(objectSpec, proto); exports.ObjectActorProto = proto;
--- a/devtools/server/actors/root.js +++ b/devtools/server/actors/root.js @@ -177,16 +177,18 @@ RootActor.prototype = { // `front.startProfiler`. This is an optional parameter but it will throw an error if // the profiled Firefox doesn't accept it. perfActorVersion: 1, // Supports native log points and modifying the condition/log of an existing // breakpoints. Fx66+ nativeLogpoints: true, // support older browsers for Fx69+ hasThreadFront: true, + // Support watchpoints in the server for Fx71+ + watchpoints: true, }, /** * Return a 'hello' packet as specified by the Remote Debugging Protocol. */ sayHello: function() { return { from: this.actorID,