Merge inbound to mozilla-central. a=merge
authorOana Pop Rus <opoprus@mozilla.com>
Mon, 25 Feb 2019 12:23:30 +0200
changeset 460853 d97cc5b9eeae57f6fb5d4b595ca68a569afa7bd2
parent 460852 9f35adb8e466e30ccc7059bf5d787b8ab4054968 (current diff)
parent 460839 aa7d1cc3ef70d2da282442deefc0372abc805a80 (diff)
child 460854 53992f6c29b314930a13f6087a448a0b486406fc
child 460867 6fd0fad9f4f11314b29eaf6697c6abdc3497825e
push id112120
push useropoprus@mozilla.com
push dateMon, 25 Feb 2019 10:33:46 +0000
treeherdermozilla-inbound@d97cc5b9eeae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone67.0a1
first release with
nightly linux32
d97cc5b9eeae / 67.0a1 / 20190225102402 / files
nightly linux64
d97cc5b9eeae / 67.0a1 / 20190225102402 / files
nightly mac
d97cc5b9eeae / 67.0a1 / 20190225102402 / files
nightly win32
d97cc5b9eeae / 67.0a1 / 20190225102402 / files
nightly win64
d97cc5b9eeae / 67.0a1 / 20190225102402 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
--- a/devtools/client/debugger/new/panel.js
+++ b/devtools/client/debugger/new/panel.js
@@ -127,21 +127,29 @@ DebuggerPanel.prototype = {
   getMappedExpression(expression) {
     return this._actions.getMappedExpression(expression);
   },
 
   isPaused() {
     return this._selectors.isPaused(this._getState());
   },
 
-  selectSource(url, line) {
+  selectSourceURL(url, line) {
     this._actions.selectSourceURL(url, { line });
   },
 
-  getSource(sourceURL) {
+  selectSource(sourceId, line) {
+    this._actions.selectSource(sourceId, { line });
+  },
+
+  getSourceByActorId(sourceId) {
+    return this._selectors.getSourceByActorId(this._getState(), sourceId);
+  },
+
+  getSourceByURL(sourceURL) {
     return this._selectors.getSourceByURL(this._getState(), sourceURL);
   },
 
   destroy: function() {
     this.panelWin.Debugger.destroy();
     this.emit("destroyed");
   }
 };
--- a/devtools/client/debugger/new/src/actions/sources/select.js
+++ b/devtools/client/debugger/new/src/actions/sources/select.js
@@ -82,19 +82,20 @@ export function selectSourceURL(
     return dispatch(selectLocation(location));
   };
 }
 
 /**
  * @memberof actions/sources
  * @static
  */
-export function selectSource(sourceId: string) {
+export function selectSource(sourceId: string,
+                             options: PartialPosition = { line: 1 }) {
   return async ({ dispatch }: ThunkArgs) => {
-    const location = createLocation({ sourceId });
+    const location = createLocation({ ...options, sourceId });
     return await dispatch(selectSpecificLocation(location));
   };
 }
 
 /**
  * @memberof actions/sources
  * @static
  */
--- a/devtools/client/debugger/new/src/reducers/sources.js
+++ b/devtools/client/debugger/new/src/reducers/sources.js
@@ -373,16 +373,27 @@ export function getSource(state: OuterSt
 export function getSourceFromId(state: OuterState, id: string): Source {
   const source = getSource(state, id);
   if (!source) {
     throw new Error(`source ${id} does not exist`);
   }
   return source;
 }
 
+export function getSourceByActorId(state: OuterState, actorId: string): Source {
+  // We don't index the sources by actor IDs, so this method should be used
+  // sparingly.
+  for (const source of Object.values(getSources(state))) {
+    if (source.actors.some(({ actor }) => actor == actorId)) {
+      return source;
+    }
+  }
+  return null;
+}
+
 export function getSourcesByURLInSources(
   sources: SourcesMap,
   urls: UrlsMap,
   url: string
 ): Source[] {
   if (!url || !urls[url]) {
     return [];
   }
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -3183,18 +3183,18 @@ Toolbox.prototype = {
   viewSourceInStyleEditor: function(sourceURL, sourceLine) {
     return viewSource.viewSourceInStyleEditor(this, sourceURL, sourceLine);
   },
 
   /**
    * Opens source in debugger. Falls back to plain "view-source:".
    * @see devtools/client/shared/source-utils.js
    */
-  viewSourceInDebugger: function(sourceURL, sourceLine, reason) {
-    return viewSource.viewSourceInDebugger(this, sourceURL, sourceLine, reason);
+  viewSourceInDebugger: function(sourceURL, sourceLine, sourceId, reason) {
+    return viewSource.viewSourceInDebugger(this, sourceURL, sourceLine, sourceId, reason);
   },
 
   /**
    * Opens source in scratchpad. Falls back to plain "view-source:".
    * TODO The `sourceURL` for scratchpad instances are like `Scratchpad/1`.
    * If instances are scoped one-per-browser-window, then we should be able
    * to infer the URL from this toolbox, or use the built in scratchpad IN
    * the toolbox.
--- a/devtools/client/shared/components/Frame.js
+++ b/devtools/client/shared/components/Frame.js
@@ -91,22 +91,23 @@ class Frame extends Component {
 
   /**
    * Utility method to convert the Frame object model to the
    * object model required by the onClick callback.
    * @param Frame frame
    * @returns {{url: *, line: *, column: *, functionDisplayName: *}}
    */
   getSourceForClick(frame) {
-    const { source, line, column } = frame;
+    const { source, line, column, sourceId } = frame;
     return {
       url: source,
       line,
       column,
       functionDisplayName: this.props.frame.functionDisplayName,
+      sourceId,
     };
   }
 
   render() {
     let frame, isSourceMapped;
     const {
       onClick,
       showFunctionName,
@@ -119,16 +120,17 @@ class Frame extends Component {
     if (this.state && this.state.isSourceMapped && this.state.frame) {
       frame = this.state.frame;
       isSourceMapped = this.state.isSourceMapped;
     } else {
       frame = this.props.frame;
     }
 
     const source = frame.source || "";
+    const sourceId = frame.sourceId;
     const line = frame.line != void 0 ? Number(frame.line) : null;
     const column = frame.column != void 0 ? Number(frame.column) : null;
 
     const { short, long, host } = getSourceNames(source);
     const unicodeShort = getUnicodeUrlPath(short);
     const unicodeLong  = getUnicodeUrl(long);
     const unicodeHost  = host ? getUnicodeHostname(host) : "";
 
@@ -218,17 +220,17 @@ class Frame extends Component {
 
     // If source is not a URL (self-hosted, eval, etc.), don't make
     // it an anchor link, as we can't link to it.
     if (isLinkable) {
       sourceEl = dom.a({
         onClick: e => {
           e.preventDefault();
           e.stopPropagation();
-          onClick(this.getSourceForClick({...frame, source}));
+          onClick(this.getSourceForClick({...frame, source, sourceId}));
         },
         href: source,
         className: "frame-link-source",
         draggable: false,
       }, sourceInnerEl);
     } else {
       sourceEl = dom.span({
         key: "source",
--- a/devtools/client/shared/components/SmartTrace.js
+++ b/devtools/client/shared/components/SmartTrace.js
@@ -204,16 +204,17 @@ class SmartTrace extends Component {
     return Frames({
       frames,
       selectFrame: ({location}) => {
         const viewSource = /^Scratchpad\/\d+$/.test(location.filename)
           ? onViewSourceInScratchpad
           : onViewSourceInDebugger || onViewSource;
 
         viewSource({
+          sourceId: location.sourceId,
           url: location.filename,
           line: location.line,
           column: location.column,
         });
       },
       getFrameTitle: url => {
         return l10n.getFormatStr("frame.viewsourceindebugger", url);
       },
--- a/devtools/client/shared/view-source.js
+++ b/devtools/client/shared/view-source.js
@@ -39,27 +39,34 @@ exports.viewSourceInStyleEditor = async 
  * it is opened in source view instead.
  * Returns a promise resolving to a boolean indicating whether or not
  * the source was able to be displayed in the Debugger, as the built-in Firefox
  * View Source is the fallback.
  *
  * @param {Toolbox} toolbox
  * @param {string} sourceURL
  * @param {number} sourceLine
+ * @param {string} sourceID
  * @param {string} [reason=unknown]
  *
  * @return {Promise<boolean>}
  */
-exports.viewSourceInDebugger = async function(toolbox, sourceURL, sourceLine,
+exports.viewSourceInDebugger = async function(toolbox, sourceURL, sourceLine, sourceId,
                                               reason = "unknown") {
   const dbg = await toolbox.loadTool("jsdebugger");
-  const source = dbg.getSource(sourceURL);
-  if (source || await toolbox.sourceMapService.hasOriginalURL(sourceURL)) {
+  const source = dbg.getSourceByURL(sourceURL) || dbg.getSourceByActorId(sourceId);
+  if (source) {
     await toolbox.selectTool("jsdebugger", reason);
-    dbg.selectSource(sourceURL, sourceLine);
+    dbg.selectSource(source.id, sourceLine);
+    return true;
+  } else if (await toolbox.sourceMapService.hasOriginalURL(sourceURL)) {
+    // We have seen a source map for the URL but no source. The debugger will
+    // still be able to load the source.
+    await toolbox.selectTool("jsdebugger", reason);
+    dbg.selectSourceURL(sourceURL, sourceLine);
     return true;
   }
 
   exports.viewSource(toolbox, sourceURL, sourceLine);
   return false;
 };
 
 /**
--- a/devtools/client/webconsole/test/fixtures/stub-generators/head.js
+++ b/devtools/client/webconsole/test/fixtures/stub-generators/head.js
@@ -101,16 +101,30 @@ function getCleanedPacket(key, packet) {
             // clean the `ownPropertyLength` property from the grip.
             if (newArgument.class === "Window") {
               newArgument.ownPropertyLength = existingArgument.ownPropertyLength;
             }
           }
           return newArgument;
         });
       }
+
+      if (res.message.sourceId) {
+        res.message.sourceId = existingPacket.message.sourceId;
+      }
+
+      if (Array.isArray(res.message.stacktrace)) {
+        res.message.stacktrace = res.message.stacktrace.map((frame, i) => {
+          const existingFrame = existingPacket.message.stacktrace[i];
+          if (frame && existingFrame && frame.sourceId) {
+            frame.sourceId = existingFrame.sourceId;
+          }
+          return frame;
+        });
+      }
     }
 
     if (res.result && existingPacket.result) {
       // Clean actor ids on evaluation result messages.
       res.result.actor = existingPacket.result.actor;
       if (res.result.preview) {
         if (res.result.preview.timestamp) {
           // Clean timestamp there too.
@@ -161,16 +175,30 @@ function getCleanedPacket(key, packet) {
       res.pageError.timeStamp = existingPacket.pageError.timeStamp;
 
       if (
         typeof res.pageError.errorMessage === "object"
         && res.pageError.errorMessage.type === "longString"
       ) {
         res.pageError.errorMessage.actor = existingPacket.pageError.errorMessage.actor;
       }
+
+      if (res.pageError.sourceId) {
+        res.pageError.sourceId = existingPacket.pageError.sourceId;
+      }
+
+      if (Array.isArray(res.pageError.stacktrace)) {
+        res.pageError.stacktrace = res.pageError.stacktrace.map((frame, i) => {
+          const existingFrame = existingPacket.pageError.stacktrace[i];
+          if (frame && existingFrame && frame.sourceId) {
+            frame.sourceId = existingFrame.sourceId;
+          }
+          return frame;
+        });
+      }
     }
 
     if (res.packet) {
       const override = {};
       const keys = ["totalTime", "from", "contentSize", "transferredSize"];
       keys.forEach(x => {
         if (res.packet[x] !== undefined) {
           override[x] = existingPacket.packet[key];
--- a/devtools/client/webconsole/test/fixtures/stubs/consoleApi.js
+++ b/devtools/client/webconsole/test/fixtures/stubs/consoleApi.js
@@ -21,20 +21,21 @@ stubPreparedMessages.set(`console.log('f
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "foobar",
     "test"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foobar\",\"test\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foobar\",\"test\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -52,20 +53,21 @@ stubPreparedMessages.set(`console.log(un
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     {
       "type": "undefined"
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"undefined\"}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"undefined\"}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -81,20 +83,21 @@ stubPreparedMessages.set(`console.warn('
   "timeStamp": 1502884924487,
   "type": "warn",
   "helperType": null,
   "level": "warn",
   "messageText": null,
   "parameters": [
     "danger, will robinson!"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":null,\"parameters\":[\"danger, will robinson!\"],\"source\":\"console-api\",\"type\":\"warn\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":null,\"parameters\":[\"danger, will robinson!\"],\"source\":\"console-api\",\"type\":\"warn\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -112,20 +115,21 @@ stubPreparedMessages.set(`console.log(Na
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     {
       "type": "NaN"
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"NaN\"}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"NaN\"}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -143,20 +147,21 @@ stubPreparedMessages.set(`console.log(nu
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     {
       "type": "null"
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"null\"}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"null\"}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -172,20 +177,21 @@ stubPreparedMessages.set(`console.log('鼬')`, new ConsoleMessage({
   "timeStamp": 1502884924506,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "鼬"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"鼬\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"鼬\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -201,20 +207,21 @@ stubPreparedMessages.set(`console.clear(
   "timeStamp": 1502884924512,
   "type": "clear",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "Console was cleared."
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"source\":\"console-api\",\"type\":\"clear\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"source\":\"console-api\",\"type\":\"clear\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -228,20 +235,21 @@ stubPreparedMessages.set(`console.count(
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1502884924515,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": "bar: 1",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"bar: 1\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"bar: 1\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -280,27 +288,29 @@ stubPreparedMessages.set(`console.assert
         },
         "ownSymbols": [],
         "ownPropertiesLength": 1,
         "ownSymbolsLength": 0,
         "safeGetterValues": {}
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj30\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"message\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"foobar\"}},\"ownSymbols\":[],\"ownPropertiesLength\":1,\"ownSymbolsLength\":0,\"safeGetterValues\":{}}}],\"source\":\"console-api\",\"type\":\"assert\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":[{\"columnNumber\":35,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"triggerPacket\",\"lineNumber\":1}]}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source33\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj30\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"message\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"foobar\"}},\"ownSymbols\":[],\"ownPropertiesLength\":1,\"ownSymbolsLength\":0,\"safeGetterValues\":{}}}],\"source\":\"console-api\",\"type\":\"assert\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":[{\"columnNumber\":35,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"triggerPacket\",\"lineNumber\":1,\"sourceId\":159}]}",
   "stacktrace": [
     {
       "columnNumber": 35,
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
       "functionName": "triggerPacket",
-      "lineNumber": 1
+      "lineNumber": 1,
+      "sourceId": 159
     }
   ],
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source33",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -316,20 +326,21 @@ stubPreparedMessages.set(`console.log('h
   "timeStamp": 1502884924528,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "hello \nfrom \rthe \"string world!"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"hello \\nfrom \\rthe \\\"string world!\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"hello \\nfrom \\rthe \\\"string world!\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -345,20 +356,21 @@ stubPreparedMessages.set(`console.log('úṇĩçödê țĕșť')`, new ConsoleMessage({
   "timeStamp": 1502884924586,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "úṇĩçödê țĕșť"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"úṇĩçödê țĕșť\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"úṇĩçödê țĕșť\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -386,20 +398,21 @@ stubPreparedMessages.set(`console.dirxml
       "sealed": false,
       "ownPropertyLength": 830,
       "preview": {
         "kind": "ObjectWithURL",
         "url": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html"
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj31\",\"class\":\"Window\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":830,\"preview\":{\"kind\":\"ObjectWithURL\",\"url\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\"}}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj31\",\"class\":\"Window\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":830,\"preview\":{\"kind\":\"ObjectWithURL\",\"url\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\"}}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -433,20 +446,21 @@ stubPreparedMessages.set(`console.log('m
         "items": [
           "red",
           "green",
           "blue"
         ]
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"myarray\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj32\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"red\",\"green\",\"blue\"]}}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"myarray\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj32\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"red\",\"green\",\"blue\"]}}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -472,20 +486,21 @@ stubPreparedMessages.set(`console.log('m
       "class": "RegExp",
       "extensible": true,
       "frozen": false,
       "sealed": false,
       "ownPropertyLength": 1,
       "displayString": "/a.b.c/"
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"myregex\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj33\",\"class\":\"RegExp\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"displayString\":\"/a.b.c/\"}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"myregex\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj33\",\"class\":\"RegExp\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"displayString\":\"/a.b.c/\"}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -518,20 +533,21 @@ stubPreparedMessages.set(`console.table(
         "items": [
           "red",
           "green",
           "blue"
         ]
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj34\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"red\",\"green\",\"blue\"]}}],\"source\":\"console-api\",\"type\":\"table\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj34\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"red\",\"green\",\"blue\"]}}],\"source\":\"console-api\",\"type\":\"table\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -583,20 +599,21 @@ stubPreparedMessages.set(`console.log('m
         },
         "ownSymbols": [],
         "ownPropertiesLength": 3,
         "ownSymbolsLength": 0,
         "safeGetterValues": {}
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"myobject\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj35\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":3,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"red\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"redValue\"},\"green\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"greenValue\"},\"blue\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"blueValue\"}},\"ownSymbols\":[],\"ownPropertiesLength\":3,\"ownSymbolsLength\":0,\"safeGetterValues\":{}}}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"myobject\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj35\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":3,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"red\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"redValue\"},\"green\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"greenValue\"},\"blue\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"blueValue\"}},\"ownSymbols\":[],\"ownPropertiesLength\":3,\"ownSymbolsLength\":0,\"safeGetterValues\":{}}}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -612,20 +629,21 @@ stubPreparedMessages.set(`console.debug(
   "timeStamp": 1502884924621,
   "type": "debug",
   "helperType": null,
   "level": "debug",
   "messageText": null,
   "parameters": [
     "debug message"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"debug\",\"messageText\":null,\"parameters\":[\"debug message\"],\"source\":\"console-api\",\"type\":\"debug\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"debug\",\"messageText\":null,\"parameters\":[\"debug message\"],\"source\":\"console-api\",\"type\":\"debug\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -641,20 +659,21 @@ stubPreparedMessages.set(`console.info('
   "timeStamp": 1502884924625,
   "type": "info",
   "helperType": null,
   "level": "info",
   "messageText": null,
   "parameters": [
     "info message"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"info\",\"messageText\":null,\"parameters\":[\"info message\"],\"source\":\"console-api\",\"type\":\"info\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"info\",\"messageText\":null,\"parameters\":[\"info message\"],\"source\":\"console-api\",\"type\":\"info\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -670,27 +689,29 @@ stubPreparedMessages.set(`console.error(
   "timeStamp": 1502884924628,
   "type": "error",
   "helperType": null,
   "level": "error",
   "messageText": null,
   "parameters": [
     "error message"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":null,\"parameters\":[\"error message\"],\"source\":\"console-api\",\"type\":\"error\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":[{\"columnNumber\":35,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"triggerPacket\",\"lineNumber\":1}]}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source33\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":null,\"parameters\":[\"error message\"],\"source\":\"console-api\",\"type\":\"error\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":[{\"columnNumber\":35,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"triggerPacket\",\"lineNumber\":1,\"sourceId\":159}]}",
   "stacktrace": [
     {
       "columnNumber": 35,
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
       "functionName": "triggerPacket",
-      "lineNumber": 1
+      "lineNumber": 1,
+      "sourceId": 159
     }
   ],
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source33",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -729,20 +750,21 @@ stubPreparedMessages.set(`console.log('m
           [
             "key2",
             "value2"
           ]
         ]
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":5,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"mymap\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj36\",\"class\":\"Map\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":0,\"preview\":{\"kind\":\"MapLike\",\"size\":2,\"entries\":[[\"key1\",\"value1\"],[\"key2\",\"value2\"]]}}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source50\",\"line\":5,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"mymap\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj36\",\"class\":\"Map\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":0,\"preview\":{\"kind\":\"MapLike\",\"size\":2,\"entries\":[[\"key1\",\"value1\"],[\"key2\",\"value2\"]]}}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source50",
     "line": 5,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -775,20 +797,21 @@ stubPreparedMessages.set(`console.log('m
         "length": 2,
         "items": [
           "a",
           "b"
         ]
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"myset\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj37\",\"class\":\"Set\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":0,\"preview\":{\"kind\":\"ArrayLike\",\"length\":2,\"items\":[\"a\",\"b\"]}}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"myset\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj37\",\"class\":\"Set\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":0,\"preview\":{\"kind\":\"ArrayLike\",\"length\":2,\"items\":[\"a\",\"b\"]}}],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source52",
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -802,39 +825,43 @@ stubPreparedMessages.set(`console.trace(
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1502884924752,
   "type": "trace",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":3,\"column\":11},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"source\":\"console-api\",\"type\":\"trace\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":[{\"columnNumber\":11,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"testStacktraceFiltering\",\"lineNumber\":3},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"foo\",\"lineNumber\":6},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"triggerPacket\",\"lineNumber\":9}]}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source55\",\"line\":3,\"column\":11},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"source\":\"console-api\",\"type\":\"trace\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":[{\"columnNumber\":11,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"testStacktraceFiltering\",\"lineNumber\":3,\"sourceId\":193},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"foo\",\"lineNumber\":6,\"sourceId\":193},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"triggerPacket\",\"lineNumber\":9,\"sourceId\":193}]}",
   "stacktrace": [
     {
       "columnNumber": 11,
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
       "functionName": "testStacktraceFiltering",
-      "lineNumber": 3
+      "lineNumber": 3,
+      "sourceId": 193
     },
     {
       "columnNumber": 3,
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
       "functionName": "foo",
-      "lineNumber": 6
+      "lineNumber": 6,
+      "sourceId": 193
     },
     {
       "columnNumber": 1,
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
       "functionName": "triggerPacket",
-      "lineNumber": 9
+      "lineNumber": 9,
+      "sourceId": 193
     }
   ],
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source55",
     "line": 3,
     "column": 11
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -892,39 +919,43 @@ stubPreparedMessages.set(`console.trace(
         "items": [
           1,
           2,
           3
         ]
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":3,\"column\":11},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj35\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"foo\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"bar\"}},\"ownSymbols\":[],\"ownPropertiesLength\":1,\"ownSymbolsLength\":0,\"safeGetterValues\":{}}},{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj36\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[1,2,3]}}],\"source\":\"console-api\",\"type\":\"trace\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":[{\"columnNumber\":11,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"testStacktraceWithLog\",\"lineNumber\":3},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"foo\",\"lineNumber\":6},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"triggerPacket\",\"lineNumber\":9}]}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source56\",\"line\":3,\"column\":11},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj35\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"foo\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"bar\"}},\"ownSymbols\":[],\"ownPropertiesLength\":1,\"ownSymbolsLength\":0,\"safeGetterValues\":{}}},{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj36\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[1,2,3]}}],\"source\":\"console-api\",\"type\":\"trace\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":[{\"columnNumber\":11,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"testStacktraceWithLog\",\"lineNumber\":3,\"sourceId\":195},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"foo\",\"lineNumber\":6,\"sourceId\":193},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"triggerPacket\",\"lineNumber\":9,\"sourceId\":193}]}",
   "stacktrace": [
     {
       "columnNumber": 11,
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
       "functionName": "testStacktraceWithLog",
-      "lineNumber": 3
+      "lineNumber": 3,
+      "sourceId": 195
     },
     {
       "columnNumber": 3,
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
       "functionName": "foo",
-      "lineNumber": 6
+      "lineNumber": 6,
+      "sourceId": 193
     },
     {
       "columnNumber": 1,
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
       "functionName": "triggerPacket",
-      "lineNumber": 9
+      "lineNumber": 9,
+      "sourceId": 193
     }
   ],
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source56",
     "line": 3,
     "column": 11
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -938,20 +969,21 @@ stubPreparedMessages.set(`console.time('
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1502884924757,
   "type": "nullMessage",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"nullMessage\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"nullMessage\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source52",
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -965,20 +997,21 @@ stubPreparedMessages.set(`timerAlreadyEx
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1502884924758,
   "type": "time",
   "helperType": null,
   "level": "warn",
   "messageText": "Timer “bar” already exists.",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Timer “bar” already exists.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"time\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Timer “bar” already exists.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"time\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source59",
     "line": 3,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -994,20 +1027,21 @@ stubPreparedMessages.set(`console.timeLo
   "timeStamp": 1526920999996,
   "type": "timeLog",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "bar: 1ms"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":4,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar: 1ms\"],\"source\":\"console-api\",\"type\":\"timeLog\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":4,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar: 1ms\"],\"source\":\"console-api\",\"type\":\"timeLog\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source59",
     "line": 4,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1048,20 +1082,21 @@ stubPreparedMessages.set(`console.timeLo
         },
         "ownSymbols": [],
         "ownPropertiesLength": 1,
         "ownSymbolsLength": 0,
         "safeGetterValues": {}
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":5,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar: 1ms\",\"second call\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj34\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"state\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":1}},\"ownSymbols\":[],\"ownPropertiesLength\":1,\"ownSymbolsLength\":0,\"safeGetterValues\":{}}}],\"source\":\"console-api\",\"type\":\"timeLog\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source50\",\"line\":5,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar: 1ms\",\"second call\",{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj34\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"state\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":1}},\"ownSymbols\":[],\"ownPropertiesLength\":1,\"ownSymbolsLength\":0,\"safeGetterValues\":{}}}],\"source\":\"console-api\",\"type\":\"timeLog\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source50",
     "line": 5,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1075,20 +1110,21 @@ stubPreparedMessages.set(`console.timeEn
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1502884924759,
   "type": "timeEnd",
   "helperType": null,
   "level": "log",
   "messageText": "bar: 1.21ms",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":6,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"bar: 1.21ms\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"timeEnd\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":6,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"bar: 1.21ms\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"timeEnd\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source59",
     "line": 6,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1102,20 +1138,21 @@ stubPreparedMessages.set(`timeEnd.timerD
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1526920999998,
   "type": "timeEnd",
   "helperType": null,
   "level": "warn",
   "messageText": "Timer “bar” doesn’t exist.",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":7,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Timer “bar” doesn’t exist.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"timeEnd\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":7,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Timer “bar” doesn’t exist.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"timeEnd\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source59",
     "line": 7,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1129,20 +1166,21 @@ stubPreparedMessages.set(`timeLog.timerD
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1526920999999,
   "type": "timeLog",
   "helperType": null,
   "level": "warn",
   "messageText": "Timer “bar” doesn’t exist.",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":8,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Timer “bar” doesn’t exist.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"timeLog\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":8,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Timer “bar” doesn’t exist.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"timeLog\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source59",
     "line": 8,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1158,20 +1196,21 @@ stubPreparedMessages.set(`console.table(
   "timeStamp": 1502884924801,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "bar"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source52",
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1204,20 +1243,21 @@ stubPreparedMessages.set(`console.table(
         "items": [
           "a",
           "b",
           "c"
         ]
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj39\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"a\",\"b\",\"c\"]}}],\"source\":\"console-api\",\"type\":\"table\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj39\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"a\",\"b\",\"c\"]}}],\"source\":\"console-api\",\"type\":\"table\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source52",
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1233,20 +1273,21 @@ stubPreparedMessages.set(`console.group(
   "timeStamp": 1502884924863,
   "type": "startGroup",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "bar"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\"],\"source\":\"console-api\",\"type\":\"startGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\"],\"source\":\"console-api\",\"type\":\"startGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source52",
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1260,20 +1301,21 @@ stubPreparedMessages.set(`console.groupE
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1502884924864,
   "type": "endGroup",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source59",
     "line": 3,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1289,20 +1331,21 @@ stubPreparedMessages.set(`console.groupC
   "timeStamp": 1502884924870,
   "type": "startGroupCollapsed",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "foo"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\"],\"source\":\"console-api\",\"type\":\"startGroupCollapsed\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\"],\"source\":\"console-api\",\"type\":\"startGroupCollapsed\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source52",
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1316,20 +1359,21 @@ stubPreparedMessages.set(`console.groupE
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1502884924871,
   "type": "endGroup",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source59",
     "line": 3,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1345,20 +1389,21 @@ stubPreparedMessages.set(`console.group(
   "timeStamp": 1502884924878,
   "type": "startGroup",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "<no group label>"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"<no group label>\"],\"source\":\"console-api\",\"type\":\"startGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"<no group label>\"],\"source\":\"console-api\",\"type\":\"startGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source52",
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1372,20 +1417,21 @@ stubPreparedMessages.set(`console.groupE
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1502884924879,
   "type": "endGroup",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source59",
     "line": 3,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1402,20 +1448,21 @@ stubPreparedMessages.set(`console.log(%c
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "foo",
     "bar"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"bar\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[\"color:blue; font-size:1.3em; background:url('http://example.com/test'); position:absolute; top:10px; \",\"color:red; line-height: 1.5; background:url('http://example.com/test')\"],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"bar\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[\"color:blue; font-size:1.3em; background:url('http://example.com/test'); position:absolute; top:10px; \",\"color:red; line-height: 1.5; background:url('http://example.com/test')\"],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source52",
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [
     "color:blue; font-size:1.3em; background:url('http://example.com/test'); position:absolute; top:10px; ",
@@ -1436,20 +1483,21 @@ stubPreparedMessages.set(`console.log("%
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "Hello",
     "|",
     "World"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":11},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Hello\",\"|\",\"World\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[\"color:red\",\"\",\"color: blue\"],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source68\",\"line\":2,\"column\":11},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Hello\",\"|\",\"World\"],\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[\"color:red\",\"\",\"color: blue\"],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source68",
     "line": 2,
     "column": 11
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [
     "color:red",
@@ -1470,20 +1518,21 @@ stubPreparedMessages.set(`console.group(
   "type": "startGroup",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "foo",
     "bar"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"bar\"],\"source\":\"console-api\",\"type\":\"startGroup\",\"userProvidedStyles\":[\"color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px\",\"color:red;background:url('http://example.com/test')\"],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"bar\"],\"source\":\"console-api\",\"type\":\"startGroup\",\"userProvidedStyles\":[\"color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px\",\"color:red;background:url('http://example.com/test')\"],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source52",
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [
     "color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px",
@@ -1500,20 +1549,21 @@ stubPreparedMessages.set(`console.groupE
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1502884924887,
   "type": "endGroup",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":6,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":6,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source59",
     "line": 6,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1530,20 +1580,21 @@ stubPreparedMessages.set(`console.groupC
   "type": "startGroupCollapsed",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "foo",
     "baz"
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"baz\"],\"source\":\"console-api\",\"type\":\"startGroupCollapsed\",\"userProvidedStyles\":[\"color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px\",\"color:red;background:url('http://example.com/test')\"],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"baz\"],\"source\":\"console-api\",\"type\":\"startGroupCollapsed\",\"userProvidedStyles\":[\"color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px\",\"color:red;background:url('http://example.com/test')\"],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source52",
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [
     "color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px",
@@ -1560,20 +1611,21 @@ stubPreparedMessages.set(`console.groupE
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1502884924893,
   "type": "endGroup",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":6,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":6,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source59",
     "line": 6,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1630,20 +1682,21 @@ stubPreparedMessages.set(`console.dir({C
         },
         "ownSymbols": [],
         "ownPropertiesLength": 4,
         "ownSymbolsLength": 0,
         "safeGetterValues": {}
       }
     }
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj36\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"cyan\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"C\"},\"magenta\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"M\"},\"yellow\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"Y\"},\"black\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"K\"}},\"ownSymbols\":[],\"ownPropertiesLength\":4,\"ownSymbolsLength\":0,\"safeGetterValues\":{}}}],\"source\":\"console-api\",\"type\":\"dir\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj36\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"cyan\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"C\"},\"magenta\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"M\"},\"yellow\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"Y\"},\"black\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"K\"}},\"ownSymbols\":[],\"ownPropertiesLength\":4,\"ownSymbolsLength\":0,\"safeGetterValues\":{}}}],\"source\":\"console-api\",\"type\":\"dir\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source25",
     "line": 1,
     "column": 35
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1657,20 +1710,21 @@ stubPreparedMessages.set(`console.count 
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1511365913333,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": "default: 1",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 1\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":2,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 1\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source73",
     "line": 2,
     "column": 13
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1684,20 +1738,21 @@ stubPreparedMessages.set(`console.count 
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1511365913334,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": "default: 2",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":3,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 2\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":3,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 2\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source73",
     "line": 3,
     "column": 13
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1711,20 +1766,21 @@ stubPreparedMessages.set(`console.count 
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1511365913334,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": "test counter: 1",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":4,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 1\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":4,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 1\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source73",
     "line": 4,
     "column": 13
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1738,20 +1794,21 @@ stubPreparedMessages.set(`console.count 
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1511365913334,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": "test counter: 2",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":5,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 2\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":5,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 2\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source73",
     "line": 5,
     "column": 13
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1765,20 +1822,21 @@ stubPreparedMessages.set(`console.count 
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1511365913334,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": "default: 3",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":6,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 3\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":6,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 3\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source73",
     "line": 6,
     "column": 13
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1794,20 +1852,21 @@ stubPreparedMessages.set(`console.count 
   "timeStamp": 1511365913334,
   "type": "clear",
   "helperType": null,
   "level": "log",
   "messageText": null,
   "parameters": [
     "Console was cleared."
   ],
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":7,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"source\":\"console-api\",\"type\":\"clear\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":7,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"source\":\"console-api\",\"type\":\"clear\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source73",
     "line": 7,
     "column": 13
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1821,20 +1880,21 @@ stubPreparedMessages.set(`console.count 
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1511365913335,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": "default: 4",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":8,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 4\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":8,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 4\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source73",
     "line": 8,
     "column": 13
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1848,20 +1908,21 @@ stubPreparedMessages.set(`console.count 
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1511365913335,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": "test counter: 3",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":9,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 3\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":9,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 3\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source73",
     "line": 9,
     "column": 13
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1875,20 +1936,21 @@ stubPreparedMessages.set(`console.countR
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1526920412190,
   "type": "log",
   "helperType": null,
   "level": "log",
   "messageText": "test counter: 0",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":10,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 0\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":10,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 0\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source73",
     "line": 10,
     "column": 13
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1902,20 +1964,21 @@ stubPreparedMessages.set(`console.countR
   "allowRepeating": true,
   "source": "console-api",
   "timeStamp": 1526920412191,
   "type": "log",
   "helperType": null,
   "level": "warn",
   "messageText": "Counter “test counter” doesn’t exist.",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":11,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Counter “test counter” doesn’t exist.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":11,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Counter “test counter” doesn’t exist.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source73",
     "line": 11,
     "column": 13
   },
   "groupId": null,
   "errorMessageName": null,
   "exceptionDocURL": null,
   "userProvidedStyles": [],
   "notes": null,
@@ -1935,16 +1998,17 @@ stubPackets.set(`console.log('foobar', '
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924471,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -1962,16 +2026,17 @@ stubPackets.set(`console.log(undefined)`
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924479,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -1987,16 +2052,17 @@ stubPackets.set(`console.warn('danger, w
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "warn",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924487,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2014,16 +2080,17 @@ stubPackets.set(`console.log(NaN)`, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924495,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2041,16 +2108,17 @@ stubPackets.set(`console.log(null)`, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924501,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2066,16 +2134,17 @@ stubPackets.set(`console.log('鼬')`, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924506,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2089,16 +2158,17 @@ stubPackets.set(`console.clear()`, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "clear",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "timeStamp": 1502884924512,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2117,16 +2187,17 @@ stubPackets.set(`console.count('bar')`, 
     },
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "count",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "timeStamp": 1502884924515,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2165,25 +2236,27 @@ stubPackets.set(`console.assert(false, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "assert",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source33",
     "styles": [],
     "timeStamp": 1502884924521,
     "timer": null,
     "stacktrace": [
       {
         "columnNumber": 35,
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
         "functionName": "triggerPacket",
-        "lineNumber": 1
+        "lineNumber": 1,
+        "sourceId": 159
       }
     ],
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
 });
@@ -2198,16 +2271,17 @@ stubPackets.set(`console.log('hello \nfr
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924528,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2223,16 +2297,17 @@ stubPackets.set(`console.log('úṇĩçödê țĕșť')`, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924586,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2260,16 +2335,17 @@ stubPackets.set(`console.dirxml(window)`
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "dirxml",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "timeStamp": 1502884924596,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2303,16 +2379,17 @@ stubPackets.set(`console.log('myarray', 
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924604,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2338,16 +2415,17 @@ stubPackets.set(`console.log('myregex', 
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924610,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2380,16 +2458,17 @@ stubPackets.set(`console.table(['red', '
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "table",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "timeStamp": 1502884924612,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2441,16 +2520,17 @@ stubPackets.set(`console.log('myobject',
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924614,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2466,16 +2546,17 @@ stubPackets.set(`console.debug('debug me
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "debug",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924621,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2491,16 +2572,17 @@ stubPackets.set(`console.info('info mess
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "info",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "styles": [],
     "timeStamp": 1502884924625,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2516,25 +2598,27 @@ stubPackets.set(`console.error('error me
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "error",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source33",
     "styles": [],
     "timeStamp": 1502884924628,
     "timer": null,
     "stacktrace": [
       {
         "columnNumber": 35,
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
         "functionName": "triggerPacket",
-        "lineNumber": 1
+        "lineNumber": 1,
+        "sourceId": 159
       }
     ],
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
 });
@@ -2572,16 +2656,17 @@ stubPackets.set(`console.log('mymap')`, 
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 5,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source50",
     "styles": [],
     "timeStamp": 1502884924631,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2614,16 +2699,17 @@ stubPackets.set(`console.log('myset')`, 
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source52",
     "styles": [],
     "timeStamp": 1502884924746,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2637,36 +2723,40 @@ stubPackets.set(`console.trace()`, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "testStacktraceFiltering",
     "groupName": "",
     "level": "trace",
     "lineNumber": 3,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source55",
     "timeStamp": 1502884924752,
     "timer": null,
     "stacktrace": [
       {
         "columnNumber": 11,
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
         "functionName": "testStacktraceFiltering",
-        "lineNumber": 3
+        "lineNumber": 3,
+        "sourceId": 193
       },
       {
         "columnNumber": 3,
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
         "functionName": "foo",
-        "lineNumber": 6
+        "lineNumber": 6,
+        "sourceId": 193
       },
       {
         "columnNumber": 1,
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
         "functionName": "triggerPacket",
-        "lineNumber": 9
+        "lineNumber": 9,
+        "sourceId": 193
       }
     ],
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2724,36 +2814,40 @@ stubPackets.set(`console.trace('bar', {'
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "testStacktraceWithLog",
     "groupName": "",
     "level": "trace",
     "lineNumber": 3,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source56",
     "timeStamp": 1538037986659,
     "timer": null,
     "stacktrace": [
       {
         "columnNumber": 11,
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
         "functionName": "testStacktraceWithLog",
-        "lineNumber": 3
+        "lineNumber": 3,
+        "sourceId": 195
       },
       {
         "columnNumber": 3,
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
         "functionName": "foo",
-        "lineNumber": 6
+        "lineNumber": 6,
+        "sourceId": 193
       },
       {
         "columnNumber": 1,
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
         "functionName": "triggerPacket",
-        "lineNumber": 9
+        "lineNumber": 9,
+        "sourceId": 193
       }
     ],
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -2769,16 +2863,17 @@ stubPackets.set(`console.time('bar')`, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "time",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source52",
     "timeStamp": 1502884924757,
     "timer": {
       "name": "bar"
     },
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
@@ -2796,16 +2891,17 @@ stubPackets.set(`timerAlreadyExists`, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "time",
     "lineNumber": 3,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source59",
     "timeStamp": 1502884924758,
     "timer": {
       "error": "timerAlreadyExists",
       "name": "bar"
     },
     "workerType": "none",
     "styles": [],
     "category": "webdev"
@@ -2824,16 +2920,17 @@ stubPackets.set(`console.timeLog('bar') 
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "timeLog",
     "lineNumber": 4,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source59",
     "timeStamp": 1526920999996,
     "timer": {
       "duration": 1,
       "name": "bar"
     },
     "workerType": "none",
     "styles": [],
     "category": "webdev"
@@ -2877,16 +2974,17 @@ stubPackets.set(`console.timeLog('bar') 
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "timeLog",
     "lineNumber": 5,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source50",
     "timeStamp": 1526920999996,
     "timer": {
       "duration": 1,
       "name": "bar"
     },
     "workerType": "none",
     "styles": [],
     "category": "webdev"
@@ -2905,16 +3003,17 @@ stubPackets.set(`console.timeEnd('bar')`
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "timeEnd",
     "lineNumber": 6,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source59",
     "timeStamp": 1502884924759,
     "timer": {
       "duration": 1.2149999999999181,
       "name": "bar"
     },
     "workerType": "none",
     "styles": [],
     "category": "webdev"
@@ -2933,16 +3032,17 @@ stubPackets.set(`timeEnd.timerDoesntExis
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "timeEnd",
     "lineNumber": 7,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source59",
     "timeStamp": 1526920999998,
     "timer": {
       "error": "timerDoesntExist",
       "name": "bar"
     },
     "workerType": "none",
     "styles": [],
     "category": "webdev"
@@ -2961,16 +3061,17 @@ stubPackets.set(`timeLog.timerDoesntExis
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "timeLog",
     "lineNumber": 8,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source59",
     "timeStamp": 1526920999999,
     "timer": {
       "error": "timerDoesntExist",
       "name": "bar"
     },
     "workerType": "none",
     "styles": [],
     "category": "webdev"
@@ -2989,16 +3090,17 @@ stubPackets.set(`console.table('bar')`, 
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "table",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source52",
     "timeStamp": 1502884924801,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3031,16 +3133,17 @@ stubPackets.set(`console.table(['a', 'b'
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "table",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source52",
     "timeStamp": 1502884924859,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3056,16 +3159,17 @@ stubPackets.set(`console.group('bar')`, 
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "bar",
     "level": "group",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source52",
     "styles": [],
     "timeStamp": 1502884924863,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3079,16 +3183,17 @@ stubPackets.set(`console.groupEnd('bar')
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "bar",
     "level": "groupEnd",
     "lineNumber": 3,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source59",
     "timeStamp": 1502884924864,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3104,16 +3209,17 @@ stubPackets.set(`console.groupCollapsed(
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "foo",
     "level": "groupCollapsed",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source52",
     "styles": [],
     "timeStamp": 1502884924870,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3127,16 +3233,17 @@ stubPackets.set(`console.groupEnd('foo')
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "foo",
     "level": "groupEnd",
     "lineNumber": 3,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source59",
     "timeStamp": 1502884924871,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3150,16 +3257,17 @@ stubPackets.set(`console.group()`, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "group",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source52",
     "styles": [],
     "timeStamp": 1502884924878,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3173,16 +3281,17 @@ stubPackets.set(`console.groupEnd()`, {
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "groupEnd",
     "lineNumber": 3,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source59",
     "timeStamp": 1502884924879,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3199,16 +3308,17 @@ stubPackets.set(`console.log(%cfoobar)`,
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source52",
     "styles": [
       "color:blue; font-size:1.3em; background:url('http://example.com/test'); position:absolute; top:10px; ",
       "color:red; line-height: 1.5; background:url('http://example.com/test')"
     ],
     "timeStamp": 1502884924883,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
@@ -3229,16 +3339,17 @@ stubPackets.set(`console.log("%cHello%c|
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "log",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source68",
     "styles": [
       "color:red",
       "",
       "color: blue"
     ],
     "timeStamp": 1518681614352,
     "timer": null,
     "workerType": "none",
@@ -3259,16 +3370,17 @@ stubPackets.set(`console.group(%cfoo%cba
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "foo bar",
     "level": "group",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source52",
     "styles": [
       "color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px",
       "color:red;background:url('http://example.com/test')"
     ],
     "timeStamp": 1502884924887,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
@@ -3285,16 +3397,17 @@ stubPackets.set(`console.groupEnd(%cfoo%
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "foo bar",
     "level": "groupEnd",
     "lineNumber": 6,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source59",
     "timeStamp": 1502884924887,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3311,16 +3424,17 @@ stubPackets.set(`console.groupCollapsed(
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "foo baz",
     "level": "groupCollapsed",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source52",
     "styles": [
       "color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px",
       "color:red;background:url('http://example.com/test')"
     ],
     "timeStamp": 1502884924892,
     "timer": null,
     "workerType": "none",
     "category": "webdev"
@@ -3337,16 +3451,17 @@ stubPackets.set(`console.groupEnd(%cfoo%
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "foo baz",
     "level": "groupEnd",
     "lineNumber": 6,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source59",
     "timeStamp": 1502884924893,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3403,16 +3518,17 @@ stubPackets.set(`console.dir({C, M, Y, K
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "dir",
     "lineNumber": 1,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source25",
     "timeStamp": 1502884924899,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3431,16 +3547,17 @@ stubPackets.set(`console.count | default
     },
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "count",
     "lineNumber": 2,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source73",
     "timeStamp": 1511365913333,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3459,16 +3576,17 @@ stubPackets.set(`console.count | default
     },
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "count",
     "lineNumber": 3,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source73",
     "timeStamp": 1511365913334,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3487,16 +3605,17 @@ stubPackets.set(`console.count | test co
     },
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "count",
     "lineNumber": 4,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source73",
     "timeStamp": 1511365913334,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3515,16 +3634,17 @@ stubPackets.set(`console.count | test co
     },
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "count",
     "lineNumber": 5,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source73",
     "timeStamp": 1511365913334,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3543,16 +3663,17 @@ stubPackets.set(`console.count | default
     },
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "count",
     "lineNumber": 6,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source73",
     "timeStamp": 1511365913334,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3566,16 +3687,17 @@ stubPackets.set(`console.count | clear`,
     "counter": null,
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "clear",
     "lineNumber": 7,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source73",
     "timeStamp": 1511365913334,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3594,16 +3716,17 @@ stubPackets.set(`console.count | default
     },
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "count",
     "lineNumber": 8,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source73",
     "timeStamp": 1511365913335,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3622,16 +3745,17 @@ stubPackets.set(`console.count | test co
     },
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "count",
     "lineNumber": 9,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source73",
     "timeStamp": 1511365913335,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3650,16 +3774,17 @@ stubPackets.set(`console.countReset | te
     },
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "countReset",
     "lineNumber": 10,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source73",
     "timeStamp": 1526920412190,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
@@ -3678,16 +3803,17 @@ stubPackets.set(`console.countReset | co
     },
     "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
     "functionName": "triggerPacket",
     "groupName": "",
     "level": "countReset",
     "lineNumber": 11,
     "prefix": "",
     "private": false,
+    "sourceId": "server1.conn0.child1/source73",
     "timeStamp": 1526920412191,
     "timer": null,
     "workerType": "none",
     "styles": [],
     "category": "webdev"
   },
   "type": "consoleAPICall",
   "from": "server1.conn0.child1/consoleActor2"
--- a/devtools/client/webconsole/test/fixtures/stubs/cssMessage.js
+++ b/devtools/client/webconsole/test/fixtures/stubs/cssMessage.js
@@ -18,20 +18,21 @@ stubPreparedMessages.set(`Unknown property ‘such-unknown-property’.  Declaration dropped.`, new ConsoleMessage({
   "allowRepeating": true,
   "source": "css",
   "timeStamp": 1479159920406,
   "type": "log",
   "helperType": null,
   "level": "warn",
   "messageText": "Unknown property ‘such-unknown-property’.  Declaration dropped.",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-css-message.html\",\"line\":3,\"column\":25},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Unknown property ‘such-unknown-property’.  Declaration dropped.\",\"parameters\":null,\"source\":\"css\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-css-message.html\",\"sourceId\":null,\"line\":3,\"column\":25},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Unknown property ‘such-unknown-property’.  Declaration dropped.\",\"parameters\":null,\"source\":\"css\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-css-message.html",
+    "sourceId": null,
     "line": 3,
     "column": 25
   },
   "groupId": null,
   "errorMessageName": "",
   "userProvidedStyles": null,
   "notes": null,
   "indent": 0,
@@ -44,20 +45,21 @@ stubPreparedMessages.set(`Error in parsing value for ‘padding-top’.  Declaration dropped.`, new ConsoleMessage({
   "allowRepeating": true,
   "source": "css",
   "timeStamp": 1479159920465,
   "type": "log",
   "helperType": null,
   "level": "warn",
   "messageText": "Error in parsing value for ‘padding-top’.  Declaration dropped.",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-css-message.html\",\"line\":3,\"column\":16},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Error in parsing value for ‘padding-top’.  Declaration dropped.\",\"parameters\":null,\"source\":\"css\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":null}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-css-message.html\",\"sourceId\":null,\"line\":3,\"column\":16},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Error in parsing value for ‘padding-top’.  Declaration dropped.\",\"parameters\":null,\"source\":\"css\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":null}",
   "stacktrace": null,
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-css-message.html",
+    "sourceId": null,
     "line": 3,
     "column": 16
   },
   "groupId": null,
   "errorMessageName": "",
   "userProvidedStyles": null,
   "notes": null,
   "indent": 0,
@@ -65,16 +67,17 @@ stubPreparedMessages.set(`Error in parsing value for ‘padding-top’.  Declaration dropped.`, new ConsoleMessage({
   "private": false
 }));
 
 stubPackets.set(`Unknown property ‘such-unknown-property’.  Declaration dropped.`, {
   "pageError": {
     "errorMessage": "Unknown property ‘such-unknown-property’.  Declaration dropped.",
     "errorMessageName": "",
     "sourceName": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-css-message.html",
+    "sourceId": null,
     "lineText": "",
     "lineNumber": 3,
     "columnNumber": 25,
     "category": "CSS Parser",
     "timeStamp": 1479159920406,
     "warning": true,
     "error": false,
     "exception": false,
@@ -88,16 +91,17 @@ stubPackets.set(`Unknown property ‘such-unknown-property’.  Declaration dropped.`, {
   "from": "server1.conn0.child1/consoleActor2"
 });
 
 stubPackets.set(`Error in parsing value for ‘padding-top’.  Declaration dropped.`, {
   "pageError": {
     "errorMessage": "Error in parsing value for ‘padding-top’.  Declaration dropped.",
     "errorMessageName": "",
     "sourceName": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-css-message.html",
+    "sourceId": null,
     "lineText": "",
     "lineNumber": 3,
     "columnNumber": 16,
     "category": "CSS Parser",
     "timeStamp": 1479159920465,
     "warning": true,
     "error": false,
     "exception": false,
--- a/devtools/client/webconsole/test/fixtures/stubs/pageError.js
+++ b/devtools/client/webconsole/test/fixtures/stubs/pageError.js
@@ -18,51 +18,57 @@ stubPreparedMessages.set(`ReferenceError
   "allowRepeating": true,
   "source": "javascript",
   "timeStamp": 1476573167137,
   "type": "log",
   "helperType": null,
   "level": "error",
   "messageText": "ReferenceError: asdf is not defined",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":3,\"column\":5},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"source\":\"javascript\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js line 59 > eval\",\"lineNumber\":7,\"columnNumber\":31,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js\",\"lineNumber\":60,\"columnNumber\":29,\"functionName\":null}]}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":null,\"line\":3,\"column\":5},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"source\":\"javascript\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js line 59 > eval\",\"sourceId\":null,\"lineNumber\":7,\"columnNumber\":31,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js\",\"sourceId\":null,\"lineNumber\":60,\"columnNumber\":29,\"functionName\":null}]}",
   "stacktrace": [
     {
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+      "sourceId": "server1.conn0.child1/source25",
       "lineNumber": 3,
       "columnNumber": 5,
       "functionName": "bar"
     },
     {
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+      "sourceId": "server1.conn0.child1/source25",
       "lineNumber": 6,
       "columnNumber": 5,
       "functionName": "foo"
     },
     {
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+      "sourceId": "server1.conn0.child1/source25",
       "lineNumber": 9,
       "columnNumber": 3,
       "functionName": null
     },
     {
       "filename": "resource://testing-common/content-task.js line 59 > eval",
+      "sourceId": null,
       "lineNumber": 7,
       "columnNumber": 31,
       "functionName": null
     },
     {
       "filename": "resource://testing-common/content-task.js",
+      "sourceId": null,
       "lineNumber": 60,
       "columnNumber": 29,
       "functionName": null
     }
   ],
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": null,
     "line": 3,
     "column": 5
   },
   "groupId": null,
   "errorMessageName": "JSMSG_NOT_DEFINED",
   "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default",
   "userProvidedStyles": null,
   "notes": null,
@@ -76,44 +82,48 @@ stubPreparedMessages.set(`SyntaxError: r
   "allowRepeating": true,
   "source": "javascript",
   "timeStamp": 1487992945524,
   "type": "log",
   "helperType": null,
   "level": "error",
   "messageText": "SyntaxError: redeclaration of let a",
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":\"SyntaxError: redeclaration of let a\",\"parameters\":null,\"source\":\"javascript\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":[{\"filename\":\"resource://testing-common/content-task.js line 59 > eval\",\"lineNumber\":7,\"columnNumber\":31,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js\",\"lineNumber\":60,\"columnNumber\":29,\"functionName\":null}]}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":null,\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":\"SyntaxError: redeclaration of let a\",\"parameters\":null,\"source\":\"javascript\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":[{\"filename\":\"resource://testing-common/content-task.js line 59 > eval\",\"sourceId\":null,\"lineNumber\":7,\"columnNumber\":31,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js\",\"sourceId\":null,\"lineNumber\":60,\"columnNumber\":29,\"functionName\":null}]}",
   "stacktrace": [
     {
       "filename": "resource://testing-common/content-task.js line 59 > eval",
+      "sourceId": null,
       "lineNumber": 7,
       "columnNumber": 31,
       "functionName": null
     },
     {
       "filename": "resource://testing-common/content-task.js",
+      "sourceId": null,
       "lineNumber": 60,
       "columnNumber": 29,
       "functionName": null
     }
   ],
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": null,
     "line": 2,
     "column": 9
   },
   "groupId": null,
   "errorMessageName": "JSMSG_REDECLARED_VAR",
   "userProvidedStyles": null,
   "notes": [
     {
       "messageBody": "Previously declared at line 2, column 6",
       "frame": {
         "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+        "sourceId": null,
         "line": 2,
         "column": 6
       }
     }
   ],
   "indent": 0,
   "prefix": "",
   "private": false
@@ -129,39 +139,43 @@ stubPreparedMessages.set(`TypeError long
   "level": "error",
   "messageText": {
     "type": "longString",
     "initial": "Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Lon",
     "length": 110007,
     "actor": "server1.conn0.child1/longString30"
   },
   "parameters": null,
-  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"line\":1,\"column\":7},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":{\"type\":\"longString\",\"initial\":\"Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Lon\",\"length\":110007,\"actor\":\"server1.conn0.child1/longString30\"},\"parameters\":null,\"source\":\"javascript\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"lineNumber\":1,\"columnNumber\":7,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js line 59 > eval\",\"lineNumber\":7,\"columnNumber\":31,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js\",\"lineNumber\":60,\"columnNumber\":29,\"functionName\":null}]}",
+  "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source26\",\"line\":1,\"column\":7},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":{\"type\":\"longString\",\"initial\":\"Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Lon\",\"length\":110007,\"actor\":\"server1.conn0.child1/longString30\"},\"parameters\":null,\"source\":\"javascript\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source26\",\"lineNumber\":1,\"columnNumber\":7,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js line 59 > eval\",\"sourceId\":null,\"lineNumber\":7,\"columnNumber\":31,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js\",\"sourceId\":null,\"lineNumber\":60,\"columnNumber\":29,\"functionName\":null}]}",
   "stacktrace": [
     {
       "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+      "sourceId": "server1.conn0.child1/source26",
       "lineNumber": 1,
       "columnNumber": 7,
       "functionName": null
     },
     {
       "filename": "resource://testing-common/content-task.js line 59 > eval",
+      "sourceId": null,
       "lineNumber": 7,
       "columnNumber": 31,
       "functionName": null
     },
     {
       "filename": "resource://testing-common/content-task.js",
+      "sourceId": null,
       "lineNumber": 60,
       "columnNumber": 29,
       "functionName": null
     }
   ],
   "frame": {
     "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source26",
     "line": 1,
     "column": 7
   },
   "groupId": null,
   "errorMessageName": "",
   "userProvidedStyles": null,
   "notes": null,
   "indent": 0,
@@ -214,100 +228,110 @@ stubPreparedMessages.set(`throw "tomato"
 }));
 
 stubPackets.set(`ReferenceError: asdf is not defined`, {
   "pageError": {
     "errorMessage": "ReferenceError: asdf is not defined",
     "errorMessageName": "JSMSG_NOT_DEFINED",
     "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default",
     "sourceName": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": null,
     "lineText": "",
     "lineNumber": 3,
     "columnNumber": 5,
     "category": "content javascript",
     "timeStamp": 1476573167137,
     "warning": false,
     "error": false,
     "exception": true,
     "strict": false,
     "info": false,
     "private": false,
     "stacktrace": [
       {
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+        "sourceId": "server1.conn0.child1/source25",
         "lineNumber": 3,
         "columnNumber": 5,
         "functionName": "bar"
       },
       {
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+        "sourceId": "server1.conn0.child1/source25",
         "lineNumber": 6,
         "columnNumber": 5,
         "functionName": "foo"
       },
       {
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+        "sourceId": "server1.conn0.child1/source25",
         "lineNumber": 9,
         "columnNumber": 3,
         "functionName": null
       },
       {
         "filename": "resource://testing-common/content-task.js line 59 > eval",
+        "sourceId": null,
         "lineNumber": 7,
         "columnNumber": 31,
         "functionName": null
       },
       {
         "filename": "resource://testing-common/content-task.js",
+        "sourceId": null,
         "lineNumber": 60,
         "columnNumber": 29,
         "functionName": null
       }
     ],
     "notes": null
   },
   "type": "pageError",
   "from": "server1.conn0.child1/consoleActor2"
 });
 
 stubPackets.set(`SyntaxError: redeclaration of let a`, {
   "pageError": {
     "errorMessage": "SyntaxError: redeclaration of let a",
     "errorMessageName": "JSMSG_REDECLARED_VAR",
     "sourceName": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": null,
     "lineText": "  let a, a;",
     "lineNumber": 2,
     "columnNumber": 9,
     "category": "content javascript",
     "timeStamp": 1487992945524,
     "warning": false,
     "error": false,
     "exception": true,
     "strict": false,
     "info": false,
     "private": false,
     "stacktrace": [
       {
         "filename": "resource://testing-common/content-task.js line 59 > eval",
+        "sourceId": null,
         "lineNumber": 7,
         "columnNumber": 31,
         "functionName": null
       },
       {
         "filename": "resource://testing-common/content-task.js",
+        "sourceId": null,
         "lineNumber": 60,
         "columnNumber": 29,
         "functionName": null
       }
     ],
     "notes": [
       {
         "messageBody": "Previously declared at line 2, column 6",
         "frame": {
           "source": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+          "sourceId": null,
           "line": 2,
           "column": 6
         }
       }
     ]
   },
   "type": "pageError",
   "from": "server1.conn0.child1/consoleActor2"
@@ -318,58 +342,63 @@ stubPackets.set(`TypeError longString me
     "errorMessage": {
       "type": "longString",
       "initial": "Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Lon",
       "length": 110007,
       "actor": "server1.conn0.child1/longString30"
     },
     "errorMessageName": "",
     "sourceName": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+    "sourceId": "server1.conn0.child1/source26",
     "lineText": "",
     "lineNumber": 1,
     "columnNumber": 7,
     "category": "content javascript",
     "timeStamp": 1493109507061,
     "warning": false,
     "error": false,
     "exception": true,
     "strict": false,
     "info": false,
     "private": false,
     "stacktrace": [
       {
         "filename": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html",
+        "sourceId": "server1.conn0.child1/source26",
         "lineNumber": 1,
         "columnNumber": 7,
         "functionName": null
       },
       {
         "filename": "resource://testing-common/content-task.js line 59 > eval",
+        "sourceId": null,
         "lineNumber": 7,
         "columnNumber": 31,
         "functionName": null
       },
       {
         "filename": "resource://testing-common/content-task.js",
+        "sourceId": null,
         "lineNumber": 60,
         "columnNumber": 29,
         "functionName": null
       }
     ],
     "notes": null
   },
   "type": "pageError",
   "from": "server1.conn0.child1/consoleActor2"
 });
 
 stubPackets.set(`throw ""`, {
   "pageError": {
     "errorMessage": "uncaught exception: ",
     "errorMessageName": "JSMSG_UNCAUGHT_EXCEPTION",
     "sourceName": "",
+    "sourceId": null,
     "lineText": "",
     "lineNumber": 0,
     "columnNumber": 0,
     "category": "content javascript",
     "timeStamp": 1517942398629,
     "warning": false,
     "error": false,
     "exception": false,
@@ -383,16 +412,17 @@ stubPackets.set(`throw ""`, {
   "from": "server1.conn0.child1/consoleActor2"
 });
 
 stubPackets.set(`throw "tomato"`, {
   "pageError": {
     "errorMessage": "uncaught exception: tomato",
     "errorMessageName": "JSMSG_UNCAUGHT_EXCEPTION",
     "sourceName": "",
+    "sourceId": null,
     "lineText": "",
     "lineNumber": 0,
     "columnNumber": 0,
     "category": "content javascript",
     "timeStamp": 1517942398637,
     "warning": false,
     "error": false,
     "exception": false,
--- a/devtools/client/webconsole/test/mochitest/browser.ini
+++ b/devtools/client/webconsole/test/mochitest/browser.ini
@@ -72,16 +72,17 @@ support-files =
   test-data.json
   test-data.json^headers^
   test-duplicate-error.html
   test-dynamic-import.html
   test-dynamic-import.js
   test-encoding-ISO-8859-1.html
   test-error.html
   test-eval-in-stackframe.html
+  test-eval-sources.html
   test-exception-stackframe.html
   test-external-script-errors.html
   test-external-script-errors.js
   test-file-location.js
   test-filter.html
   test-for-of.html
   test-iframe-insecure-form-action.html
   test-iframe1.html
@@ -315,16 +316,17 @@ subsuite = clipboard
 [browser_webconsole_document_focus.js]
 [browser_webconsole_duplicate_errors.js]
 [browser_webconsole_error_with_grouped_stack.js]
 [browser_webconsole_error_with_longstring_stack.js]
 [browser_webconsole_error_with_unicode.js]
 [browser_webconsole_errors_after_page_reload.js]
 [browser_webconsole_eval_in_debugger_stackframe.js]
 [browser_webconsole_eval_in_debugger_stackframe2.js]
+[browser_webconsole_eval_sources.js]
 [browser_webconsole_execution_scope.js]
 [browser_webconsole_external_script_errors.js]
 [browser_webconsole_file_uri.js]
 skip-if = true #	Bug 1404382
 [browser_webconsole_filter_by_input.js]
 [browser_webconsole_filter_scroll.js]
 [browser_webconsole_filters.js]
 [browser_webconsole_filters_persist.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_eval_sources.js
@@ -0,0 +1,49 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
+                 "test/mochitest/test-eval-sources.html";
+
+async function clickFirstStackElement(hud, message) {
+  const button = message.querySelector(".collapse-button");
+  ok(button, "has button");
+
+  button.click();
+
+  let frame;
+  await waitUntil(() => {
+    frame = message.querySelector(".frame");
+    return !!frame;
+  });
+
+  EventUtils.sendMouseEvent({ type: "mousedown" }, frame);
+
+  await once(hud.ui, "source-in-debugger-opened");
+}
+
+// Test that stack/message links in console API and error messages originating
+// from eval code go to a source in the debugger. This should work even when the
+// console is opened first.
+add_task(async function() {
+  const hud = await openNewTabAndConsole(TEST_URI);
+  const target = await TargetFactory.forTab(gBrowser.selectedTab);
+  const toolbox = gDevTools.getToolbox(target);
+
+  const messageNode = await waitFor(() => findMessage(hud, "BAR"));
+  await clickFirstStackElement(hud, messageNode);
+
+  const dbg = toolbox.getPanel("jsdebugger");
+
+  is(
+    dbg._selectors.getSelectedSource(dbg._getState()).url,
+    null,
+    "expected source url"
+  );
+
+  await testOpenInDebugger(hud, toolbox, "FOO", false);
+  await testOpenInDebugger(hud, toolbox, "BAR", false);
+});
--- a/devtools/client/webconsole/test/mochitest/head.js
+++ b/devtools/client/webconsole/test/mochitest/head.js
@@ -334,29 +334,32 @@ function waitForNodeMutation(node, obser
  *
  * @param {Object} hud
  *        The webconsole
  * @param {Object} toolbox
  *        The toolbox
  * @param {String} text
  *        The text to search for.  This should be contained in the
  *        message.  The searching is done with @see findMessage.
+ * @param {boolean} expectUrl
+ *        Whether the URL in the opened source should match the link, or whether
+ *        it is expected to be null.
  */
-async function testOpenInDebugger(hud, toolbox, text) {
+async function testOpenInDebugger(hud, toolbox, text, expectUrl = true) {
   info(`Finding message for open-in-debugger test; text is "${text}"`);
   const messageNode = await waitFor(() => findMessage(hud, text));
   const frameLinkNode = messageNode.querySelector(".message-location .frame-link");
   ok(frameLinkNode, "The message does have a location link");
-  await checkClickOnNode(hud, toolbox, frameLinkNode);
+  await checkClickOnNode(hud, toolbox, frameLinkNode, expectUrl);
 }
 
 /**
  * Helper function for testOpenInDebugger.
  */
-async function checkClickOnNode(hud, toolbox, frameLinkNode) {
+async function checkClickOnNode(hud, toolbox, frameLinkNode, expectUrl) {
   info("checking click on node location");
 
   const url = frameLinkNode.getAttribute("data-url");
   ok(url, `source url found ("${url}")`);
 
   const line = frameLinkNode.getAttribute("data-line");
   ok(line, `source line found ("${line}")`);
 
@@ -371,17 +374,17 @@ async function checkClickOnNode(hud, too
 
   // Wait for the source to finish loading, if it is pending.
   await waitFor(() => {
     return !!dbg._selectors.getSelectedSource(dbg._getState());
   });
 
   is(
     dbg._selectors.getSelectedSource(dbg._getState()).url,
-    url,
+    expectUrl ? url : null,
     "expected source url"
   );
 }
 
 /**
  * Returns true if the give node is currently focused.
  */
 function hasFocus(node) {
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/test/mochitest/test-eval-sources.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset=UTF-8>
+<script>
+/* eslint-disable */
+eval("window.foo = function() { console.log('FOO'); }");
+eval("window.bar = function() { throw new Error('BAR') };");
+foo();
+bar();
+</script>
--- a/devtools/client/webconsole/utils/messages.js
+++ b/devtools/client/webconsole/utils/messages.js
@@ -168,16 +168,17 @@ function transformConsoleAPICallPacket(p
     case "dirxml":
       // Handle console.dirxml calls as simple console.log
       type = "log";
       break;
   }
 
   const frame = message.filename ? {
     source: message.filename,
+    sourceId: message.sourceId,
     line: message.lineNumber,
     column: message.columnNumber,
   } : null;
 
   return new ConsoleMessage({
     source: MESSAGE_SOURCE.CONSOLE_API,
     type,
     level,
@@ -225,16 +226,17 @@ function transformPageErrorPacket(packet
   if (pageError.warning || pageError.strict) {
     level = MESSAGE_LEVEL.WARN;
   } else if (pageError.info) {
     level = MESSAGE_LEVEL.INFO;
   }
 
   const frame = pageError.sourceName ? {
     source: pageError.sourceName,
+    sourceId: pageError.sourceId,
     line: pageError.lineNumber,
     column: pageError.columnNumber,
   } : null;
 
   const matchesCSS = /^(?:CSS|Layout)\b/.test(pageError.category);
   const messageSource = matchesCSS ? MESSAGE_SOURCE.CSS
                                   : MESSAGE_SOURCE.JAVASCRIPT;
   return new ConsoleMessage({
--- a/devtools/client/webconsole/webconsole-wrapper.js
+++ b/devtools/client/webconsole/webconsole-wrapper.js
@@ -235,19 +235,22 @@ class WebConsoleWrapper {
 
       if (this.toolbox) {
         this.toolbox.threadClient.addListener("paused", this.dispatchPaused.bind(this));
         this.toolbox.threadClient.addListener(
           "progress", this.dispatchProgress.bind(this));
 
         Object.assign(serviceContainer, {
           onViewSourceInDebugger: frame => {
-            this.toolbox.viewSourceInDebugger(frame.url, frame.line).then(() => {
-              this.telemetry.recordEvent("jump_to_source", "webconsole",
-                                         null, { "session_id": this.toolbox.sessionId }
+            this.toolbox.viewSourceInDebugger(
+              frame.url, frame.line, frame.sourceId
+            ).then(() => {
+              this.telemetry.recordEvent(
+                "jump_to_source", "webconsole",
+                null, { "session_id": this.toolbox.sessionId }
               );
               this.webConsoleUI.emit("source-in-debugger-opened");
             });
           },
           onViewSourceInScratchpad: frame => this.toolbox.viewSourceInScratchpad(
             frame.url,
             frame.line
           ).then(() => {
--- a/devtools/server/actors/utils/TabSources.js
+++ b/devtools/server/actors/utils/TabSources.js
@@ -25,16 +25,25 @@ function TabSources(threadActor, allowSo
     return !isHiddenSource(source) && allowSourceFn(source);
   };
 
   this.blackBoxedSources = new Map();
   this.neverAutoBlackBoxSources = new Set();
 
   // Debugger.Source -> SourceActor
   this._sourceActors = new Map();
+
+  // Debugger.Source.id -> Debugger.Source
+  //
+  // The IDs associated with ScriptSources and available via DebuggerSource.id
+  // are internal to this process and should not be exposed to the client. This
+  // map associates these IDs with the corresponding source, provided the source
+  // has not been GC'ed and the actor has been created. This is lazily populated
+  // the first time it is needed.
+  this._sourcesByInternalSourceId = null;
 }
 
 /**
  * Matches strings of the form "foo.min.js" or "foo-min.js", etc. If the regular
  * expression matches, we can be fairly sure that the source is minified, and
  * treat it as such.
  */
 const MINIFIED_SOURCE_REGEXP = /\bmin\.js$/;
@@ -56,16 +65,17 @@ TabSources.prototype = {
     }
   },
 
   /**
    * Clear existing sources so they are recreated on the next access.
    */
   reset: function() {
     this._sourceActors = new Map();
+    this._sourcesByInternalSourceId = null;
   },
 
   /**
    * Return the source actor representing the `source` (or
    * `originalUrl`), creating one if none exists already. May return
    * null if the source is disallowed.
    *
    * @param Debugger.Source source
@@ -101,16 +111,19 @@ TabSources.prototype = {
     if (this._autoBlackBox &&
         !this.neverAutoBlackBoxSources.has(actor.url) &&
         this._isMinifiedURL(actor.url)) {
       this.blackBox(actor.url);
       this.neverAutoBlackBoxSources.add(actor.url);
     }
 
     this._sourceActors.set(source, actor);
+    if (this._sourcesByInternalSourceId && source.id) {
+      this._sourcesByInternalSourceId.set(source.id, source);
+    }
 
     this.emit("newSource", actor);
     return actor;
   },
 
   _getSourceActor: function(source) {
     if (this._sourceActors.has(source)) {
       return this._sourceActors.get(source);
@@ -129,16 +142,35 @@ TabSources.prototype = {
     if (!sourceActor) {
       throw new Error("getSource: could not find source actor for " +
                       (source.url || "source"));
     }
 
     return sourceActor;
   },
 
+  getSourceActorByInternalSourceId: function(id) {
+    if (!this._sourcesByInternalSourceId) {
+      this._sourcesByInternalSourceId = new Map();
+      for (const source of this._thread.dbg.findSources()) {
+        if (source.id) {
+          this._sourcesByInternalSourceId.set(source.id, source);
+        }
+      }
+    }
+    const source = this._sourcesByInternalSourceId.get(id);
+    if (source) {
+      if (this.hasSourceActor(source)) {
+        return this.getSourceActor(source);
+      }
+      return this.createSourceActor(source);
+    }
+    return null;
+  },
+
   getSourceActorsByURL: function(url) {
     const rv = [];
     if (url) {
       for (const [source, actor] of this._sourceActors) {
         if (source.url === url) {
           rv.push(actor);
         }
       }
--- a/devtools/server/actors/webconsole.js
+++ b/devtools/server/actors/webconsole.js
@@ -1443,16 +1443,21 @@ WebConsoleActor.prototype =
         type: "logMessage",
         message: this._createStringGrip(message.message),
         timeStamp: message.timeStamp,
       };
     }
     this.conn.send(packet);
   },
 
+  getActorIdForInternalSourceId(id) {
+    const actor = this.parentActor.sources.getSourceActorByInternalSourceId(id);
+    return actor ? actor.actorID : null;
+  },
+
   /**
    * Prepare an nsIScriptError to be sent to the client.
    *
    * @param nsIScriptError pageError
    *        The page error we need to send to the client.
    * @return object
    *         The object you can send to the remote client.
    */
@@ -1462,16 +1467,17 @@ WebConsoleActor.prototype =
     // Bug 1348885: If the global from which this error came from has been
     // nuked, stack is going to be a dead wrapper.
     if (pageError.stack && !Cu.isDeadWrapper(pageError.stack)) {
       stack = [];
       let s = pageError.stack;
       while (s !== null) {
         stack.push({
           filename: s.source,
+          sourceId: this.getActorIdForInternalSourceId(s.sourceId),
           lineNumber: s.line,
           columnNumber: s.column,
           functionName: s.functionDisplayName,
         });
         s = s.parent;
       }
     }
     let lineText = pageError.sourceLine;
@@ -1484,28 +1490,30 @@ WebConsoleActor.prototype =
     if (notes && notes.length) {
       notesArray = [];
       for (let i = 0, len = notes.length; i < len; i++) {
         const note = notes.queryElementAt(i, Ci.nsIScriptErrorNote);
         notesArray.push({
           messageBody: this._createStringGrip(note.errorMessage),
           frame: {
             source: note.sourceName,
+            sourceId: this.getActorIdForInternalSourceId(note.sourceId),
             line: note.lineNumber,
             column: note.columnNumber,
           },
         });
       }
     }
 
     return {
       errorMessage: this._createStringGrip(pageError.errorMessage),
       errorMessageName: pageError.errorMessageName,
       exceptionDocURL: ErrorDocs.GetURL(pageError),
       sourceName: pageError.sourceName,
+      sourceId: this.getActorIdForInternalSourceId(pageError.sourceId),
       lineText: lineText,
       lineNumber: pageError.lineNumber,
       columnNumber: pageError.columnNumber,
       category: pageError.category,
       timeStamp: pageError.timeStamp,
       warning: !!(pageError.flags & pageError.warningFlag),
       error: !!(pageError.flags & pageError.errorFlag),
       exception: !!(pageError.flags & pageError.exceptionFlag),
@@ -1675,16 +1683,18 @@ WebConsoleActor.prototype =
    * @return object
    *         The object that can be sent to the remote client.
    */
   prepareConsoleMessageForRemote: function(message, useObjectGlobal = true) {
     const result = WebConsoleUtils.cloneObject(message);
 
     result.workerType = WebConsoleUtils.getWorkerType(result) || "none";
 
+    result.sourceId = this.getActorIdForInternalSourceId(result.sourceId);
+
     delete result.wrappedJSObject;
     delete result.ID;
     delete result.innerID;
     delete result.consoleID;
 
     result.arguments = Array.map(message.arguments || [], (obj) => {
       const dbgObj = this.makeDebuggeeValue(obj, useObjectGlobal);
       return this.createValueGrip(dbgObj);
--- a/devtools/shared/heapsnapshot/DeserializedNode.h
+++ b/devtools/shared/heapsnapshot/DeserializedNode.h
@@ -282,16 +282,20 @@ class ConcreteStackFrame<DeserializedSta
   uint32_t line() const override { return get().line; }
   uint32_t column() const override { return get().column; }
   bool isSystem() const override { return get().isSystem; }
   bool isSelfHosted(JSContext* cx) const override { return get().isSelfHosted; }
   void trace(JSTracer* trc) override {}
   AtomOrTwoByteChars source() const override {
     return AtomOrTwoByteChars(get().source);
   }
+  uint32_t sourceId() const override {
+    // Source IDs are local to their host process and are not serialized.
+    return 0;
+  }
   AtomOrTwoByteChars functionDisplayName() const override {
     return AtomOrTwoByteChars(get().functionDisplayName);
   }
 
   StackFrame parent() const override;
   bool constructSavedFrameStack(
       JSContext* cx, MutableHandleObject outSavedFrameStack) const override;
 };
--- a/dom/base/DOMException.cpp
+++ b/dom/base/DOMException.cpp
@@ -285,16 +285,24 @@ JSObject* Exception::WrapObject(JSContex
 }
 
 void Exception::GetMessageMoz(nsString& retval) {
   CopyUTF8toUTF16(mMessage, retval);
 }
 
 uint32_t Exception::Result() const { return (uint32_t)mResult; }
 
+uint32_t Exception::SourceId(JSContext* aCx) const {
+  if (mLocation) {
+    return mLocation->GetSourceId(aCx);
+  }
+
+  return 0;
+}
+
 uint32_t Exception::LineNumber(JSContext* aCx) const {
   if (mLocation) {
     return mLocation->GetLineNumber(aCx);
   }
 
   return 0;
 }
 
--- a/dom/base/DOMException.h
+++ b/dom/base/DOMException.h
@@ -81,16 +81,18 @@ class Exception : public nsIException, p
     // method to ensure the right error message creation.
     nsAutoString name;
     GetName(name);
     CreateErrorMessage(name, aRetVal);
   }
 
   void GetFilename(JSContext* aCx, nsAString& aFilename);
 
+  uint32_t SourceId(JSContext* aCx) const;
+
   uint32_t LineNumber(JSContext* aCx) const;
 
   uint32_t ColumnNumber() const;
 
   already_AddRefed<nsIStackFrame> GetLocation() const;
 
   nsISupports* GetData() const;
 
--- a/dom/bindings/Exceptions.cpp
+++ b/dom/bindings/Exceptions.cpp
@@ -221,35 +221,39 @@ class JSStackFrame final : public nsISta
   JS::Heap<JSObject*> mStack;
   nsString mFormattedStack;
 
   nsCOMPtr<nsIStackFrame> mCaller;
   nsCOMPtr<nsIStackFrame> mAsyncCaller;
   nsString mFilename;
   nsString mFunname;
   nsString mAsyncCause;
+  int32_t mSourceId;
   int32_t mLineno;
   int32_t mColNo;
 
   bool mFilenameInitialized;
   bool mFunnameInitialized;
+  bool mSourceIdInitialized;
   bool mLinenoInitialized;
   bool mColNoInitialized;
   bool mAsyncCauseInitialized;
   bool mAsyncCallerInitialized;
   bool mCallerInitialized;
   bool mFormattedStackInitialized;
 };
 
 JSStackFrame::JSStackFrame(JS::Handle<JSObject*> aStack)
     : mStack(aStack),
+      mSourceId(0),
       mLineno(0),
       mColNo(0),
       mFilenameInitialized(false),
       mFunnameInitialized(false),
+      mSourceIdInitialized(false),
       mLinenoInitialized(false),
       mColNoInitialized(false),
       mAsyncCauseInitialized(false),
       mAsyncCallerInitialized(false),
       mCallerInitialized(false),
       mFormattedStackInitialized(false) {
   MOZ_ASSERT(mStack);
   MOZ_ASSERT(JS::IsUnwrappedSavedFrame(mStack));
@@ -446,16 +450,44 @@ void JSStackFrame::GetName(JSContext* aC
   }
 
   if (canCache) {
     mFunname = aFunction;
     mFunnameInitialized = true;
   }
 }
 
+int32_t JSStackFrame::GetSourceId(JSContext* aCx) {
+  if (!mStack) {
+    return 0;
+  }
+
+  uint32_t id;
+  bool canCache = false, useCachedValue = false;
+  GetValueIfNotCached(aCx, mStack, JS::GetSavedFrameSourceId, mSourceIdInitialized,
+                      &canCache, &useCachedValue, &id);
+
+  if (useCachedValue) {
+    return mSourceId;
+  }
+
+  if (canCache) {
+    mSourceId = id;
+    mSourceIdInitialized = true;
+  }
+
+  return id;
+}
+
+NS_IMETHODIMP
+JSStackFrame::GetSourceIdXPCOM(JSContext* aCx, int32_t* aSourceId) {
+  *aSourceId = GetSourceId(aCx);
+  return NS_OK;
+}
+
 int32_t JSStackFrame::GetLineNumber(JSContext* aCx) {
   if (!mStack) {
     return 0;
   }
 
   uint32_t line;
   bool canCache = false, useCachedValue = false;
   GetValueIfNotCached(aCx, mStack, JS::GetSavedFrameLine, mLinenoInitialized,
--- a/dom/bindings/nsIScriptError.idl
+++ b/dom/bindings/nsIScriptError.idl
@@ -17,16 +17,23 @@ interface nsIURI;
 #include "nsString.h" // for nsDependentCString
 %}
 
 [scriptable, uuid(e8933fc9-c302-4e12-a55b-4f88611d9c6c)]
 interface nsIScriptErrorNote : nsISupports
 {
     readonly attribute AString errorMessage;
     readonly attribute AString sourceName;
+
+    /**
+     * Unique identifier within the process for the script source this note is
+     * associated with, or zero.
+     */
+    readonly attribute uint32_t sourceId;
+
     readonly attribute uint32_t lineNumber;
     readonly attribute uint32_t columnNumber;
 
     AUTF8String toString();
 };
 
 [scriptable, uuid(63eb4d3e-7d99-4150-b4f3-11314f9d82a9)]
 interface nsIScriptError : nsIConsoleMessage
@@ -52,16 +59,23 @@ interface nsIScriptError : nsIConsoleMes
      *
      * @note nsIConsoleMessage.message will return the error formatted
      *       with file/line information.
      */
     readonly attribute AString errorMessage;
 
     readonly attribute AString sourceName;
     readonly attribute AString sourceLine;
+
+    /**
+     * Unique identifier within the process for the script source this error is
+     * associated with, or zero.
+     */
+    readonly attribute uint32_t sourceId;
+
     readonly attribute uint32_t lineNumber;
     readonly attribute uint32_t columnNumber;
     readonly attribute uint32_t flags;
 
     /**
      * Categories I know about -
      * XUL javascript
      * content javascript (both of these from nsDocShell, currently)
@@ -153,16 +167,19 @@ interface nsIScriptError : nsIConsoleMes
                            in nsIURI sourceURI,
                            in AString sourceLine,
                            in uint32_t lineNumber,
                            in uint32_t columnNumber,
                            in uint32_t flags,
                            in ACString category,
                            in unsigned long long innerWindowID);
 
+    /* Initialize the script source ID in a new error. */
+    void initSourceId(in uint32_t sourceId);
+
 %{C++
     // These overloads allow passing a literal string for category.
     template<uint32_t N>
     nsresult InitWithWindowID(const nsAString& message,
                               const nsAString& sourceName,
                               const nsAString& sourceLine,
                               uint32_t lineNumber,
                               uint32_t columnNumber,
--- a/dom/bindings/nsScriptError.cpp
+++ b/dom/bindings/nsScriptError.cpp
@@ -28,16 +28,17 @@ static_assert(nsIScriptError::errorFlag 
                   nsIScriptError::strictFlag == JSREPORT_STRICT &&
                   nsIScriptError::infoFlag == JSREPORT_USER_1,
               "flags should be consistent");
 
 nsScriptErrorBase::nsScriptErrorBase()
     : mMessage(),
       mMessageName(),
       mSourceName(),
+      mSourceId(0),
       mLineNumber(0),
       mSourceLine(),
       mColumnNumber(0),
       mFlags(0),
       mCategory(),
       mOuterWindowID(0),
       mInnerWindowID(0),
       mTimeStamp(0),
@@ -64,16 +65,22 @@ void nsScriptErrorBase::InitializeOnMain
 
       mIsFromPrivateWindow = ComputeIsFromPrivateWindow(window);
     }
   }
 
   mInitializedOnMainThread = true;
 }
 
+NS_IMETHODIMP
+nsScriptErrorBase::InitSourceId(uint32_t value) {
+  mSourceId = value;
+  return NS_OK;
+}
+
 // nsIConsoleMessage methods
 NS_IMETHODIMP
 nsScriptErrorBase::GetMessageMoz(nsAString& aMessage) {
   nsAutoCString message;
   nsresult rv = ToString(message);
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -103,16 +110,22 @@ nsScriptErrorBase::GetErrorMessage(nsASt
 
 NS_IMETHODIMP
 nsScriptErrorBase::GetSourceName(nsAString& aResult) {
   aResult.Assign(mSourceName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsScriptErrorBase::GetSourceId(uint32_t* result) {
+  *result = mSourceId;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsScriptErrorBase::GetSourceLine(nsAString& aResult) {
   aResult.Assign(mSourceLine);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScriptErrorBase::GetLineNumber(uint32_t* result) {
   *result = mLineNumber;
@@ -387,25 +400,28 @@ nsScriptErrorBase::GetNotes(nsIArray** a
   nsIPrincipal* winPrincipal = aWindow->GetPrincipal();
   return aWindow->IsPrivateBrowsing() &&
          !nsContentUtils::IsSystemPrincipal(winPrincipal);
 }
 
 NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError)
 
 nsScriptErrorNote::nsScriptErrorNote()
-    : mMessage(), mSourceName(), mLineNumber(0), mColumnNumber(0) {}
+: mMessage(), mSourceName(), mSourceId(0), mLineNumber(0), mColumnNumber(0) {}
 
 nsScriptErrorNote::~nsScriptErrorNote() {}
 
 void nsScriptErrorNote::Init(const nsAString& message,
-                             const nsAString& sourceName, uint32_t lineNumber,
+                             const nsAString& sourceName,
+                             uint32_t sourceId,
+                             uint32_t lineNumber,
                              uint32_t columnNumber) {
   mMessage.Assign(message);
   AssignSourceNameHelper(mSourceName, sourceName);
+  mSourceId = sourceId;
   mLineNumber = lineNumber;
   mColumnNumber = columnNumber;
 }
 
 // nsIScriptErrorNote methods
 NS_IMETHODIMP
 nsScriptErrorNote::GetErrorMessage(nsAString& aResult) {
   aResult.Assign(mMessage);
@@ -414,16 +430,22 @@ nsScriptErrorNote::GetErrorMessage(nsASt
 
 NS_IMETHODIMP
 nsScriptErrorNote::GetSourceName(nsAString& aResult) {
   aResult.Assign(mSourceName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsScriptErrorNote::GetSourceId(uint32_t* result) {
+  *result = mSourceId;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsScriptErrorNote::GetLineNumber(uint32_t* result) {
   *result = mLineNumber;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScriptErrorNote::GetColumnNumber(uint32_t* result) {
   *result = mColumnNumber;
--- a/dom/bindings/nsScriptError.h
+++ b/dom/bindings/nsScriptError.h
@@ -24,24 +24,25 @@ class nsGlobalWindowInner;
 class nsScriptErrorNote final : public nsIScriptErrorNote {
  public:
   nsScriptErrorNote();
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSISCRIPTERRORNOTE
 
   void Init(const nsAString& message, const nsAString& sourceName,
-            uint32_t lineNumber, uint32_t columnNumber);
+            uint32_t sourceId, uint32_t lineNumber, uint32_t columnNumber);
 
  private:
   virtual ~nsScriptErrorNote();
 
   nsString mMessage;
   nsString mSourceName;
   nsString mSourceLine;
+  uint32_t mSourceId;
   uint32_t mLineNumber;
   uint32_t mColumnNumber;
 };
 
 // Definition of nsScriptError..
 class nsScriptErrorBase : public nsIScriptError {
  public:
   nsScriptErrorBase();
@@ -63,16 +64,17 @@ class nsScriptErrorBase : public nsIScri
                             uint32_t columnNumber, uint32_t flags,
                             const nsACString& category,
                             uint64_t aInnerWindowID);
 
   nsCOMArray<nsIScriptErrorNote> mNotes;
   nsString mMessage;
   nsString mMessageName;
   nsString mSourceName;
+  uint32_t mSourceId;
   uint32_t mLineNumber;
   nsString mSourceLine;
   uint32_t mColumnNumber;
   uint32_t mFlags;
   nsCString mCategory;
   // mOuterWindowID is set on the main thread from InitializeOnMainThread().
   uint64_t mOuterWindowID;
   uint64_t mInnerWindowID;
--- a/dom/console/Console.cpp
+++ b/dom/console/Console.cpp
@@ -1318,18 +1318,18 @@ void Console::ProfileMethodInternal(JSCo
 namespace {
 
 void StackFrameToStackEntry(JSContext* aCx, nsIStackFrame* aStackFrame,
                             ConsoleStackEntry& aStackEntry) {
   MOZ_ASSERT(aStackFrame);
 
   aStackFrame->GetFilename(aCx, aStackEntry.mFilename);
 
+  aStackEntry.mSourceId = aStackFrame->GetSourceId(aCx);
   aStackEntry.mLineNumber = aStackFrame->GetLineNumber(aCx);
-
   aStackEntry.mColumnNumber = aStackFrame->GetColumnNumber(aCx);
 
   aStackFrame->GetName(aCx, aStackEntry.mFunctionName);
 
   nsString cause;
   aStackFrame->GetAsyncCause(aCx, cause);
   if (!cause.IsEmpty()) {
     aStackEntry.mAsyncCause.Construct(cause);
@@ -1691,16 +1691,17 @@ bool Console::PopulateConsoleNotificatio
     nsCOMPtr<nsISensitiveInfoHiddenURI> safeURI =
         do_QueryInterface(filenameURI);
     nsAutoCString spec;
     if (safeURI && NS_SUCCEEDED(safeURI->GetSensitiveInfoHiddenSpec(spec))) {
       CopyUTF8toUTF16(spec, event.mFilename);
     }
   }
 
+  event.mSourceId = frame.mSourceId;
   event.mLineNumber = frame.mLineNumber;
   event.mColumnNumber = frame.mColumnNumber;
   event.mFunctionName = frame.mFunctionName;
   event.mTimeStamp = aData->mTimeStamp;
   event.mPrivate = !!aData->mOriginAttributes.mPrivateBrowsingId;
 
   switch (aData->mMethodName) {
     case MethodLog:
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -2568,17 +2568,19 @@ nsresult ScriptLoader::EvaluateScript(Sc
   // we've executed a script, which may cause all other references to
   // the context to go away.
   nsCOMPtr<nsIScriptContext> context = globalObject->GetScriptContext();
   if (!context) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow();
+#ifdef MOZ_GECKO_PROFILER
   nsIDocShell* docShell = window ? window->GetDocShell() : nullptr;
+#endif
   nsAutoCString profilerLabelString;
   GetProfilerLabelForRequest(aRequest, profilerLabelString);
   AUTO_PROFILER_TEXT_MARKER_DOCSHELL("Script", profilerLabelString, JS,
                                      docShell);
 
   // New script entry point required, due to the "Create a script" sub-step of
   // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block
   nsAutoMicroTask mt;
--- a/dom/webidl/Console.webidl
+++ b/dom/webidl/Console.webidl
@@ -82,16 +82,19 @@ namespace console {
 // This is used to propagate console events to the observers.
 dictionary ConsoleEvent {
   (unsigned long long or DOMString) ID;
   (unsigned long long or DOMString) innerID;
   DOMString consoleID = "";
   DOMString addonId = "";
   DOMString level = "";
   DOMString filename = "";
+  // Unique identifier within the process for the script source this event is
+  // associated with, or zero.
+  unsigned long sourceId = 0;
   unsigned long lineNumber = 0;
   unsigned long columnNumber = 0;
   DOMString functionName = "";
   double timeStamp = 0;
   sequence<any> arguments;
   sequence<DOMString?> styles;
   boolean private = false;
   // stacktrace is handled via a getter in some cases so we can construct it
@@ -110,16 +113,19 @@ dictionary ConsoleEvent {
 dictionary ConsoleProfileEvent {
   DOMString action = "";
   sequence<any> arguments;
 };
 
 // This dictionary is used to manage stack trace data.
 dictionary ConsoleStackEntry {
   DOMString filename = "";
+  // Unique identifier within the process for the script source this entry is
+  // associated with, or zero.
+  unsigned long sourceId = 0;
   unsigned long lineNumber = 0;
   unsigned long columnNumber = 0;
   DOMString functionName = "";
   DOMString? asyncCause;
 };
 
 dictionary ConsoleTimerStart {
   DOMString name = "";
--- a/dom/workers/WorkerError.cpp
+++ b/dom/workers/WorkerError.cpp
@@ -497,17 +497,17 @@ void WorkerErrorReport::AssignErrorRepor
       NS_WARNING("Failed to init script error!");
       scriptError = nullptr;
     }
 
     for (size_t i = 0, len = aReport.notes().Length(); i < len; i++) {
       const ErrorDataNote& note = aReport.notes().ElementAt(i);
 
       nsScriptErrorNote* noteObject = new nsScriptErrorNote();
-      noteObject->Init(note.message(), note.filename(), note.lineNumber(),
+      noteObject->Init(note.message(), note.filename(), 0, note.lineNumber(),
                        note.columnNumber());
       scriptError->AddNote(noteObject);
     }
   }
 
   nsCOMPtr<nsIConsoleService> consoleService =
       do_GetService(NS_CONSOLESERVICE_CONTRACTID);
   NS_WARNING_ASSERTION(consoleService, "Failed to get console service!");
--- a/js/public/ErrorReport.h
+++ b/js/public/ErrorReport.h
@@ -88,31 +88,35 @@ class JSErrorBase {
   // The (default) error message.
   // If ownsMessage_ is true, the it is freed in destructor.
   JS::ConstUTF8CharsZ message_;
 
  public:
   // Source file name, URL, etc., or null.
   const char* filename;
 
+  // Unique identifier for the script source.
+  unsigned sourceId;
+
   // Source line number.
   unsigned lineno;
 
   // Zero-based column index in line.
   unsigned column;
 
   // the error number, e.g. see js.msg.
   unsigned errorNumber;
 
  private:
   bool ownsMessage_ : 1;
 
  public:
   JSErrorBase()
       : filename(nullptr),
+        sourceId(0),
         lineno(0),
         column(0),
         errorNumber(0),
         ownsMessage_(false) {}
 
   ~JSErrorBase() { freeMessage(); }
 
  public:
@@ -144,23 +148,26 @@ class JSErrorNotes {
   // Stores pointers to each note.
   js::Vector<js::UniquePtr<Note>, 1, js::SystemAllocPolicy> notes_;
 
  public:
   JSErrorNotes();
   ~JSErrorNotes();
 
   // Add an note to the given position.
-  bool addNoteASCII(JSContext* cx, const char* filename, unsigned lineno,
+  bool addNoteASCII(JSContext* cx, const char* filename,
+                    unsigned sourceId, unsigned lineno,
                     unsigned column, JSErrorCallback errorCallback,
                     void* userRef, const unsigned errorNumber, ...);
-  bool addNoteLatin1(JSContext* cx, const char* filename, unsigned lineno,
+  bool addNoteLatin1(JSContext* cx, const char* filename,
+                     unsigned sourceId, unsigned lineno,
                      unsigned column, JSErrorCallback errorCallback,
                      void* userRef, const unsigned errorNumber, ...);
-  bool addNoteUTF8(JSContext* cx, const char* filename, unsigned lineno,
+  bool addNoteUTF8(JSContext* cx, const char* filename,
+                   unsigned sourceId, unsigned lineno,
                    unsigned column, JSErrorCallback errorCallback,
                    void* userRef, const unsigned errorNumber, ...);
 
   JS_PUBLIC_API size_t length();
 
   // Create a deep copy of notes.
   js::UniquePtr<JSErrorNotes> copy(JSContext* cx);
 
--- a/js/public/SavedFrameAPI.h
+++ b/js/public/SavedFrameAPI.h
@@ -61,16 +61,25 @@ enum class SavedFrameSelfHosted { Includ
  * string.
  */
 extern JS_PUBLIC_API SavedFrameResult GetSavedFrameSource(
     JSContext* cx, JSPrincipals* principals, Handle<JSObject*> savedFrame,
     MutableHandle<JSString*> sourcep,
     SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
 
 /**
+ * Given a SavedFrame JSObject, get an ID identifying its ScriptSource.
+ * Defaults to 0.
+ */
+extern JS_PUBLIC_API SavedFrameResult GetSavedFrameSourceId(
+    JSContext* cx, JSPrincipals* principals, Handle<JSObject*> savedFrame,
+    uint32_t* sourceIdp,
+    SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
+
+/**
  * Given a SavedFrame JSObject, get its line property. Defaults to 0.
  */
 extern JS_PUBLIC_API SavedFrameResult GetSavedFrameLine(
     JSContext* cx, JSPrincipals* principals, Handle<JSObject*> savedFrame,
     uint32_t* linep,
     SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
 
 /**
--- a/js/public/UbiNode.h
+++ b/js/public/UbiNode.h
@@ -242,16 +242,19 @@ class BaseStackFrame {
   virtual uint32_t line() const = 0;
 
   // Get this frame's column number.
   virtual uint32_t column() const = 0;
 
   // Get this frame's source name. Never null.
   virtual AtomOrTwoByteChars source() const = 0;
 
+  // Get a unique per-process ID for this frame's source. Defaults to zero.
+  virtual uint32_t sourceId() const = 0;
+
   // Return this frame's function name if named, otherwise the inferred
   // display name. Can be null.
   virtual AtomOrTwoByteChars functionDisplayName() const = 0;
 
   // Returns true if this frame's function is system JavaScript running with
   // trusted principals, false otherwise.
   virtual bool isSystem() const = 0;
 
@@ -409,16 +412,17 @@ class StackFrame {
   uint64_t identifier() const {
     auto id = base()->identifier();
     MOZ_ASSERT(JS::Value::isNumberRepresentable(id));
     return id;
   }
   uint32_t line() const { return base()->line(); }
   uint32_t column() const { return base()->column(); }
   AtomOrTwoByteChars source() const { return base()->source(); }
+  uint32_t sourceId() const { return base()->sourceId(); }
   AtomOrTwoByteChars functionDisplayName() const {
     return base()->functionDisplayName();
   }
   StackFrame parent() const { return base()->parent(); }
   bool isSystem() const { return base()->isSystem(); }
   bool isSelfHosted(JSContext* cx) const { return base()->isSelfHosted(cx); }
   MOZ_MUST_USE bool constructSavedFrameStack(
       JSContext* cx, MutableHandleObject outSavedFrameStack) const {
@@ -459,16 +463,17 @@ class ConcreteStackFrame<void> : public 
     return true;
   }
 
   uint32_t line() const override { MOZ_CRASH("null JS::ubi::StackFrame"); }
   uint32_t column() const override { MOZ_CRASH("null JS::ubi::StackFrame"); }
   AtomOrTwoByteChars source() const override {
     MOZ_CRASH("null JS::ubi::StackFrame");
   }
+  uint32_t sourceId() const override { MOZ_CRASH("null JS::ubi::StackFrame"); }
   AtomOrTwoByteChars functionDisplayName() const override {
     MOZ_CRASH("null JS::ubi::StackFrame");
   }
   StackFrame parent() const override { MOZ_CRASH("null JS::ubi::StackFrame"); }
   bool isSystem() const override { MOZ_CRASH("null JS::ubi::StackFrame"); }
   bool isSelfHosted(JSContext* cx) const override {
     MOZ_CRASH("null JS::ubi::StackFrame");
   }
--- a/js/src/doc/Debugger/Debugger.Source.md
+++ b/js/src/doc/Debugger/Debugger.Source.md
@@ -100,16 +100,21 @@ from its prototype:
     (Note that code passed to `eval`, the `Function` constructor, or a
     similar function is <i>not</i> considered to be loaded from a URL; the
     `url` accessor on `Debugger.Source` instances for such sources should
     return `undefined`.)
 
     **If the instance refers to WebAssembly code**, the URL of the script that
     called `new WebAssembly.Module` with the string `"> wasm"` appended.
 
+`id`
+:   **If the instance refers to JavaScript source**, an int32 counter that identifies
+    the source within the current process.  This ID is used in other places in Gecko
+    that weakly refer to sources, such as nsIScriptError.
+
 `sourceMapURL`
 :   **If the instance refers to JavaScript source**, if this source was
     produced by a minimizer or translated from some other language, and we
     know the URL of a <b>source map</b> document relating the source positions
     in this source to the corresponding source positions in the original
     source, then this property's value is that URL. Otherwise, this is `null`.
 
     (On the web, the translator may provide the source map URL in a
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -459,17 +459,17 @@ void GeneralParser<ParseHandler, Unit>::
   tokenStream.computeLineAndColumn(openedPos, &line, &column);
 
   const size_t MaxWidth = sizeof("4294967295");
   char columnNumber[MaxWidth];
   SprintfLiteral(columnNumber, "%" PRIu32, column);
   char lineNumber[MaxWidth];
   SprintfLiteral(lineNumber, "%" PRIu32, line);
 
-  if (!notes->addNoteASCII(pc_->sc()->cx_, getFilename(), line, column,
+  if (!notes->addNoteASCII(pc_->sc()->cx_, getFilename(), 0, line, column,
                            GetErrorMessage, nullptr, noteNumber, lineNumber,
                            columnNumber)) {
     return;
   }
 
   errorWithNotes(std::move(notes), errorNumber);
 }
 
@@ -498,17 +498,17 @@ void GeneralParser<ParseHandler, Unit>::
   tokenStream.computeLineAndColumn(prevPos, &line, &column);
 
   const size_t MaxWidth = sizeof("4294967295");
   char columnNumber[MaxWidth];
   SprintfLiteral(columnNumber, "%" PRIu32, column);
   char lineNumber[MaxWidth];
   SprintfLiteral(lineNumber, "%" PRIu32, line);
 
-  if (!notes->addNoteASCII(pc_->sc()->cx_, getFilename(), line, column,
+  if (!notes->addNoteASCII(pc_->sc()->cx_, getFilename(), 0, line, column,
                            GetErrorMessage, nullptr, JSMSG_REDECLARED_PREV,
                            lineNumber, columnNumber)) {
     return;
   }
 
   errorWithNotesAt(std::move(notes), pos.begin, JSMSG_REDECLARED_VAR,
                    DeclarationKindString(prevKind), bytes.get());
 }
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -754,17 +754,18 @@ MOZ_COLD void TokenStreamChars<Utf8Unit,
       relevantUnits--;
     }
 
     ptr[-1] = '\0';
 
     uint32_t line, column;
     computeLineAndColumn(offset, &line, &column);
 
-    if (!notes->addNoteASCII(anyChars.cx, anyChars.getFilename(), line, column,
+    if (!notes->addNoteASCII(anyChars.cx, anyChars.getFilename(),
+                             0, line, column,
                              GetErrorMessage, nullptr, JSMSG_BAD_CODE_UNITS,
                              badUnitsStr)) {
       break;
     }
 
     ReportCompileError(anyChars.cx, std::move(err), std::move(notes),
                        JSREPORT_ERROR, errorNumber, &args);
   } while (false);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5295,85 +5295,93 @@ void JSErrorBase::freeMessage() {
   message_ = JS::ConstUTF8CharsZ();
 }
 
 JSErrorNotes::JSErrorNotes() : notes_() {}
 
 JSErrorNotes::~JSErrorNotes() {}
 
 static UniquePtr<JSErrorNotes::Note> CreateErrorNoteVA(
-    JSContext* cx, const char* filename, unsigned lineno, unsigned column,
+    JSContext* cx, const char* filename, unsigned sourceId,
+    unsigned lineno, unsigned column,
     JSErrorCallback errorCallback, void* userRef, const unsigned errorNumber,
     ErrorArgumentsType argumentsType, va_list ap) {
   auto note = MakeUnique<JSErrorNotes::Note>();
   if (!note) {
     ReportOutOfMemory(cx);
     return nullptr;
   }
 
   note->errorNumber = errorNumber;
   note->filename = filename;
+  note->sourceId = sourceId;
   note->lineno = lineno;
   note->column = column;
 
   if (!ExpandErrorArgumentsVA(cx, errorCallback, userRef, errorNumber, nullptr,
                               argumentsType, note.get(), ap)) {
     return nullptr;
   }
 
   return note;
 }
 
 bool JSErrorNotes::addNoteASCII(JSContext* cx, const char* filename,
+                                unsigned sourceId,
                                 unsigned lineno, unsigned column,
                                 JSErrorCallback errorCallback, void* userRef,
                                 const unsigned errorNumber, ...) {
   va_list ap;
   va_start(ap, errorNumber);
-  auto note = CreateErrorNoteVA(cx, filename, lineno, column, errorCallback,
+  auto note = CreateErrorNoteVA(cx, filename, sourceId, lineno, column,
+                                errorCallback,
                                 userRef, errorNumber, ArgumentsAreASCII, ap);
   va_end(ap);
 
   if (!note) {
     return false;
   }
   if (!notes_.append(std::move(note))) {
     ReportOutOfMemory(cx);
     return false;
   }
   return true;
 }
 
 bool JSErrorNotes::addNoteLatin1(JSContext* cx, const char* filename,
+                                 unsigned sourceId,
                                  unsigned lineno, unsigned column,
                                  JSErrorCallback errorCallback, void* userRef,
                                  const unsigned errorNumber, ...) {
   va_list ap;
   va_start(ap, errorNumber);
-  auto note = CreateErrorNoteVA(cx, filename, lineno, column, errorCallback,
+  auto note = CreateErrorNoteVA(cx, filename, sourceId, lineno, column,
+                                errorCallback,
                                 userRef, errorNumber, ArgumentsAreLatin1, ap);
   va_end(ap);
 
   if (!note) {
     return false;
   }
   if (!notes_.append(std::move(note))) {
     ReportOutOfMemory(cx);
     return false;
   }
   return true;
 }
 
 bool JSErrorNotes::addNoteUTF8(JSContext* cx, const char* filename,
+                               unsigned sourceId,
                                unsigned lineno, unsigned column,
                                JSErrorCallback errorCallback, void* userRef,
                                const unsigned errorNumber, ...) {
   va_list ap;
   va_start(ap, errorNumber);
-  auto note = CreateErrorNoteVA(cx, filename, lineno, column, errorCallback,
+  auto note = CreateErrorNoteVA(cx, filename, sourceId, lineno, column,
+                                errorCallback,
                                 userRef, errorNumber, ArgumentsAreUTF8, ap);
   va_end(ap);
 
   if (!note) {
     return false;
   }
   if (!notes_.append(std::move(note))) {
     ReportOutOfMemory(cx);
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -275,16 +275,17 @@ static UniquePtr<T> CopyErrorHelper(JSCo
 
   if (!CopyExtraData(cx, &cursor, copy.get(), report)) {
     return nullptr;
   }
 
   MOZ_ASSERT(cursor == (uint8_t*)copy.get() + mallocSize);
 
   /* Copy non-pointer members. */
+  copy->sourceId = report->sourceId;
   copy->lineno = report->lineno;
   copy->column = report->column;
   copy->errorNumber = report->errorNumber;
 
   return copy;
 }
 
 UniquePtr<JSErrorNotes::Note> js::CopyErrorNote(JSContext* cx,
@@ -412,24 +413,28 @@ bool Error(JSContext* cx, unsigned argc,
       return false;
     }
   }
 
   // Find the scripted caller, but only ones we're allowed to know about.
   NonBuiltinFrameIter iter(cx, cx->realm()->principals());
 
   RootedString fileName(cx);
+  uint32_t sourceId = 0;
   if (args.length() > 1) {
     fileName = ToString<CanGC>(cx, args[1]);
   } else {
     fileName = cx->runtime()->emptyString;
     if (!iter.done()) {
       if (const char* cfilename = iter.filename()) {
         fileName = JS_NewStringCopyZ(cx, cfilename);
       }
+      if (iter.hasScript()) {
+        sourceId = iter.script()->scriptSource()->id();
+      }
     }
   }
   if (!fileName) {
     return false;
   }
 
   uint32_t lineNumber, columnNumber = 0;
   if (args.length() > 2) {
@@ -442,18 +447,19 @@ bool Error(JSContext* cx, unsigned argc,
   }
 
   RootedObject stack(cx);
   if (!CaptureStack(cx, &stack)) {
     return false;
   }
 
   RootedObject obj(cx,
-                   ErrorObject::create(cx, exnType, stack, fileName, lineNumber,
-                                       columnNumber, nullptr, message, proto));
+                   ErrorObject::create(cx, exnType, stack, fileName, sourceId,
+                                       lineNumber, columnNumber, nullptr,
+                                       message, proto));
   if (!obj) {
     return false;
   }
 
   args.rval().setObject(*obj);
   return true;
 }
 
@@ -644,31 +650,32 @@ void js::ErrorToException(JSContext* cx,
     return;
   }
 
   RootedString fileName(cx, JS_NewStringCopyZ(cx, reportp->filename));
   if (!fileName) {
     return;
   }
 
+  uint32_t sourceId = reportp->sourceId;
   uint32_t lineNumber = reportp->lineno;
   uint32_t columnNumber = reportp->column;
 
   RootedObject stack(cx);
   if (!CaptureStack(cx, &stack)) {
     return;
   }
 
   UniquePtr<JSErrorReport> report = CopyErrorReport(cx, reportp);
   if (!report) {
     return;
   }
 
   ErrorObject* errObject =
-      ErrorObject::create(cx, exnType, stack, fileName, lineNumber,
+    ErrorObject::create(cx, exnType, stack, fileName, sourceId, lineNumber,
                           columnNumber, std::move(report), messageStr);
   if (!errObject) {
     return;
   }
 
   // Throw it.
   RootedValue errValue(cx, ObjectValue(*errObject));
   cx->setPendingException(errValue);
@@ -874,16 +881,17 @@ bool ErrorReport::init(JSContext* cx, Ha
     }
 
     reportp = &ownedReport;
     new (reportp) JSErrorReport();
     ownedReport.filename = filename.get();
     ownedReport.lineno = lineno;
     ownedReport.exnType = JSEXN_INTERNALERR;
     ownedReport.column = column;
+
     if (str) {
       // Note that using |str| for |message_| here is kind of wrong,
       // because |str| is supposed to be of the format
       // |ErrorName: ErrorMessage|, and |message_| is supposed to
       // correspond to |ErrorMessage|. But this is what we've
       // historically done for duck-typed error objects.
       //
       // If only this stuff could get specced one day...
@@ -945,16 +953,18 @@ bool ErrorReport::populateUncaughtExcept
   ownedReport.errorNumber = JSMSG_UNCAUGHT_EXCEPTION;
   // XXXbz this assumes the stack we have right now is still
   // related to our exception object.  It would be better if we
   // could accept a passed-in stack of some sort instead.
   NonBuiltinFrameIter iter(cx, cx->realm()->principals());
   if (!iter.done()) {
     ownedReport.filename = iter.filename();
     uint32_t column;
+    ownedReport.sourceId =
+      iter.script() ? iter.script()->scriptSource()->id() : 0;
     ownedReport.lineno = iter.computeLine(&column);
     ownedReport.column = FixupColumnForDisplay(column);
     ownedReport.isMuted = iter.mutedErrors();
   }
 
   if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr,
                               JSMSG_UNCAUGHT_EXCEPTION, nullptr,
                               ArgumentsAreUTF8, &ownedReport, ap)) {
@@ -982,23 +992,25 @@ JSObject* js::CopyErrorObject(JSContext*
   RootedString fileName(cx, err->fileName(cx));
   if (!cx->compartment()->wrap(cx, &fileName)) {
     return nullptr;
   }
   RootedObject stack(cx, err->stack());
   if (!cx->compartment()->wrap(cx, &stack)) {
     return nullptr;
   }
+  uint32_t sourceId = err->sourceId();
   uint32_t lineNumber = err->lineNumber();
   uint32_t columnNumber = err->columnNumber();
   JSExnType errorType = err->type();
 
   // Create the Error object.
-  return ErrorObject::create(cx, errorType, stack, fileName, lineNumber,
-                             columnNumber, std::move(copyReport), message);
+  return ErrorObject::create(cx, errorType, stack, fileName, sourceId,
+                             lineNumber, columnNumber,
+                             std::move(copyReport), message);
 }
 
 JS_PUBLIC_API bool JS::CreateError(JSContext* cx, JSExnType type,
                                    HandleObject stack, HandleString fileName,
                                    uint32_t lineNumber, uint32_t columnNumber,
                                    JSErrorReport* report, HandleString message,
                                    MutableHandleValue rval) {
   cx->check(stack, fileName, message);
@@ -1008,17 +1020,17 @@ JS_PUBLIC_API bool JS::CreateError(JSCon
   if (report) {
     rep = CopyErrorReport(cx, report);
     if (!rep) {
       return false;
     }
   }
 
   JSObject* obj =
-      js::ErrorObject::create(cx, type, stack, fileName, lineNumber,
+      js::ErrorObject::create(cx, type, stack, fileName, 0, lineNumber,
                               columnNumber, std::move(rep), message);
   if (!obj) {
     return false;
   }
 
   rval.setObject(*obj);
   return true;
 }
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -8320,16 +8320,38 @@ static bool DebuggerSource_getURL(JSCont
     }
     args.rval().setString(*str);
   } else {
     args.rval().setNull();
   }
   return true;
 }
 
+class DebuggerSourceGetIdMatcher {
+ public:
+  using ReturnType = uint32_t;
+
+  ReturnType match(HandleScriptSourceObject sourceObject) {
+    ScriptSource* ss = sourceObject->source();
+    return ss->id();
+  }
+  ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
+    return 0;
+  }
+};
+
+static bool DebuggerSource_getId(JSContext* cx, unsigned argc, Value* vp) {
+  THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get id)", args, obj, referent);
+
+  DebuggerSourceGetIdMatcher matcher;
+  uint32_t id = referent.match(matcher);
+  args.rval().setNumber(id);
+  return true;
+}
+
 struct DebuggerSourceGetDisplayURLMatcher {
   using ReturnType = const char16_t*;
   ReturnType match(HandleScriptSourceObject sourceObject) {
     ScriptSource* ss = sourceObject->source();
     MOZ_ASSERT(ss);
     return ss->hasDisplayURL() ? ss->displayURL() : nullptr;
   }
   ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
@@ -8583,16 +8605,17 @@ static bool DebuggerSource_getSourceMapU
   }
   return true;
 }
 
 static const JSPropertySpec DebuggerSource_properties[] = {
     JS_PSG("text", DebuggerSource_getText, 0),
     JS_PSG("binary", DebuggerSource_getBinary, 0),
     JS_PSG("url", DebuggerSource_getURL, 0),
+    JS_PSG("id", DebuggerSource_getId, 0),
     JS_PSG("element", DebuggerSource_getElement, 0),
     JS_PSG("displayURL", DebuggerSource_getDisplayURL, 0),
     JS_PSG("introductionScript", DebuggerSource_getIntroductionScript, 0),
     JS_PSG("introductionOffset", DebuggerSource_getIntroductionOffset, 0),
     JS_PSG("introductionType", DebuggerSource_getIntroductionType, 0),
     JS_PSG("elementAttributeName", DebuggerSource_getElementProperty, 0),
     JS_PSGS("sourceMapURL", DebuggerSource_getSourceMapURL,
             DebuggerSource_setSourceMapURL, 0),
--- a/js/src/vm/ErrorObject-inl.h
+++ b/js/src/vm/ErrorObject-inl.h
@@ -11,16 +11,21 @@
 
 #include "vm/JSContext.h"
 
 inline JSString* js::ErrorObject::fileName(JSContext* cx) const {
   const HeapSlot& slot = getReservedSlotRef(FILENAME_SLOT);
   return slot.isString() ? slot.toString() : cx->names().empty;
 }
 
+inline uint32_t js::ErrorObject::sourceId() const {
+  const HeapSlot& slot = getReservedSlotRef(SOURCEID_SLOT);
+  return slot.isInt32() ? slot.toInt32() : 0;
+}
+
 inline uint32_t js::ErrorObject::lineNumber() const {
   const HeapSlot& slot = getReservedSlotRef(LINENUMBER_SLOT);
   return slot.isInt32() ? slot.toInt32() : 0;
 }
 
 inline uint32_t js::ErrorObject::columnNumber() const {
   const HeapSlot& slot = getReservedSlotRef(COLUMNNUMBER_SLOT);
   return slot.isInt32() ? slot.toInt32() : 0;
--- a/js/src/vm/ErrorObject.cpp
+++ b/js/src/vm/ErrorObject.cpp
@@ -41,17 +41,18 @@ using namespace js;
   return NativeObject::addDataProperty(cx, obj, cx->names().columnNumber,
                                        COLUMNNUMBER_SLOT, 0);
 }
 
 /* static */ bool js::ErrorObject::init(JSContext* cx, Handle<ErrorObject*> obj,
                                         JSExnType type,
                                         UniquePtr<JSErrorReport> errorReport,
                                         HandleString fileName,
-                                        HandleObject stack, uint32_t lineNumber,
+                                        HandleObject stack, uint32_t sourceId,
+                                        uint32_t lineNumber,
                                         uint32_t columnNumber,
                                         HandleString message) {
   AssertObjectIsSavedFrameOrWrapper(cx, stack);
   cx->check(obj, stack);
 
   // Null out early in case of error, for exn_finalize's sake.
   obj->initReservedSlot(ERROR_REPORT_SLOT, PrivateValue(nullptr));
 
@@ -90,16 +91,17 @@ using namespace js;
   obj->initReservedSlot(STACK_SLOT, ObjectOrNullValue(stack));
   obj->setReservedSlot(ERROR_REPORT_SLOT, PrivateValue(report));
   obj->initReservedSlot(FILENAME_SLOT, StringValue(fileName));
   obj->initReservedSlot(LINENUMBER_SLOT, Int32Value(lineNumber));
   obj->initReservedSlot(COLUMNNUMBER_SLOT, Int32Value(columnNumber));
   if (message) {
     obj->setSlotWithType(cx, messageShape, StringValue(message));
   }
+  obj->initReservedSlot(SOURCEID_SLOT, Int32Value(sourceId));
 
   // When recording/replaying and running on the main thread, get a counter
   // which the devtools can use to warp to this point in the future.
   if (mozilla::recordreplay::IsRecordingOrReplaying() &&
       !cx->runtime()->parentRuntime) {
     uint64_t timeWarpTarget = mozilla::recordreplay::NewTimeWarpTarget();
 
     // Make sure we don't truncate the time warp target by storing it as a
@@ -109,17 +111,18 @@ using namespace js;
     obj->initReservedSlot(TIME_WARP_SLOT, DoubleValue(timeWarpTarget));
   }
 
   return true;
 }
 
 /* static */ ErrorObject* js::ErrorObject::create(
     JSContext* cx, JSExnType errorType, HandleObject stack,
-    HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
+    HandleString fileName, uint32_t sourceId,
+    uint32_t lineNumber, uint32_t columnNumber,
     UniquePtr<JSErrorReport> report, HandleString message,
     HandleObject protoArg /* = nullptr */) {
   AssertObjectIsSavedFrameOrWrapper(cx, stack);
 
   RootedObject proto(cx, protoArg);
   if (!proto) {
     proto = GlobalObject::getOrCreateCustomErrorPrototype(cx, cx->global(),
                                                           errorType);
@@ -134,17 +137,17 @@ using namespace js;
     JSObject* obj = NewObjectWithGivenProto(cx, clasp, proto);
     if (!obj) {
       return nullptr;
     }
     errObject = &obj->as<ErrorObject>();
   }
 
   if (!ErrorObject::init(cx, errObject, errorType, std::move(report), fileName,
-                         stack, lineNumber, columnNumber, message)) {
+                         stack, sourceId, lineNumber, columnNumber, message)) {
     return nullptr;
   }
 
   return errObject;
 }
 
 JSErrorReport* js::ErrorObject::getOrCreateErrorReport(JSContext* cx) {
   if (JSErrorReport* r = getErrorReport()) {
@@ -162,16 +165,17 @@ JSErrorReport* js::ErrorObject::getOrCre
   // Filename.
   UniqueChars filenameStr = JS_EncodeStringToLatin1(cx, fileName(cx));
   if (!filenameStr) {
     return nullptr;
   }
   report.filename = filenameStr.get();
 
   // Coordinates.
+  report.sourceId = sourceId();
   report.lineno = lineNumber();
   report.column = columnNumber();
 
   // Message. Note that |new Error()| will result in an undefined |message|
   // slot, so we need to explicitly substitute the empty string in that case.
   RootedString message(cx, getMessage());
   if (!message) {
     message = cx->runtime()->emptyString;
--- a/js/src/vm/ErrorObject.h
+++ b/js/src/vm/ErrorObject.h
@@ -26,31 +26,32 @@ class ErrorObject : public NativeObject 
 
   static JSObject* createConstructor(JSContext* cx, JSProtoKey key);
 
   /* For access to createProto. */
   friend JSObject* js::InitExceptionClasses(JSContext* cx, HandleObject global);
 
   static bool init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
                    UniquePtr<JSErrorReport> errorReport, HandleString fileName,
-                   HandleObject stack, uint32_t lineNumber,
+                   HandleObject stack, uint32_t sourceId, uint32_t lineNumber,
                    uint32_t columnNumber, HandleString message);
 
   static const ClassSpec classSpecs[JSEXN_ERROR_LIMIT];
   static const Class protoClasses[JSEXN_ERROR_LIMIT];
 
  protected:
   static const uint32_t EXNTYPE_SLOT = 0;
   static const uint32_t STACK_SLOT = EXNTYPE_SLOT + 1;
   static const uint32_t ERROR_REPORT_SLOT = STACK_SLOT + 1;
   static const uint32_t FILENAME_SLOT = ERROR_REPORT_SLOT + 1;
   static const uint32_t LINENUMBER_SLOT = FILENAME_SLOT + 1;
   static const uint32_t COLUMNNUMBER_SLOT = LINENUMBER_SLOT + 1;
   static const uint32_t MESSAGE_SLOT = COLUMNNUMBER_SLOT + 1;
-  static const uint32_t TIME_WARP_SLOT = MESSAGE_SLOT + 1;
+  static const uint32_t SOURCEID_SLOT = MESSAGE_SLOT + 1;
+  static const uint32_t TIME_WARP_SLOT = SOURCEID_SLOT + 1;
 
   static const uint32_t RESERVED_SLOTS = TIME_WARP_SLOT + 1;
 
  public:
   static const Class classes[JSEXN_ERROR_LIMIT];
 
   static const Class* classForType(JSExnType type) {
     MOZ_ASSERT(type < JSEXN_WARN);
@@ -62,18 +63,18 @@ class ErrorObject : public NativeObject 
            clasp < &classes[0] + mozilla::ArrayLength(classes);
   }
 
   // Create an error of the given type corresponding to the provided location
   // info.  If |message| is non-null, then the error will have a .message
   // property with that value; otherwise the error will have no .message
   // property.
   static ErrorObject* create(JSContext* cx, JSExnType type, HandleObject stack,
-                             HandleString fileName, uint32_t lineNumber,
-                             uint32_t columnNumber,
+                             HandleString fileName, uint32_t sourceId,
+                             uint32_t lineNumber, uint32_t columnNumber,
                              UniquePtr<JSErrorReport> report,
                              HandleString message,
                              HandleObject proto = nullptr);
 
   /*
    * Assign the initial error shape to the empty object.  (This shape does
    * *not* include .message, which must be added separately if needed; see
    * ErrorObject::init.)
@@ -90,16 +91,17 @@ class ErrorObject : public NativeObject 
       return nullptr;
     }
     return static_cast<JSErrorReport*>(slot.toPrivate());
   }
 
   JSErrorReport* getOrCreateErrorReport(JSContext* cx);
 
   inline JSString* fileName(JSContext* cx) const;
+  inline uint32_t sourceId() const;
   inline uint32_t lineNumber() const;
   inline uint32_t columnNumber() const;
   inline JSObject* stack() const;
   inline uint64_t timeWarpTarget() const;
 
   JSString* getMessage() const {
     const HeapSlot& slot = getReservedSlotRef(MESSAGE_SLOT);
     return slot.isString() ? slot.toString() : nullptr;
--- a/js/src/vm/JSContext.cpp
+++ b/js/src/vm/JSContext.cpp
@@ -253,16 +253,19 @@ static void PopulateReportBlame(JSContex
    * rather than a builtin frame and which we're allowed to know about.
    */
   NonBuiltinFrameIter iter(cx, realm->principals());
   if (iter.done()) {
     return;
   }
 
   report->filename = iter.filename();
+  if (iter.hasScript()) {
+    report->sourceId = iter.script()->scriptSource()->id();
+  }
   uint32_t column;
   report->lineno = iter.computeLine(&column);
   report->column = FixupColumnForDisplay(column);
   report->isMuted = iter.mutedErrors();
 }
 
 /*
  * Since memory has been exhausted, avoid the normal error-handling path which
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -2843,16 +2843,18 @@ bool ScriptSource::setSourceMapURL(JSCon
   if (len == 1) {
     return true;
   }
 
   sourceMapURL_ = DuplicateString(cx, sourceMapURL);
   return sourceMapURL_ != nullptr;
 }
 
+/* static */ mozilla::Atomic<uint32_t> ScriptSource::idCount_;
+
 /*
  * [SMDOC] JSScript data layout (shared)
  *
  * Shared script data management.
  *
  * SharedScriptData::data contains data that can be shared within a
  * runtime. The atoms() data is placed first to simplify its alignment.
  *
--- a/js/src/vm/JSScript.h
+++ b/js/src/vm/JSScript.h
@@ -605,16 +605,27 @@ class ScriptSource {
   // Instant at which the first parse of this source ended, or null
   // if the source hasn't been parsed yet.
   //
   // Used for statistics purposes, to determine how much time code spends
   // syntax parsed before being full parsed, to help determine whether
   // our syntax parse vs. full parse heuristics are correct.
   mozilla::TimeStamp parseEnded_;
 
+  // An id for this source that is unique across the process. This can be used
+  // to refer to this source from places that don't want to hold a strong
+  // reference on the source itself.
+  //
+  // This is a 32 bit ID and could overflow, in which case the ID will not be
+  // unique anymore.
+  uint32_t id_;
+
+  // How many ids have been handed out to sources.
+  static mozilla::Atomic<uint32_t> idCount_;
+
   // True if we can call JSRuntime::sourceHook to load the source on
   // demand. If sourceRetrievable_ and hasSourceText() are false, it is not
   // possible to get source at all.
   bool sourceRetrievable_ : 1;
   bool hasIntroductionOffset_ : 1;
   bool containsAsmJS_ : 1;
 
   UniquePtr<frontend::BinASTSourceMetadata> binASTMetadata_;
@@ -649,16 +660,17 @@ class ScriptSource {
         displayURL_(nullptr),
         sourceMapURL_(nullptr),
         mutedErrors_(false),
         introductionOffset_(0),
         parameterListEnd_(0),
         introducerFilename_(nullptr),
         introductionType_(nullptr),
         xdrEncoder_(nullptr),
+        id_(++idCount_),
         sourceRetrievable_(false),
         hasIntroductionOffset_(false),
         containsAsmJS_(false) {}
 
   ~ScriptSource() { MOZ_ASSERT(refs == 0); }
 
   void incref() { refs++; }
   void decref() {
@@ -1030,16 +1042,18 @@ class ScriptSource {
   }
   bool hasIntroductionType() const { return introductionType_; }
   const char* introductionType() const {
     MOZ_ASSERT(hasIntroductionType());
     return introductionType_;
   }
   const char* filename() const { return filename_.get(); }
 
+  uint32_t id() const { return id_; }
+
   // Display URLs
   MOZ_MUST_USE bool setDisplayURL(JSContext* cx, const char16_t* displayURL);
   bool hasDisplayURL() const { return displayURL_ != nullptr; }
   const char16_t* displayURL() {
     MOZ_ASSERT(hasDisplayURL());
     return displayURL_.get();
   }
 
--- a/js/src/vm/SavedFrame.h
+++ b/js/src/vm/SavedFrame.h
@@ -26,29 +26,31 @@ class SavedFrame : public NativeObject {
   static const Class protoClass_;
   static const JSPropertySpec protoAccessors[];
   static const JSFunctionSpec protoFunctions[];
   static const JSFunctionSpec staticFunctions[];
 
   // Prototype methods and properties to be exposed to JS.
   static bool construct(JSContext* cx, unsigned argc, Value* vp);
   static bool sourceProperty(JSContext* cx, unsigned argc, Value* vp);
+  static bool sourceIdProperty(JSContext* cx, unsigned argc, Value* vp);
   static bool lineProperty(JSContext* cx, unsigned argc, Value* vp);
   static bool columnProperty(JSContext* cx, unsigned argc, Value* vp);
   static bool functionDisplayNameProperty(JSContext* cx, unsigned argc,
                                           Value* vp);
   static bool asyncCauseProperty(JSContext* cx, unsigned argc, Value* vp);
   static bool asyncParentProperty(JSContext* cx, unsigned argc, Value* vp);
   static bool parentProperty(JSContext* cx, unsigned argc, Value* vp);
   static bool toStringMethod(JSContext* cx, unsigned argc, Value* vp);
 
   static void finalize(FreeOp* fop, JSObject* obj);
 
   // Convenient getters for SavedFrame's reserved slots for use from C++.
   JSAtom* getSource();
+  uint32_t getSourceId();
   uint32_t getLine();
   uint32_t getColumn();
   JSAtom* getFunctionDisplayName();
   JSAtom* getAsyncCause();
   SavedFrame* getParent() const;
   JSPrincipals* getPrincipals();
   bool isSelfHosted(JSContext* cx);
   bool isWasm();
@@ -124,27 +126,29 @@ class SavedFrame : public NativeObject {
 
  private:
   static SavedFrame* create(JSContext* cx);
   static MOZ_MUST_USE bool finishSavedFrameInit(JSContext* cx,
                                                 HandleObject ctor,
                                                 HandleObject proto);
   void initFromLookup(JSContext* cx, HandleLookup lookup);
   void initSource(JSAtom* source);
+  void initSourceId(uint32_t id);
   void initLine(uint32_t line);
   void initColumn(uint32_t column);
   void initFunctionDisplayName(JSAtom* maybeName);
   void initAsyncCause(JSAtom* maybeCause);
   void initParent(SavedFrame* maybeParent);
   void initPrincipalsAlreadyHeld(JSPrincipals* principals);
   void initPrincipals(JSPrincipals* principals);
 
   enum {
     // The reserved slots in the SavedFrame class.
     JSSLOT_SOURCE,
+    JSSLOT_SOURCEID,
     JSSLOT_LINE,
     JSSLOT_COLUMN,
     JSSLOT_FUNCTIONDISPLAYNAME,
     JSSLOT_ASYNCCAUSE,
     JSSLOT_PARENT,
     JSSLOT_PRINCIPALS,
 
     // The total number of reserved slots in the SavedFrame class.
@@ -255,16 +259,18 @@ class ConcreteStackFrame<SavedFrame> : p
   uint32_t line() const override { return get().getLine(); }
   uint32_t column() const override { return get().getColumn(); }
 
   AtomOrTwoByteChars source() const override {
     auto source = get().getSource();
     return AtomOrTwoByteChars(source);
   }
 
+  uint32_t sourceId() const override { return get().getSourceId(); }
+
   AtomOrTwoByteChars functionDisplayName() const override {
     auto name = get().getFunctionDisplayName();
     return AtomOrTwoByteChars(name);
   }
 
   void trace(JSTracer* trc) override {
     JSObject* prev = &get();
     JSObject* next = prev;
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -168,22 +168,23 @@ void LiveSavedFrameCache::findWithoutInv
       return;
     }
   }
 
   frame.set(nullptr);
 }
 
 struct SavedFrame::Lookup {
-  Lookup(JSAtom* source, uint32_t line, uint32_t column,
+  Lookup(JSAtom* source, uint32_t sourceId, uint32_t line, uint32_t column,
          JSAtom* functionDisplayName, JSAtom* asyncCause, SavedFrame* parent,
          JSPrincipals* principals,
          const Maybe<LiveSavedFrameCache::FramePtr>& framePtr = Nothing(),
          jsbytecode* pc = nullptr, Activation* activation = nullptr)
       : source(source),
+        sourceId(sourceId),
         line(line),
         column(column),
         functionDisplayName(functionDisplayName),
         asyncCause(asyncCause),
         parent(parent),
         principals(principals),
         framePtr(framePtr),
         pc(pc),
@@ -192,29 +193,31 @@ struct SavedFrame::Lookup {
     MOZ_ASSERT_IF(framePtr.isSome(), activation);
 #ifdef JS_MORE_DETERMINISTIC
     column = 0;
 #endif
   }
 
   explicit Lookup(SavedFrame& savedFrame)
       : source(savedFrame.getSource()),
+        sourceId(savedFrame.getSourceId()),
         line(savedFrame.getLine()),
         column(savedFrame.getColumn()),
         functionDisplayName(savedFrame.getFunctionDisplayName()),
         asyncCause(savedFrame.getAsyncCause()),
         parent(savedFrame.getParent()),
         principals(savedFrame.getPrincipals()),
         framePtr(Nothing()),
         pc(nullptr),
         activation(nullptr) {
     MOZ_ASSERT(source);
   }
 
   JSAtom* source;
+  uint32_t sourceId;
   uint32_t line;
   uint32_t column;
   JSAtom* functionDisplayName;
   JSAtom* asyncCause;
   SavedFrame* parent;
   JSPrincipals* principals;
 
   // These are used only by the LiveSavedFrameCache and not used for identity or
@@ -365,16 +368,17 @@ const Class SavedFrame::protoClass_ = {
 /* static */ const JSFunctionSpec SavedFrame::staticFunctions[] = {JS_FS_END};
 
 /* static */ const JSFunctionSpec SavedFrame::protoFunctions[] = {
     JS_FN("constructor", SavedFrame::construct, 0, 0),
     JS_FN("toString", SavedFrame::toStringMethod, 0, 0), JS_FS_END};
 
 /* static */ const JSPropertySpec SavedFrame::protoAccessors[] = {
     JS_PSG("source", SavedFrame::sourceProperty, 0),
+    JS_PSG("sourceId", SavedFrame::sourceIdProperty, 0),
     JS_PSG("line", SavedFrame::lineProperty, 0),
     JS_PSG("column", SavedFrame::columnProperty, 0),
     JS_PSG("functionDisplayName", SavedFrame::functionDisplayNameProperty, 0),
     JS_PSG("asyncCause", SavedFrame::asyncCauseProperty, 0),
     JS_PSG("asyncParent", SavedFrame::asyncParentProperty, 0),
     JS_PSG("parent", SavedFrame::parentProperty, 0),
     JS_PS_END};
 
@@ -388,16 +392,21 @@ const Class SavedFrame::protoClass_ = {
 }
 
 JSAtom* SavedFrame::getSource() {
   const Value& v = getReservedSlot(JSSLOT_SOURCE);
   JSString* s = v.toString();
   return &s->asAtom();
 }
 
+uint32_t SavedFrame::getSourceId() {
+  const Value& v = getReservedSlot(JSSLOT_SOURCEID);
+  return v.toPrivateUint32();
+}
+
 uint32_t SavedFrame::getLine() {
   const Value& v = getReservedSlot(JSSLOT_LINE);
   return v.toPrivateUint32();
 }
 
 uint32_t SavedFrame::getColumn() {
   const Value& v = getReservedSlot(JSSLOT_COLUMN);
   return v.toPrivateUint32();
@@ -434,16 +443,20 @@ JSPrincipals* SavedFrame::getPrincipals(
   return static_cast<JSPrincipals*>(v.toPrivate());
 }
 
 void SavedFrame::initSource(JSAtom* source) {
   MOZ_ASSERT(source);
   initReservedSlot(JSSLOT_SOURCE, StringValue(source));
 }
 
+void SavedFrame::initSourceId(uint32_t sourceId) {
+  initReservedSlot(JSSLOT_SOURCEID, PrivateUint32Value(sourceId));
+}
+
 void SavedFrame::initLine(uint32_t line) {
   initReservedSlot(JSSLOT_LINE, PrivateUint32Value(line));
 }
 
 void SavedFrame::initColumn(uint32_t column) {
 #ifdef JS_MORE_DETERMINISTIC
   column = 0;
 #endif
@@ -489,16 +502,17 @@ void SavedFrame::initFromLookup(JSContex
   if (lookup->functionDisplayName) {
     cx->markAtom(lookup->functionDisplayName);
   }
   if (lookup->asyncCause) {
     cx->markAtom(lookup->asyncCause);
   }
 
   initSource(lookup->source);
+  initSourceId(lookup->sourceId);
   initLine(lookup->line);
   initColumn(lookup->column);
   initFunctionDisplayName(lookup->functionDisplayName);
   initAsyncCause(lookup->asyncCause);
   initParent(lookup->parent);
   initPrincipals(lookup->principals);
 }
 
@@ -723,16 +737,35 @@ JS_PUBLIC_API SavedFrameResult GetSavedF
     sourcep.set(frame->getSource());
   }
   if (sourcep->isAtom()) {
     cx->markAtom(&sourcep->asAtom());
   }
   return SavedFrameResult::Ok;
 }
 
+JS_PUBLIC_API SavedFrameResult GetSavedFrameSourceId(
+    JSContext* cx, JSPrincipals* principals, HandleObject savedFrame,
+    uint32_t* sourceIdp,
+    SavedFrameSelfHosted selfHosted /* = SavedFrameSelfHosted::Include */) {
+  js::AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  MOZ_RELEASE_ASSERT(cx->realm());
+
+  bool skippedAsync;
+  js::RootedSavedFrame frame(cx, UnwrapSavedFrame(cx, principals, savedFrame,
+                                                  selfHosted, skippedAsync));
+  if (!frame) {
+    *sourceIdp = 0;
+    return SavedFrameResult::AccessDenied;
+  }
+  *sourceIdp = frame->getSourceId();
+  return SavedFrameResult::Ok;
+}
+
 JS_PUBLIC_API SavedFrameResult GetSavedFrameLine(
     JSContext* cx, JSPrincipals* principals, HandleObject savedFrame,
     uint32_t* linep,
     SavedFrameSelfHosted selfHosted /* = SavedFrameSelfHosted::Include */) {
   js::AssertHeapIsIdle();
   CHECK_THREAD(cx);
   MOZ_RELEASE_ASSERT(cx->realm());
   MOZ_ASSERT(linep);
@@ -1053,16 +1086,30 @@ namespace js {
     }
     args.rval().setString(source);
   } else {
     args.rval().setNull();
   }
   return true;
 }
 
+/* static */ bool SavedFrame::sourceIdProperty(JSContext* cx, unsigned argc,
+                                             Value* vp) {
+  THIS_SAVEDFRAME(cx, argc, vp, "(get sourceId)", args, frame);
+  JSPrincipals* principals = cx->realm()->principals();
+  uint32_t sourceId;
+  if (JS::GetSavedFrameSourceId(cx, principals, frame, &sourceId) ==
+      JS::SavedFrameResult::Ok) {
+    args.rval().setNumber(sourceId);
+  } else {
+    args.rval().setNull();
+  }
+  return true;
+}
+
 /* static */ bool SavedFrame::lineProperty(JSContext* cx, unsigned argc,
                                            Value* vp) {
   THIS_SAVEDFRAME(cx, argc, vp, "(get line)", args, frame);
   JSPrincipals* principals = cx->realm()->principals();
   uint32_t line;
   if (JS::GetSavedFrameLine(cx, principals, frame, &line) ==
       JS::SavedFrameResult::Ok) {
     args.rval().setNumber(line);
@@ -1341,17 +1388,18 @@ bool SavedStacks::insertFrames(JSContext
     }
 
     RootedAtom displayAtom(cx, iter.maybeFunctionDisplayAtom());
 
     auto principals = iter.realm()->principals();
     MOZ_ASSERT_IF(framePtr && !iter.isWasm(), iter.pc());
 
     if (!stackChain->emplaceBack(
-            location.source(), location.line(), location.column(), displayAtom,
+            location.source(), location.sourceId(),
+            location.line(), location.column(), displayAtom,
             nullptr,  // asyncCause
             nullptr,  // parent (not known yet)
             principals, framePtr, iter.pc(), &activation)) {
       ReportOutOfMemory(cx);
       return false;
     }
 
     if (captureIsSatisfied(cx, principals, location.source(), capture)) {
@@ -1651,21 +1699,22 @@ bool SavedStacks::getLocation(JSContext*
     } else {
       const char* filename = script->filename() ? script->filename() : "";
       source = Atomize(cx, filename, strlen(filename));
     }
     if (!source) {
       return false;
     }
 
+    uint32_t sourceId = script->scriptSource()->id();
     uint32_t column;
     uint32_t line = PCToLineNumber(script, pc, &column);
 
     // Make the column 1-based. See comment above.
-    LocationValue value(source, line, column + 1);
+    LocationValue value(source, sourceId, line, column + 1);
     if (!pcLocationMap.add(p, key, value)) {
       ReportOutOfMemory(cx);
       return false;
     }
   }
 
   locationp.set(p->value());
   return true;
@@ -1837,17 +1886,18 @@ JS_PUBLIC_API bool ConstructSavedFrameSt
       if (!functionDisplayName) {
         return false;
       }
     }
 
     auto principals =
         js::ReconstructedSavedFramePrincipals::getSingleton(ubiFrame.get());
 
-    if (!stackChain->emplaceBack(source, ubiFrame.get().line(),
+    if (!stackChain->emplaceBack(source, ubiFrame.get().sourceId(),
+                                 ubiFrame.get().line(),
                                  ubiFrame.get().column(), functionDisplayName,
                                  /* asyncCause */ nullptr,
                                  /* parent */ nullptr, principals)) {
       ReportOutOfMemory(cx);
       return false;
     }
 
     ubiFrame = ubiFrame.get().parent();
--- a/js/src/vm/SavedStacks.h
+++ b/js/src/vm/SavedStacks.h
@@ -238,34 +238,35 @@ class SavedStacks {
 
     void trace(JSTracer* trc) { /* PCKey is weak. */
     }
     bool needsSweep() { return IsAboutToBeFinalized(&script); }
   };
 
  public:
   struct LocationValue {
-    LocationValue() : source(nullptr), line(0), column(0) {}
-    LocationValue(JSAtom* source, size_t line, uint32_t column)
-        : source(source), line(line), column(column) {}
+    LocationValue() : source(nullptr), sourceId(0), line(0), column(0) {}
+    LocationValue(JSAtom* source, uint32_t sourceId, size_t line, uint32_t column)
+        : source(source), sourceId(sourceId), line(line), column(column) {}
 
     void trace(JSTracer* trc) {
       TraceNullableEdge(trc, &source, "SavedStacks::LocationValue::source");
     }
 
     bool needsSweep() {
       // LocationValue is always held strongly, but in a weak map.
       // Assert that it has been marked already, but allow it to be
       // ejected from the map when the key dies.
       MOZ_ASSERT(source);
       MOZ_ASSERT(!IsAboutToBeFinalized(&source));
       return true;
     }
 
     HeapPtr<JSAtom*> source;
+    uint32_t sourceId;
     size_t line;
     uint32_t column;
   };
 
  private:
   struct PCLocationHasher : public DefaultHasher<PCKey> {
     using ScriptPtrHasher = DefaultHasher<JSScript*>;
     using BytecodePtrHasher = DefaultHasher<jsbytecode*>;
@@ -294,29 +295,31 @@ class SavedStacks {
 
   MOZ_MUST_USE bool getLocation(JSContext* cx, const FrameIter& iter,
                                 MutableHandle<LocationValue> locationp);
 };
 
 template <typename Wrapper>
 struct WrappedPtrOperations<SavedStacks::LocationValue, Wrapper> {
   JSAtom* source() const { return loc().source; }
+  uint32_t sourceId() const { return loc().sourceId; }
   size_t line() const { return loc().line; }
   uint32_t column() const { return loc().column; }
 
  private:
   const SavedStacks::LocationValue& loc() const {
     return static_cast<const Wrapper*>(this)->get();
   }
 };
 
 template <typename Wrapper>
 struct MutableWrappedPtrOperations<SavedStacks::LocationValue, Wrapper>
     : public WrappedPtrOperations<SavedStacks::LocationValue, Wrapper> {
   void setSource(JSAtom* v) { loc().source = v; }
+  void setSourceId(uint32_t v) { loc().sourceId = v; }
   void setLine(size_t v) { loc().line = v; }
   void setColumn(uint32_t v) { loc().column = v; }
 
  private:
   SavedStacks::LocationValue& loc() {
     return static_cast<Wrapper*>(this)->get();
   }
 };
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -2815,16 +2815,20 @@ JSObject* JSStructuredCloneReader::readS
   RootedValue columnVal(context());
   uint32_t column;
   if (!startRead(&columnVal) || !columnVal.isNumber() ||
       !ToUint32(context(), columnVal, &column)) {
     return nullptr;
   }
   savedFrame->initColumn(column);
 
+  // Don't specify a source ID when reading a cloned saved frame, as these IDs
+  // are only valid within a specific process.
+  savedFrame->initSourceId(0);
+
   RootedValue name(context());
   if (!startRead(&name) || !(name.isString() || name.isNull())) {
     return nullptr;
   }
   JSAtom* atomName = nullptr;
   if (name.isString()) {
     atomName = AtomizeString(context(), name.toString());
     if (!atomName) {
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -2827,18 +2827,18 @@ static bool Reject(JSContext* cx, const 
   }
 
   RootedString message(cx, NewLatin1StringZ(cx, std::move(str)));
   if (!message) {
     return false;
   }
 
   RootedObject errorObj(
-      cx, ErrorObject::create(cx, JSEXN_WASMCOMPILEERROR, stack, filename, line,
-                              0, nullptr, message));
+      cx, ErrorObject::create(cx, JSEXN_WASMCOMPILEERROR, stack, filename, 0,
+                              line, 0, nullptr, message));
   if (!errorObj) {
     return false;
   }
 
   RootedValue rejectionValue(cx, ObjectValue(*errorObj));
   return PromiseObject::reject(cx, promise, rejectionValue);
 }
 
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -745,16 +745,21 @@ nsresult nsXPCWrappedJSClass::CheckForEx
 
             nsresult rv = scriptError->InitWithWindowID(
                 NS_ConvertUTF8toUTF16(newMessage), sourceName, EmptyString(),
                 lineNumber, 0, 0, "XPConnect JavaScript",
                 nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx));
             if (NS_FAILED(rv)) {
               scriptError = nullptr;
             }
+
+            rv = scriptError->InitSourceId(location->GetSourceId(cx));
+            if (NS_FAILED(rv)) {
+              scriptError = nullptr;
+            }
           }
         }
         if (nullptr != scriptError) {
           consoleService->LogMessage(scriptError);
         }
       }
     }
     // Whether or not it passes the 'reportable' test, it might
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -175,16 +175,17 @@ bool nsXPConnect::IsISupportsDescendant(
 
 void xpc::ErrorBase::Init(JSErrorBase* aReport) {
   if (!aReport->filename) {
     mFileName.SetIsVoid(true);
   } else {
     CopyUTF8toUTF16(mozilla::MakeStringSpan(aReport->filename), mFileName);
   }
 
+  mSourceId = aReport->sourceId;
   mLineNumber = aReport->lineno;
   mColumn = aReport->column;
 }
 
 void xpc::ErrorNote::Init(JSErrorNotes::Note* aNote) {
   xpc::ErrorBase::Init(aNote);
 
   ErrorNoteToMessageString(aNote, mErrorMsg);
@@ -235,16 +236,17 @@ void xpc::ErrorReport::Init(JSContext* a
   mWindowID = aWindowID;
 
   aException->GetErrorMessage(mErrorMsg);
 
   aException->GetFilename(aCx, mFileName);
   if (mFileName.IsEmpty()) {
     mFileName.SetIsVoid(true);
   }
+  mSourceId = aException->SourceId(aCx);
   mLineNumber = aException->LineNumber(aCx);
   mColumn = aException->ColumnNumber();
 
   mFlags = JSREPORT_EXCEPTION;
 }
 
 static LazyLogModule gJSDiagnostics("JSDiagnostics");
 
@@ -343,22 +345,25 @@ void xpc::ErrorReport::LogToConsoleWithS
   errorObject->SetErrorMessageName(mErrorMsgName);
   errorObject->SetTimeWarpTarget(aTimeWarpTarget);
 
   nsresult rv = errorObject->InitWithWindowID(mErrorMsg, mFileName, mSourceLine,
                                               mLineNumber, mColumn, mFlags,
                                               mCategory, mWindowID);
   NS_ENSURE_SUCCESS_VOID(rv);
 
+  rv = errorObject->InitSourceId(mSourceId);
+  NS_ENSURE_SUCCESS_VOID(rv);
+
   for (size_t i = 0, len = mNotes.Length(); i < len; i++) {
     ErrorNote& note = mNotes[i];
 
     nsScriptErrorNote* noteObject = new nsScriptErrorNote();
-    noteObject->Init(note.mErrorMsg, note.mFileName, note.mLineNumber,
-                     note.mColumn);
+    noteObject->Init(note.mErrorMsg, note.mFileName,
+                     note.mSourceId, note.mLineNumber, note.mColumn);
     errorObject->AddNote(noteObject);
   }
 
   consoleService->LogMessage(errorObject);
 }
 
 /* static */
 void xpc::ErrorNote::ErrorNoteToMessageString(JSErrorNotes::Note* aNote,
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -547,20 +547,21 @@ bool ShouldDiscardSystemSource();
 void SetPrefableRealmOptions(JS::RealmOptions& options);
 
 bool ExtraWarningsForSystemJS();
 
 class ErrorBase {
  public:
   nsString mErrorMsg;
   nsString mFileName;
+  uint32_t mSourceId;
   uint32_t mLineNumber;
   uint32_t mColumn;
 
-  ErrorBase() : mLineNumber(0), mColumn(0) {}
+  ErrorBase() : mSourceId(0), mLineNumber(0), mColumn(0) {}
 
   void Init(JSErrorBase* aReport);
 
   void AppendErrorDetailsTo(nsCString& error);
 };
 
 class ErrorNote : public ErrorBase {
  public:
--- a/xpcom/base/nsIException.idl
+++ b/xpcom/base/nsIException.idl
@@ -13,16 +13,19 @@ native StackFrameRef(already_AddRefed<ns
 
 [scriptable, builtinclass, uuid(28bfb2a2-5ea6-4738-918b-049dc4d51f0b)]
 interface nsIStackFrame : nsISupports
 {
     [implicit_jscontext, binaryname(FilenameXPCOM)]
     readonly attribute AString                 filename;
     [implicit_jscontext, binaryname(NameXPCOM)]
     readonly attribute AString                 name;
+    // Unique identifier of the script source for the frame, or zero.
+    [implicit_jscontext, binaryname(SourceIdXPCOM)]
+    readonly attribute int32_t                 sourceId;
     // Valid line numbers begin at '1'. '0' indicates unknown.
     [implicit_jscontext, binaryname(LineNumberXPCOM)]
     readonly attribute int32_t                 lineNumber;
     [implicit_jscontext, binaryname(ColumnNumberXPCOM)]
     readonly attribute int32_t                 columnNumber;
     readonly attribute AUTF8String             sourceLine;
     [implicit_jscontext, binaryname(AsyncCauseXPCOM)]
     readonly attribute AString                 asyncCause;
@@ -45,16 +48,18 @@ interface nsIStackFrame : nsISupports
     AUTF8String toString();
 
     // Infallible things to be called from C++.
     [notxpcom, nostdcall]
     void getFilename(in JSContext aCx, out AString aFilename);
     [notxpcom, nostdcall]
     void getName(in JSContext aCx, out AString aName);
     [notxpcom, nostdcall]
+    int32_t getSourceId(in JSContext aCx);
+    [notxpcom, nostdcall]
     int32_t getLineNumber(in JSContext aCx);
     [notxpcom, nostdcall]
     int32_t getColumnNumber(in JSContext aCx);
     [notxpcom, nostdcall]
     void getAsyncCause(in JSContext aCx, out AString aAsyncCause);
     [notxpcom, nostdcall]
     StackFrameRef getAsyncCaller(in JSContext aCx);
     [notxpcom, nostdcall]