/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "mozilla/ScopeExit.h"
#include "mozilla/SizePrintfMacros.h"

#include "jsprf.h"
#include "jsutil.h"
#include "jit/arm/Simulator-arm.h"
#include "jit/BaselineIC.h"
#include "jit/BaselineJIT.h"
#include "jit/CompileInfo.h"
#include "jit/JitSpewer.h"
#include "jit/mips32/Simulator-mips32.h"
#include "jit/mips64/Simulator-mips64.h"
#include "jit/Recover.h"
#include "jit/RematerializedFrame.h"

#include "vm/ArgumentsObject.h"
#include "vm/Debugger.h"
#include "vm/TraceLogging.h"

#include "jsscriptinlines.h"

#include "jit/JitFrames-inl.h"

using namespace js;
using namespace js::jit;

// BaselineStackBuilder may reallocate its buffer if the current one is too
// small. To avoid dangling pointers, BufferPointer represents a pointer into
// this buffer as a pointer to the header and a fixed offset.
template <typename T>
class BufferPointer
{
    BaselineBailoutInfo** header_;
    size_t offset_;
    bool heap_;

  public:
    BufferPointer(BaselineBailoutInfo** header, size_t offset, bool heap)
      : header_(header), offset_(offset), heap_(heap)
    { }

    T* get() const {
        BaselineBailoutInfo* header = *header_;
        if (!heap_)
            return (T*)(header->incomingStack + offset_);

        uint8_t* p = header->copyStackTop - offset_;
        MOZ_ASSERT(p >= header->copyStackBottom && p < header->copyStackTop);
        return (T*)p;
    }

    T& operator*() const { return *get(); }
    T* operator->() const { return get(); }
};

/**
 * BaselineStackBuilder helps abstract the process of rebuilding the C stack on the heap.
 * It takes a bailout iterator and keeps track of the point on the C stack from which
 * the reconstructed frames will be written.
 *
 * It exposes methods to write data into the heap memory storing the reconstructed
 * stack.  It also exposes method to easily calculate addresses.  This includes both the
 * virtual address that a particular value will be at when it's eventually copied onto
 * the stack, as well as the current actual address of that value (whether on the heap
 * allocated portion being constructed or the existing stack).
 *
 * The abstraction handles transparent re-allocation of the heap memory when it
 * needs to be enlarged to accommodate 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
{
    JitFrameIterator& iter_;
    JitFrameLayout* 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(JitFrameIterator& iter, size_t initialSize)
      : iter_(iter),
        frame_(static_cast<JitFrameLayout*>(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_);
        MOZ_ASSERT(bufferUsed_ == 0);
        buffer_ = reinterpret_cast<uint8_t*>(js_calloc(bufferTotal_));
        if (!buffer_)
            return false;
        bufferAvail_ = bufferTotal_ - HeaderSize();
        bufferUsed_ = 0;

        header_ = reinterpret_cast<BaselineBailoutInfo*>(buffer_);
        header_->incomingStack = reinterpret_cast<uint8_t*>(frame_);
        header_->copyStackTop = buffer_ + bufferTotal_;
        header_->copyStackBottom = header_->copyStackTop;
        header_->setR0 = 0;
        header_->valueR0 = UndefinedValue();
        header_->setR1 = 0;
        header_->valueR1 = UndefinedValue();
        header_->resumeFramePtr = nullptr;
        header_->resumeAddr = nullptr;
        header_->resumePC = nullptr;
        header_->monitorStub = nullptr;
        header_->numFrames = 0;
        return true;
    }

    bool enlarge() {
        MOZ_ASSERT(buffer_ != nullptr);
        if (bufferTotal_ & mozilla::tl::MulOverflowMask<2>::value)
            return false;
        size_t newSize = bufferTotal_ * 2;
        uint8_t* newBuffer = reinterpret_cast<uint8_t*>(js_calloc(newSize));
        if (!newBuffer)
            return false;
        memcpy((newBuffer + newSize) - bufferUsed_, header_->copyStackBottom, bufferUsed_);
        memcpy(newBuffer, header_, sizeof(BaselineBailoutInfo));
        js_free(buffer_);
        buffer_ = newBuffer;
        bufferTotal_ = newSize;
        bufferAvail_ = newSize - (HeaderSize() + bufferUsed_);

        header_ = reinterpret_cast<BaselineBailoutInfo*>(buffer_);
        header_->copyStackTop = buffer_ + bufferTotal_;
        header_->copyStackBottom = header_->copyStackTop - bufferUsed_;
        return true;
    }

    BaselineBailoutInfo* info() {
        MOZ_ASSERT(header_ == reinterpret_cast<BaselineBailoutInfo*>(buffer_));
        return header_;
    }

    BaselineBailoutInfo* takeBuffer() {
        MOZ_ASSERT(header_ == reinterpret_cast<BaselineBailoutInfo*>(buffer_));
        buffer_ = nullptr;
        return header_;
    }

    void resetFramePushed() {
        framePushed_ = 0;
    }

    size_t framePushed() const {
        return framePushed_;
    }

    bool subtract(size_t size, const char* info = nullptr) {
        // enlarge the buffer if need be.
        while (size > bufferAvail_) {
            if (!enlarge())
                return false;
        }

        // write out element.
        header_->copyStackBottom -= size;
        bufferAvail_ -= size;
        bufferUsed_ += size;
        framePushed_ += size;
        if (info) {
            JitSpew(JitSpew_BaselineBailouts,
                    "      SUB_%03d   %p/%p %-15s",
                    (int) size, header_->copyStackBottom, virtualPointerAtStackOffset(0), info);
        }
        return true;
    }

    template <typename T>
    bool write(const T& t) {
        if (!subtract(sizeof(T)))
            return false;
        memcpy(header_->copyStackBottom, &t, sizeof(T));
        return true;
    }

    template <typename T>
    bool writePtr(T* t, const char* info) {
        if (!write<T*>(t))
            return false;
        if (info)
            JitSpew(JitSpew_BaselineBailouts,
                    "      WRITE_PTR %p/%p %-15s %p",
                    header_->copyStackBottom, virtualPointerAtStackOffset(0), info, t);
        return true;
    }

    bool writeWord(size_t w, const char* info) {
        if (!write<size_t>(w))
            return false;
        if (info) {
            if (sizeof(size_t) == 4) {
                JitSpew(JitSpew_BaselineBailouts,
                        "      WRITE_WRD %p/%p %-15s %08x",
                        header_->copyStackBottom, virtualPointerAtStackOffset(0), info, w);
            } else {
                JitSpew(JitSpew_BaselineBailouts,
                        "      WRITE_WRD %p/%p %-15s %016llx",
                        header_->copyStackBottom, virtualPointerAtStackOffset(0), info, w);
            }
        }
        return true;
    }

    bool writeValue(Value val, const char* info) {
        if (!write<Value>(val))
            return false;
        if (info) {
            JitSpew(JitSpew_BaselineBailouts,
                    "      WRITE_VAL %p/%p %-15s %016llx",
                    header_->copyStackBottom, virtualPointerAtStackOffset(0), info,
                    *((uint64_t*) &val));
        }
        return true;
    }

    bool maybeWritePadding(size_t alignment, size_t after, const char* info) {
        MOZ_ASSERT(framePushed_ % sizeof(Value) == 0);
        MOZ_ASSERT(after % sizeof(Value) == 0);
        size_t offset = ComputeByteAlignment(after, alignment);
        while (framePushed_ % alignment != offset) {
            if (!writeValue(MagicValue(JS_ARG_POISON), info))
                return false;
        }

        return true;
    }

    Value popValue() {
        MOZ_ASSERT(bufferUsed_ >= sizeof(Value));
        MOZ_ASSERT(framePushed_ >= sizeof(Value));
        bufferAvail_ += sizeof(Value);
        bufferUsed_ -= sizeof(Value);
        framePushed_ -= sizeof(Value);
        Value result = *((Value*) header_->copyStackBottom);
        header_->copyStackBottom += sizeof(Value);
        return result;
    }

    void popValueInto(PCMappingSlotInfo::SlotLocation loc) {
        MOZ_ASSERT(PCMappingSlotInfo::ValidSlotLocation(loc));
        switch(loc) {
          case PCMappingSlotInfo::SlotInR0:
            header_->setR0 = 1;
            header_->valueR0 = popValue();
            break;
          case PCMappingSlotInfo::SlotInR1:
            header_->setR1 = 1;
            header_->valueR1 = popValue();
            break;
          default:
            MOZ_ASSERT(loc == PCMappingSlotInfo::SlotIgnore);
            popValue();
            break;
        }
    }

    void setResumeFramePtr(void* resumeFramePtr) {
        header_->resumeFramePtr = resumeFramePtr;
    }

    void setResumeAddr(void* resumeAddr) {
        header_->resumeAddr = resumeAddr;
    }

    void setResumePC(jsbytecode* pc) {
        header_->resumePC = pc;
    }

    void setMonitorStub(ICStub* stub) {
        header_->monitorStub = stub;
    }

    template <typename T>
    BufferPointer<T> pointerAtStackOffset(size_t offset) {
        if (offset < bufferUsed_) {
            // Calculate offset from copyStackTop.
            offset = header_->copyStackTop - (header_->copyStackBottom + offset);
            return BufferPointer<T>(&header_, offset, /* heap = */ true);
        }

        return BufferPointer<T>(&header_, offset - bufferUsed_, /* heap = */ false);
    }

    BufferPointer<Value> valuePointerAtStackOffset(size_t offset) {
        return pointerAtStackOffset<Value>(offset);
    }

    inline uint8_t* virtualPointerAtStackOffset(size_t offset) {
        if (offset < bufferUsed_)
            return reinterpret_cast<uint8_t*>(frame_) - (bufferUsed_ - offset);
        return reinterpret_cast<uint8_t*>(frame_) + (offset - bufferUsed_);
    }

    inline JitFrameLayout* startFrame() {
        return frame_;
    }

    BufferPointer<JitFrameLayout> topFrameAddress() {
        return pointerAtStackOffset<JitFrameLayout>(0);
    }

    //
    // This method should only be called when the builder is in a state where it is
    // starting to construct the stack frame for the next callee.  This means that
    // the lowest value on the constructed stack is the return address for the previous
    // caller frame.
    //
    // This method is used to compute the value of the frame pointer (e.g. ebp on x86)
    // that would have been saved by the baseline jitcode when it was entered.  In some
    // cases, this value can be bogus since we can ensure that the caller would have saved
    // it anyway.
    //
    void* calculatePrevFramePtr() {
        // Get the incoming frame.
        BufferPointer<JitFrameLayout> topFrame = topFrameAddress();
        FrameType type = topFrame->prevType();

        // For IonJS, IonAccessorIC and Entry frames, the "saved" frame pointer
        // in the baseline frame is meaningless, since Ion saves all registers
        // before calling other ion frames, and the entry frame saves all
        // registers too.
        if (type == JitFrame_IonJS || type == JitFrame_Entry || type == JitFrame_IonAccessorIC)
            return nullptr;

        // BaselineStub - Baseline calling into Ion.
        //  PrevFramePtr needs to point to the BaselineStubFrame's saved frame pointer.
        //      STACK_START_ADDR + JitFrameLayout::Size() + PREV_FRAME_SIZE
        //                      - BaselineStubFrameLayout::reverseOffsetOfSavedFramePtr()
        if (type == JitFrame_BaselineStub) {
            size_t offset = JitFrameLayout::Size() + topFrame->prevFrameLocalSize() +
                            BaselineStubFrameLayout::reverseOffsetOfSavedFramePtr();
            return virtualPointerAtStackOffset(offset);
        }

        MOZ_ASSERT(type == JitFrame_Rectifier);
        // Rectifier - behaviour depends on the frame preceding the rectifier frame, and
        // whether the arch is x86 or not.  The x86 rectifier frame saves the frame pointer,
        // so we can calculate it directly.  For other archs, the previous frame pointer
        // is stored on the stack in the frame that precedes the rectifier frame.
        size_t priorOffset = JitFrameLayout::Size() + topFrame->prevFrameLocalSize();
#if defined(JS_CODEGEN_X86)
        // On X86, the FramePointer is pushed as the first value in the Rectifier frame.
        MOZ_ASSERT(BaselineFrameReg == FramePointer);
        priorOffset -= sizeof(void*);
        return virtualPointerAtStackOffset(priorOffset);
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || \
      defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) || \
      defined(JS_CODEGEN_X64)
        // On X64, ARM, ARM64, and MIPS, the frame pointer save location depends on
        // the caller of the rectifier frame.
        BufferPointer<RectifierFrameLayout> priorFrame =
            pointerAtStackOffset<RectifierFrameLayout>(priorOffset);
        FrameType priorType = priorFrame->prevType();
        MOZ_ASSERT(priorType == JitFrame_IonJS || priorType == JitFrame_BaselineStub);

        // If the frame preceding the rectifier is an IonJS frame, then once again
        // the frame pointer does not matter.
        if (priorType == JitFrame_IonJS)
            return nullptr;

        // Otherwise, the frame preceding the rectifier is a BaselineStub frame.
        //  let X = STACK_START_ADDR + JitFrameLayout::Size() + PREV_FRAME_SIZE
        //      X + RectifierFrameLayout::Size()
        //        + ((RectifierFrameLayout*) X)->prevFrameLocalSize()
        //        - BaselineStubFrameLayout::reverseOffsetOfSavedFramePtr()
        size_t extraOffset = RectifierFrameLayout::Size() + priorFrame->prevFrameLocalSize() +
                             BaselineStubFrameLayout::reverseOffsetOfSavedFramePtr();
        return virtualPointerAtStackOffset(priorOffset + extraOffset);
#elif defined(JS_CODEGEN_NONE)
        MOZ_CRASH();
#else
#  error "Bad architecture!"
#endif
    }
};

// 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.
    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)
{
    return icEntry->isCall_Fallback() || icEntry->isGetProp_Fallback() ||
           icEntry->isSetProp_Fallback();
}
#endif

static inline void*
GetStubReturnAddress(JSContext* cx, jsbytecode* pc)
{
    if (IsGetPropPC(pc))
        return cx->compartment()->jitCompartment()->baselineGetPropReturnAddr();
    if (IsSetPropPC(pc))
        return cx->compartment()->jitCompartment()->baselineSetPropReturnAddr();
    // This should be a call op of some kind, now.
    MOZ_ASSERT(IsCallPC(pc));
    return cx->compartment()->jitCompartment()->baselineCallReturnAddr(JSOp(*pc) == JSOP_NEW);
}

static inline jsbytecode*
GetNextNonLoopEntryPc(jsbytecode* pc)
{
    JSOp op = JSOp(*pc);
    if (op == JSOP_GOTO)
        return pc + GET_JUMP_OFFSET(pc);
    if (op == JSOP_LOOPENTRY || op == JSOP_NOP || op == JSOP_LOOPHEAD)
        return GetNextPc(pc);
    return pc;
}

static bool
HasLiveIteratorAtStackDepth(JSScript* script, jsbytecode* pc, uint32_t stackDepth)
{
    if (!script->hasTrynotes())
        return false;

    JSTryNote* tn = script->trynotes()->vector;
    JSTryNote* tnEnd = tn + script->trynotes()->length;
    uint32_t pcOffset = uint32_t(pc - script->main());
    for (; tn != tnEnd; ++tn) {
        if (pcOffset < tn->start)
            continue;
        if (pcOffset >= tn->start + tn->length)
            continue;

        // For-in loops have only the iterator on stack.
        if (tn->kind == JSTRY_FOR_IN && stackDepth == tn->stackDepth)
            return true;

        // For-of loops have both the iterator and the result object on
        // stack. The iterator is below the result object.
        if (tn->kind == JSTRY_FOR_OF && stackDepth == tn->stackDepth - 1)
            return true;
    }

    return false;
}

// For every inline frame, we write out the following data:
//
//                      |      ...      |
//                      +---------------+
//                      |  Descr(???)   |  --- Descr size here is (PREV_FRAME_SIZE)
//                      +---------------+
//                      |  ReturnAddr   |
//             --       +===============+  --- OVERWRITE STARTS HERE  (START_STACK_ADDR)
//             |        | PrevFramePtr  |
//             |    +-> +---------------+
//             |    |   |   Baseline    |
//             |    |   |    Frame      |
//             |    |   +---------------+
//             |    |   |    Fixed0     |
//             |    |   +---------------+
//         +--<     |   |     ...       |
//         |   |    |   +---------------+
//         |   |    |   |    FixedF     |
//         |   |    |   +---------------+
//         |   |    |   |    Stack0     |
//         |   |    |   +---------------+
//         |   |    |   |     ...       |
//         |   |    |   +---------------+
//         |   |    |   |    StackS     |
//         |   --   |   +---------------+  --- IF NOT LAST INLINE FRAME,
//         +------------|  Descr(BLJS)  |  --- CALLING INFO STARTS HERE
//                  |   +---------------+
//                  |   |  ReturnAddr   | <-- return into main jitcode after IC
//             --   |   +===============+
//             |    |   |    StubPtr    |
//             |    |   +---------------+
//             |    +---|   FramePtr    |
//             |        +---------------+  --- The inlined frame might OSR in Ion
//             |        |   Padding?    |  --- Thus the return address should be aligned.
//             |        +---------------+
//         +--<         |     ArgA      |
//         |   |        +---------------+
//         |   |        |     ...       |
//         |   |        +---------------+
//         |   |        |     Arg0      |
//         |   |        +---------------+
//         |   |        |     ThisV     |
//         |   --       +---------------+
//         |            |  ActualArgC   |
//         |            +---------------+
//         |            |  CalleeToken  |
//         |            +---------------+
//         +------------| Descr(BLStub) |
//                      +---------------+
//                      |  ReturnAddr   | <-- return into ICCall_Scripted IC
//             --       +===============+ --- IF CALLEE FORMAL ARGS > ActualArgC
//             |        |   Padding?    |
//             |        +---------------+
//             |        |  UndefinedU   |
//             |        +---------------+
//             |        |     ...       |
//             |        +---------------+
//             |        |  Undefined0   |
//         +--<         +---------------+
//         |   |        |     ArgA      |
//         |   |        +---------------+
//         |   |        |     ...       |
//         |   |        +---------------+
//         |   |        |     Arg0      |
//         |   |        +---------------+
//         |   |        |     ThisV     |
//         |   --       +---------------+
//         |            |  ActualArgC   |
//         |            +---------------+
//         |            |  CalleeToken  |
//         |            +---------------+
//         +------------|  Descr(Rect)  |
//                      +---------------+
//                      |  ReturnAddr   | <-- return into ArgumentsRectifier after call
//                      +===============+
//
static bool
InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC,
                HandleFunction fun, HandleScript script, IonScript* ionScript,
                SnapshotIterator& iter, bool invalidate, BaselineStackBuilder& builder,
                AutoValueVector& startFrameFormals, MutableHandleFunction nextCallee,
                jsbytecode** callPC, 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(script->hasBaselineScript());

    // Are we catching an exception?
    bool catchingException = excInfo && excInfo->catchingException();

    // If we are catching an exception, we are bailing out to a catch or
    // finally block and this is the frame where we will resume. Usually the
    // expression stack should be empty in this case but there can be
    // iterators on the stack.
    uint32_t exprStackSlots;
    if (catchingException)
        exprStackSlots = excInfo->numExprSlots();
    else
        exprStackSlots = iter.numAllocations() - (script->nfixed() + CountArgSlots(script, fun));

    builder.resetFramePushed();

    // Build first baseline frame:
    // +===============+
    // | PrevFramePtr  |
    // +---------------+
    // |   Baseline    |
    // |    Frame      |
    // +---------------+
    // |    Fixed0     |
    // +---------------+
    // |     ...       |
    // +---------------+
    // |    FixedF     |
    // +---------------+
    // |    Stack0     |
    // +---------------+
    // |     ...       |
    // +---------------+
    // |    StackS     |
    // +---------------+  --- IF NOT LAST INLINE FRAME,
    // |  Descr(BLJS)  |  --- CALLING INFO STARTS HERE
    // +---------------+
    // |  ReturnAddr   | <-- return into main jitcode after IC
    // +===============+

    JitSpew(JitSpew_BaselineBailouts, "      Unpacking %s:%d", script->filename(), script->lineno());
    JitSpew(JitSpew_BaselineBailouts, "      [BASELINE-JS FRAME]");

    // Calculate and write the previous frame pointer value.
    // Record the virtual stack offset at this location.  Later on, if we end up
    // writing out a BaselineStub frame for the next callee, we'll need to save the
    // address.
    void* prevFramePtr = builder.calculatePrevFramePtr();
    if (!builder.writePtr(prevFramePtr, "PrevFramePtr"))
        return false;
    prevFramePtr = builder.virtualPointerAtStackOffset(0);

    // Write struct BaselineFrame.
    if (!builder.subtract(BaselineFrame::Size(), "BaselineFrame"))
        return false;
    BufferPointer<BaselineFrame> blFrame = builder.pointerAtStackOffset<BaselineFrame>(0);

    uint32_t flags = 0;

    // If we are bailing to a script whose execution is observed, mark the
    // baseline frame as a debuggee frame. This is to cover the case where we
    // don't rematerialize the Ion frame via the Debugger.
    if (script->isDebuggee())
        flags |= BaselineFrame::DEBUGGEE;

    // Initialize BaselineFrame's scopeChain and argsObj
    JSObject* scopeChain = nullptr;
    Value returnValue;
    ArgumentsObject* argsObj = nullptr;
    BailoutKind bailoutKind = iter.bailoutKind();
    if (bailoutKind == Bailout_ArgumentCheck) {
        // Temporary hack -- skip the (unused) scopeChain, because it could be
        // bogus (we can fail before the scope chain slot is set). Strip the
        // hasScopeChain flag and this will be fixed up later in |FinishBailoutToBaseline|,
        // which calls |EnsureHasScopeObjects|.
        JitSpew(JitSpew_BaselineBailouts, "      Bailout_ArgumentCheck! (no valid scopeChain)");
        iter.skip();

        // skip |return value|
        iter.skip();
        returnValue = UndefinedValue();

        // Scripts with |argumentsHasVarBinding| have an extra slot.
        if (script->argumentsHasVarBinding()) {
            JitSpew(JitSpew_BaselineBailouts,
                    "      Bailout_ArgumentCheck for script with argumentsHasVarBinding!"
                    "Using empty arguments object");
            iter.skip();
        }
    } else {
        Value v = iter.read();
        if (v.isObject()) {
            scopeChain = &v.toObject();
            if (fun && fun->needsCallObject())
                flags |= BaselineFrame::HAS_CALL_OBJ;
        } else {
            MOZ_ASSERT(v.isUndefined() || v.isMagic(JS_OPTIMIZED_OUT));

            // Get scope chain from function or script.
            if (fun) {
                // If pcOffset == 0, we may have to push a new call object, so
                // we leave scopeChain nullptr and enter baseline code before
                // the prologue.
                //
                // If we are propagating an exception for debug mode, we will
                // not resume into baseline code, but instead into
                // HandleExceptionBaseline, so *do* set the scope chain here.
                if (iter.pcOffset() != 0 || iter.resumeAfter() ||
                    (excInfo && excInfo->propagatingIonExceptionForDebugMode()))
                {
                    scopeChain = fun->environment();
                }
            } else if (script->module()) {
                scopeChain = script->module()->environment();
            } else {
                // For global scripts without a non-syntactic scope the scope
                // chain is the script's global lexical scope (Ion does not
                // compile scripts with a non-syntactic global scope). Also
                // note that it's invalid to resume into the prologue in this
                // case because the prologue expects the scope chain in R1 for
                // eval and global scripts.
                MOZ_ASSERT(!script->isForEval());
                MOZ_ASSERT(!script->hasNonSyntacticScope());
                scopeChain = &(script->global().lexicalScope());
            }
        }

        // Make sure to add HAS_RVAL to flags here because setFlags() below
        // will clobber it.
        returnValue = iter.read();
        flags |= BaselineFrame::HAS_RVAL;

        // If script maybe has an arguments object, the third slot will hold it.
        if (script->argumentsHasVarBinding()) {
            v = iter.read();
            MOZ_ASSERT(v.isObject() || v.isUndefined() || v.isMagic(JS_OPTIMIZED_OUT));
            if (v.isObject())
                argsObj = &v.toObject().as<ArgumentsObject>();
        }
    }
    JitSpew(JitSpew_BaselineBailouts, "      ScopeChain=%p", scopeChain);
    blFrame->setScopeChain(scopeChain);
    JitSpew(JitSpew_BaselineBailouts, "      ReturnValue=%016llx", *((uint64_t*) &returnValue));
    blFrame->setReturnValue(returnValue);

    // Do not need to initialize scratchValue field in BaselineFrame.
    blFrame->setFlags(flags);

    // initArgsObjUnchecked modifies the frame's flags, so call it after setFlags.
    if (argsObj)
        blFrame->initArgsObjUnchecked(*argsObj);

    if (fun) {
        // The unpacked thisv and arguments should overwrite the pushed args present
        // in the calling frame.
        Value thisv = iter.read();
        JitSpew(JitSpew_BaselineBailouts, "      Is function!");
        JitSpew(JitSpew_BaselineBailouts, "      thisv=%016llx", *((uint64_t*) &thisv));

        size_t thisvOffset = builder.framePushed() + JitFrameLayout::offsetOfThis();
        *builder.valuePointerAtStackOffset(thisvOffset) = thisv;

        MOZ_ASSERT(iter.numAllocations() >= CountArgSlots(script, fun));
        JitSpew(JitSpew_BaselineBailouts, "      frame slots %u, nargs %u, nfixed %u",
                iter.numAllocations(), fun->nargs(), script->nfixed());

        if (!callerPC) {
            // This is the first frame. Store the formals in a Vector until we
            // are done. Due to UCE and phi elimination, we could store an
            // UndefinedValue() here for formals we think are unused, but
            // locals may still reference the original argument slot
            // (MParameter/LArgument) and expect the original Value.
            MOZ_ASSERT(startFrameFormals.empty());
            if (!startFrameFormals.resize(fun->nargs()))
                return false;
        }

        for (uint32_t i = 0; i < fun->nargs(); i++) {
            Value arg = iter.read();
            JitSpew(JitSpew_BaselineBailouts, "      arg %d = %016llx",
                        (int) i, *((uint64_t*) &arg));
            if (callerPC) {
                size_t argOffset = builder.framePushed() + JitFrameLayout::offsetOfActualArg(i);
                *builder.valuePointerAtStackOffset(argOffset) = arg;
            } else {
                startFrameFormals[i].set(arg);
            }
        }
    }

    for (uint32_t i = 0; i < script->nfixed(); i++) {
        Value slot = iter.read();
        if (!builder.writeValue(slot, "FixedValue"))
            return false;
    }

    // Get the pc. If we are handling an exception, resume at the pc of the
    // catch or finally block.
    jsbytecode* pc = catchingException ? excInfo->resumePC() : script->offsetToPC(iter.pcOffset());
    bool resumeAfter = catchingException ? false : iter.resumeAfter();

    // When pgo is enabled, increment the counter of the block in which we
    // resume, as Ion does not keep track of the code coverage.
    //
    // We need to do that when pgo is enabled, as after a specific number of
    // FirstExecution bailouts, we invalidate and recompile the script with
    // IonMonkey. Failing to increment the counter of the current basic block
    // might lead to repeated bailouts and invalidations.
    if (!JitOptions.disablePgo && script->hasScriptCounts())
        script->incHitCount(pc);

    JSOp op = JSOp(*pc);

    // Fixup inlined JSOP_FUNCALL, JSOP_FUNAPPLY, and accessors on the caller side.
    // On the caller side this must represent like the function wasn't inlined.
    uint32_t pushedSlots = 0;
    AutoValueVector savedCallerArgs(cx);
    bool needToSaveArgs = op == JSOP_FUNAPPLY || IsGetPropPC(pc) || IsSetPropPC(pc);
    if (iter.moreFrames() && (op == JSOP_FUNCALL || needToSaveArgs))
    {
        uint32_t inlined_args = 0;
        if (op == JSOP_FUNCALL)
            inlined_args = 2 + GET_ARGC(pc) - 1;
        else if (op == JSOP_FUNAPPLY)
            inlined_args = 2 + blFrame->numActualArgs();
        else
            inlined_args = 2 + IsSetPropPC(pc);

        MOZ_ASSERT(exprStackSlots >= inlined_args);
        pushedSlots = exprStackSlots - inlined_args;

        JitSpew(JitSpew_BaselineBailouts,
                "      pushing %u expression stack slots before fixup",
                pushedSlots);
        for (uint32_t i = 0; i < pushedSlots; i++) {
            Value v = iter.read();
            if (!builder.writeValue(v, "StackValue"))
                return false;
        }

        if (op == JSOP_FUNCALL) {
            // When funcall got inlined and the native js_fun_call was bypassed,
            // the stack state is incorrect. To restore correctly it must look like
            // js_fun_call was actually called. This means transforming the stack
            // from |target, this, args| to |js_fun_call, target, this, args|
            // The js_fun_call is never read, so just pushing undefined now.
            JitSpew(JitSpew_BaselineBailouts, "      pushing undefined to fixup funcall");
            if (!builder.writeValue(UndefinedValue(), "StackValue"))
                return false;
        }

        if (needToSaveArgs) {
            // When an accessor is inlined, the whole thing is a lie. There
            // should never have been a call there. Fix the caller's stack to
            // forget it ever happened.

            // When funapply gets inlined we take all arguments out of the
            // arguments array. So the stack state is incorrect. To restore
            // correctly it must look like js_fun_apply was actually called.
            // This means transforming the stack from |target, this, arg1, ...|
            // to |js_fun_apply, target, this, argObject|.
            // Since the information is never read, we can just push undefined
            // for all values.
            if (op == JSOP_FUNAPPLY) {
                JitSpew(JitSpew_BaselineBailouts, "      pushing 4x undefined to fixup funapply");
                if (!builder.writeValue(UndefinedValue(), "StackValue"))
                    return false;
                if (!builder.writeValue(UndefinedValue(), "StackValue"))
                    return false;
                if (!builder.writeValue(UndefinedValue(), "StackValue"))
                    return false;
                if (!builder.writeValue(UndefinedValue(), "StackValue"))
                    return false;
            }
            // Save the actual arguments. They are needed on the callee side
            // as the arguments. Else we can't recover them.
            if (!savedCallerArgs.resize(inlined_args))
                return false;
            for (uint32_t i = 0; i < inlined_args; i++)
                savedCallerArgs[i].set(iter.read());

            if (IsSetPropPC(pc)) {
                // We would love to just save all the arguments and leave them
                // in the stub frame pushed below, but we will lose the inital
                // argument which the function was called with, which we must
                // return to the caller, even if the setter internally modifies
                // its arguments. Stash the initial argument on the stack, to be
                // later retrieved by the SetProp_Fallback stub.
                Value initialArg = savedCallerArgs[inlined_args - 1];
                JitSpew(JitSpew_BaselineBailouts, "     pushing setter's initial argument");
                if (!builder.writeValue(initialArg, "StackValue"))
                    return false;
            }
            pushedSlots = exprStackSlots;
        }
    }

    JitSpew(JitSpew_BaselineBailouts, "      pushing %u expression stack slots",
                                      exprStackSlots - pushedSlots);
    for (uint32_t i = pushedSlots; i < exprStackSlots; i++) {
        Value v;

        if (!iter.moreFrames() && i == exprStackSlots - 1 &&
            cx->runtime()->jitRuntime()->hasIonReturnOverride())
        {
            // If coming from an invalidation bailout, and this is the topmost
            // value, and a value override has been specified, don't read from the
            // iterator. Otherwise, we risk using a garbage value.
            MOZ_ASSERT(invalidate);
            iter.skip();
            JitSpew(JitSpew_BaselineBailouts, "      [Return Override]");
            v = cx->runtime()->jitRuntime()->takeIonReturnOverride();
        } else if (excInfo && excInfo->propagatingIonExceptionForDebugMode()) {
            // If we are in the middle of propagating an exception from Ion by
            // bailing to baseline due to debug mode, we might not have all
            // the stack if we are at the newest frame.
            //
            // For instance, if calling |f()| pushed an Ion frame which threw,
            // the snapshot expects the return value to be pushed, but it's
            // possible nothing was pushed before we threw. We can't drop
            // iterators, however, so read them out. They will be closed by
            // HandleExceptionBaseline.
            MOZ_ASSERT(cx->compartment()->isDebuggee());
            if (iter.moreFrames() || HasLiveIteratorAtStackDepth(script, pc, i + 1)) {
                v = iter.read();
            } else {
                iter.skip();
                v = MagicValue(JS_OPTIMIZED_OUT);
            }
        } else {
            v = iter.read();
        }
        if (!builder.writeValue(v, "StackValue"))
            return false;
    }

    // BaselineFrame::frameSize is the size of everything pushed since
    // the builder.resetFramePushed() call.
    uint32_t frameSize = builder.framePushed();
    blFrame->setFrameSize(frameSize);
    JitSpew(JitSpew_BaselineBailouts, "      FrameSize=%u", frameSize);

    // numValueSlots() is based on the frame size, do some sanity checks.
    MOZ_ASSERT(blFrame->numValueSlots() >= script->nfixed());
    MOZ_ASSERT(blFrame->numValueSlots() <= script->nslots());

    // If we are resuming at a LOOPENTRY op, resume at the next op to avoid
    // a bailout -> enter Ion -> bailout loop with --ion-eager. See also
    // ThunkToInterpreter.
    //
    // The algorithm below is the "tortoise and the hare" algorithm. See bug
    // 994444 for more explanation.
    if (!resumeAfter) {
        jsbytecode* fasterPc = pc;
        while (true) {
            pc = GetNextNonLoopEntryPc(pc);
            fasterPc = GetNextNonLoopEntryPc(GetNextNonLoopEntryPc(fasterPc));
            if (fasterPc == pc)
                break;
        }
        op = JSOp(*pc);
    }

    uint32_t pcOff = script->pcToOffset(pc);
    bool isCall = IsCallPC(pc);
    BaselineScript* baselineScript = script->baselineScript();

#ifdef DEBUG
    uint32_t expectedDepth;
    bool reachablePC;
    if (!ReconstructStackDepth(cx, script, resumeAfter ? GetNextPc(pc) : pc, &expectedDepth, &reachablePC))
        return false;

    if (reachablePC) {
        if (op != JSOP_FUNAPPLY || !iter.moreFrames() || resumeAfter) {
            if (op == JSOP_FUNCALL) {
                // For fun.call(this, ...); the reconstructStackDepth will
                // include the this. When inlining that is not included.
                // So the exprStackSlots will be one less.
                MOZ_ASSERT(expectedDepth - exprStackSlots <= 1);
            } else if (iter.moreFrames() && (IsGetPropPC(pc) || IsSetPropPC(pc))) {
                // Accessors coming out of ion are inlined via a complete
                // lie perpetrated by the compiler internally. Ion just rearranges
                // the stack, and pretends that it looked like a call all along.
                // This means that the depth is actually one *more* than expected
                // by the interpreter, as there is now a JSFunction, |this| and [arg],
                // rather than the expected |this| and [arg]
                // Note that none of that was pushed, but it's still reflected
                // in exprStackSlots.
                MOZ_ASSERT(exprStackSlots - expectedDepth == 1);
            } else {
                // For fun.apply({}, arguments) the reconstructStackDepth will
                // have stackdepth 4, but it could be that we inlined the
                // funapply. In that case exprStackSlots, will have the real
                // arguments in the slots and not be 4.
                MOZ_ASSERT(exprStackSlots == expectedDepth);
            }
        }
    }
#endif

#ifdef JS_JITSPEW
    JitSpew(JitSpew_BaselineBailouts, "      Resuming %s pc offset %d (op %s) (line %d) of %s:%" PRIuSIZE,
                resumeAfter ? "after" : "at", (int) pcOff, CodeName[op],
                PCToLineNumber(script, pc), script->filename(), script->lineno());
    JitSpew(JitSpew_BaselineBailouts, "      Bailout kind: %s",
            BailoutKindString(bailoutKind));
#endif

    bool pushedNewTarget = op == JSOP_NEW;

    // If this was the last inline frame, or we are bailing out to a catch or
    // finally block in this frame, then unpacking is almost done.
    if (!iter.moreFrames() || catchingException) {
        // Last frame, so PC for call to next frame is set to nullptr.
        *callPC = nullptr;

        // If the bailout was a resumeAfter, and the opcode is monitored,
        // then the bailed out state should be in a position to enter
        // into the ICTypeMonitor chain for the op.
        bool enterMonitorChain = false;
        if (resumeAfter && (CodeSpec[op].format & JOF_TYPESET)) {
            // Not every monitored op has a monitored fallback stub, e.g.
            // JSOP_NEWOBJECT, which always returns the same type for a
            // particular script/pc location.
            ICEntry& icEntry = baselineScript->icEntryFromPCOffset(pcOff);
            ICFallbackStub* fallbackStub = icEntry.firstStub()->getChainFallback();
            if (fallbackStub->isMonitoredFallback())
                enterMonitorChain = true;
        }

        uint32_t numCallArgs = isCall ? GET_ARGC(pc) : 0;

        if (resumeAfter && !enterMonitorChain)
            pc = GetNextPc(pc);

        builder.setResumePC(pc);
        builder.setResumeFramePtr(prevFramePtr);

        if (enterMonitorChain) {
            ICEntry& icEntry = baselineScript->icEntryFromPCOffset(pcOff);
            ICFallbackStub* fallbackStub = icEntry.firstStub()->getChainFallback();
            MOZ_ASSERT(fallbackStub->isMonitoredFallback());
            JitSpew(JitSpew_BaselineBailouts, "      [TYPE-MONITOR CHAIN]");
            ICMonitoredFallbackStub* monFallbackStub = fallbackStub->toMonitoredFallbackStub();
            ICStub* firstMonStub = monFallbackStub->fallbackMonitorStub()->firstMonitorStub();

            // To enter a monitoring chain, we load the top stack value into R0
            JitSpew(JitSpew_BaselineBailouts, "      Popping top stack value into R0.");
            builder.popValueInto(PCMappingSlotInfo::SlotInR0);

            // Need to adjust the frameSize for the frame to match the values popped
            // into registers.
            frameSize -= sizeof(Value);
            blFrame->setFrameSize(frameSize);
            JitSpew(JitSpew_BaselineBailouts, "      Adjusted framesize -= %d: %d",
                            (int) sizeof(Value), (int) frameSize);

            // If resuming into a JSOP_CALL, baseline keeps the arguments on the
            // stack and pops them only after returning from the call IC.
            // Push undefs onto the stack in anticipation of the popping of the
            // callee, thisv, and actual arguments passed from the caller's frame.
            if (isCall) {
                builder.writeValue(UndefinedValue(), "CallOp FillerCallee");
                builder.writeValue(UndefinedValue(), "CallOp FillerThis");
                for (uint32_t i = 0; i < numCallArgs; i++)
                    builder.writeValue(UndefinedValue(), "CallOp FillerArg");
                if (pushedNewTarget)
                    builder.writeValue(UndefinedValue(), "CallOp FillerNewTarget");

                frameSize += (numCallArgs + 2 + pushedNewTarget) * sizeof(Value);
                blFrame->setFrameSize(frameSize);
                JitSpew(JitSpew_BaselineBailouts, "      Adjusted framesize += %d: %d",
                                (int) ((numCallArgs + 2 + pushedNewTarget) * sizeof(Value)),
                                (int) frameSize);
            }

            // Set the resume address to the return point from the IC, and set
            // the monitor stub addr.
            builder.setResumeAddr(baselineScript->returnAddressForIC(icEntry));
            builder.setMonitorStub(firstMonStub);
            JitSpew(JitSpew_BaselineBailouts, "      Set resumeAddr=%p monitorStub=%p",
                    baselineScript->returnAddressForIC(icEntry), firstMonStub);

        } else {
            // If needed, initialize BaselineBailoutInfo's valueR0 and/or valueR1 with the
            // top stack values.
            //
            // Note that we use the 'maybe' variant of nativeCodeForPC because
            // of exception propagation for debug mode. See note below.
            PCMappingSlotInfo slotInfo;
            uint8_t* nativeCodeForPC;

            if (excInfo && excInfo->propagatingIonExceptionForDebugMode()) {
                // When propagating an exception for debug mode, set the
                // resume pc to the throwing pc, so that Debugger hooks report
                // the correct pc offset of the throwing op instead of its
                // successor (this pc will be used as the BaselineFrame's
                // override pc).
                //
                // Note that we never resume at this pc, it is set for the sake
                // of frame iterators giving the correct answer.
                //
                // We also set nativeCodeForPC to nullptr as this address
                // won't be used anywhere.
                jsbytecode* throwPC = script->offsetToPC(iter.pcOffset());
                builder.setResumePC(throwPC);
                nativeCodeForPC = nullptr;
            } else {
                nativeCodeForPC = baselineScript->nativeCodeForPC(script, pc, &slotInfo);
                MOZ_ASSERT(nativeCodeForPC);
            }

            unsigned numUnsynced = slotInfo.numUnsynced();

            MOZ_ASSERT(numUnsynced <= 2);
            PCMappingSlotInfo::SlotLocation loc1, loc2;
            if (numUnsynced > 0) {
                loc1 = slotInfo.topSlotLocation();
                JitSpew(JitSpew_BaselineBailouts, "      Popping top stack value into %d.",
                        (int) loc1);
                builder.popValueInto(loc1);
            }
            if (numUnsynced > 1) {
                loc2 = slotInfo.nextSlotLocation();
                JitSpew(JitSpew_BaselineBailouts, "      Popping next stack value into %d.",
                        (int) loc2);
                MOZ_ASSERT_IF(loc1 != PCMappingSlotInfo::SlotIgnore, loc1 != loc2);
                builder.popValueInto(loc2);
            }

            // Need to adjust the frameSize for the frame to match the values popped
            // into registers.
            frameSize -= sizeof(Value) * numUnsynced;
            blFrame->setFrameSize(frameSize);
            JitSpew(JitSpew_BaselineBailouts, "      Adjusted framesize -= %d: %d",
                    int(sizeof(Value) * numUnsynced), int(frameSize));

            // If scopeChain is nullptr, then bailout is occurring during argument check.
            // In this case, resume into the prologue.
            uint8_t* opReturnAddr;
            if (scopeChain == nullptr) {
                // Global and eval scripts expect the scope chain in R1, so only
                // resume into the prologue for function scripts.
                MOZ_ASSERT(fun);
                MOZ_ASSERT(numUnsynced == 0);
                opReturnAddr = baselineScript->prologueEntryAddr();
                JitSpew(JitSpew_BaselineBailouts, "      Resuming into prologue.");

            } else {
                opReturnAddr = nativeCodeForPC;
            }
            builder.setResumeAddr(opReturnAddr);
            JitSpew(JitSpew_BaselineBailouts, "      Set resumeAddr=%p", opReturnAddr);
        }

        if (cx->runtime()->spsProfiler.enabled()) {
            // Register bailout with profiler.
            const char* filename = script->filename();
            if (filename == nullptr)
                filename = "<unknown>";
            unsigned len = strlen(filename) + 200;
            char* buf = js_pod_malloc<char>(len);
            if (buf == nullptr)
                return false;
            JS_snprintf(buf, len, "%s %s %s on line %u of %s:%" PRIuSIZE,
                                  BailoutKindString(bailoutKind),
                                  resumeAfter ? "after" : "at",
                                  CodeName[op],
                                  PCToLineNumber(script, pc),
                                  filename,
                                  script->lineno());
            cx->runtime()->spsProfiler.markEvent(buf);
            js_free(buf);
        }

        return true;
    }

    *callPC = pc;

    // Write out descriptor of BaselineJS frame.
    size_t baselineFrameDescr = MakeFrameDescriptor((uint32_t) builder.framePushed(),
                                                    JitFrame_BaselineJS);
    if (!builder.writeWord(baselineFrameDescr, "Descriptor"))
        return false;

    // Calculate and write out return address.
    // The icEntry in question MUST have an inlinable fallback stub.
    ICEntry& icEntry = baselineScript->icEntryFromPCOffset(pcOff);
    MOZ_ASSERT(IsInlinableFallback(icEntry.firstStub()->getChainFallback()));
    if (!builder.writePtr(baselineScript->returnAddressForIC(icEntry), "ReturnAddr"))
        return false;

    // Build baseline stub frame:
    // +===============+
    // |    StubPtr    |
    // +---------------+
    // |   FramePtr    |
    // +---------------+
    // |   Padding?    |
    // +---------------+
    // |     ArgA      |
    // +---------------+
    // |     ...       |
    // +---------------+
    // |     Arg0      |
    // +---------------+
    // |     ThisV     |
    // +---------------+
    // |  ActualArgC   |
    // +---------------+
    // |  CalleeToken  |
    // +---------------+
    // | Descr(BLStub) |
    // +---------------+
    // |  ReturnAddr   |
    // +===============+

    JitSpew(JitSpew_BaselineBailouts, "      [BASELINE-STUB FRAME]");

    size_t startOfBaselineStubFrame = builder.framePushed();

    // Write stub pointer.
    MOZ_ASSERT(IsInlinableFallback(icEntry.fallbackStub()));
    if (!builder.writePtr(icEntry.fallbackStub(), "StubPtr"))
        return false;

    // Write previous frame pointer (saved earlier).
    if (!builder.writePtr(prevFramePtr, "PrevFramePtr"))
        return false;
    prevFramePtr = builder.virtualPointerAtStackOffset(0);

    // Write out actual arguments (and thisv), copied from unpacked stack of BaselineJS frame.
    // Arguments are reversed on the BaselineJS frame's stack values.
    MOZ_ASSERT(IsIonInlinablePC(pc));
    unsigned actualArgc;
    Value callee;
    if (needToSaveArgs) {
        // For FUNAPPLY or an accessor, the arguments are not on the stack anymore,
        // but they are copied in a vector and are written here.
        if (op == JSOP_FUNAPPLY)
            actualArgc = blFrame->numActualArgs();
        else
            actualArgc = IsSetPropPC(pc);
        callee = savedCallerArgs[0];

        // Align the stack based on the number of arguments.
        size_t afterFrameSize = (actualArgc + 1) * sizeof(Value) + JitFrameLayout::Size();
        if (!builder.maybeWritePadding(JitStackAlignment, afterFrameSize, "Padding"))
            return false;

        // Push arguments.
        MOZ_ASSERT(actualArgc + 2 <= exprStackSlots);
        MOZ_ASSERT(savedCallerArgs.length() == actualArgc + 2);
        for (unsigned i = 0; i < actualArgc + 1; i++) {
            size_t arg = savedCallerArgs.length() - (i + 1);
            if (!builder.writeValue(savedCallerArgs[arg], "ArgVal"))
                return false;
        }
    } else {
        actualArgc = GET_ARGC(pc);
        if (op == JSOP_FUNCALL) {
            MOZ_ASSERT(actualArgc > 0);
            actualArgc--;
        }

        // Align the stack based on the number of arguments.
        size_t afterFrameSize = (actualArgc + 1 + pushedNewTarget) * sizeof(Value) +
                                JitFrameLayout::Size();
        if (!builder.maybeWritePadding(JitStackAlignment, afterFrameSize, "Padding"))
            return false;

        // Copy the arguments and |this| from the BaselineFrame, in reverse order.
        size_t valueSlot = blFrame->numValueSlots() - 1;
        size_t calleeSlot = valueSlot - actualArgc - 1 - pushedNewTarget;

        for (size_t i = valueSlot; i > calleeSlot; i--) {
            if (!builder.writeValue(*blFrame->valueSlot(i), "ArgVal"))
                return false;
        }

        callee = *blFrame->valueSlot(calleeSlot);
    }

    // In case these arguments need to be copied on the stack again for a rectifier frame,
    // save the framePushed values here for later use.
    size_t endOfBaselineStubArgs = builder.framePushed();

    // Calculate frame size for descriptor.
    size_t baselineStubFrameSize = builder.framePushed() - startOfBaselineStubFrame;
    size_t baselineStubFrameDescr = MakeFrameDescriptor((uint32_t) baselineStubFrameSize,
                                                        JitFrame_BaselineStub);

    // Push actual argc
    if (!builder.writeWord(actualArgc, "ActualArgc"))
        return false;

    // Push callee token (must be a JS Function)
    JitSpew(JitSpew_BaselineBailouts, "      Callee = %016llx", callee.asRawBits());

    JSFunction* calleeFun = &callee.toObject().as<JSFunction>();
    if (!builder.writePtr(CalleeToToken(calleeFun, JSOp(*pc) == JSOP_NEW), "CalleeToken"))
        return false;
    nextCallee.set(calleeFun);

    // Push BaselineStub frame descriptor
    if (!builder.writeWord(baselineStubFrameDescr, "Descriptor"))
        return false;

    // Push return address into ICCall_Scripted stub, immediately after the call.
    void* baselineCallReturnAddr = GetStubReturnAddress(cx, pc);
    MOZ_ASSERT(baselineCallReturnAddr);
    if (!builder.writePtr(baselineCallReturnAddr, "ReturnAddr"))
        return false;
    MOZ_ASSERT(builder.framePushed() % JitStackAlignment == 0);

    // If actualArgc >= fun->nargs, then we are done.  Otherwise, we need to push on
    // a reconstructed rectifier frame.
    if (actualArgc >= calleeFun->nargs())
        return true;

    // Push a reconstructed rectifier frame.
    // +===============+
    // |   Padding?    |
    // +---------------+
    // |  UndefinedU   |
    // +---------------+
    // |     ...       |
    // +---------------+
    // |  Undefined0   |
    // +---------------+
    // |     ArgA      |
    // +---------------+
    // |     ...       |
    // +---------------+
    // |     Arg0      |
    // +---------------+
    // |     ThisV     |
    // +---------------+
    // |  ActualArgC   |
    // +---------------+
    // |  CalleeToken  |
    // +---------------+
    // |  Descr(Rect)  |
    // +---------------+
    // |  ReturnAddr   |
    // +===============+

    JitSpew(JitSpew_BaselineBailouts, "      [RECTIFIER FRAME]");

    size_t startOfRectifierFrame = builder.framePushed();

    // On x86-only, the frame pointer is saved again in the rectifier frame.
#if defined(JS_CODEGEN_X86)
    if (!builder.writePtr(prevFramePtr, "PrevFramePtr-X86Only"))
        return false;
    // Follow the same logic as in JitRuntime::generateArgumentsRectifier.
    prevFramePtr = builder.virtualPointerAtStackOffset(0);
    if (!builder.writePtr(prevFramePtr, "Padding-X86Only"))
        return false;
#endif

    // Align the stack based on the number of arguments.
    size_t afterFrameSize = (calleeFun->nargs() + 1 + pushedNewTarget) * sizeof(Value) +
                            RectifierFrameLayout::Size();
    if (!builder.maybeWritePadding(JitStackAlignment, afterFrameSize, "Padding"))
        return false;

    // Copy new.target, if necessary.
    if (pushedNewTarget) {
        size_t newTargetOffset = (builder.framePushed() - endOfBaselineStubArgs) +
                                 (actualArgc + 1) * sizeof(Value);
        builder.writeValue(*builder.valuePointerAtStackOffset(newTargetOffset), "CopiedNewTarget");
    }

    // Push undefined for missing arguments.
    for (unsigned i = 0; i < (calleeFun->nargs() - actualArgc); i++) {
        if (!builder.writeValue(UndefinedValue(), "FillerVal"))
            return false;
    }

    // Copy arguments + thisv from BaselineStub frame.
    if (!builder.subtract((actualArgc + 1) * sizeof(Value), "CopiedArgs"))
        return false;
    BufferPointer<uint8_t> stubArgsEnd =
        builder.pointerAtStackOffset<uint8_t>(builder.framePushed() - endOfBaselineStubArgs);
    JitSpew(JitSpew_BaselineBailouts, "      MemCpy from %p", stubArgsEnd.get());
    memcpy(builder.pointerAtStackOffset<uint8_t>(0).get(), stubArgsEnd.get(),
           (actualArgc + 1) * sizeof(Value));

    // Calculate frame size for descriptor.
    size_t rectifierFrameSize = builder.framePushed() - startOfRectifierFrame;
    size_t rectifierFrameDescr = MakeFrameDescriptor((uint32_t) rectifierFrameSize,
                                                     JitFrame_Rectifier);

    // Push actualArgc
    if (!builder.writeWord(actualArgc, "ActualArgc"))
        return false;

    // Push calleeToken again.
    if (!builder.writePtr(CalleeToToken(calleeFun, JSOp(*pc) == JSOP_NEW), "CalleeToken"))
        return false;

    // Push rectifier frame descriptor
    if (!builder.writeWord(rectifierFrameDescr, "Descriptor"))
        return false;

    // Push return address into the ArgumentsRectifier code, immediately after the ioncode
    // call.
    void* rectReturnAddr = cx->runtime()->jitRuntime()->getArgumentsRectifierReturnAddr();
    MOZ_ASSERT(rectReturnAddr);
    if (!builder.writePtr(rectReturnAddr, "ReturnAddr"))
        return false;
    MOZ_ASSERT(builder.framePushed() % JitStackAlignment == 0);

    return true;
}

uint32_t
jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIterator& iter,
                          bool invalidate, BaselineBailoutInfo** bailoutInfo,
                          const ExceptionBailoutInfo* excInfo)
{
    MOZ_ASSERT(bailoutInfo != nullptr);
    MOZ_ASSERT(*bailoutInfo == nullptr);

    TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
    TraceLogStopEvent(logger, TraceLogger_IonMonkey);
    TraceLogStartEvent(logger, TraceLogger_Baseline);

    // Ion bailout can fail due to overrecursion and OOM. In such cases we
    // cannot honor any further Debugger hooks on the frame, and need to
    // ensure that its Debugger.Frame entry is cleaned up.
    auto guardRemoveRematerializedFramesFromDebugger = mozilla::MakeScopeExit([&] {
        activation->removeRematerializedFramesFromDebugger(cx, iter.fp());
    });

    // 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.isBailoutJS());
#if defined(DEBUG) || defined(JS_JITSPEW)
    FrameType prevFrameType = iter.prevType();
    MOZ_ASSERT(prevFrameType == JitFrame_IonJS ||
               prevFrameType == JitFrame_BaselineStub ||
               prevFrameType == JitFrame_Entry ||
               prevFrameType == JitFrame_Rectifier ||
               prevFrameType == JitFrame_IonAccessorIC);
#endif

    // All incoming frames are going to look like this:
    //
    //      +---------------+
    //      |     ...       |
    //      +---------------+
    //      |     Args      |
    //      |     ...       |
    //      +---------------+
    //      |    ThisV      |
    //      +---------------+
    //      |  ActualArgC   |
    //      +---------------+
    //      |  CalleeToken  |
    //      +---------------+
    //      |  Descriptor   |
    //      +---------------+
    //      |  ReturnAddr   |
    //      +---------------+
    //      |    |||||      | <---- Overwrite starting here.
    //      |    |||||      |
    //      |    |||||      |
    //      +---------------+

    JitSpew(JitSpew_BaselineBailouts, "Bailing to baseline %s:%u (IonScript=%p) (FrameType=%d)",
            iter.script()->filename(), iter.script()->lineno(), (void*) iter.ionScript(),
            (int) prevFrameType);

    bool catchingException;
    bool propagatingExceptionForDebugMode;
    if (excInfo) {
        catchingException = excInfo->catchingException();
        propagatingExceptionForDebugMode = excInfo->propagatingIonExceptionForDebugMode();

        if (catchingException)
            JitSpew(JitSpew_BaselineBailouts, "Resuming in catch or finally block");

        if (propagatingExceptionForDebugMode)
            JitSpew(JitSpew_BaselineBailouts, "Resuming in-place for debug mode");
    } else {
        catchingException = false;
        propagatingExceptionForDebugMode = false;
    }

    JitSpew(JitSpew_BaselineBailouts, "  Reading from snapshot offset %u size %u",
            iter.snapshotOffset(), iter.ionScript()->snapshotsListSize());

    if (!excInfo)
        iter.ionScript()->incNumBailouts();
    iter.script()->updateBaselineOrIonRaw(cx);

    // Allocate buffer to hold stack replacement data.
    BaselineStackBuilder builder(iter, 1024);
    if (!builder.init()) {
        ReportOutOfMemory(cx);
        return BAILOUT_RETURN_FATAL_ERROR;
    }
    JitSpew(JitSpew_BaselineBailouts, "  Incoming frame ptr = %p", builder.startFrame());

    SnapshotIteratorForBailout snapIter(activation, iter);
    if (!snapIter.init(cx))
        return BAILOUT_RETURN_FATAL_ERROR;

#ifdef TRACK_SNAPSHOTS
    snapIter.spewBailingFrom();
#endif

    RootedFunction callee(cx, iter.maybeCallee());
    RootedScript scr(cx, iter.script());
    if (callee) {
        JitSpew(JitSpew_BaselineBailouts, "  Callee function (%s:%u)",
                scr->filename(), scr->lineno());
    } else {
        JitSpew(JitSpew_BaselineBailouts, "  No callee!");
    }

    if (iter.isConstructing())
        JitSpew(JitSpew_BaselineBailouts, "  Constructing!");
    else
        JitSpew(JitSpew_BaselineBailouts, "  Not constructing!");

    JitSpew(JitSpew_BaselineBailouts, "  Restoring frames:");
    size_t frameNo = 0;

    // Reconstruct baseline frames using the builder.
    RootedScript caller(cx);
    jsbytecode* callerPC = nullptr;
    RootedFunction fun(cx, callee);
    AutoValueVector startFrameFormals(cx);

    gc::AutoSuppressGC suppress(cx);

    while (true) {
        // Skip recover instructions as they are already recovered by |initInstructionResults|.
        snapIter.settleOnFrame();

        if (frameNo > 0) {
            // TraceLogger doesn't create entries for inlined frames. But we
            // see them in Baseline. Here we create the start events of those
            // entries. So they correspond to what we will see in Baseline.
            TraceLoggerEvent scriptEvent(logger, TraceLogger_Scripts, scr);
            TraceLogStartEvent(logger, scriptEvent);
            TraceLogStartEvent(logger, TraceLogger_Baseline);
        }

        JitSpew(JitSpew_BaselineBailouts, "    FrameNo %d", frameNo);

        // If we are bailing out to a catch or finally block in this frame,
        // pass excInfo to InitFromBailout and don't unpack any other frames.
        bool handleException = (catchingException && excInfo->frameNo() == frameNo);

        // We also need to pass excInfo if we're bailing out in place for
        // debug mode.
        bool passExcInfo = handleException || propagatingExceptionForDebugMode;

        jsbytecode* callPC = nullptr;
        RootedFunction nextCallee(cx, nullptr);
        if (!InitFromBailout(cx, caller, callerPC, fun, scr, iter.ionScript(),
                             snapIter, invalidate, builder, startFrameFormals,
                             &nextCallee, &callPC, passExcInfo ? excInfo : nullptr))
        {
            return BAILOUT_RETURN_FATAL_ERROR;
        }

        if (!snapIter.moreFrames()) {
            MOZ_ASSERT(!callPC);
            break;
        }

        if (handleException)
            break;

        MOZ_ASSERT(nextCallee);
        MOZ_ASSERT(callPC);
        caller = scr;
        callerPC = callPC;
        fun = nextCallee;
        scr = fun->existingScriptForInlinedFunction();

        frameNo++;

        snapIter.nextInstruction();
    }
    JitSpew(JitSpew_BaselineBailouts, "  Done restoring frames");

    BailoutKind bailoutKind = snapIter.bailoutKind();

    if (!startFrameFormals.empty()) {
        // Set the first frame's formals, see the comment in InitFromBailout.
        Value* argv = builder.startFrame()->argv() + 1; // +1 to skip |this|.
        mozilla::PodCopy(argv, startFrameFormals.begin(), startFrameFormals.length());
    }

    // Do stack check.
    bool overRecursed = false;
    BaselineBailoutInfo *info = builder.info();
    uint8_t* newsp = info->incomingStack - (info->copyStackTop - info->copyStackBottom);
#ifdef JS_SIMULATOR
    if (Simulator::Current()->overRecursed(uintptr_t(newsp)))
        overRecursed = true;
#else
    JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, newsp, overRecursed = true);
#endif
    if (overRecursed) {
        JitSpew(JitSpew_BaselineBailouts, "  Overrecursion check failed!");
        return BAILOUT_RETURN_OVERRECURSED;
    }

    // Take the reconstructed baseline stack so it doesn't get freed when builder destructs.
    info = builder.takeBuffer();
    info->numFrames = frameNo + 1;
    info->bailoutKind = bailoutKind;
    *bailoutInfo = info;
    guardRemoveRematerializedFramesFromDebugger.release();
    return BAILOUT_RETURN_OK;
}

static bool
InvalidateAfterBailout(JSContext* cx, HandleScript outerScript, const char* reason)
{
    // In some cases, the computation of recover instruction can invalidate the
    // Ion script before we reach the end of the bailout. Thus, if the outer
    // script no longer have any Ion script attached, then we just skip the
    // invalidation.
    //
    // For example, such case can happen if the template object for an unboxed
    // objects no longer match the content of its properties (see Bug 1174547)
    if (!outerScript->hasIonScript()) {
        JitSpew(JitSpew_BaselineBailouts, "Ion script is already invalidated");
        return true;
    }

    MOZ_ASSERT(!outerScript->ionScript()->invalidated());

    JitSpew(JitSpew_BaselineBailouts, "Invalidating due to %s", reason);
    return Invalidate(cx, outerScript);
}

static bool
HandleBoundsCheckFailure(JSContext* cx, HandleScript outerScript, HandleScript innerScript)
{
    JitSpew(JitSpew_IonBailouts, "Bounds check failure %s:%d, inlined into %s:%d",
            innerScript->filename(), innerScript->lineno(),
            outerScript->filename(), outerScript->lineno());

    if (!innerScript->failedBoundsCheck())
        innerScript->setFailedBoundsCheck();

    if (!InvalidateAfterBailout(cx, outerScript, "bounds check failure"))
        return false;

    if (innerScript->hasIonScript() && !Invalidate(cx, innerScript))
        return false;

    return true;
}

static bool
HandleShapeGuardFailure(JSContext* cx, HandleScript outerScript, HandleScript innerScript)
{
    JitSpew(JitSpew_IonBailouts, "Shape guard failure %s:%d, inlined into %s:%d",
            innerScript->filename(), innerScript->lineno(),
            outerScript->filename(), outerScript->lineno());

    // TODO: Currently this mimic's Ion's handling of this case.  Investigate setting
    // the flag on innerScript as opposed to outerScript, and maybe invalidating both
    // inner and outer scripts, instead of just the outer one.
    outerScript->setFailedShapeGuard();

    return InvalidateAfterBailout(cx, outerScript, "shape guard failure");
}

static bool
HandleBaselineInfoBailout(JSContext* cx, HandleScript outerScript, HandleScript innerScript)
{
    JitSpew(JitSpew_IonBailouts, "Baseline info failure %s:%d, inlined into %s:%d",
            innerScript->filename(), innerScript->lineno(),
            outerScript->filename(), outerScript->lineno());

    return InvalidateAfterBailout(cx, outerScript, "invalid baseline info");
}

static bool
HandleLexicalCheckFailure(JSContext* cx, HandleScript outerScript, HandleScript innerScript)
{
    JitSpew(JitSpew_IonBailouts, "Lexical check failure %s:%d, inlined into %s:%d",
            innerScript->filename(), innerScript->lineno(),
            outerScript->filename(), outerScript->lineno());

    if (!innerScript->failedLexicalCheck())
        innerScript->setFailedLexicalCheck();

    if (!InvalidateAfterBailout(cx, outerScript, "lexical check failure"))
        return false;

    if (innerScript->hasIonScript() && !Invalidate(cx, innerScript))
        return false;

    return true;
}

static bool
CopyFromRematerializedFrame(JSContext* cx, JitActivation* act, uint8_t* fp, size_t inlineDepth,
                            BaselineFrame* frame)
{
    RematerializedFrame* rematFrame = act->lookupRematerializedFrame(fp, inlineDepth);

    // We might not have rematerialized a frame if the user never requested a
    // Debugger.Frame for it.
    if (!rematFrame)
        return true;

    MOZ_ASSERT(rematFrame->script() == frame->script());
    MOZ_ASSERT(rematFrame->numActualArgs() == frame->numActualArgs());

    frame->setScopeChain(rematFrame->scopeChain());

    if (frame->isNonEvalFunctionFrame())
        frame->thisArgument() = rematFrame->thisArgument();

    for (unsigned i = 0; i < frame->numActualArgs(); i++)
        frame->argv()[i] = rematFrame->argv()[i];

    for (size_t i = 0; i < frame->script()->nfixed(); i++)
        *frame->valueSlot(i) = rematFrame->locals()[i];

    if (rematFrame->hasCachedSavedFrame())
        frame->setHasCachedSavedFrame();

    JitSpew(JitSpew_BaselineBailouts,
            "  Copied from rematerialized frame at (%p,%u)",
            fp, inlineDepth);

    // Propagate the debuggee frame flag. For the case where the Debugger did
    // not rematerialize an Ion frame, the baseline frame has its debuggee
    // flag set iff its script is considered a debuggee. See the debuggee case
    // in InitFromBailout.
    if (rematFrame->isDebuggee()) {
        frame->setIsDebuggee();
        return Debugger::handleIonBailout(cx, rematFrame, frame);
    }

    return true;
}

uint32_t
jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo)
{
    // The caller pushes R0 and R1 on the stack without rooting them.
    // Since GC here is very unlikely just suppress it.
    JSContext* cx = GetJSContextFromJitCode();
    js::gc::AutoSuppressGC suppressGC(cx);

    JitSpew(JitSpew_BaselineBailouts, "  Done restoring frames");

    // The current native code pc may not have a corresponding ICEntry, so we
    // store the bytecode pc in the frame for frame iterators. This pc is
    // cleared at the end of this function. If we return false, we don't clear
    // it: the exception handler also needs it and will clear it for us.
    BaselineFrame* topFrame = GetTopBaselineFrame(cx);
    topFrame->setOverridePc(bailoutInfo->resumePC);

    uint32_t numFrames = bailoutInfo->numFrames;
    MOZ_ASSERT(numFrames > 0);
    BailoutKind bailoutKind = bailoutInfo->bailoutKind;

    // Free the bailout buffer.
    js_free(bailoutInfo);
    bailoutInfo = nullptr;

    // Ensure the frame has a call object if it needs one. If the scope chain
    // is nullptr, we will enter baseline code at the prologue so no need to do
    // anything in that case.
    if (topFrame->scopeChain() && !EnsureHasScopeObjects(cx, topFrame))
        return false;

    // Create arguments objects for bailed out frames, to maintain the invariant
    // that script->needsArgsObj() implies frame->hasArgsObj().
    RootedScript innerScript(cx, nullptr);
    RootedScript outerScript(cx, nullptr);

    MOZ_ASSERT(cx->currentlyRunningInJit());
    JitFrameIterator iter(cx);
    uint8_t* outerFp = nullptr;

    // Iter currently points at the exit frame.  Get the previous frame
    // (which must be a baseline frame), and set it as the last profiling
    // frame.
    if (cx->runtime()->jitRuntime()->isProfilerInstrumentationEnabled(cx->runtime()))
        cx->runtime()->jitActivation->setLastProfilingFrame(iter.prevFp());

    uint32_t frameno = 0;
    while (frameno < numFrames) {
        MOZ_ASSERT(!iter.isIonJS());

        if (iter.isBaselineJS()) {
            BaselineFrame* frame = iter.baselineFrame();
            MOZ_ASSERT(frame->script()->hasBaselineScript());

            // If the frame doesn't even have a scope chain set yet, then it's resuming
            // into the the prologue before the scope chain is initialized.  Any
            // necessary args object will also be initialized there.
            if (frame->scopeChain() && frame->script()->needsArgsObj()) {
                ArgumentsObject* argsObj;
                if (frame->hasArgsObj()) {
                    argsObj = &frame->argsObj();
                } else {
                    argsObj = ArgumentsObject::createExpected(cx, frame);
                    if (!argsObj)
                        return false;
                }

                // The arguments is a local binding and needsArgsObj does not
                // check if it is clobbered. Ensure that the local binding
                // restored during bailout before storing the arguments object
                // to the slot.
                RootedScript script(cx, frame->script());
                SetFrameArgumentsObject(cx, frame, script, argsObj);
            }

            if (frameno == 0)
                innerScript = frame->script();

            if (frameno == numFrames - 1) {
                outerScript = frame->script();
                outerFp = iter.fp();
            }

            frameno++;
        }

        ++iter;
    }

    MOZ_ASSERT(innerScript);
    MOZ_ASSERT(outerScript);
    MOZ_ASSERT(outerFp);

    // If we rematerialized Ion frames due to debug mode toggling, copy their
    // values into the baseline frame. We need to do this even when debug mode
    // is off, as we should respect the mutations made while debug mode was
    // on.
    JitActivation* act = cx->runtime()->activation()->asJit();
    if (act->hasRematerializedFrame(outerFp)) {
        JitFrameIterator iter(cx);
        size_t inlineDepth = numFrames;
        while (inlineDepth > 0) {
            if (iter.isBaselineJS() &&
                !CopyFromRematerializedFrame(cx, act, outerFp, --inlineDepth,
                                             iter.baselineFrame()))
            {
                return false;
            }
            ++iter;
        }

        // After copying from all the rematerialized frames, remove them from
        // the table to keep the table up to date.
        act->removeRematerializedFrame(outerFp);
    }

    JitSpew(JitSpew_BaselineBailouts,
            "  Restored outerScript=(%s:%u,%u) innerScript=(%s:%u,%u) (bailoutKind=%u)",
            outerScript->filename(), outerScript->lineno(), outerScript->getWarmUpCount(),
            innerScript->filename(), innerScript->lineno(), innerScript->getWarmUpCount(),
            (unsigned) bailoutKind);

    switch (bailoutKind) {
      // Normal bailouts.
      case Bailout_Inevitable:
      case Bailout_DuringVMCall:
      case Bailout_NonJSFunctionCallee:
      case Bailout_DynamicNameNotFound:
      case Bailout_StringArgumentsEval:
      case Bailout_Overflow:
      case Bailout_Round:
      case Bailout_NonPrimitiveInput:
      case Bailout_PrecisionLoss:
      case Bailout_TypeBarrierO:
      case Bailout_TypeBarrierV:
      case Bailout_MonitorTypes:
      case Bailout_Hole:
      case Bailout_NegativeIndex:
      case Bailout_NonInt32Input:
      case Bailout_NonNumericInput:
      case Bailout_NonBooleanInput:
      case Bailout_NonObjectInput:
      case Bailout_NonStringInput:
      case Bailout_NonSymbolInput:
      case Bailout_NonSimdInt32x4Input:
      case Bailout_NonSimdFloat32x4Input:
      case Bailout_NonSharedTypedArrayInput:
      case Bailout_InitialState:
      case Bailout_Debugger:
      case Bailout_UninitializedThis:
      case Bailout_BadDerivedConstructorReturn:
        // Do nothing.
        break;

      case Bailout_FirstExecution:
        // Do not return directly, as this was not frequent in the first place,
        // thus rely on the check for frequent bailouts to recompile the current
        // script.
        break;

      // Invalid assumption based on baseline code.
      case Bailout_OverflowInvalidate:
      case Bailout_NonStringInputInvalidate:
      case Bailout_DoubleOutput:
      case Bailout_ObjectIdentityOrTypeGuard:
        if (!HandleBaselineInfoBailout(cx, outerScript, innerScript))
            return false;
        break;

      case Bailout_ArgumentCheck:
        // Do nothing, bailout will resume before the argument monitor ICs.
        break;
      case Bailout_BoundsCheck:
      case Bailout_Neutered:
        if (!HandleBoundsCheckFailure(cx, outerScript, innerScript))
            return false;
        break;
      case Bailout_ShapeGuard:
        if (!HandleShapeGuardFailure(cx, outerScript, innerScript))
            return false;
        break;
      case Bailout_UninitializedLexical:
        if (!HandleLexicalCheckFailure(cx, outerScript, innerScript))
            return false;
        break;
      case Bailout_IonExceptionDebugMode:
        // Return false to resume in HandleException with reconstructed
        // baseline frame.
        return false;
      default:
        MOZ_CRASH("Unknown bailout kind!");
    }

    if (!CheckFrequentBailouts(cx, outerScript, bailoutKind))
        return false;

    // We're returning to JIT code, so we should clear the override pc.
    topFrame->clearOverridePc();
    return true;
}
