Bug 1479058 Part 1 - Add NewTimeWarpTarget() API, r=mccr8.

--HG--
extra : rebase_source : 556161b281c21b19f972854b5c3b31e302d0dd26
This commit is contained in:
Brian Hackett 2018-08-02 23:26:25 +00:00
Родитель 18b12586ae
Коммит a1556089f7
5 изменённых файлов: 73 добавлений и 4 удалений

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

@ -36,6 +36,7 @@ namespace recordreplay {
Macro(InternalThingIndex, size_t, (void* aThing), (aThing)) \
Macro(InternalVirtualThingName, const char*, (void* aThing), (aThing)) \
Macro(ExecutionProgressCounter, ProgressCounter*, (), ()) \
Macro(NewTimeWarpTarget, ProgressCounter, (), ()) \
Macro(IsInternalScript, bool, (const char* aURL), (aURL)) \
Macro(DefineRecordReplayControlObject, bool, (JSContext* aCx, JSObject* aObj), (aCx, aObj))

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

@ -342,6 +342,10 @@ AdvanceExecutionProgressCounter()
++*ExecutionProgressCounter();
}
// Get an identifier for the current execution point which can be used to warp
// here later.
MFBT_API ProgressCounter NewTimeWarpTarget();
// Return whether a script is internal to the record/replay infrastructure,
// may run non-deterministically between recording and replaying, and whose
// execution must not update the progress counter.

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

@ -51,6 +51,13 @@ bool MaybeDivergeFromRecording();
// Notify navigation that a position was hit.
void PositionHit(const js::BreakpointPosition& aPosition);
// Get an execution point for hitting the specified position right now.
js::ExecutionPoint CurrentExecutionPoint(const js::BreakpointPosition& aPosition);
// Convert an identifier from NewTimeWarpTarget() which we have seen while
// executing into an ExecutionPoint.
js::ExecutionPoint TimeWarpTargetExecutionPoint(ProgressCounter aTarget);
// Called when running forward, immediately before hitting a normal or
// temporary checkpoint.
void BeforeCheckpoint();

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

@ -366,6 +366,9 @@ public:
// of how much time has elapsed.
bool mAlwaysSaveTemporaryCheckpoints;
// Checkpoints for all time warp targets that have been generated.
InfallibleVector<std::pair<ProgressCounter, size_t>, 0, UntrackedAllocPolicy> mTimeWarpTargetCheckpoints;
// Note: NavigationState is initially zeroed.
NavigationState()
: mPhase(&mForwardPhase)
@ -1138,8 +1141,8 @@ RecordReplayInterface_ExecutionProgressCounter()
} // extern "C"
static ExecutionPoint
NewExecutionPoint(const BreakpointPosition& aPosition)
ExecutionPoint
CurrentExecutionPoint(const BreakpointPosition& aPosition)
{
return ExecutionPoint(gNavigation->LastCheckpoint().mNormal,
gProgressCounter, aPosition);
@ -1149,7 +1152,57 @@ void
PositionHit(const BreakpointPosition& position)
{
AutoDisallowThreadEvents disallow;
gNavigation->PositionHit(NewExecutionPoint(position));
gNavigation->PositionHit(CurrentExecutionPoint(position));
}
extern "C" {
MOZ_EXPORT ProgressCounter
RecordReplayInterface_NewTimeWarpTarget()
{
// NewTimeWarpTarget() must be called at consistent points between recording
// and replaying.
recordreplay::RecordReplayAssert("NewTimeWarpTarget");
if (!gNavigation) {
return 0;
}
// Advance the progress counter for each time warp target. This can be called
// at any place and any number of times where recorded events are allowed.
ProgressCounter progress = ++gProgressCounter;
PositionHit(BreakpointPosition(BreakpointPosition::WarpTarget));
// Remember the checkpoint associated with each time warp target we have
// generated, so we can convert them to ExecutionPoints later. Ignore warp
// targets we have already encountered.
if (gNavigation->mTimeWarpTargetCheckpoints.empty() ||
progress > gNavigation->mTimeWarpTargetCheckpoints.back().first)
{
size_t checkpoint = gNavigation->LastCheckpoint().mNormal;
gNavigation->mTimeWarpTargetCheckpoints.emplaceBack(progress, checkpoint);
}
return progress;
}
} // extern "C"
ExecutionPoint
TimeWarpTargetExecutionPoint(ProgressCounter aTarget)
{
Maybe<size_t> checkpoint;
for (auto entry : gNavigation->mTimeWarpTargetCheckpoints) {
if (entry.first == aTarget) {
checkpoint.emplace(entry.second);
break;
}
}
MOZ_RELEASE_ASSERT(checkpoint.isSome());
return ExecutionPoint(checkpoint.ref(), aTarget,
BreakpointPosition(BreakpointPosition::WarpTarget));
}
bool

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

@ -55,7 +55,10 @@ struct BreakpointPosition
EnterFrame,
// Break when a new top-level script is created.
NewScript
NewScript,
// Break when NewTimeWarpTarget() is called.
WarpTarget
));
Kind mKind;
@ -106,6 +109,7 @@ struct BreakpointPosition
case OnPop: return "OnPop";
case EnterFrame: return "EnterFrame";
case NewScript: return "NewScript";
case WarpTarget: return "WarpTarget";
}
MOZ_CRASH("Bad BreakpointPosition kind");
}