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" });
|
return this._sendRequest({ type: "recordingEndpoint" });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
replayIsRecording: RecordReplayControl.childIsRecording,
|
||||||
|
|
||||||
addDebuggee() {},
|
addDebuggee() {},
|
||||||
removeAllDebuggees() {},
|
removeAllDebuggees() {},
|
||||||
|
|
||||||
@ -384,6 +386,14 @@ ReplayDebugger.prototype = {
|
|||||||
handler.call(this, this.getNewestFrame()); });
|
handler.call(this, this.getNewestFrame()); });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get replayingOnPositionChange() {
|
||||||
|
return this._breakpointKindGetter("PositionChange");
|
||||||
|
},
|
||||||
|
set replayingOnPositionChange(handler) {
|
||||||
|
this._breakpointKindSetter("PositionChange", handler,
|
||||||
|
() => { handler.call(this); });
|
||||||
|
},
|
||||||
|
|
||||||
getNewConsoleMessage() {
|
getNewConsoleMessage() {
|
||||||
const message = this._sendRequest({ type: "getNewConsoleMessage" });
|
const message = this._sendRequest({ type: "getNewConsoleMessage" });
|
||||||
return this._convertConsoleMessage(message);
|
return this._convertConsoleMessage(message);
|
||||||
|
@ -432,6 +432,14 @@ Middleman_HadRepaintFailure(JSContext* aCx, unsigned aArgc, Value* aVp)
|
|||||||
return true;
|
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
|
// Devtools Sandbox
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -931,6 +939,7 @@ static const JSFunctionSpec gMiddlemanMethods[] = {
|
|||||||
JS_FN("maybeSwitchToReplayingChild", Middleman_MaybeSwitchToReplayingChild, 0, 0),
|
JS_FN("maybeSwitchToReplayingChild", Middleman_MaybeSwitchToReplayingChild, 0, 0),
|
||||||
JS_FN("hadRepaint", Middleman_HadRepaint, 2, 0),
|
JS_FN("hadRepaint", Middleman_HadRepaint, 2, 0),
|
||||||
JS_FN("hadRepaintFailure", Middleman_HadRepaintFailure, 0, 0),
|
JS_FN("hadRepaintFailure", Middleman_HadRepaintFailure, 0, 0),
|
||||||
|
JS_FN("childIsRecording", Middleman_ChildIsRecording, 0, 0),
|
||||||
JS_FS_END
|
JS_FS_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,7 +66,11 @@ struct BreakpointPosition
|
|||||||
// Break when the debugger should pause even if no breakpoint has been
|
// 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
|
// set: the beginning or end of the replay has been reached, or a time
|
||||||
// warp has reached its destination.
|
// 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;
|
Kind mKind;
|
||||||
@ -120,6 +124,7 @@ struct BreakpointPosition
|
|||||||
case ConsoleMessage: return "ConsoleMessage";
|
case ConsoleMessage: return "ConsoleMessage";
|
||||||
case WarpTarget: return "WarpTarget";
|
case WarpTarget: return "WarpTarget";
|
||||||
case ForcedPause: return "ForcedPause";
|
case ForcedPause: return "ForcedPause";
|
||||||
|
case PositionChange: return "PositionChange";
|
||||||
}
|
}
|
||||||
MOZ_CRASH("Bad BreakpointPosition kind");
|
MOZ_CRASH("Bad BreakpointPosition kind");
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "js/Proxy.h"
|
#include "js/Proxy.h"
|
||||||
#include "mozilla/dom/ContentProcessMessageManager.h"
|
#include "mozilla/dom/ContentProcessMessageManager.h"
|
||||||
#include "InfallibleVector.h"
|
#include "InfallibleVector.h"
|
||||||
|
#include "JSControl.h"
|
||||||
#include "Monitor.h"
|
#include "Monitor.h"
|
||||||
#include "ProcessRecordReplay.h"
|
#include "ProcessRecordReplay.h"
|
||||||
#include "ProcessRedirect.h"
|
#include "ProcessRedirect.h"
|
||||||
@ -583,6 +584,10 @@ SpawnReplayingChildren()
|
|||||||
AssignMajorCheckpoint(gSecondReplayingChild, CheckpointId::First);
|
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.
|
// Change the current active child, and select a new role for the old one.
|
||||||
static void
|
static void
|
||||||
SwitchActiveChild(ChildProcessInfo* aChild, bool aRecoverPosition = true)
|
SwitchActiveChild(ChildProcessInfo* aChild, bool aRecoverPosition = true)
|
||||||
@ -608,6 +613,12 @@ SwitchActiveChild(ChildProcessInfo* aChild, bool aRecoverPosition = true)
|
|||||||
oldActiveChild->RecoverToCheckpoint(oldActiveChild->MostRecentSavedCheckpoint());
|
oldActiveChild->RecoverToCheckpoint(oldActiveChild->MostRecentSavedCheckpoint());
|
||||||
oldActiveChild->SetRole(MakeUnique<ChildRoleStandby>());
|
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.
|
// main thread. This will continue execution in the preferred direction.
|
||||||
static bool gResumeForwardOrBackward = false;
|
static bool gResumeForwardOrBackward = false;
|
||||||
|
|
||||||
// Hit any breakpoints installed for forced pauses.
|
|
||||||
static void HitForcedPauseBreakpoints(bool aRecordingBoundary);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MaybeSendRepaintMessage()
|
MaybeSendRepaintMessage()
|
||||||
{
|
{
|
||||||
@ -1050,7 +1058,8 @@ Resume(bool aForward)
|
|||||||
// Don't rewind if we are at the beginning of the recording.
|
// Don't rewind if we are at the beginning of the recording.
|
||||||
if (targetCheckpoint == CheckpointId::Invalid) {
|
if (targetCheckpoint == CheckpointId::Invalid) {
|
||||||
SendMessageToUIProcess("HitRecordingBeginning");
|
SendMessageToUIProcess("HitRecordingBeginning");
|
||||||
HitForcedPauseBreakpoints(true);
|
HitBreakpointsWithKind(js::BreakpointPosition::Kind::ForcedPause,
|
||||||
|
/* aRecordingBoundary = */ true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1077,7 +1086,8 @@ Resume(bool aForward)
|
|||||||
MOZ_RELEASE_ASSERT(!gActiveChild->IsRecording());
|
MOZ_RELEASE_ASSERT(!gActiveChild->IsRecording());
|
||||||
if (!gRecordingChild) {
|
if (!gRecordingChild) {
|
||||||
SendMessageToUIProcess("HitRecordingEndpoint");
|
SendMessageToUIProcess("HitRecordingEndpoint");
|
||||||
HitForcedPauseBreakpoints(true);
|
HitBreakpointsWithKind(js::BreakpointPosition::Kind::ForcedPause,
|
||||||
|
/* aRecordingBoundary = */ true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1142,7 +1152,7 @@ TimeWarp(const js::ExecutionPoint& aTarget)
|
|||||||
|
|
||||||
gActiveChild->WaitUntilPaused();
|
gActiveChild->WaitUntilPaused();
|
||||||
SendMessageToUIProcess("TimeWarpFinished");
|
SendMessageToUIProcess("TimeWarpFinished");
|
||||||
HitForcedPauseBreakpoints(false);
|
HitBreakpointsWithKind(js::BreakpointPosition::Kind::ForcedPause);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1189,6 +1199,9 @@ RecvHitCheckpoint(const HitCheckpointMessage& aMsg)
|
|||||||
UpdateCheckpointTimes(aMsg);
|
UpdateCheckpointTimes(aMsg);
|
||||||
MaybeUpdateGraphicsAtCheckpoint(aMsg.mCheckpointId);
|
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
|
// 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
|
// 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.
|
// the process to pause. Immediately resume if the main thread is blocked.
|
||||||
@ -1247,11 +1260,11 @@ RecvHitBreakpoint(const HitBreakpointMessage& aMsg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
HitForcedPauseBreakpoints(bool aRecordingBoundary)
|
HitBreakpointsWithKind(js::BreakpointPosition::Kind aKind, bool aRecordingBoundary)
|
||||||
{
|
{
|
||||||
Vector<uint32_t> breakpoints;
|
Vector<uint32_t> breakpoints;
|
||||||
gActiveChild->GetMatchingInstalledBreakpoints([=](js::BreakpointPosition::Kind aKind) {
|
gActiveChild->GetMatchingInstalledBreakpoints([=](js::BreakpointPosition::Kind aInstalled) {
|
||||||
return aKind == js::BreakpointPosition::ForcedPause;
|
return aInstalled == aKind;
|
||||||
}, breakpoints);
|
}, breakpoints);
|
||||||
if (!breakpoints.empty()) {
|
if (!breakpoints.empty()) {
|
||||||
uint32_t* newBreakpoints = new uint32_t[breakpoints.length()];
|
uint32_t* newBreakpoints = new uint32_t[breakpoints.length()];
|
||||||
|
Loading…
Reference in New Issue
Block a user