Issue #2257 - Remove rematerialized frames after bailouts and exceptions.

This ensures that rematerialized frames used by the devtools debugger
are properly removed so that no stale data is used during bailouts.
This commit is contained in:
Moonchild 2023-06-01 18:45:35 +02:00 committed by roytam1
commit 2a7ff7ce1a
3 changed files with 25 additions and 4 deletions

View file

@ -1803,6 +1803,14 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo)
MOZ_ASSERT(numFrames > 0);
BailoutKind bailoutKind = bailoutInfo->bailoutKind;
bool checkGlobalDeclarationConflicts = bailoutInfo->checkGlobalDeclarationConflicts;
uint8_t* incomingStack = bailoutInfo->incomingStack;
// We have to get rid of the rematerialized frame, whether it is
// restored or unwound.
auto guardRemoveRematerializedFramesFromDebugger = mozilla::MakeScopeExit([&] {
JitActivation* act = cx->activation()->asJit();
act->removeRematerializedFramesFromDebugger(cx, incomingStack);
});
// Free the bailout buffer.
js_free(bailoutInfo);
@ -1876,6 +1884,7 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo)
if (frameno == numFrames - 1) {
outerScript = frame->script();
outerFp = iter.fp();
MOZ_ASSERT(outerFp == incomingStack);
}
frameno++;
@ -1902,18 +1911,23 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo)
// We must attempt to copy all rematerialized frames over,
// even if earlier ones failed, to invoke the proper frame
// cleanup in the Debugger.
ok = CopyFromRematerializedFrame(cx, act, outerFp, --inlineDepth,
iter.baselineFrame());
if (!CopyFromRematerializedFrame(cx, act, outerFp, --inlineDepth,
iter.baselineFrame()))
{
ok = false;
}
}
++iter;
}
// After copying from all the rematerialized frames, remove them from
// the table to keep the table up to date.
act->removeRematerializedFrame(outerFp);
if (!ok)
return false;
// After copying from all the rematerialized frames, remove them from
// the table to keep the table up to date.
guardRemoveRematerializedFramesFromDebugger.release();
act->removeRematerializedFrame(outerFp);
}
JitSpew(JitSpew_BaselineBailouts,

View file

@ -888,7 +888,12 @@ HandleException(ResumeFromException* rfe)
++frames;
}
// Remove left-over state which might have been needed for bailout.
activation->removeIonFrameRecovery(iter.jsFrame());
activation->removeRematerializedFrame(iter.fp());
// If invalidated, decrement the number of frames remaining on the
// stack for the given IonScript.
if (invalidated)
ionScript->decrementInvalidationCount(cx->runtime()->defaultFreeOp());

View file

@ -1584,6 +1584,8 @@ jit::JitActivation::removeRematerializedFramesFromDebugger(JSContext* cx, uint8_
if (RematerializedFrameTable::Ptr p = rematerializedFrames_->lookup(top)) {
for (uint32_t i = 0; i < p->value().length(); i++)
Debugger::handleUnrecoverableIonBailoutError(cx, p->value()[i]);
RematerializedFrame::FreeInVector(p->value());
rematerializedFrames_->remove(p);
}
}