Skip to content

Commit

Permalink
Set driver progress callback, for backend issue 2391
Browse files Browse the repository at this point in the history
  • Loading branch information
bhackett1024 committed Jun 20, 2021
1 parent 131644b commit e07aff1
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 1 deletion.
9 changes: 9 additions & 0 deletions devtools/server/actors/replay/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ const commands = {
"Target.getCurrentMessageContents": Target_getCurrentMessageContents,
"Target.getFunctionsInRange": Target_getFunctionsInRange,
"Target.getHTMLSource": Target_getHTMLSource,
"Target.getStackFunctionIDs": Target_getStackFunctionIDs,
"Target.getStepOffsets": Target_getStepOffsets,
"Target.getSourceMapURL": Target_getSourceMapURL,
"Target.getSheetSourceMapURL": Target_getSheetSourceMapURL,
Expand Down Expand Up @@ -897,6 +898,14 @@ function Target_getFunctionsInRange({ sourceId, begin, end }) {
return { functions };
}

function Target_getStackFunctionIDs() {
const rv = [];
forEachScriptFrame(frame => {
rv.push(scriptToFunctionId(frame.script));
});
return { frameFunctions: rv.reverse() };
}

function Target_getStepOffsets({ functionId }) {
const script = functionIdToScript(functionId);
const offsets = script
Expand Down
19 changes: 19 additions & 0 deletions js/src/jit/BaselineCodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2138,6 +2138,25 @@ bool BaselineCodeGen<Handler>::emit_ExecutionProgress() {
masm.maybeCallExecutionProgressHook(scratch);
}
masm.inc64(AbsoluteAddress(ExecutionProgressCounter()));
if (mozilla::recordreplay::IsReplaying()) {
frame.syncStack(0);

Register scratch = R0.scratchReg();
Label done;

masm.loadPtr(AbsoluteAddress(ExecutionProgressTarget()), scratch);
masm.branchPtr(Assembler::Equal, scratch, ImmPtr(nullptr), &done);
masm.branchPtr(Assembler::NotEqual, AbsoluteAddress(ExecutionProgressCounter()),
scratch, &done);

prepareVMCall();
using Fn = bool (*)(JSContext*);
if (!callVM<Fn, RecordReplayProgressReached>()) {
return false;
}

masm.bind(&done);
}
}
return true;
}
Expand Down
13 changes: 13 additions & 0 deletions js/src/jit/CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13868,6 +13868,19 @@ void CodeGenerator::visitInterruptCheck(LInterruptCheck* lir) {
void CodeGenerator::visitExecutionProgress(LExecutionProgress* lir) {
masm.maybeCallExecutionProgressHook(lir->mir()->script());
masm.inc64(AbsoluteAddress(ExecutionProgressCounter()));

if (mozilla::recordreplay::IsReplaying()) {
using Fn = bool (*)(JSContext*);
OutOfLineCode* ool =
oolCallVM<Fn, RecordReplayProgressReached>(lir, ArgList(), StoreNothing());

Register tmp = ToRegister(lir->scratch());
masm.loadPtr(AbsoluteAddress(ExecutionProgressTarget()), tmp);
masm.branchPtr(Assembler::Equal, tmp, ImmPtr(nullptr), ool->rejoin());
masm.branchPtr(Assembler::Equal, AbsoluteAddress(ExecutionProgressCounter()),
tmp, ool->entry());
masm.bind(ool->rejoin());
}
}

void CodeGenerator::visitWasmInterruptCheck(LWasmInterruptCheck* lir) {
Expand Down
1 change: 1 addition & 0 deletions js/src/jit/VMFunctionList-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ namespace jit {
_(Int32ToString, js::Int32ToString<CanGC>) \
_(InterpretResume, js::jit::InterpretResume) \
_(InterruptCheck, js::jit::InterruptCheck) \
_(RecordReplayProgressReached, js::RecordReplayProgressReached) \
_(InvokeFunction, js::jit::InvokeFunction) \
_(IonBinaryArithICUpdate, js::jit::IonBinaryArithIC::update) \
_(IonBindNameICUpdate, js::jit::IonBindNameIC::update) \
Expand Down
4 changes: 3 additions & 1 deletion js/src/jit/shared/LIR-shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -629,12 +629,14 @@ class LInterruptCheck : public LInstructionHelper<0, 0, 0> {
MInterruptCheck* mir() const { return mir_->toInterruptCheck(); }
};

class LExecutionProgress : public LInstructionHelper<0, 0, 0> {
class LExecutionProgress : public LInstructionHelper<0, 0, 1> {
public:
LIR_HEADER(ExecutionProgress)

LExecutionProgress() : LInstructionHelper(classOpcode) {}
MExecutionProgress* mir() const { return mir_->toExecutionProgress(); }

const LDefinition* scratch() { return getTemp(0); }
};

class LWasmInterruptCheck : public LInstructionHelper<0, 1, 0> {
Expand Down
3 changes: 3 additions & 0 deletions js/src/vm/Initialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ JS_PUBLIC_API const char* JS::detail::InitWithFailureDiagnostic(
if (getenv("RECORD_REPLAY_FORCE_RECORD_JS_ASSERTS")) {
gForceEmitRecordReplayAsserts = true;
}
if (mozilla::recordreplay::IsReplaying()) {
mozilla::recordreplay::SetExecutionProgressCallback(SetExecutionProgressTargetCallback);
}
#endif

libraryInitState = InitState::Running;
Expand Down
19 changes: 19 additions & 0 deletions js/src/vm/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -916,12 +916,31 @@ uint64_t* js::ExecutionProgressCounter() {
: mozilla::recordreplay::ExecutionProgressCounter();
}

static uint64_t gExecutionProgressTarget;

void js::AdvanceExecutionProgressCounter() {
if (!gForceEmitExecutionProgress) {
mozilla::recordreplay::AdvanceExecutionProgressCounter();
if (*ExecutionProgressCounter() == gExecutionProgressTarget) {
mozilla::recordreplay::ExecutionProgressReached();
}
}
}

uint64_t* js::ExecutionProgressTarget() {
return &gExecutionProgressTarget;
}

void js::SetExecutionProgressTargetCallback(uint64_t aProgress) {
MOZ_RELEASE_ASSERT(mozilla::recordreplay::IsReplaying());
gExecutionProgressTarget = aProgress;
}

bool js::RecordReplayProgressReached(JSContext* cx) {
mozilla::recordreplay::ExecutionProgressReached();
return true;
}

bool js::RecordReplayAssertValue(JSContext* cx, HandlePropertyName name, HandleValue value) {
if (!mozilla::recordreplay::IsRecordingOrReplaying()) {
MOZ_RELEASE_ASSERT(gForceEmitRecordReplayAsserts);
Expand Down
10 changes: 10 additions & 0 deletions js/src/vm/Runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -1225,9 +1225,19 @@ extern bool gRecordDataBuffers;
extern bool gForceEmitExecutionProgress;
extern bool gForceEmitRecordReplayAsserts;

// Current value of the record/replay progress counter.
extern uint64_t* ExecutionProgressCounter();
extern void AdvanceExecutionProgressCounter();

// Any progress value at which we need to notify the record/replay driver when reaching.
extern uint64_t* ExecutionProgressTarget();

// Callback used by the record/replay driver to set a progress to run to.
extern void SetExecutionProgressTargetCallback(uint64_t aProgress);

// Called when the target progress has been reached.
extern bool RecordReplayProgressReached(JSContext* cx);

extern bool ShouldEmitRecordReplayAssert(const char* aFilename,
unsigned aLineno, unsigned aColumn);

Expand Down
2 changes: 2 additions & 0 deletions mfbt/RecordReplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ namespace recordreplay {
(aToken, aBuffer, aLength)) \
Macro(EndContentParse, (const void* aToken), (aToken)) \
Macro(AdvanceExecutionProgressCounter, (), ()) \
Macro(SetExecutionProgressCallback, (void (*aCallback)(uint64_t)), (aCallback)) \
Macro(ExecutionProgressReached, (), ()) \
Macro(InternalAssertScriptedCaller, (const char* aWhy), (aWhy))
// clang-format on

Expand Down
6 changes: 6 additions & 0 deletions mfbt/RecordReplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,12 @@ MFBT_API ProgressCounter* ExecutionProgressCounter();
// Advance the execution progress counter.
MFBT_API void AdvanceExecutionProgressCounter();

// Set a callback the driver can use to set a destination progress value.
MFBT_API void SetExecutionProgressCallback(void (*aCallback)(uint64_t));

// Called when the last destination progress value which was set has been reached.
MFBT_API void ExecutionProgressReached();

// Get an identifier for the current execution point which can be used to warp
// here later.
MFBT_API ProgressCounter NewTimeWarpTarget();
Expand Down
14 changes: 14 additions & 0 deletions toolkit/recordreplay/ProcessRecordReplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ static void (*gAssert)(const char* format, va_list);
static void (*gAssertBytes)(const char* why, const void*, size_t);
static void (*gFinishRecording)();
static uint64_t* (*gProgressCounter)();
static void (*gSetProgressCallback)(void (*aCallback)(uint64_t));
static void (*gProgressReached)();
static void (*gBeginPassThroughEvents)();
static void (*gEndPassThroughEvents)();
static bool (*gAreEventsPassedThrough)();
Expand Down Expand Up @@ -192,6 +194,8 @@ MOZ_EXPORT void RecordReplayInterface_Initialize(int* aArgc, char*** aArgv) {
LoadSymbol("RecordReplayAssert", gAssert);
LoadSymbol("RecordReplayAssertBytes", gAssertBytes);
LoadSymbol("RecordReplayProgressCounter", gProgressCounter);
LoadSymbol("RecordReplaySetProgressCallback", gSetProgressCallback, /* aOptional */ true);
LoadSymbol("RecordReplayProgressReached", gProgressReached, /* aOptional */ true);
LoadSymbol("RecordReplayBeginPassThroughEvents", gBeginPassThroughEvents);
LoadSymbol("RecordReplayEndPassThroughEvents", gEndPassThroughEvents);
LoadSymbol("RecordReplayAreEventsPassedThrough", gAreEventsPassedThrough);
Expand Down Expand Up @@ -348,6 +352,16 @@ MOZ_EXPORT void RecordReplayInterface_AdvanceExecutionProgressCounter() {
++*gProgressCounter();
}

MOZ_EXPORT void RecordReplayInterface_SetExecutionProgressCallback(void (*aCallback)(uint64_t)) {
if (gSetProgressCallback) {
gSetProgressCallback(aCallback);
}
}

MOZ_EXPORT void RecordReplayInterface_ExecutionProgressReached() {
gProgressReached();
}

MOZ_EXPORT void RecordReplayInterface_InternalBeginPassThroughThreadEvents() {
gBeginPassThroughEvents();
}
Expand Down

0 comments on commit e07aff1

Please sign in to comment.