Bug 1581665 - Tidy up handling of pause and paint data, r=jlast.

Differential Revision: https://phabricator.services.mozilla.com/D46087

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Brian Hackett 2019-09-16 22:43:39 +00:00
Родитель e12771ba94
Коммит 458ed0080a
3 изменённых файлов: 34 добавлений и 55 удалений

Просмотреть файл

@ -238,7 +238,7 @@ ChildProcess.prototype = {
return; return;
} }
RecordReplayControl.waitUntilPaused(this.id, maybeCreateCheckpoint); RecordReplayControl.waitUntilPaused(this.id, maybeCreateCheckpoint);
assert(this.paused); assert(this.paused || this.crashed);
}, },
// Add a checkpoint for this child to save. // Add a checkpoint for this child to save.
@ -323,7 +323,6 @@ function lookupChild(id) {
if (id == gMainChild.id) { if (id == gMainChild.id) {
return gMainChild; return gMainChild;
} }
assert(gReplayingChildren[id]);
return gReplayingChildren[id]; return gReplayingChildren[id];
} }
@ -1263,6 +1262,7 @@ function resume(forward) {
maybeResumeRecording(); maybeResumeRecording();
return; return;
} }
ensureFlushed();
} }
if ( if (
gPausePoint.checkpoint == FirstCheckpointId && gPausePoint.checkpoint == FirstCheckpointId &&
@ -1827,7 +1827,12 @@ function Initialize(recordingChildId) {
function ManifestFinished(id, response) { function ManifestFinished(id, response) {
try { try {
dumpv(`ManifestFinished #${id} ${stringify(response)}`); dumpv(`ManifestFinished #${id} ${stringify(response)}`);
lookupChild(id).manifestFinished(response); const child = lookupChild(id);
if (child) {
child.manifestFinished(response);
} else {
// Ignore messages from child processes that we have marked as crashed.
}
} catch (e) { } catch (e) {
dump(`ERROR: ManifestFinished threw exception: ${e} ${e.stack}\n`); dump(`ERROR: ManifestFinished threw exception: ${e} ${e.stack}\n`);
} }
@ -2005,7 +2010,7 @@ const gControl = {
return gDebuggerRequests; return gDebuggerRequests;
}, },
getPauseData() { getPauseDataAndRepaint() {
// If the child has not arrived at the pause point yet, see if there is // If the child has not arrived at the pause point yet, see if there is
// cached pause data for this point already which we can immediately return. // cached pause data for this point already which we can immediately return.
if (gPauseMode == PauseModes.ARRIVING && !gDebuggerRequests.length) { if (gPauseMode == PauseModes.ARRIVING && !gDebuggerRequests.length) {
@ -2014,11 +2019,21 @@ const gControl = {
// After the child pauses, it will need to generate the pause data so // After the child pauses, it will need to generate the pause data so
// that any referenced objects will be instantiated. // that any referenced objects will be instantiated.
addDebuggerRequest({ type: "pauseData" }); addDebuggerRequest({ type: "pauseData" });
RecordReplayControl.hadRepaint(data.paintData);
return data; return data;
} }
} }
gControl.maybeSwitchToReplayingChild(); gControl.maybeSwitchToReplayingChild();
return gControl.sendRequest({ type: "pauseData" }); const data = gControl.sendRequest({ type: "pauseData" });
if (data.unhandledDivergence) {
RecordReplayControl.clearGraphics();
} else {
addPauseData(gPausePoint, data, /* trackCached */ true);
if (data.paintData) {
RecordReplayControl.hadRepaint(data.paintData);
}
}
return data;
}, },
paint(point) { paint(point) {
@ -2028,35 +2043,6 @@ const gControl = {
} }
}, },
repaint() {
if (!gPausePoint) {
return;
}
if (
gMainChild.paused &&
pointEquals(gPausePoint, gMainChild.pausePoint())
) {
// Flush the recording if we are repainting because we interrupted things
// and will now rewind.
if (gMainChild.recording) {
ensureFlushed();
}
return;
}
const data = maybeGetPauseData(gPausePoint);
if (data && data.paintData) {
RecordReplayControl.hadRepaint(data.paintData);
} else {
gControl.maybeSwitchToReplayingChild();
const rv = gControl.sendRequest({ type: "repaint" });
if (rv && rv.length) {
RecordReplayControl.hadRepaint(rv);
} else {
RecordReplayControl.clearGraphics();
}
}
},
isPausedAtDebuggerStatement() { isPausedAtDebuggerStatement() {
const point = gControl.pausePoint(); const point = gControl.pausePoint();
if (point) { if (point) {

Просмотреть файл

@ -476,9 +476,6 @@ ReplayDebugger.prototype = {
// There is no preferred direction of travel after an explicit pause. // There is no preferred direction of travel after an explicit pause.
this._direction = Direction.NONE; this._direction = Direction.NONE;
// Update graphics according to the current state of the child.
this._control.repaint();
// If breakpoint handlers for the pause haven't been called yet, don't // If breakpoint handlers for the pause haven't been called yet, don't
// call them at all. // call them at all.
this._cancelPerformPause = true; this._cancelPerformPause = true;
@ -537,13 +534,14 @@ ReplayDebugger.prototype = {
}, },
// Fill in the debugger with (hopefully) all data the client/server need to // Fill in the debugger with (hopefully) all data the client/server need to
// pause at the current location. // pause at the current location. This also updates graphics to match the
// current location.
_capturePauseData() { _capturePauseData() {
if (this._pool.frames.length) { if (this._pool.frames.length) {
return; return;
} }
const pauseData = this._control.getPauseData(); const pauseData = this._control.getPauseDataAndRepaint();
if (!pauseData.frames) { if (!pauseData.frames) {
return; return;
} }

Просмотреть файл

@ -366,8 +366,6 @@ Services.obs.addObserver(
contents.arguments.forEach(v => contents.arguments.forEach(v =>
contents.argumentsData.addValue(v, PropertyLevels.FULL) contents.argumentsData.addValue(v, PropertyLevels.FULL)
); );
ClearPausedState();
} }
newConsoleMessage(contents); newConsoleMessage(contents);
@ -911,12 +909,6 @@ function getDebuggeeValue(value) {
return value; return value;
} }
// eslint-disable-next-line no-unused-vars
function ClearPausedState() {
gPausedObjects = new IdMap();
gDereferencedObjects = new Map();
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Manifest Management // Manifest Management
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -1015,7 +1007,6 @@ const gManifestStartHandlers = {
getPauseData() { getPauseData() {
divergeFromRecording(); divergeFromRecording();
const data = getPauseData(); const data = getPauseData();
data.paintData = RecordReplayControl.repaint();
RecordReplayControl.manifestFinished(data); RecordReplayControl.manifestFinished(data);
}, },
@ -1034,12 +1025,7 @@ const gManifestStartHandlers = {
const displayName = formatDisplayName(frame); const displayName = formatDisplayName(frame);
const rv = frame.evalWithBindings(`[${text}]`, { displayName }); const rv = frame.evalWithBindings(`[${text}]`, { displayName });
let pauseData; const pauseData = skipPauseData ? undefined : getPauseData();
if (!skipPauseData) {
pauseData = getPauseData();
pauseData.paintData = RecordReplayControl.repaint();
ClearPausedState();
}
let result; let result;
if (rv.return) { if (rv.return) {
@ -1189,6 +1175,12 @@ function HitCheckpoint(id) {
gLastCheckpoint = id; gLastCheckpoint = id;
const point = currentExecutionPoint(); const point = currentExecutionPoint();
// Reset paused state at each checkpoint. In order to reach the checkpoint we
// must have unpaused, and resetting the state allows these objects to be
// collected by the GC.
gPausedObjects = new IdMap();
gDereferencedObjects = new Map();
try { try {
processManifestAfterCheckpoint(point); processManifestAfterCheckpoint(point);
} catch (e) { } catch (e) {
@ -1778,13 +1770,16 @@ PreviewedObjects.prototype = {
// as the server will end up needing to make more requests before the client can // as the server will end up needing to make more requests before the client can
// finish pausing. // finish pausing.
function getPauseData() { function getPauseData() {
const paintData = RecordReplayControl.repaint();
const numFrames = countScriptFrames(); const numFrames = countScriptFrames();
if (!numFrames) { if (!numFrames) {
return {}; return { paintData };
} }
const rv = new PreviewedObjects(); const rv = new PreviewedObjects();
rv.paintData = paintData;
rv.frames = []; rv.frames = [];
rv.scripts = {}; rv.scripts = {};
rv.offsetMetadata = []; rv.offsetMetadata = [];