diff options
Diffstat (limited to 'js/src/vm/JitActivation.cpp')
-rw-r--r-- | js/src/vm/JitActivation.cpp | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/js/src/vm/JitActivation.cpp b/js/src/vm/JitActivation.cpp index 83ec19df8a..e3ff3dd990 100644 --- a/js/src/vm/JitActivation.cpp +++ b/js/src/vm/JitActivation.cpp @@ -13,6 +13,7 @@ #include <utility> // std::move #include "debugger/DebugAPI.h" // js::DebugAPI +#include "jit/Invalidation.h" // js::jit::Invalidate #include "jit/JSJitFrameIter.h" // js::jit::InlineFrameIterator #include "jit/RematerializedFrame.h" // js::jit::RematerializedFrame #include "js/AllocPolicy.h" // js::ReportOutOfMemory @@ -58,7 +59,9 @@ js::jit::JitActivation::~JitActivation() { // Traps get handled immediately. MOZ_ASSERT(!isWasmTrapping()); - clearRematerializedFrames(); + // Rematerialized frames must have been removed by either the bailout code or + // the exception handler. + MOZ_ASSERT_IF(rematerializedFrames_, rematerializedFrames_->empty()); } void js::jit::JitActivation::setBailoutData( @@ -82,20 +85,9 @@ void js::jit::JitActivation::removeRematerializedFrame(uint8_t* top) { } } -void js::jit::JitActivation::clearRematerializedFrames() { - if (!rematerializedFrames_) { - return; - } - - for (RematerializedFrameTable::Enum e(*rematerializedFrames_); !e.empty(); - e.popFront()) { - e.removeFront(); - } -} - js::jit::RematerializedFrame* js::jit::JitActivation::getRematerializedFrame( JSContext* cx, const JSJitFrameIter& iter, size_t inlineDepth, - MaybeReadFallback::FallbackConsequence consequence) { + IsLeavingFrame leaving) { MOZ_ASSERT(iter.activation() == this); MOZ_ASSERT(iter.isIonScripted()); @@ -117,6 +109,14 @@ js::jit::RematerializedFrame* js::jit::JitActivation::getRematerializedFrame( // preserve identity. Therefore, we always rematerialize an uninlined // frame and all its inlined frames at once. InlineFrameIterator inlineIter(cx, &iter); + + // We can run recover instructions without invalidating if we're always + // leaving the frame. + MaybeReadFallback::FallbackConsequence consequence = + MaybeReadFallback::Fallback_Invalidate; + if (leaving == IsLeavingFrame::Yes) { + consequence = MaybeReadFallback::Fallback_DoNothing; + } MaybeReadFallback recover(cx, this, &iter, consequence); // Frames are often rematerialized with the cx inside a Debugger's @@ -124,6 +124,14 @@ js::jit::RematerializedFrame* js::jit::JitActivation::getRematerializedFrame( // be in the script's realm. AutoRealmUnchecked ar(cx, iter.script()->realm()); + // The Ion frame must be invalidated to ensure the rematerialized frame will + // be removed by the bailout code or the exception handler. If we're always + // leaving the frame, the caller is responsible for cleaning up the + // rematerialized frame. + if (leaving == IsLeavingFrame::No && !iter.checkInvalidation()) { + jit::Invalidate(cx, iter.script()); + } + if (!RematerializedFrame::RematerializeInlineFrames(cx, top, inlineIter, recover, frames)) { return nullptr; |