Skip to content

Commit

Permalink
Step without using pause data, fixes mozilla#125
Browse files Browse the repository at this point in the history
  • Loading branch information
bhackett1024 committed Mar 5, 2020
1 parent a21fa01 commit 997fe47
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
4 changes: 4 additions & 0 deletions devtools/client/debugger/src/actions/pause/paused.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export function paused(pauseInfo: Pause) {
const cx = getThreadContext(getState());
assert(cx.thread == thread, "Thread mismatch");

if (frame) {
await dispatch(selectLocation(cx, frame.location));
}

await dispatch(fetchFrames(cx));

const hiddenBreakpoint = getHiddenBreakpoint(getState());
Expand Down
8 changes: 8 additions & 0 deletions devtools/server/actors/thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const { ActorPool } = require("devtools/server/actors/common");
const { createValueGrip } = require("devtools/server/actors/object/utils");
const { ActorClassWithSpec, Actor } = require("devtools/shared/protocol");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
const ChromeUtils = require("ChromeUtils");
const { assert, dumpn, reportException } = DevToolsUtils;
const { threadSpec } = require("devtools/shared/specs/thread");
const {
Expand Down Expand Up @@ -1100,6 +1101,10 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
rewinding,
});

if (isReplaying) {
await this.youngestFrame.ensureMinimalOlderFrame();
}

// Make sure there is still a frame on the stack if we are to continue
// stepping.
const stepFrame = this._getNextStepFrame(this.youngestFrame, rewinding);
Expand Down Expand Up @@ -1129,11 +1134,13 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
// Fall through.
case "finish":
if (rewinding) {
await stepFrame.ensureMinimalOlderFrame();
let olderFrame = stepFrame.older;
while (
olderFrame &&
(!olderFrame.script || this.sources.isFrameBlackBoxed(olderFrame))
) {
await olderFrame.ensureMinimalOlderFrame();
olderFrame = olderFrame.older;
}
if (olderFrame) {
Expand Down Expand Up @@ -1229,6 +1236,7 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
this.doResume({ resumeLimit, rewind });
return {};
} catch (error) {
ChromeUtils.recordReplayLog(`ThreadActor.onResume Error: ${error}`);
return error instanceof Error
? {
error: "unknownError",
Expand Down
51 changes: 43 additions & 8 deletions toolkit/recordreplay/ipc/JSControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,7 @@ enum ChangeFrameKind {
ChangeFrameEnter,
ChangeFrameExit,
ChangeFrameResume,
ChangeFrameCall,
NumChangeFrameKinds
};

Expand Down Expand Up @@ -1281,12 +1282,16 @@ struct ScriptHitInfo {

struct AnyScriptHit {
uint32_t mScript;
uint32_t mFrameIndex;
ProgressCounter mProgress;
uint32_t mOffset;
uint32_t mFrameIndex : 16;
ProgressCounter mProgress : 48;

AnyScriptHit() {}

AnyScriptHit(uint32_t aScript, uint32_t aFrameIndex,
AnyScriptHit(uint32_t aScript, uint32_t aOffset, uint32_t aFrameIndex,
ProgressCounter aProgress)
: mScript(aScript), mFrameIndex(aFrameIndex), mProgress(aProgress) {
: mScript(aScript), mOffset(aOffset), mFrameIndex(aFrameIndex),
mProgress(aProgress) {
static_assert(sizeof(AnyScriptHit) == 16);
}
};
Expand Down Expand Up @@ -1339,7 +1344,7 @@ struct ScriptHitInfo {
for (auto& vector : mChangeFrames) {
MOZ_RELEASE_ASSERT(vector.empty());
size_t numChangeFrames = aStream.ReadScalar32();
vector.appendN(AnyScriptHit(0, 0, 0), numChangeFrames);
vector.appendN(AnyScriptHit(), numChangeFrames);
aStream.ReadBytes(vector.begin(), vector.length() * sizeof(AnyScriptHit));
}

Expand All @@ -1352,6 +1357,10 @@ struct ScriptHitInfo {

InfallibleVector<CheckpointInfo*, 1024> mInfo;

// When scanning the recording, this has the last breakpoint hit on a script
// at each frame depth.
InfallibleVector<AnyScriptHit, 256> mLastHits;

CheckpointInfo* GetInfo(uint32_t aCheckpoint, bool aIncorporateData = true) {
if (aIncorporateData) {
MaybeIncorporateScanData();
Expand Down Expand Up @@ -1387,13 +1396,28 @@ struct ScriptHitInfo {

ScriptHitVector* hits = p->value();
hits->append(ScriptHit(aFrameIndex, aProgress));

while (aFrameIndex >= mLastHits.length()) {
mLastHits.emplaceBack();
}
AnyScriptHit& lastHit = mLastHits[aFrameIndex];
lastHit.mScript = aScript;
lastHit.mOffset = aOffset;
lastHit.mFrameIndex = aFrameIndex;
lastHit.mProgress = aProgress;
}

const AnyScriptHit& LastHit(uint32_t aFrameIndex) {
MOZ_RELEASE_ASSERT(aFrameIndex < mLastHits.length());
return mLastHits[aFrameIndex];
}

void AddChangeFrame(uint32_t aCheckpoint, uint32_t aWhich, uint32_t aScript,
uint32_t aFrameIndex, ProgressCounter aProgress) {
uint32_t aOffset, uint32_t aFrameIndex,
ProgressCounter aProgress) {
CheckpointInfo* info = GetInfo(aCheckpoint);
MOZ_RELEASE_ASSERT(aWhich < NumChangeFrameKinds);
info->mChangeFrames[aWhich].emplaceBack(aScript, aFrameIndex, aProgress);
info->mChangeFrames[aWhich].emplaceBack(aScript, aOffset, aFrameIndex, aProgress);
}

AnyScriptHitVector* FindChangeFrames(uint32_t aCheckpoint, uint32_t aWhich) {
Expand Down Expand Up @@ -1566,7 +1590,16 @@ static bool RecordReplay_OnChangeFrame(JSContext* aCx, unsigned aArgc,
}

uint32_t frameIndex = gFrameDepth - 1;
gScriptHits->AddChangeFrame(GetLastCheckpoint(), Kind, script, frameIndex,

if (Kind == ChangeFrameEnter && frameIndex) {
// Find the last breakpoint hit in the calling frame.
const ScriptHitInfo::AnyScriptHit& lastHit = gScriptHits->LastHit(frameIndex - 1);
gScriptHits->AddChangeFrame(GetLastCheckpoint(), ChangeFrameCall,
lastHit.mScript, lastHit.mOffset,
lastHit.mFrameIndex, lastHit.mProgress);
}

gScriptHits->AddChangeFrame(GetLastCheckpoint(), Kind, script, 0, frameIndex,
gProgressCounter);

if (Kind == ChangeFrameExit) {
Expand Down Expand Up @@ -1784,6 +1817,8 @@ static bool RecordReplay_FindChangeFrames(JSContext* aCx, unsigned aArgc,
JSPROP_ENUMERATE) ||
!JS_DefineProperty(aCx, hitObject, "frameIndex", hit.mFrameIndex,
JSPROP_ENUMERATE) ||
!JS_DefineProperty(aCx, hitObject, "offset", hit.mOffset,
JSPROP_ENUMERATE) ||
!values.append(ObjectValue(*hitObject))) {
return false;
}
Expand Down

0 comments on commit 997fe47

Please sign in to comment.