diff --git a/js/src/jit/Bailouts.cpp b/js/src/jit/Bailouts.cpp index 89f7151cc13..88085d4a76d 100644 --- a/js/src/jit/Bailouts.cpp +++ b/js/src/jit/Bailouts.cpp @@ -87,6 +87,7 @@ jit::Bailout(BailoutStack *sp, BaselineBailoutInfo **bailoutInfo) JitActivationIterator jitActivations(cx->runtime()); IonBailoutIterator iter(jitActivations, sp); JitActivation *activation = jitActivations->asJit(); + JitActivation::RegisterBailoutIterator registerIterator(*activation, &iter); TraceLogger *logger = TraceLoggerForMainThread(cx->runtime()); TraceLogTimestamp(logger, TraceLogger::Bailout); @@ -140,6 +141,7 @@ jit::InvalidationBailout(InvalidationBailoutStack *sp, size_t *frameSizeOut, JitActivationIterator jitActivations(cx->runtime()); IonBailoutIterator iter(jitActivations, sp); JitActivation *activation = jitActivations->asJit(); + JitActivation::RegisterBailoutIterator registerIterator(*activation, &iter); TraceLogger *logger = TraceLoggerForMainThread(cx->runtime()); TraceLogTimestamp(logger, TraceLogger::Invalidation); @@ -228,6 +230,7 @@ jit::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame, JitActivationIterator jitActivations(cx->runtime()); IonBailoutIterator iter(jitActivations, frame.frame()); JitActivation *activation = jitActivations->asJit(); + JitActivation::RegisterBailoutIterator registerIterator(*activation, &iter); BaselineBailoutInfo *bailoutInfo = nullptr; uint32_t retval = BailoutIonToBaseline(cx, activation, iter, true, &bailoutInfo, &excInfo); diff --git a/js/src/jit/ParallelFunctions.cpp b/js/src/jit/ParallelFunctions.cpp index 84863c3ac74..e728bce16d8 100644 --- a/js/src/jit/ParallelFunctions.cpp +++ b/js/src/jit/ParallelFunctions.cpp @@ -546,6 +546,7 @@ jit::BailoutPar(BailoutStack *sp, uint8_t **entryFramePointer) JitActivationIterator jitActivations(cx->perThreadData); IonBailoutIterator frameIter(jitActivations, sp); SnapshotIterator snapIter(frameIter); + JitActivation::RegisterBailoutIterator registerIterator(*jitActivations->asJit(), &frameIter); cx->bailoutRecord->setIonBailoutKind(snapIter.bailoutKind()); cx->bailoutRecord->rematerializeFrames(cx, frameIter); diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 76e4488eef7..31b7c2e96cb 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -1404,7 +1404,8 @@ jit::JitActivation::JitActivation(JSContext *cx, bool active) : Activation(cx, Jit), active_(active), rematerializedFrames_(nullptr), - ionRecovery_(cx) + ionRecovery_(cx), + ionBailoutIterator_(nullptr) { if (active) { prevJitTop_ = cx->mainThread().jitTop; @@ -1420,7 +1421,8 @@ jit::JitActivation::JitActivation(ForkJoinContext *cx) : Activation(cx, Jit), active_(true), rematerializedFrames_(nullptr), - ionRecovery_(cx) + ionRecovery_(cx), + ionBailoutIterator_(nullptr) { prevJitTop_ = cx->perThreadData->jitTop; prevJitJSContext_ = cx->perThreadData->jitJSContext; @@ -1434,12 +1436,31 @@ jit::JitActivation::~JitActivation() cx_->perThreadData->jitJSContext = prevJitJSContext_; } - clearRematerializedFrames(); // All reocvered value are taken from activation during the bailout. MOZ_ASSERT(ionRecovery_.empty()); + + // The Ion Bailout Iterator should have unregistered itself from the + // JitActivations. + MOZ_ASSERT(!ionBailoutIterator_); + + clearRematerializedFrames(); js_delete(rematerializedFrames_); } +jit::JitActivation::RegisterBailoutIterator::RegisterBailoutIterator(JitActivation &activation, + IonBailoutIterator *iter) + : activation_(activation) +{ + MOZ_ASSERT(!activation_.ionBailoutIterator_); + activation_.ionBailoutIterator_ = iter; +} + +jit::JitActivation::RegisterBailoutIterator::~RegisterBailoutIterator() +{ + MOZ_ASSERT(activation_.ionBailoutIterator_); + activation_.ionBailoutIterator_ = nullptr; +} + // setActive() is inlined in GenerateFFIIonExit() with explicit masm instructions so // changes to the logic here need to be reflected in GenerateFFIIonExit() in the enable // and disable activation instruction sequences. diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index 8757795bf4d..2deb4ca6aa9 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -1327,6 +1327,11 @@ class JitActivation : public Activation typedef Vector IonRecoveryMap; IonRecoveryMap ionRecovery_; + // If we are bailing out from Ion, then this field should be a non-null + // pointer which references the IonBailoutIterator used to walk the inner + // frames. + IonBailoutIterator *ionBailoutIterator_; + void clearRematerializedFrames(); #ifdef CHECK_OSIPOINT_REGISTERS @@ -1415,6 +1420,15 @@ class JitActivation : public Activation void maybeTakeIonFrameRecovery(IonJSFrameLayout *fp, RInstructionResults *results); void markIonRecovery(JSTracer *trc); + + class RegisterBailoutIterator + { + JitActivation &activation_; + + public: + RegisterBailoutIterator(JitActivation &activation, IonBailoutIterator *iter); + ~RegisterBailoutIterator(); + }; }; // A filtering of the ActivationIterator to only stop at JitActivations.