mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-24 02:35:41 +00:00
Bug 1505895 - Add handler for changes to a recording/replaying child's state, r=lsmyth.
--HG-- extra : rebase_source : 5cf996fd6d7dfef4a9fc85d697ad35819809ad96
This commit is contained in:
parent
2ec0586f2c
commit
4be9981b8d
@ -76,6 +76,8 @@ ReplayDebugger.prototype = {
|
||||
return this._sendRequest({ type: "recordingEndpoint" });
|
||||
},
|
||||
|
||||
replayIsRecording: RecordReplayControl.childIsRecording,
|
||||
|
||||
addDebuggee() {},
|
||||
removeAllDebuggees() {},
|
||||
|
||||
@ -384,6 +386,14 @@ ReplayDebugger.prototype = {
|
||||
handler.call(this, this.getNewestFrame()); });
|
||||
},
|
||||
|
||||
get replayingOnPositionChange() {
|
||||
return this._breakpointKindGetter("PositionChange");
|
||||
},
|
||||
set replayingOnPositionChange(handler) {
|
||||
this._breakpointKindSetter("PositionChange", handler,
|
||||
() => { handler.call(this); });
|
||||
},
|
||||
|
||||
getNewConsoleMessage() {
|
||||
const message = this._sendRequest({ type: "getNewConsoleMessage" });
|
||||
return this._convertConsoleMessage(message);
|
||||
|
@ -432,6 +432,14 @@ Middleman_HadRepaintFailure(JSContext* aCx, unsigned aArgc, Value* aVp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
Middleman_ChildIsRecording(JSContext* aCx, unsigned aArgc, Value* aVp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(aArgc, aVp);
|
||||
args.rval().setBoolean(parent::ActiveChildIsRecording());
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Devtools Sandbox
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -931,6 +939,7 @@ static const JSFunctionSpec gMiddlemanMethods[] = {
|
||||
JS_FN("maybeSwitchToReplayingChild", Middleman_MaybeSwitchToReplayingChild, 0, 0),
|
||||
JS_FN("hadRepaint", Middleman_HadRepaint, 2, 0),
|
||||
JS_FN("hadRepaintFailure", Middleman_HadRepaintFailure, 0, 0),
|
||||
JS_FN("childIsRecording", Middleman_ChildIsRecording, 0, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
@ -66,7 +66,11 @@ struct BreakpointPosition
|
||||
// Break when the debugger should pause even if no breakpoint has been
|
||||
// set: the beginning or end of the replay has been reached, or a time
|
||||
// warp has reached its destination.
|
||||
ForcedPause
|
||||
ForcedPause,
|
||||
|
||||
// Break when the child process reaches a checkpoint or we switch between
|
||||
// recording and replaying child processes.
|
||||
PositionChange
|
||||
));
|
||||
|
||||
Kind mKind;
|
||||
@ -120,6 +124,7 @@ struct BreakpointPosition
|
||||
case ConsoleMessage: return "ConsoleMessage";
|
||||
case WarpTarget: return "WarpTarget";
|
||||
case ForcedPause: return "ForcedPause";
|
||||
case PositionChange: return "PositionChange";
|
||||
}
|
||||
MOZ_CRASH("Bad BreakpointPosition kind");
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "js/Proxy.h"
|
||||
#include "mozilla/dom/ContentProcessMessageManager.h"
|
||||
#include "InfallibleVector.h"
|
||||
#include "JSControl.h"
|
||||
#include "Monitor.h"
|
||||
#include "ProcessRecordReplay.h"
|
||||
#include "ProcessRedirect.h"
|
||||
@ -583,6 +584,10 @@ SpawnReplayingChildren()
|
||||
AssignMajorCheckpoint(gSecondReplayingChild, CheckpointId::First);
|
||||
}
|
||||
|
||||
// Hit any installed breakpoints with the specified kind.
|
||||
static void HitBreakpointsWithKind(js::BreakpointPosition::Kind aKind,
|
||||
bool aRecordingBoundary = false);
|
||||
|
||||
// Change the current active child, and select a new role for the old one.
|
||||
static void
|
||||
SwitchActiveChild(ChildProcessInfo* aChild, bool aRecoverPosition = true)
|
||||
@ -608,6 +613,12 @@ SwitchActiveChild(ChildProcessInfo* aChild, bool aRecoverPosition = true)
|
||||
oldActiveChild->RecoverToCheckpoint(oldActiveChild->MostRecentSavedCheckpoint());
|
||||
oldActiveChild->SetRole(MakeUnique<ChildRoleStandby>());
|
||||
}
|
||||
|
||||
// Position state is affected when we switch between recording and
|
||||
// replaying children.
|
||||
if (aChild->IsRecording() != oldActiveChild->IsRecording()) {
|
||||
HitBreakpointsWithKind(js::BreakpointPosition::Kind::PositionChange);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -995,9 +1006,6 @@ static bool gChildExecuteBackward = false;
|
||||
// main thread. This will continue execution in the preferred direction.
|
||||
static bool gResumeForwardOrBackward = false;
|
||||
|
||||
// Hit any breakpoints installed for forced pauses.
|
||||
static void HitForcedPauseBreakpoints(bool aRecordingBoundary);
|
||||
|
||||
static void
|
||||
MaybeSendRepaintMessage()
|
||||
{
|
||||
@ -1050,7 +1058,8 @@ Resume(bool aForward)
|
||||
// Don't rewind if we are at the beginning of the recording.
|
||||
if (targetCheckpoint == CheckpointId::Invalid) {
|
||||
SendMessageToUIProcess("HitRecordingBeginning");
|
||||
HitForcedPauseBreakpoints(true);
|
||||
HitBreakpointsWithKind(js::BreakpointPosition::Kind::ForcedPause,
|
||||
/* aRecordingBoundary = */ true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1077,7 +1086,8 @@ Resume(bool aForward)
|
||||
MOZ_RELEASE_ASSERT(!gActiveChild->IsRecording());
|
||||
if (!gRecordingChild) {
|
||||
SendMessageToUIProcess("HitRecordingEndpoint");
|
||||
HitForcedPauseBreakpoints(true);
|
||||
HitBreakpointsWithKind(js::BreakpointPosition::Kind::ForcedPause,
|
||||
/* aRecordingBoundary = */ true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1142,7 +1152,7 @@ TimeWarp(const js::ExecutionPoint& aTarget)
|
||||
|
||||
gActiveChild->WaitUntilPaused();
|
||||
SendMessageToUIProcess("TimeWarpFinished");
|
||||
HitForcedPauseBreakpoints(false);
|
||||
HitBreakpointsWithKind(js::BreakpointPosition::Kind::ForcedPause);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1189,6 +1199,9 @@ RecvHitCheckpoint(const HitCheckpointMessage& aMsg)
|
||||
UpdateCheckpointTimes(aMsg);
|
||||
MaybeUpdateGraphicsAtCheckpoint(aMsg.mCheckpointId);
|
||||
|
||||
// Position state is affected when new checkpoints are reached.
|
||||
HitBreakpointsWithKind(js::BreakpointPosition::Kind::PositionChange);
|
||||
|
||||
// Resume either forwards or backwards. Break the resume off into a separate
|
||||
// runnable, to avoid starving any code already on the stack and waiting for
|
||||
// the process to pause. Immediately resume if the main thread is blocked.
|
||||
@ -1247,11 +1260,11 @@ RecvHitBreakpoint(const HitBreakpointMessage& aMsg)
|
||||
}
|
||||
|
||||
static void
|
||||
HitForcedPauseBreakpoints(bool aRecordingBoundary)
|
||||
HitBreakpointsWithKind(js::BreakpointPosition::Kind aKind, bool aRecordingBoundary)
|
||||
{
|
||||
Vector<uint32_t> breakpoints;
|
||||
gActiveChild->GetMatchingInstalledBreakpoints([=](js::BreakpointPosition::Kind aKind) {
|
||||
return aKind == js::BreakpointPosition::ForcedPause;
|
||||
gActiveChild->GetMatchingInstalledBreakpoints([=](js::BreakpointPosition::Kind aInstalled) {
|
||||
return aInstalled == aKind;
|
||||
}, breakpoints);
|
||||
if (!breakpoints.empty()) {
|
||||
uint32_t* newBreakpoints = new uint32_t[breakpoints.length()];
|
||||
|
Loading…
Reference in New Issue
Block a user