--- a/js/src/jit/Bailouts.cpp
+++ b/js/src/jit/Bailouts.cpp
@@ -19,90 +19,42 @@
#include "vm/Probes-inl.h"
#include "vm/Stack-inl.h"
using namespace js;
using namespace js::jit;
using mozilla::IsInRange;
-// These constructor are exactly the same except for the type of the iterator
-// which is given to the SnapshotIterator constructor. Doing so avoid the
-// creation of virtual functions for the IonIterator but may introduce some
-// weirdness as IonInlineIterator is using a JitFrameIterator reference.
-//
-// If a function relies on ionScript() or to use OsiIndex(), due to the
-// lack of virtual, these functions will use the JitFrameIterator reference
-// contained in the InlineFrameIterator and thus are not able to recover
-// correctly the data stored in IonBailoutIterator.
-//
-// Currently, such cases should not happen because our only use case of the
-// JitFrameIterator within InlineFrameIterator is to read the frame content, or
-// to clone it to find the parent scripted frame. Both use cases are fine and
-// should not cause any issue since the only potential issue is to read the
-// bailed out frame.
-
-SnapshotIterator::SnapshotIterator(const IonBailoutIterator &iter)
- : snapshot_(iter.ionScript()->snapshots(),
- iter.snapshotOffset(),
- iter.ionScript()->snapshotsRVATableSize(),
- iter.ionScript()->snapshotsListSize()),
- recover_(snapshot_,
- iter.ionScript()->recovers(),
- iter.ionScript()->recoversSize()),
- fp_(iter.jsFrame()),
- machine_(iter.machineState()),
- ionScript_(iter.ionScript()),
- instructionResults_(nullptr)
-{
-}
-
-void
-IonBailoutIterator::dump() const
-{
- if (type_ == JitFrame_IonJS) {
- InlineFrameIterator frames(GetJSContextFromJitCode(), this);
- for (;;) {
- frames.dump();
- if (!frames.more())
- break;
- ++frames;
- }
- } else {
- JitFrameIterator::dump();
- }
-}
-
uint32_t
jit::Bailout(BailoutStack *sp, BaselineBailoutInfo **bailoutInfo)
{
JSContext *cx = GetJSContextFromJitCode();
MOZ_ASSERT(bailoutInfo);
// We don't have an exit frame.
MOZ_ASSERT(IsInRange(FAKE_JIT_TOP_FOR_BAILOUT, 0, 0x1000) &&
IsInRange(FAKE_JIT_TOP_FOR_BAILOUT + sizeof(IonCommonFrameLayout), 0, 0x1000),
"Fake jitTop pointer should be within the first page.");
cx->mainThread().jitTop = FAKE_JIT_TOP_FOR_BAILOUT;
gc::AutoSuppressGC suppress(cx);
JitActivationIterator jitActivations(cx->runtime());
- IonBailoutIterator iter(jitActivations, sp);
- JitActivation *activation = jitActivations->asJit();
- JitActivation::RegisterBailoutIterator registerIterator(*activation, &iter);
+ BailoutFrameInfo bailoutData(jitActivations, sp);
+ JitFrameIterator iter(jitActivations);
TraceLogger *logger = TraceLoggerForMainThread(cx->runtime());
TraceLogTimestamp(logger, TraceLogger::Bailout);
JitSpew(JitSpew_IonBailouts, "Took bailout! Snapshot offset: %d", iter.snapshotOffset());
MOZ_ASSERT(IsBaselineEnabled(cx));
*bailoutInfo = nullptr;
- uint32_t retval = BailoutIonToBaseline(cx, activation, iter, false, bailoutInfo);
+ uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, false, bailoutInfo);
MOZ_ASSERT(retval == BAILOUT_RETURN_OK ||
retval == BAILOUT_RETURN_FATAL_ERROR ||
retval == BAILOUT_RETURN_OVERRECURSED);
MOZ_ASSERT_IF(retval == BAILOUT_RETURN_OK, *bailoutInfo != nullptr);
if (retval != BAILOUT_RETURN_OK) {
// If the bailout failed, then bailout trampoline will pop the
// current frame and jump straight to exception handling code when
@@ -134,32 +86,31 @@ jit::InvalidationBailout(InvalidationBai
JSContext *cx = GetJSContextFromJitCode();
// We don't have an exit frame.
cx->mainThread().jitTop = FAKE_JIT_TOP_FOR_BAILOUT;
gc::AutoSuppressGC suppress(cx);
JitActivationIterator jitActivations(cx->runtime());
- IonBailoutIterator iter(jitActivations, sp);
- JitActivation *activation = jitActivations->asJit();
- JitActivation::RegisterBailoutIterator registerIterator(*activation, &iter);
+ BailoutFrameInfo bailoutData(jitActivations, sp);
+ JitFrameIterator iter(jitActivations);
TraceLogger *logger = TraceLoggerForMainThread(cx->runtime());
TraceLogTimestamp(logger, TraceLogger::Invalidation);
JitSpew(JitSpew_IonBailouts, "Took invalidation bailout! Snapshot offset: %d", iter.snapshotOffset());
// Note: the frame size must be computed before we return from this function.
- *frameSizeOut = iter.topFrameSize();
+ *frameSizeOut = iter.frameSize();
MOZ_ASSERT(IsBaselineEnabled(cx));
*bailoutInfo = nullptr;
- uint32_t retval = BailoutIonToBaseline(cx, activation, iter, true, bailoutInfo);
+ uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true, bailoutInfo);
MOZ_ASSERT(retval == BAILOUT_RETURN_OK ||
retval == BAILOUT_RETURN_FATAL_ERROR ||
retval == BAILOUT_RETURN_OVERRECURSED);
MOZ_ASSERT_IF(retval == BAILOUT_RETURN_OK, *bailoutInfo != nullptr);
if (retval != BAILOUT_RETURN_OK) {
// If the bailout failed, then bailout trampoline will pop the
// current frame and jump straight to exception handling code when
@@ -192,29 +143,26 @@ jit::InvalidationBailout(InvalidationBai
JitSpew(JitSpew_IonInvalidate, " new ra %p", (void *) frame->returnAddress());
}
iter.ionScript()->decref(cx->runtime()->defaultFreeOp());
return retval;
}
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
- const JitFrameIterator &frame)
- : JitFrameIterator(activations),
- machine_(frame.machineState())
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations,
+ const JitFrameIterator &frame)
+ : machine_(frame.machineState())
{
- kind_ = Kind_BailoutIterator;
- returnAddressToFp_ = frame.returnAddressToFp();
+ framePointer_ = (uint8_t *) frame.fp();
+ topFrameSize_ = frame.frameSize();
topIonScript_ = frame.ionScript();
+ attachOnJitActivation(activations);
+
const OsiIndex *osiIndex = frame.osiIndex();
-
- current_ = (uint8_t *) frame.fp();
- type_ = JitFrame_IonJS;
- topFrameSize_ = frame.frameSize();
snapshotOffset_ = osiIndex->snapshotOffset();
}
uint32_t
jit::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame,
ResumeFromException *rfe,
const ExceptionBailoutInfo &excInfo,
bool *overrecursed)
@@ -223,22 +171,21 @@ jit::ExceptionHandlerBailout(JSContext *
// actual exception pending. For instance, when we return false from an
// operation callback like a timeout handler.
MOZ_ASSERT_IF(!excInfo.propagatingIonExceptionForDebugMode(), cx->isExceptionPending());
cx->mainThread().jitTop = FAKE_JIT_TOP_FOR_BAILOUT;
gc::AutoSuppressGC suppress(cx);
JitActivationIterator jitActivations(cx->runtime());
- IonBailoutIterator iter(jitActivations, frame.frame());
- JitActivation *activation = jitActivations->asJit();
- JitActivation::RegisterBailoutIterator registerIterator(*activation, &iter);
+ BailoutFrameInfo bailoutData(jitActivations, frame.frame());
+ JitFrameIterator iter(jitActivations);
BaselineBailoutInfo *bailoutInfo = nullptr;
- uint32_t retval = BailoutIonToBaseline(cx, activation, iter, true, &bailoutInfo, &excInfo);
+ uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true, &bailoutInfo, &excInfo);
if (retval == BAILOUT_RETURN_OK) {
MOZ_ASSERT(bailoutInfo);
// Overwrite the kind so HandleException after the bailout returns
// false, jumping directly to the exception tail.
if (excInfo.propagatingIonExceptionForDebugMode())
bailoutInfo->bailoutKind = Bailout_IonExceptionDebugMode;
@@ -295,8 +242,21 @@ jit::CheckFrequentBailouts(JSContext *cx
if (!Invalidate(cx, script))
return false;
}
}
return true;
}
+
+void
+BailoutFrameInfo::attachOnJitActivation(const JitActivationIterator &jitActivations)
+{
+ MOZ_ASSERT(jitActivations.jitTop() == FAKE_JIT_TOP_FOR_BAILOUT);
+ activation_ = jitActivations->asJit();
+ activation_->setBailoutData(this);
+}
+
+BailoutFrameInfo::~BailoutFrameInfo()
+{
+ activation_->cleanBailoutData();
+}
--- a/js/src/jit/Bailouts.h
+++ b/js/src/jit/Bailouts.h
@@ -108,54 +108,54 @@ class JitCompartment;
// BailoutStack is an architecture specific pointer to the stack, given by the
// bailout handler.
class BailoutStack;
class InvalidationBailoutStack;
// Must be implemented by each architecture.
-// This iterator is constructed at a time where there is no exit frame at the
-// moment. They must be initialized to the first JS frame instead of the exit
-// frame as usually done with JitFrameIterator.
-class IonBailoutIterator : public JitFrameIterator
+// This structure is constructed before recovering the baseline frames for a
+// bailout. It records all information extracted from the stack, and which are
+// needed for the JitFrameIterator.
+class BailoutFrameInfo
{
MachineState machine_;
- uint32_t snapshotOffset_;
+ uint8_t *framePointer_;
size_t topFrameSize_;
IonScript *topIonScript_;
+ uint32_t snapshotOffset_;
+ JitActivation *activation_;
+
+ void attachOnJitActivation(const JitActivationIterator &activations);
public:
- IonBailoutIterator(const JitActivationIterator &activations, BailoutStack *sp);
- IonBailoutIterator(const JitActivationIterator &activations, InvalidationBailoutStack *sp);
- IonBailoutIterator(const JitActivationIterator &activations, const JitFrameIterator &frame);
+ BailoutFrameInfo(const JitActivationIterator &activations, BailoutStack *sp);
+ BailoutFrameInfo(const JitActivationIterator &activations, InvalidationBailoutStack *sp);
+ BailoutFrameInfo(const JitActivationIterator &activations, const JitFrameIterator &frame);
+ ~BailoutFrameInfo();
+ uint8_t *fp() const {
+ return framePointer_;
+ }
SnapshotOffset snapshotOffset() const {
- if (topIonScript_)
- return snapshotOffset_;
- return osiIndex()->snapshotOffset();
+ return snapshotOffset_;
}
const MachineState machineState() const {
- if (topIonScript_)
- return machine_;
- return JitFrameIterator::machineState();
+ return machine_;
}
size_t topFrameSize() const {
- MOZ_ASSERT(topIonScript_);
return topFrameSize_;
}
IonScript *ionScript() const {
- if (topIonScript_)
- return topIonScript_;
- return JitFrameIterator::ionScript();
+ return topIonScript_;
}
-
- IonBailoutIterator &operator++() MOZ_DELETE;
-
- void dump() const;
+ JitActivation *activation() const {
+ return activation_;
+ }
};
bool EnsureHasScopeObjects(JSContext *cx, AbstractFramePtr fp);
struct BaselineBailoutInfo;
// Called from a bailout thunk. Returns a BAILOUT_* error code.
uint32_t Bailout(BailoutStack *sp, BaselineBailoutInfo **info);
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -69,41 +69,42 @@ class BufferPointer
* needs to be enlarged to accomodate new data. Similarly to the C stack, the
* data that's written to the reconstructed stack grows from high to low in memory.
*
* The lowest region of the allocated memory contains a BaselineBailoutInfo structure that
* points to the start and end of the written data.
*/
struct BaselineStackBuilder
{
- IonBailoutIterator &iter_;
+ JitFrameIterator &iter_;
IonJSFrameLayout *frame_;
static size_t HeaderSize() {
return AlignBytes(sizeof(BaselineBailoutInfo), sizeof(void *));
}
size_t bufferTotal_;
size_t bufferAvail_;
size_t bufferUsed_;
uint8_t *buffer_;
BaselineBailoutInfo *header_;
size_t framePushed_;
- BaselineStackBuilder(IonBailoutIterator &iter, size_t initialSize)
+ BaselineStackBuilder(JitFrameIterator &iter, size_t initialSize)
: iter_(iter),
frame_(static_cast<IonJSFrameLayout*>(iter.current())),
bufferTotal_(initialSize),
bufferAvail_(0),
bufferUsed_(0),
buffer_(nullptr),
header_(nullptr),
framePushed_(0)
{
MOZ_ASSERT(bufferTotal_ >= HeaderSize());
+ MOZ_ASSERT(iter.isBailoutJS());
}
~BaselineStackBuilder() {
js_free(buffer_);
}
bool init() {
MOZ_ASSERT(!buffer_);
@@ -382,20 +383,21 @@ 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
{
RInstructionResults results_;
public:
- SnapshotIteratorForBailout(const IonBailoutIterator &iter)
+ SnapshotIteratorForBailout(const JitFrameIterator &iter)
: SnapshotIterator(iter),
results_(iter.jsFrame())
{
+ MOZ_ASSERT(iter.isBailoutJS());
}
// Take previously computed result out of the activation, or compute the
// results of all recover instructions contained in the snapshot.
bool init(JSContext *cx, JitActivation *activation) {
activation->maybeTakeIonFrameRecovery(fp_, &results_);
if (!results_.isInitialized() && !computeInstructionResults(cx, &results_))
return false;
@@ -1282,17 +1284,17 @@ InitFromBailout(JSContext *cx, HandleScr
MOZ_ASSERT(rectReturnAddr);
if (!builder.writePtr(rectReturnAddr, "ReturnAddr"))
return false;
return true;
}
uint32_t
-jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIterator &iter,
+jit::BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIterator &iter,
bool invalidate, BaselineBailoutInfo **bailoutInfo,
const ExceptionBailoutInfo *excInfo)
{
// The Baseline frames we will reconstruct on the heap are not rooted, so GC
// must be suppressed here.
MOZ_ASSERT(cx->mainThread().suppressGC);
MOZ_ASSERT(bailoutInfo != nullptr);
@@ -1302,17 +1304,17 @@ jit::BailoutIonToBaseline(JSContext *cx,
TraceLogStopEvent(logger, TraceLogger::IonMonkey);
TraceLogStartEvent(logger, TraceLogger::Baseline);
// The caller of the top frame must be one of the following:
// IonJS - Ion calling into Ion.
// BaselineStub - Baseline calling into Ion.
// Entry - Interpreter or other calling into Ion.
// Rectifier - Arguments rectifier calling into Ion.
- MOZ_ASSERT(iter.isIonJS());
+ MOZ_ASSERT(iter.isBailoutJS());
FrameType prevFrameType = iter.prevType();
MOZ_ASSERT(prevFrameType == JitFrame_IonJS ||
prevFrameType == JitFrame_BaselineStub ||
prevFrameType == JitFrame_Entry ||
prevFrameType == JitFrame_Rectifier);
// All incoming frames are going to look like this:
//
--- a/js/src/jit/BaselineJIT.h
+++ b/js/src/jit/BaselineJIT.h
@@ -432,17 +432,17 @@ struct BaselineBailoutInfo
// Number of baseline frames to push on the stack.
uint32_t numFrames;
// The bailout kind.
BailoutKind bailoutKind;
};
uint32_t
-BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIterator &iter,
+BailoutIonToBaseline(JSContext *cx, JitActivation *activation, JitFrameIterator &iter,
bool invalidate, BaselineBailoutInfo **bailoutInfo,
const ExceptionBailoutInfo *exceptionInfo = nullptr);
// Mark baseline scripts on the stack as active, so that they are not discarded
// during GC.
void
MarkActiveBaselineScripts(Zone *zone);
--- a/js/src/jit/IonFrames.cpp
+++ b/js/src/jit/IonFrames.cpp
@@ -81,69 +81,54 @@ ReadFrameBooleanSlot(IonJSFrameLayout *f
}
JitFrameIterator::JitFrameIterator()
: current_(nullptr),
type_(JitFrame_Exit),
returnAddressToFp_(nullptr),
frameSize_(0),
mode_(SequentialExecution),
- kind_(Kind_FrameIterator),
cachedSafepointIndex_(nullptr),
activation_(nullptr)
{
}
JitFrameIterator::JitFrameIterator(ThreadSafeContext *cx)
: current_(cx->perThreadData->jitTop),
type_(JitFrame_Exit),
returnAddressToFp_(nullptr),
frameSize_(0),
mode_(cx->isForkJoinContext() ? ParallelExecution : SequentialExecution),
- kind_(Kind_FrameIterator),
cachedSafepointIndex_(nullptr),
activation_(cx->perThreadData->activation()->asJit())
{
if (activation_->bailoutData()) {
current_ = activation_->bailoutData()->fp();
+ frameSize_ = activation_->bailoutData()->topFrameSize();
type_ = JitFrame_Bailout;
}
}
JitFrameIterator::JitFrameIterator(const ActivationIterator &activations)
: current_(activations.jitTop()),
type_(JitFrame_Exit),
returnAddressToFp_(nullptr),
frameSize_(0),
mode_(activations->asJit()->cx()->isForkJoinContext() ? ParallelExecution
: SequentialExecution),
- kind_(Kind_FrameIterator),
cachedSafepointIndex_(nullptr),
activation_(activations->asJit())
{
if (activation_->bailoutData()) {
current_ = activation_->bailoutData()->fp();
+ frameSize_ = activation_->bailoutData()->topFrameSize();
type_ = JitFrame_Bailout;
}
}
-IonBailoutIterator *
-JitFrameIterator::asBailoutIterator()
-{
- MOZ_ASSERT(isBailoutIterator());
- return static_cast<IonBailoutIterator *>(this);
-}
-
-const IonBailoutIterator *
-JitFrameIterator::asBailoutIterator() const
-{
- MOZ_ASSERT(isBailoutIterator());
- return static_cast<const IonBailoutIterator *>(this);
-}
-
bool
JitFrameIterator::checkInvalidation() const
{
IonScript *dummy;
return checkInvalidation(&dummy);
}
bool
@@ -1933,17 +1918,17 @@ SnapshotIterator::maybeReadAllocByIndex(
return s;
}
IonJSFrameLayout *
JitFrameIterator::jsFrame() const
{
MOZ_ASSERT(isScripted());
if (isBailoutJS())
- return activation_->bailoutData()->jsFrame();
+ return (IonJSFrameLayout *) activation_->bailoutData()->fp();
return (IonJSFrameLayout *) fp();
}
IonScript *
JitFrameIterator::ionScript() const
{
MOZ_ASSERT(isIonScripted());
@@ -2007,41 +1992,25 @@ InlineFrameIterator::InlineFrameIterator
InlineFrameIterator::InlineFrameIterator(JSRuntime *rt, const JitFrameIterator *iter)
: callee_(rt),
script_(rt)
{
resetOn(iter);
}
-InlineFrameIterator::InlineFrameIterator(ThreadSafeContext *cx, const IonBailoutIterator *iter)
- : frame_(iter),
- framesRead_(0),
- frameCount_(UINT32_MAX),
- callee_(cx),
- script_(cx)
-{
- if (iter) {
- start_ = SnapshotIterator(*iter);
- findNextFrame();
- }
-}
-
InlineFrameIterator::InlineFrameIterator(ThreadSafeContext *cx, const InlineFrameIterator *iter)
: frame_(iter ? iter->frame_ : nullptr),
framesRead_(0),
frameCount_(iter ? iter->frameCount_ : UINT32_MAX),
callee_(cx),
script_(cx)
{
if (frame_) {
- if (frame_->isBailoutIterator())
- start_ = SnapshotIterator(*frame_->asBailoutIterator());
- else
- start_ = SnapshotIterator(*frame_);
+ start_ = SnapshotIterator(*frame_);
// findNextFrame will iterate to the next frame and init. everything.
// Therefore to settle on the same frame, we report one frame less readed.
framesRead_ = iter->framesRead_ - 1;
findNextFrame();
}
}
--- a/js/src/jit/JitFrameIterator.h
+++ b/js/src/jit/JitFrameIterator.h
@@ -75,52 +75,41 @@ enum ReadFrameArgsBehavior {
// Read all args (i.e. [0 ... numActuals()])
ReadFrame_Actuals
};
class IonCommonFrameLayout;
class IonJSFrameLayout;
class IonExitFrameLayout;
-class IonBailoutIterator;
class BaselineFrame;
class JitActivation;
class JitFrameIterator
{
protected:
uint8_t *current_;
FrameType type_;
uint8_t *returnAddressToFp_;
size_t frameSize_;
ExecutionMode mode_;
- enum Kind {
- Kind_FrameIterator,
- Kind_BailoutIterator
- } kind_;
private:
mutable const SafepointIndex *cachedSafepointIndex_;
const JitActivation *activation_;
void dumpBaseline() const;
public:
explicit JitFrameIterator();
explicit JitFrameIterator(ThreadSafeContext *cx);
explicit JitFrameIterator(const ActivationIterator &activations);
- bool isBailoutIterator() const {
- return kind_ == Kind_BailoutIterator;
- }
- IonBailoutIterator *asBailoutIterator();
- const IonBailoutIterator *asBailoutIterator() const;
-
// Current frame information.
FrameType type() const {
return type_;
}
uint8_t *fp() const {
return current_;
}
const JitActivation *activation() const {
@@ -475,17 +464,16 @@ class SnapshotIterator
public:
// Connect all informations about the current script in order to recover the
// content of baseline frames.
SnapshotIterator(IonScript *ionScript, SnapshotOffset snapshotOffset,
IonJSFrameLayout *fp, const MachineState &machine);
explicit SnapshotIterator(const JitFrameIterator &iter);
- explicit SnapshotIterator(const IonBailoutIterator &iter);
SnapshotIterator();
Value read() {
return allocationValue(readAllocation());
}
Value maybeRead(MaybeReadFallback &fallback) {
RValueAllocation a = readAllocation();
@@ -590,17 +578,16 @@ class InlineFrameIterator
private:
void findNextFrame();
JSObject *computeScopeChain(Value scopeChainValue) const;
public:
InlineFrameIterator(ThreadSafeContext *cx, const JitFrameIterator *iter);
InlineFrameIterator(JSRuntime *rt, const JitFrameIterator *iter);
- InlineFrameIterator(ThreadSafeContext *cx, const IonBailoutIterator *iter);
InlineFrameIterator(ThreadSafeContext *cx, const InlineFrameIterator *iter);
bool more() const {
return frame_ && framesRead_ < frameCount_;
}
JSFunction *callee() const {
MOZ_ASSERT(callee_);
return callee_;
--- a/js/src/jit/ParallelFunctions.cpp
+++ b/js/src/jit/ParallelFunctions.cpp
@@ -539,18 +539,17 @@ jit::BailoutPar(BailoutStack *sp, uint8_
// We don't have an exit frame.
MOZ_ASSERT(IsInRange(FAKE_JIT_TOP_FOR_BAILOUT, 0, 0x1000) &&
IsInRange(FAKE_JIT_TOP_FOR_BAILOUT + sizeof(IonCommonFrameLayout), 0, 0x1000),
"Fake jitTop pointer should be within the first page.");
cx->perThreadData->jitTop = FAKE_JIT_TOP_FOR_BAILOUT;
JitActivationIterator jitActivations(cx->perThreadData);
- IonBailoutIterator bailoutData(jitActivations, sp);
- JitActivation::RegisterBailoutIterator registerIterator(*jitActivations->asJit(), &bailoutData);
+ BailoutFrameInfo bailoutData(jitActivations, sp);
JitFrameIterator frameIter(jitActivations);
SnapshotIterator snapIter(frameIter);
cx->bailoutRecord->setIonBailoutKind(snapIter.bailoutKind());
cx->bailoutRecord->rematerializeFrames(cx, frameIter);
MOZ_ASSERT(frameIter.done());
*entryFramePointer = frameIter.fp();
--- a/js/src/jit/arm/Bailouts-arm.cpp
+++ b/js/src/jit/arm/Bailouts-arm.cpp
@@ -64,63 +64,59 @@ class BailoutStack
};
// Make sure the compiler doesn't add extra padding.
static_assert((sizeof(BailoutStack) % 8) == 0, "BailoutStack should be 8-byte aligned.");
} // namespace jit
} // namespace js
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
- BailoutStack *bailout)
- : JitFrameIterator(activations),
- machine_(bailout->machine())
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations,
+ BailoutStack *bailout)
+ : machine_(bailout->machine())
{
uint8_t *sp = bailout->parentStackPointer();
- uint8_t *fp = sp + bailout->frameSize();
+ framePointer_ = sp + bailout->frameSize();
+ topFrameSize_ = framePointer_ - sp;
- kind_ = Kind_BailoutIterator;
- current_ = fp;
- type_ = JitFrame_IonJS;
- topFrameSize_ = current_ - sp;
- switch (mode_) {
- case SequentialExecution: topIonScript_ = script()->ionScript(); break;
- case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
- default: MOZ_CRASH("No such execution mode");
- }
+ JSScript *script = ScriptFromCalleeToken(((IonJSFrameLayout *) framePointer_)->calleeToken());
+ JitActivation *activation = activations.activation()->asJit();
+ if (activation->cx()->isForkJoinContext())
+ topIonScript_ = script->parallelIonScript();
+ else
+ topIonScript_ = script->ionScript();
+
+ attachOnJitActivation(activations);
if (bailout->frameClass() == FrameSizeClass::None()) {
snapshotOffset_ = bailout->snapshotOffset();
return;
}
// Compute the snapshot offset from the bailout ID.
- JitActivation *activation = activations.activation()->asJit();
JSRuntime *rt = activation->compartment()->runtimeFromMainThread();
JitCode *code = rt->jitRuntime()->getBailoutTable(bailout->frameClass());
uintptr_t tableOffset = bailout->tableOffset();
uintptr_t tableStart = reinterpret_cast<uintptr_t>(Assembler::BailoutTableStart(code->raw()));
MOZ_ASSERT(tableOffset >= tableStart &&
tableOffset < tableStart + code->instructionsSize());
MOZ_ASSERT((tableOffset - tableStart) % BAILOUT_TABLE_ENTRY_SIZE == 0);
uint32_t bailoutId = ((tableOffset - tableStart) / BAILOUT_TABLE_ENTRY_SIZE) - 1;
MOZ_ASSERT(bailoutId < BAILOUT_TABLE_SIZE);
snapshotOffset_ = topIonScript_->bailoutToSnapshot(bailoutId);
}
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
- InvalidationBailoutStack *bailout)
- : JitFrameIterator(activations),
- machine_(bailout->machine())
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations,
+ InvalidationBailoutStack *bailout)
+ : machine_(bailout->machine())
{
- kind_ = Kind_BailoutIterator;
- returnAddressToFp_ = bailout->osiPointReturnAddress();
+ framePointer_ = (uint8_t*) bailout->fp();
+ topFrameSize_ = framePointer_ - bailout->sp();
topIonScript_ = bailout->ionScript();
+ attachOnJitActivation(activations);
+
+ uint8_t *returnAddressToFp_ = bailout->osiPointReturnAddress();
const OsiIndex *osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_);
-
- current_ = (uint8_t*) bailout->fp();
- type_ = JitFrame_IonJS;
- topFrameSize_ = current_ - bailout->sp();
snapshotOffset_ = osiIndex->snapshotOffset();
}
--- a/js/src/jit/mips/Bailouts-mips.cpp
+++ b/js/src/jit/mips/Bailouts-mips.cpp
@@ -7,63 +7,59 @@
#include "jit/mips/Bailouts-mips.h"
#include "jscntxt.h"
#include "jscompartment.h"
using namespace js;
using namespace js::jit;
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
- BailoutStack *bailout)
- : JitFrameIterator(activations),
- machine_(bailout->machine())
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations,
+ BailoutStack *bailout)
+ : machine_(bailout->machine())
{
uint8_t *sp = bailout->parentStackPointer();
- uint8_t *fp = sp + bailout->frameSize();
+ framePointer_ = sp + bailout->frameSize();
+ topFrameSize_ = framePointer_ - sp;
- kind_ = Kind_BailoutIterator;
- current_ = fp;
- type_ = JitFrame_IonJS;
- topFrameSize_ = current_ - sp;
- switch (mode_) {
- case SequentialExecution: topIonScript_ = script()->ionScript(); break;
- case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
- default: MOZ_CRASH("No such execution mode");
- }
+ JSScript *script = ScriptFromCalleeToken(((IonJSFrameLayout *) framePointer_)->calleeToken());
+ JitActivation *activation = activations.activation()->asJit();
+ if (activation->cx()->isForkJoinContext())
+ topIonScript_ = script->parallelIonScript();
+ else
+ topIonScript_ = script->ionScript();
+
+ attachOnJitActivation(activations);
if (bailout->frameClass() == FrameSizeClass::None()) {
snapshotOffset_ = bailout->snapshotOffset();
return;
}
// Compute the snapshot offset from the bailout ID.
- JitActivation *activation = activations.activation()->asJit();
JSRuntime *rt = activation->compartment()->runtimeFromMainThread();
JitCode *code = rt->jitRuntime()->getBailoutTable(bailout->frameClass());
uintptr_t tableOffset = bailout->tableOffset();
uintptr_t tableStart = reinterpret_cast<uintptr_t>(code->raw());
MOZ_ASSERT(tableOffset >= tableStart &&
- tableOffset < tableStart + code->instructionsSize());
+ tableOffset < tableStart + code->instructionsSize());
MOZ_ASSERT((tableOffset - tableStart) % BAILOUT_TABLE_ENTRY_SIZE == 0);
uint32_t bailoutId = ((tableOffset - tableStart) / BAILOUT_TABLE_ENTRY_SIZE) - 1;
MOZ_ASSERT(bailoutId < BAILOUT_TABLE_SIZE);
snapshotOffset_ = topIonScript_->bailoutToSnapshot(bailoutId);
}
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
- InvalidationBailoutStack *bailout)
- : JitFrameIterator(activations),
- machine_(bailout->machine())
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations,
+ InvalidationBailoutStack *bailout)
+ : machine_(bailout->machine())
{
- kind_ = Kind_BailoutIterator;
- returnAddressToFp_ = bailout->osiPointReturnAddress();
+ framePointer_ = (uint8_t*) bailout->fp();
+ topFrameSize_ = framePointer_ - bailout->sp();
topIonScript_ = bailout->ionScript();
+ attachOnJitActivation(activations);
+
+ uint8_t *returnAddressToFp_ = bailout->osiPointReturnAddress();
const OsiIndex *osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_);
-
- current_ = (uint8_t*) bailout->fp();
- type_ = JitFrame_IonJS;
- topFrameSize_ = current_ - bailout->sp();
snapshotOffset_ = osiIndex->snapshotOffset();
}
--- a/js/src/jit/none/Trampoline-none.cpp
+++ b/js/src/jit/none/Trampoline-none.cpp
@@ -42,24 +42,22 @@ void MacroAssembler::alignFrameForICArgu
void MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive &) { MOZ_CRASH(); }
const Register ABIArgGenerator::NonArgReturnReg0 = { 0 };
const Register ABIArgGenerator::NonArgReturnReg1 = { 0 };
const Register ABIArgGenerator::NonArg_VolatileReg = { 0 };
const Register ABIArgGenerator::NonReturn_VolatileReg0 = { 0 };
const Register ABIArgGenerator::NonReturn_VolatileReg1 = { 0 };
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &iter, BailoutStack *bailout)
- : JitFrameIterator(iter)
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &iter, BailoutStack *bailout)
{
MOZ_CRASH();
}
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &iter, InvalidationBailoutStack *bailout)
- : JitFrameIterator(iter)
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &iter, InvalidationBailoutStack *bailout)
{
MOZ_CRASH();
}
bool ICCompare_Int32::Compiler::generateStubCode(MacroAssembler &) { MOZ_CRASH(); }
bool ICCompare_Double::Compiler::generateStubCode(MacroAssembler &) { MOZ_CRASH(); }
bool ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler &) { MOZ_CRASH(); }
bool ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler &) { MOZ_CRASH(); }
--- a/js/src/jit/x64/Bailouts-x64.cpp
+++ b/js/src/jit/x64/Bailouts-x64.cpp
@@ -40,43 +40,40 @@ class BailoutStack
} // namespace jit
} // namespace js
#if defined(_WIN32)
# pragma pack(pop)
#endif
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
- BailoutStack *bailout)
- : JitFrameIterator(activations),
- machine_(bailout->machineState())
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations,
+ BailoutStack *bailout)
+ : machine_(bailout->machineState())
{
uint8_t *sp = bailout->parentStackPointer();
- uint8_t *fp = sp + bailout->frameSize();
+ framePointer_ = sp + bailout->frameSize();
+ topFrameSize_ = framePointer_ - sp;
- kind_ = Kind_BailoutIterator;
- current_ = fp;
- type_ = JitFrame_IonJS;
- topFrameSize_ = current_ - sp;
- switch (mode_) {
- case SequentialExecution: topIonScript_ = script()->ionScript(); break;
- case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
- default: MOZ_CRASH("No such execution mode");
- }
+ JSScript *script = ScriptFromCalleeToken(((IonJSFrameLayout *) framePointer_)->calleeToken());
+ JitActivation *activation = activations.activation()->asJit();
+ if (activation->cx()->isForkJoinContext())
+ topIonScript_ = script->parallelIonScript();
+ else
+ topIonScript_ = script->ionScript();
+
+ attachOnJitActivation(activations);
snapshotOffset_ = bailout->snapshotOffset();
}
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
- InvalidationBailoutStack *bailout)
- : JitFrameIterator(activations),
- machine_(bailout->machine())
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations,
+ InvalidationBailoutStack *bailout)
+ : machine_(bailout->machine())
{
- kind_ = Kind_BailoutIterator;
- returnAddressToFp_ = bailout->osiPointReturnAddress();
+ framePointer_ = (uint8_t*) bailout->fp();
+ topFrameSize_ = framePointer_ - bailout->sp();
topIonScript_ = bailout->ionScript();
+ attachOnJitActivation(activations);
+
+ uint8_t *returnAddressToFp_ = bailout->osiPointReturnAddress();
const OsiIndex *osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_);
-
- current_ = (uint8_t*) bailout->fp();
- type_ = JitFrame_IonJS;
- topFrameSize_ = current_ - bailout->sp();
snapshotOffset_ = osiIndex->snapshotOffset();
}
--- a/js/src/jit/x86/Bailouts-x86.cpp
+++ b/js/src/jit/x86/Bailouts-x86.cpp
@@ -60,63 +60,59 @@ class BailoutStack
} // namespace jit
} // namespace js
#if defined(_WIN32)
# pragma pack(pop)
#endif
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
- BailoutStack *bailout)
- : JitFrameIterator(activations),
- machine_(bailout->machine())
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations,
+ BailoutStack *bailout)
+ : machine_(bailout->machine())
{
uint8_t *sp = bailout->parentStackPointer();
- uint8_t *fp = sp + bailout->frameSize();
+ framePointer_ = sp + bailout->frameSize();
+ topFrameSize_ = framePointer_ - sp;
- kind_ = Kind_BailoutIterator;
- current_ = fp;
- type_ = JitFrame_IonJS;
- topFrameSize_ = current_ - sp;
- switch (mode_) {
- case SequentialExecution: topIonScript_ = script()->ionScript(); break;
- case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
- default: MOZ_CRASH("No such execution mode");
- }
+ JSScript *script = ScriptFromCalleeToken(((IonJSFrameLayout *) framePointer_)->calleeToken());
+ JitActivation *activation = activations.activation()->asJit();
+ if (activation->cx()->isForkJoinContext())
+ topIonScript_ = script->parallelIonScript();
+ else
+ topIonScript_ = script->ionScript();
+
+ attachOnJitActivation(activations);
if (bailout->frameClass() == FrameSizeClass::None()) {
snapshotOffset_ = bailout->snapshotOffset();
return;
}
// Compute the snapshot offset from the bailout ID.
- JitActivation *activation = activations.activation()->asJit();
JSRuntime *rt = activation->compartment()->runtimeFromMainThread();
JitCode *code = rt->jitRuntime()->getBailoutTable(bailout->frameClass());
uintptr_t tableOffset = bailout->tableOffset();
uintptr_t tableStart = reinterpret_cast<uintptr_t>(code->raw());
MOZ_ASSERT(tableOffset >= tableStart &&
tableOffset < tableStart + code->instructionsSize());
MOZ_ASSERT((tableOffset - tableStart) % BAILOUT_TABLE_ENTRY_SIZE == 0);
uint32_t bailoutId = ((tableOffset - tableStart) / BAILOUT_TABLE_ENTRY_SIZE) - 1;
MOZ_ASSERT(bailoutId < BAILOUT_TABLE_SIZE);
snapshotOffset_ = topIonScript_->bailoutToSnapshot(bailoutId);
}
-IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
- InvalidationBailoutStack *bailout)
- : JitFrameIterator(activations),
- machine_(bailout->machine())
+BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations,
+ InvalidationBailoutStack *bailout)
+ : machine_(bailout->machine())
{
- kind_ = Kind_BailoutIterator;
- returnAddressToFp_ = bailout->osiPointReturnAddress();
+ framePointer_ = (uint8_t*) bailout->fp();
+ topFrameSize_ = framePointer_ - bailout->sp();
topIonScript_ = bailout->ionScript();
+ attachOnJitActivation(activations);
+
+ uint8_t *returnAddressToFp_ = bailout->osiPointReturnAddress();
const OsiIndex *osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_);
-
- current_ = (uint8_t*) bailout->fp();
- type_ = JitFrame_IonJS;
- topFrameSize_ = current_ - bailout->sp();
snapshotOffset_ = osiIndex->snapshotOffset();
}
--- a/js/src/vm/ForkJoin.h
+++ b/js/src/vm/ForkJoin.h
@@ -321,17 +321,16 @@ enum ParallelBailoutCause {
// parallel.
ParallelBailoutRequestedGC,
ParallelBailoutRequestedZoneGC
};
namespace jit {
class BailoutStack;
class JitFrameIterator;
-class IonBailoutIterator;
class RematerializedFrame;
}
// See "Bailouts" section in comment above.
struct ParallelBailoutRecord
{
// Captured Ion frames at the point of bailout. Stored younger-to-older,
// i.e., the 0th frame is the youngest frame.
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -1400,70 +1400,70 @@ js::CheckLocalUnaliased(MaybeCheckAliasi
}
#endif
jit::JitActivation::JitActivation(JSContext *cx, bool active)
: Activation(cx, Jit),
active_(active),
rematerializedFrames_(nullptr),
ionRecovery_(cx),
- ionBailoutIterator_(nullptr)
+ bailoutData_(nullptr)
{
if (active) {
prevJitTop_ = cx->mainThread().jitTop;
prevJitJSContext_ = cx->mainThread().jitJSContext;
cx->mainThread().jitJSContext = cx;
} else {
prevJitTop_ = nullptr;
prevJitJSContext_ = nullptr;
}
}
jit::JitActivation::JitActivation(ForkJoinContext *cx)
: Activation(cx, Jit),
active_(true),
rematerializedFrames_(nullptr),
ionRecovery_(cx),
- ionBailoutIterator_(nullptr)
+ bailoutData_(nullptr)
{
prevJitTop_ = cx->perThreadData->jitTop;
prevJitJSContext_ = cx->perThreadData->jitJSContext;
cx->perThreadData->jitJSContext = nullptr;
}
jit::JitActivation::~JitActivation()
{
if (active_) {
cx_->perThreadData->jitTop = prevJitTop_;
cx_->perThreadData->jitJSContext = prevJitJSContext_;
}
// All reocvered value are taken from activation during the bailout.
MOZ_ASSERT(ionRecovery_.empty());
- // The Ion Bailout Iterator should have unregistered itself from the
+ // The BailoutFrameInfo should have unregistered itself from the
// JitActivations.
- MOZ_ASSERT(!ionBailoutIterator_);
+ MOZ_ASSERT(!bailoutData_);
clearRematerializedFrames();
js_delete(rematerializedFrames_);
}
-jit::JitActivation::RegisterBailoutIterator::RegisterBailoutIterator(JitActivation &activation,
- IonBailoutIterator *iter)
- : activation_(activation)
+void
+jit::JitActivation::setBailoutData(jit::BailoutFrameInfo *bailoutData)
{
- MOZ_ASSERT(!activation_.ionBailoutIterator_);
- activation_.ionBailoutIterator_ = iter;
+ MOZ_ASSERT(!bailoutData_);
+ bailoutData_ = bailoutData;
}
-jit::JitActivation::RegisterBailoutIterator::~RegisterBailoutIterator()
+void
+jit::JitActivation::cleanBailoutData()
{
- MOZ_ASSERT(activation_.ionBailoutIterator_);
- activation_.ionBailoutIterator_ = nullptr;
+ MOZ_ASSERT(bailoutData_);
+ bailoutData_ = 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.
void
jit::JitActivation::setActive(JSContext *cx, bool active)
{
@@ -1502,19 +1502,18 @@ jit::JitActivation::clearRematerializedF
return;
for (RematerializedFrameTable::Enum e(*rematerializedFrames_); !e.empty(); e.popFront()) {
RematerializedFrame::FreeInVector(e.front().value());
e.removeFront();
}
}
-template <class T>
jit::RematerializedFrame *
-jit::JitActivation::getRematerializedFrame(ThreadSafeContext *cx, const T &iter, size_t inlineDepth)
+jit::JitActivation::getRematerializedFrame(ThreadSafeContext *cx, const JitFrameIterator &iter, size_t inlineDepth)
{
// Only allow rematerializing from the same thread.
MOZ_ASSERT(cx->perThreadData == cx_->perThreadData);
MOZ_ASSERT(iter.activation() == this);
MOZ_ASSERT(iter.isIonScripted());
if (!rematerializedFrames_) {
rematerializedFrames_ = cx->new_<RematerializedFrameTable>(cx);
@@ -1539,25 +1538,16 @@ jit::JitActivation::getRematerializedFra
InlineFrameIterator inlineIter(cx, &iter);
if (!RematerializedFrame::RematerializeInlineFrames(cx, top, inlineIter, p->value()))
return nullptr;
}
return p->value()[inlineDepth];
}
-template jit::RematerializedFrame *
-jit::JitActivation::getRematerializedFrame<jit::JitFrameIterator>(ThreadSafeContext *cx,
- const jit::JitFrameIterator &iter,
- size_t inlineDepth);
-template jit::RematerializedFrame *
-jit::JitActivation::getRematerializedFrame<jit::IonBailoutIterator>(ThreadSafeContext *cx,
- const jit::IonBailoutIterator &iter,
- size_t inlineDepth);
-
jit::RematerializedFrame *
jit::JitActivation::lookupRematerializedFrame(uint8_t *top, size_t inlineDepth)
{
if (!rematerializedFrames_)
return nullptr;
if (RematerializedFrameTable::Ptr p = rematerializedFrames_->lookup(top))
return inlineDepth < p->value().length() ? p->value()[inlineDepth] : nullptr;
return nullptr;
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -1296,16 +1296,18 @@ class ActivationIterator
}
bool done() const {
return activation_ == nullptr;
}
};
namespace jit {
+class BailoutFrameInfo;
+
// A JitActivation is used for frames running in Baseline or Ion.
class JitActivation : public Activation
{
uint8_t *prevJitTop_;
JSContext *prevJitJSContext_;
bool active_;
// Rematerialized Ion frames which has info copied out of snapshots. Maps
@@ -1323,19 +1325,21 @@ class JitActivation : public Activation
// RInstructionResults are appended into this vector when Snapshot values
// have to be read, or when the evaluation has to run before some mutating
// code. Each RInstructionResults belongs to one frame which has to bailout
// as soon as we get back to it.
typedef Vector<RInstructionResults, 1> 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_;
+ // pointer which references the BailoutFrameInfo used to walk the inner
+ // frames. This field is used for all newly constructed JitFrameIterators to
+ // read the innermost frame information from this bailout data instead of
+ // reading it from the stack.
+ BailoutFrameInfo *bailoutData_;
void clearRematerializedFrames();
#ifdef CHECK_OSIPOINT_REGISTERS
protected:
// Used to verify that live registers don't change between a VM call and
// the OsiPoint that follows it. Protected to silence Clang warning.
uint32_t checkRegs_;
@@ -1382,21 +1386,18 @@ class JitActivation : public Activation
}
#endif
// Look up a rematerialized frame keyed by the fp, rematerializing the
// frame if one doesn't already exist. A frame can only be rematerialized
// if an IonFrameIterator pointing to the nearest uninlined frame can be
// provided, as values need to be read out of snapshots.
//
- // T is either JitFrameIterator or IonBailoutIterator.
- //
// The inlineDepth must be within bounds of the frame pointed to by iter.
- template <class T>
- RematerializedFrame *getRematerializedFrame(ThreadSafeContext *cx, const T &iter,
+ RematerializedFrame *getRematerializedFrame(ThreadSafeContext *cx, const JitFrameIterator &iter,
size_t inlineDepth = 0);
// Look up a rematerialized frame by the fp. If inlineDepth is out of
// bounds of what has been rematerialized, nullptr is returned.
RematerializedFrame *lookupRematerializedFrame(uint8_t *top, size_t inlineDepth = 0);
bool hasRematerializedFrame(uint8_t *top, size_t inlineDepth = 0) {
return !!lookupRematerializedFrame(top, inlineDepth);
@@ -1416,27 +1417,24 @@ class JitActivation : public Activation
// If an Ion frame recovery exists for the |fp| frame exists on the
// activation, then move its content to the |results| argument, and remove
// it from the activation.
void maybeTakeIonFrameRecovery(IonJSFrameLayout *fp, RInstructionResults *results);
void markIonRecovery(JSTracer *trc);
- class RegisterBailoutIterator
- {
- JitActivation &activation_;
+ // Return the bailout information if it is registered.
+ const BailoutFrameInfo *bailoutData() const { return bailoutData_; }
- public:
- RegisterBailoutIterator(JitActivation &activation, IonBailoutIterator *iter);
- ~RegisterBailoutIterator();
- };
+ // Register the bailout data when it is constructed.
+ void setBailoutData(BailoutFrameInfo *bailoutData);
- // Return the bailout information if it is registered.
- const IonBailoutIterator *bailoutData() const { return ionBailoutIterator_; }
+ // Unregister the bailout data when the frame is reconstructed.
+ void cleanBailoutData();
};
// A filtering of the ActivationIterator to only stop at JitActivations.
class JitActivationIterator : public ActivationIterator
{
void settle() {
while (!done() && !activation_->isJit())
ActivationIterator::operator++();