Bug 1530133 Part 1 - Debugger changes for removing obsolete log points, r=lsmyth.
authorBrian Hackett <bhackett1024@gmail.com>
Sat, 23 Feb 2019 16:18:57 -1000
changeset 520397 b0310f8849e0806a47e5c45f41be37dd4c1cc39e
parent 520396 f19a83763e503190da29a68f2a644412142f3c1d
child 520398 1e997aba85bb7f086ca9a41d3df8a020dee57118
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsmyth
bugs1530133
milestone67.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 1530133 Part 1 - Debugger changes for removing obsolete log points, r=lsmyth.
devtools/client/debugger/new/src/client/firefox/commands.js
devtools/client/debugger/new/src/types.js
devtools/server/actors/breakpoint.js
--- a/devtools/client/debugger/new/src/client/firefox/commands.js
+++ b/devtools/client/debugger/new/src/client/firefox/commands.js
@@ -171,20 +171,36 @@ function locationKey(location) {
   const { sourceUrl, sourceId, line, column } = location;
   return `${(sourceUrl: any)}:${(sourceId: any)}:${line}:${(column: any)}`;
 }
 
 function waitForWorkers(shouldWait: boolean) {
   shouldWaitForWorkers = shouldWait;
 }
 
+function maybeGenerateLogGroupId(options) {
+  if (options.logValue && tabTarget.traits && tabTarget.traits.canRewind) {
+    return { ...options, logGroupId: `logGroup-${Math.random()}` };
+  }
+  return options;
+}
+
+function maybeClearLogpoint(location) {
+  const bp = breakpoints[locationKey(location)];
+  if (bp && bp.options.logGroupId && tabTarget.activeConsole) {
+    tabTarget.activeConsole.emit("clearLogpointMessages", bp.options.logGroupId);
+  }
+}
+
 async function setBreakpoint(
   location: BreakpointLocation,
   options: BreakpointOptions
 ) {
+  maybeClearLogpoint(location);
+  options = maybeGenerateLogGroupId(options);
   breakpoints[locationKey(location)] = { location, options };
   await threadClient.setBreakpoint(location, options);
 
   // Set breakpoints in other threads as well, but do not wait for the requests
   // to complete, so that we don't get hung up if one of the threads stops
   // responding. We don't strictly need to wait for the main thread to finish
   // setting its breakpoint, but this leads to more consistent behavior if the
   // user sets a breakpoint and immediately starts interacting with the page.
@@ -196,16 +212,17 @@ async function setBreakpoint(
   } else {
     for (const thread of listWorkerThreadClients()) {
       thread.setBreakpoint(location, options);
     }
   }
 }
 
 async function removeBreakpoint(location: BreakpointLocation) {
+  maybeClearLogpoint(location);
   delete breakpoints[locationKey(location)];
   await threadClient.removeBreakpoint(location);
 
   // Remove breakpoints without waiting for the thread to respond, for the same
   // reason as in setBreakpoint.
   if (shouldWaitForWorkers) {
     for (const thread of listWorkerThreadClients()) {
       await thread.removeBreakpoint(location);
--- a/devtools/client/debugger/new/src/types.js
+++ b/devtools/client/debugger/new/src/types.js
@@ -126,17 +126,18 @@ export type Breakpoint = {|
 |};
 
 /**
  * Options for a breakpoint that can be modified by the user.
  */
 export type BreakpointOptions = {
   hidden?: boolean,
   condition?: string | null,
-  logValue?: string | null
+  logValue?: string | null,
+  logGroupId?: string | null
 };
 
 export type BreakpointActor = {|
   +actor: ActorId,
   +source: SourceActor
 |};
 
 /**
--- a/devtools/server/actors/breakpoint.js
+++ b/devtools/server/actors/breakpoint.js
@@ -39,17 +39,17 @@ function BreakpointActor(threadActor, lo
   this.threadActor = threadActor;
   this.location = location;
   this.options = null;
 }
 
 BreakpointActor.prototype = {
   setOptions(options) {
     for (const [script, offsets] of this.scripts) {
-      this._updateOptionsForScript(script, offsets, this.options, options);
+      this._updateOptionsForScript(script, offsets, options);
     }
 
     this.options = options;
   },
 
   destroy: function() {
     this.removeScripts();
   },
@@ -68,52 +68,50 @@ BreakpointActor.prototype = {
    *        Any offsets in the script the breakpoint is associated with.
    */
   addScript: function(script, offsets) {
     this.scripts.set(script, offsets.concat(this.scripts.get(offsets) || []));
     for (const offset of offsets) {
       script.setBreakpoint(offset, this);
     }
 
-    this._updateOptionsForScript(script, offsets, null, this.options);
+    this._updateOptionsForScript(script, offsets, this.options);
   },
 
   /**
    * Remove the breakpoints from associated scripts and clear the script cache.
    */
   removeScripts: function() {
-    for (const [script, offsets] of this.scripts) {
-      this._updateOptionsForScript(script, offsets, this.options, null);
+    for (const [script] of this.scripts) {
       script.clearBreakpoint(this);
     }
     this.scripts.clear();
   },
 
   // Update any state affected by changing options on a script this breakpoint
   // is associated with.
-  _updateOptionsForScript(script, offsets, oldOptions, newOptions) {
-    if (this.threadActor.dbg.replaying) {
-      // When replaying, logging breakpoints are handled using an API to get logged
-      // messages from throughout the recording.
-      const oldLogValue = oldOptions && oldOptions.logValue;
-      const newLogValue = newOptions && newOptions.logValue;
-      if (oldLogValue != newLogValue) {
-        for (const offset of offsets) {
-          const { lineNumber, columnNumber } = script.getOffsetLocation(offset);
-          script.replayVirtualConsoleLog(offset, newLogValue, (point, rv) => {
+  _updateOptionsForScript(script, offsets, options) {
+    // When replaying, logging breakpoints are handled using an API to get logged
+    // messages from throughout the recording.
+    if (this.threadActor.dbg.replaying && options.logValue) {
+      for (const offset of offsets) {
+        const { lineNumber, columnNumber } = script.getOffsetLocation(offset);
+        script.replayVirtualConsoleLog(
+          offset, options.logValue, options.condition, (executionPoint, rv) => {
             const message = {
               filename: script.url,
               lineNumber,
               columnNumber,
-              executionPoint: point,
+              executionPoint,
               "arguments": ["return" in rv ? rv.return : rv.throw],
+              logpointId: options.logGroupId,
             };
             this.threadActor._parent._consoleActor.onConsoleAPICall(message);
-          });
-        }
+          }
+        );
       }
     }
   },
 
   // Get a string message to display when a frame evaluation throws.
   getThrownMessage(completion) {
     try {
       if (completion.throw.getOwnPropertyDescriptor) {