summaryrefslogtreecommitdiffstats
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/src/jit/BaselineBailouts.cpp56
-rw-r--r--js/src/jit/JitFrameIterator.h2
2 files changed, 20 insertions, 38 deletions
diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp
index 3ab722b3d..ad2757ae1 100644
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -419,41 +419,6 @@ struct BaselineStackBuilder
}
};
-// Ensure that all value locations are readable from the SnapshotIterator.
-// Remove RInstructionResults from the JitActivation if the frame got recovered
-// ahead of the bailout.
-class SnapshotIteratorForBailout : public SnapshotIterator
-{
- JitActivation* activation_;
- JitFrameIterator& iter_;
-
- public:
- SnapshotIteratorForBailout(JitActivation* activation, JitFrameIterator& iter)
- : SnapshotIterator(iter, activation->bailoutData()->machineState()),
- activation_(activation),
- iter_(iter)
- {
- MOZ_ASSERT(iter.isBailoutJS());
- }
-
- ~SnapshotIteratorForBailout() {
- // The bailout is complete, we no longer need the recover instruction
- // results.
- activation_->removeIonFrameRecovery(fp_);
- }
-
- // Take previously computed result out of the activation, or compute the
- // results of all recover instructions contained in the snapshot.
- MOZ_MUST_USE bool init(JSContext* cx) {
-
- // Under a bailout, there is no need to invalidate the frame after
- // evaluating the recover instruction, as the invalidation is only
- // needed to cause of the frame which has been introspected.
- MaybeReadFallback recoverBailout(cx, activation_, &iter_, MaybeReadFallback::Fallback_DoNothing);
- return initInstructionResults(recoverBailout);
- }
-};
-
#ifdef DEBUG
static inline bool
IsInlinableFallback(ICFallbackStub* icEntry)
@@ -1476,6 +1441,7 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter
{
MOZ_ASSERT(bailoutInfo != nullptr);
MOZ_ASSERT(*bailoutInfo == nullptr);
+ MOZ_ASSERT(iter.isBailoutJS());
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
TraceLogStopEvent(logger, TraceLogger_IonMonkey);
@@ -1488,6 +1454,12 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter
activation->removeRematerializedFramesFromDebugger(cx, iter.fp());
});
+ // Always remove the RInstructionResults from the JitActivation, even in
+ // case of failures as the stack frame is going away after the bailout.
+ auto removeIonFrameRecovery = mozilla::MakeScopeExit([&] {
+ activation->removeIonFrameRecovery(iter.jsFrame());
+ });
+
// The caller of the top frame must be one of the following:
// IonJS - Ion calling into Ion.
// BaselineStub - Baseline calling into Ion.
@@ -1561,9 +1533,19 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter
}
JitSpew(JitSpew_BaselineBailouts, " Incoming frame ptr = %p", builder.startFrame());
- SnapshotIteratorForBailout snapIter(activation, iter);
- if (!snapIter.init(cx))
+ // Under a bailout, there is no need to invalidate the frame after
+ // evaluating the recover instruction, as the invalidation is only needed in
+ // cases where the frame is introspected ahead of the bailout.
+ MaybeReadFallback recoverBailout(cx, activation, &iter, MaybeReadFallback::Fallback_DoNothing);
+
+ // Ensure that all value locations are readable from the SnapshotIterator.
+ // Get the RInstructionResults from the JitActivation if the frame got
+ // recovered ahead of the bailout.
+ SnapshotIterator snapIter(iter, activation->bailoutData()->machineState());
+ if (!snapIter.initInstructionResults(recoverBailout)) {
+ ReportOutOfMemory(cx);
return BAILOUT_RETURN_FATAL_ERROR;
+ }
#ifdef TRACK_SNAPSHOTS
snapIter.spewBailingFrom();
diff --git a/js/src/jit/JitFrameIterator.h b/js/src/jit/JitFrameIterator.h
index 3620badbd..76d04d092 100644
--- a/js/src/jit/JitFrameIterator.h
+++ b/js/src/jit/JitFrameIterator.h
@@ -509,13 +509,13 @@ class SnapshotIterator
return recover_.moreInstructions();
}
- protected:
// Register a vector used for storing the results of the evaluation of
// recover instructions. This vector should be registered before the
// beginning of the iteration. This function is in charge of allocating
// enough space for all instructions results, and return false iff it fails.
MOZ_MUST_USE bool initInstructionResults(MaybeReadFallback& fallback);
+ protected:
// This function is used internally for computing the result of the recover
// instructions.
MOZ_MUST_USE bool computeInstructionResults(JSContext* cx, RInstructionResults* results) const;