/* -*- 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/. */

#ifndef jit_BaselineIC_h
#define jit_BaselineIC_h

#ifdef JS_ION

#include "jscntxt.h"
#include "jscompartment.h"
#include "jsgc.h"
#include "jsopcode.h"
#include "jsproxy.h"
#include "BaselineJIT.h"
#include "BaselineRegisters.h"

#include "gc/Heap.h"

namespace js {
namespace jit {

//
// Baseline Inline Caches are polymorphic caches that aggressively
// share their stub code.
//
// Every polymorphic site contains a linked list of stubs which are
// specific to that site.  These stubs are composed of a |StubData|
// structure that stores parametrization information (e.g.
// the shape pointer for a shape-check-and-property-get stub), any
// dynamic information (e.g. use counts), a pointer to the stub code,
// and a pointer to the next stub state in the linked list.
//
// Every BaselineScript keeps an table of |CacheDescriptor| data
// structures, which store the following:
//      A pointer to the first StubData in the cache.
//      The bytecode PC of the relevant IC.
//      The machine-code PC where the call to the stubcode returns.
//
// A diagram:
//
//        Control flow                  Pointers
//      =======#                     ----.     .---->
//             #                         |     |
//             #======>                  \-----/
//
//
//                                   .---------------------------------------.
//                                   |         .-------------------------.   |
//                                   |         |         .----.          |   |
//         Baseline                  |         |         |    |          |   |
//         JIT Code              0   ^     1   ^     2   ^    |          |   |
//     +--------------+    .-->+-----+   +-----+   +-----+    |          |   |
//     |              |  #=|==>|     |==>|     |==>| FB  |    |          |   |
//     |              |  # |   +-----+   +-----+   +-----+    |          |   |
//     |              |  # |      #         #         #       |          |   |
//     |==============|==# |      #         #         #       |          |   |
//     |=== IC =======|    |      #         #         #       |          |   |
//  .->|==============|<===|======#=========#=========#       |          |   |
//  |  |              |    |                                  |          |   |
//  |  |              |    |                                  |          |   |
//  |  |              |    |                                  |          |   |
//  |  |              |    |                                  v          |   |
//  |  |              |    |                              +---------+    |   |
//  |  |              |    |                              | Fallback|    |   |
//  |  |              |    |                              | Stub    |    |   |
//  |  |              |    |                              | Code    |    |   |
//  |  |              |    |                              +---------+    |   |
//  |  +--------------+    |                                             |   |
//  |         |_______     |                              +---------+    |   |
//  |                |     |                              | Stub    |<---/   |
//  |        IC      |     \--.                           | Code    |        |
//  |    Descriptor  |        |                           +---------+        |
//  |      Table     v        |                                              |
//  |  +-----------------+    |                           +---------+        |
//  \--| Ins | PC | Stub |----/                           | Stub    |<-------/
//     +-----------------+                                | Code    |
//     |       ...       |                                +---------+
//     +-----------------+
//                                                          Shared
//                                                          Stub Code
//
//
// Type ICs
// ========
//
// Type ICs are otherwise regular ICs that are actually nested within
// other IC chains.  They serve to optimize locations in the code where the
// baseline compiler would have otherwise had to perform a type Monitor operation
// (e.g. the result of GetProp, GetElem, etc.), or locations where the baseline
// compiler would have had to modify a heap typeset using the type of an input
// value (e.g. SetProp, SetElem, etc.)
//
// There are two kinds of Type ICs: Monitor and Update.
//
// Note that type stub bodies are no-ops.  The stubs only exist for their
// guards, and their existence simply signifies that the typeset (implicit)
// that is being checked already contains that type.
//
// TypeMonitor ICs
// ---------------
// Monitor ICs are shared between stubs in the general IC, and monitor the resulting
// types of getter operations (call returns, getprop outputs, etc.)
//
//        +-----------+     +-----------+     +-----------+     +-----------+
//   ---->| Stub 1    |---->| Stub 2    |---->| Stub 3    |---->| FB Stub   |
//        +-----------+     +-----------+     +-----------+     +-----------+
//             |                  |                 |                  |
//             |------------------/-----------------/                  |
//             v                                                       |
//        +-----------+     +-----------+     +-----------+            |
//        | Type 1    |---->| Type 2    |---->| Type FB   |            |
//        +-----------+     +-----------+     +-----------+            |
//             |                 |                  |                  |
//  <----------/-----------------/------------------/------------------/
//                r e t u r n    p a t h
//
// After an optimized IC stub successfully executes, it passes control to the type stub
// chain to check the resulting type.  If no type stub succeeds, and the monitor fallback
// stub is reached, the monitor fallback stub performs a manual monitor, and also adds the
// appropriate type stub to the chain.
//
// The IC's main fallback, in addition to generating new mainline stubs, also generates
// type stubs as reflected by its returned value.
//
// NOTE: The type IC chain returns directly to the mainline code, not back to the
// stub it was entered from.  Thus, entering a type IC is a matter of a |jump|, not
// a |call|.  This allows us to safely call a VM Monitor function from within the monitor IC's
// fallback chain, since the return address (needed for stack inspection) is preserved.
//
//
// TypeUpdate ICs
// --------------
// Update ICs update heap typesets and monitor the input types of setter operations
// (setelem, setprop inputs, etc.).  Unlike monitor ICs, they are not shared
// between stubs on an IC, but instead are kept track of on a per-stub basis.
//
// This is because the main stubs for the operation will each identify a potentially
// different TypeObject to update.  New input types must be tracked on a typeobject-to-
// typeobject basis.
//
// Type-update ICs cannot be called in tail position (they must return to the
// the stub that called them so that the stub may continue to perform its original
// purpose).  This means that any VMCall to perform a manual type update from C++ must be
// done from within the main IC stub.  This necessitates that the stub enter a
// "BaselineStub" frame before making the call.
//
// If the type-update IC chain could itself make the VMCall, then the BaselineStub frame
// must be entered before calling the type-update chain, and exited afterward.  This
// is very expensive for a common case where we expect the type-update fallback to not
// be called.  To avoid the cost of entering and exiting a BaselineStub frame when
// using the type-update IC chain, we design the chain to not perform any VM-calls
// in its fallback.
//
// Instead, the type-update IC chain is responsible for returning 1 or 0, depending
// on if a type is represented in the chain or not.  The fallback stub simply returns
// 0, and all other optimized stubs return 1.
// If the chain returns 1, then the IC stub goes ahead and performs its operation.
// If the chain returns 0, then the IC stub performs a call to the fallback function
// inline (doing the requisite BaselineStub frame enter/exit).
// This allows us to avoid the expensive subfram enter/exit in the common case.
//
//                                 r e t u r n    p a t h
//   <--------------.-----------------.-----------------.-----------------.
//                  |                 |                 |                 |
//        +-----------+     +-----------+     +-----------+     +-----------+
//   ---->| Stub 1    |---->| Stub 2    |---->| Stub 3    |---->| FB Stub   |
//        +-----------+     +-----------+     +-----------+     +-----------+
//          |   ^             |   ^             |   ^
//          |   |             |   |             |   |
//          |   |             |   |             |   |----------------.
//          |   |             |   |             v   |1               |0
//          |   |             |   |         +-----------+    +-----------+
//          |   |             |   |         | Type 3.1  |--->|    FB 3   |
//          |   |             |   |         +-----------+    +-----------+
//          |   |             |   |
//          |   |             |   \-------------.-----------------.
//          |   |             |   |             |                 |
//          |   |             v   |1            |1                |0
//          |   |         +-----------+     +-----------+     +-----------+
//          |   |         | Type 2.1  |---->| Type 2.2  |---->|    FB 2   |
//          |   |         +-----------+     +-----------+     +-----------+
//          |   |
//          |   \-------------.-----------------.
//          |   |             |                 |
//          v   |1            |1                |0
//     +-----------+     +-----------+     +-----------+
//     | Type 1.1  |---->| Type 1.2  |---->|   FB 1    |
//     +-----------+     +-----------+     +-----------+
//

class ICStub;
class ICFallbackStub;

//
// An entry in the Baseline IC descriptor table.
//
class ICEntry
{
  private:
    // Offset from the start of the JIT code where the IC
    // load and call instructions are.
    uint32_t returnOffset_;

    // The PC of this IC's bytecode op within the JSScript.
    uint32_t pcOffset_ : 31;

    // Whether this IC is for a bytecode op.
    uint32_t isForOp_ : 1;

    // A pointer to the baseline IC stub for this instruction.
    ICStub *firstStub_;

  public:
    ICEntry(uint32_t pcOffset, bool isForOp)
      : returnOffset_(), pcOffset_(pcOffset), isForOp_(isForOp), firstStub_(NULL)
    {}

    CodeOffsetLabel returnOffset() const {
        return CodeOffsetLabel(returnOffset_);
    }

    void setReturnOffset(CodeOffsetLabel offset) {
        JS_ASSERT(offset.offset() <= (size_t) UINT32_MAX);
        returnOffset_ = (uint32_t) offset.offset();
    }

    void fixupReturnOffset(MacroAssembler &masm) {
        CodeOffsetLabel offset = returnOffset();
        offset.fixup(&masm);
        JS_ASSERT(offset.offset() <= UINT32_MAX);
        returnOffset_ = (uint32_t) offset.offset();
    }

    uint32_t pcOffset() const {
        return pcOffset_;
    }

    jsbytecode *pc(JSScript *script) const {
        return script->code + pcOffset_;
    }

    bool isForOp() const {
        return isForOp_;
    }

    bool hasStub() const {
        return firstStub_ != NULL;
    }
    ICStub *firstStub() const {
        JS_ASSERT(hasStub());
        return firstStub_;
    }

    ICFallbackStub *fallbackStub() const;

    void setFirstStub(ICStub *stub) {
        firstStub_ = stub;
    }

    static inline size_t offsetOfFirstStub() {
        return offsetof(ICEntry, firstStub_);
    }

    inline ICStub **addressOfFirstStub() {
        return &firstStub_;
    }
};

// List of baseline IC stub kinds.
#define IC_STUB_KIND_LIST(_)    \
    _(UseCount_Fallback)        \
                                \
    _(Profiler_Fallback)        \
    _(Profiler_PushFunction)    \
                                \
    _(TypeMonitor_Fallback)     \
    _(TypeMonitor_SingleObject) \
    _(TypeMonitor_TypeObject)   \
    _(TypeMonitor_PrimitiveSet) \
                                \
    _(TypeUpdate_Fallback)      \
    _(TypeUpdate_SingleObject)  \
    _(TypeUpdate_TypeObject)    \
    _(TypeUpdate_PrimitiveSet)  \
                                \
    _(This_Fallback)            \
                                \
    _(NewArray_Fallback)        \
    _(NewObject_Fallback)       \
                                \
    _(Compare_Fallback)         \
    _(Compare_Int32)            \
    _(Compare_Double)           \
    _(Compare_NumberWithUndefined) \
    _(Compare_String)           \
    _(Compare_Boolean)          \
    _(Compare_Object)           \
    _(Compare_ObjectWithUndefined) \
    _(Compare_Int32WithBoolean) \
                                \
    _(ToBool_Fallback)          \
    _(ToBool_Int32)             \
    _(ToBool_String)            \
    _(ToBool_NullUndefined)     \
    _(ToBool_Double)            \
    _(ToBool_Object)            \
                                \
    _(ToNumber_Fallback)        \
                                \
    _(BinaryArith_Fallback)     \
    _(BinaryArith_Int32)        \
    _(BinaryArith_Double)       \
    _(BinaryArith_StringConcat) \
    _(BinaryArith_StringObjectConcat) \
    _(BinaryArith_BooleanWithInt32) \
    _(BinaryArith_DoubleWithInt32) \
                                \
    _(UnaryArith_Fallback)      \
    _(UnaryArith_Int32)         \
    _(UnaryArith_Double)        \
                                \
    _(Call_Fallback)            \
    _(Call_Scripted)            \
    _(Call_AnyScripted)         \
    _(Call_Native)              \
    _(Call_ScriptedApplyArguments) \
                                \
    _(GetElem_Fallback)         \
    _(GetElem_Native)           \
    _(GetElem_NativePrototype)  \
    _(GetElem_String)           \
    _(GetElem_Dense)            \
    _(GetElem_TypedArray)       \
    _(GetElem_Arguments)        \
                                \
    _(SetElem_Fallback)         \
    _(SetElem_Dense)            \
    _(SetElem_DenseAdd)         \
    _(SetElem_TypedArray)       \
                                \
    _(In_Fallback)              \
                                \
    _(GetName_Fallback)         \
    _(GetName_Global)           \
    _(GetName_Scope0)           \
    _(GetName_Scope1)           \
    _(GetName_Scope2)           \
    _(GetName_Scope3)           \
    _(GetName_Scope4)           \
    _(GetName_Scope5)           \
    _(GetName_Scope6)           \
                                \
    _(BindName_Fallback)        \
                                \
    _(GetIntrinsic_Fallback)    \
    _(GetIntrinsic_Constant)    \
                                \
    _(GetProp_Fallback)         \
    _(GetProp_ArrayLength)      \
    _(GetProp_TypedArrayLength) \
    _(GetProp_String)           \
    _(GetProp_StringLength)     \
    _(GetProp_Native)           \
    _(GetProp_NativePrototype)  \
    _(GetProp_CallScripted)     \
    _(GetProp_CallNative)       \
    _(GetProp_CallDOMProxyNative)\
    _(GetProp_CallDOMProxyWithGenerationNative)\
    _(GetProp_DOMProxyShadowed) \
    _(GetProp_ArgumentsLength)  \
                                \
    _(SetProp_Fallback)         \
    _(SetProp_Native)           \
    _(SetProp_NativeAdd)        \
    _(SetProp_CallScripted)     \
    _(SetProp_CallNative)       \
                                \
    _(TableSwitch)              \
                                \
    _(IteratorNew_Fallback)     \
    _(IteratorMore_Fallback)    \
    _(IteratorMore_Native)      \
    _(IteratorNext_Fallback)    \
    _(IteratorNext_Native)      \
    _(IteratorClose_Fallback)   \
                                \
    _(InstanceOf_Fallback)      \
                                \
    _(TypeOf_Fallback)          \
    _(TypeOf_Typed)             \
                                \
    _(Rest_Fallback)            \
                                \
    _(RetSub_Fallback)          \
    _(RetSub_Resume)

#define FORWARD_DECLARE_STUBS(kindName) class IC##kindName;
    IC_STUB_KIND_LIST(FORWARD_DECLARE_STUBS)
#undef FORWARD_DECLARE_STUBS

class ICMonitoredStub;
class ICMonitoredFallbackStub;
class ICUpdatedStub;

// Constant iterator that traverses arbitrary chains of ICStubs.
// No requirements are made of the ICStub used to construct this
// iterator, aside from that the stub be part of a NULL-terminated
// chain.
// The iterator is considered to be at its end once it has been
// incremented _past_ the last stub.  Thus, if 'atEnd()' returns
// true, the '*' and '->' operations are not valid.
class ICStubConstIterator
{
    friend class ICStub;
    friend class ICFallbackStub;

  private:
    ICStub *currentStub_;

  public:
    ICStubConstIterator(ICStub *currentStub) : currentStub_(currentStub) {}

    static ICStubConstIterator StartingAt(ICStub *stub) {
        return ICStubConstIterator(stub);
    }
    static ICStubConstIterator End(ICStub *stub) {
        return ICStubConstIterator(NULL);
    }

    bool operator ==(const ICStubConstIterator &other) const {
        return currentStub_ == other.currentStub_;
    }
    bool operator !=(const ICStubConstIterator &other) const {
        return !(*this == other);
    }

    ICStubConstIterator &operator++();

    ICStubConstIterator operator++(int) {
        ICStubConstIterator oldThis(*this);
        ++(*this);
        return oldThis;
    }

    ICStub *operator *() const {
        JS_ASSERT(currentStub_);
        return currentStub_;
    }

    ICStub *operator ->() const {
        JS_ASSERT(currentStub_);
        return currentStub_;
    }

    bool atEnd() const {
        return currentStub_ == NULL;
    }
};

// Iterator that traverses "regular" IC chains that start at an ICEntry
// and are terminated with an ICFallbackStub.
//
// The iterator is considered to be at its end once it is _at_ the
// fallback stub.  Thus, unlike the ICStubConstIterator, operators
// '*' and '->' are valid even if 'atEnd()' returns true - they
// will act on the fallback stub.
//
// This iterator also allows unlinking of stubs being traversed.
// Note that 'unlink' does not implicitly advance the iterator -
// it must be advanced explicitly using '++'.
class ICStubIterator
{
    friend class ICFallbackStub;

  private:
    ICEntry *icEntry_;
    ICFallbackStub *fallbackStub_;
    ICStub *previousStub_;
    ICStub *currentStub_;
    bool unlinked_;

    ICStubIterator(ICFallbackStub *fallbackStub, bool end=false);
  public:

    bool operator ==(const ICStubIterator &other) const {
        // == should only ever be called on stubs from the same chain.
        JS_ASSERT(icEntry_ == other.icEntry_);
        JS_ASSERT(fallbackStub_ == other.fallbackStub_);
        return currentStub_ == other.currentStub_;
    }
    bool operator !=(const ICStubIterator &other) const {
        return !(*this == other);
    }

    ICStubIterator &operator++();

    ICStubIterator operator++(int) {
        ICStubIterator oldThis(*this);
        ++(*this);
        return oldThis;
    }

    ICStub *operator *() const {
        return currentStub_;
    }

    ICStub *operator ->() const {
        return currentStub_;
    }

    bool atEnd() const {
        return currentStub_ == (ICStub *) fallbackStub_;
    }

    void unlink(Zone *zone);
};

//
// Base class for all IC stubs.
//
class ICStub
{
    friend class ICFallbackStub;

  public:
    enum Kind {
        INVALID = 0,
#define DEF_ENUM_KIND(kindName) kindName,
        IC_STUB_KIND_LIST(DEF_ENUM_KIND)
#undef DEF_ENUM_KIND
        LIMIT
    };

    static inline bool IsValidKind(Kind k) {
        return (k > INVALID) && (k < LIMIT);
    }

    static const char *KindString(Kind k) {
        switch(k) {
#define DEF_KIND_STR(kindName) case kindName: return #kindName;
            IC_STUB_KIND_LIST(DEF_KIND_STR)
#undef DEF_KIND_STR
          default:
            JS_NOT_REACHED("Invalid kind.");
            return "INVALID_KIND";
        }
    }

    enum Trait {
        Regular             = 0x0,
        Fallback            = 0x1,
        Monitored           = 0x2,
        MonitoredFallback   = 0x3,
        Updated             = 0x4
    };

    void markCode(JSTracer *trc, const char *name);
    void updateCode(IonCode *stubCode);
    void trace(JSTracer *trc);

  protected:
    // The kind of the stub.
    //  High bit is 'isFallback' flag.
    //  Second high bit is 'isMonitored' flag.
    Trait trait_ : 3;
    Kind kind_ : 13;

    // A 16-bit field usable by subtypes of ICStub for subtype-specific small-info
    uint16_t extra_;

    // The raw jitcode to call for this stub.
    uint8_t *stubCode_;

    // Pointer to next IC stub.  This is null for the last IC stub, which should
    // either be a fallback or inert IC stub.
    ICStub *next_;

    inline ICStub(Kind kind, IonCode *stubCode)
      : trait_(Regular),
        kind_(kind),
        extra_(0),
        stubCode_(stubCode->raw()),
        next_(NULL)
    {
        JS_ASSERT(stubCode != NULL);
    }

    inline ICStub(Kind kind, Trait trait, IonCode *stubCode)
      : trait_(trait),
        kind_(kind),
        extra_(0),
        stubCode_(stubCode->raw()),
        next_(NULL)
    {
        JS_ASSERT(stubCode != NULL);
    }

    inline Trait trait() const {
        // Workaround for MSVC reading trait_ as signed value.
        return (Trait)(trait_ & 0x7);
    }

  public:

    inline Kind kind() const {
        return static_cast<Kind>(kind_);
    }

    inline bool isFallback() const {
        return trait() == Fallback || trait() == MonitoredFallback;
    }

    inline bool isMonitored() const {
        return trait() == Monitored;
    }

    inline bool isUpdated() const {
        return trait() == Updated;
    }

    inline bool isMonitoredFallback() const {
        return trait() == MonitoredFallback;
    }

    inline const ICFallbackStub *toFallbackStub() const {
        JS_ASSERT(isFallback());
        return reinterpret_cast<const ICFallbackStub *>(this);
    }

    inline ICFallbackStub *toFallbackStub() {
        JS_ASSERT(isFallback());
        return reinterpret_cast<ICFallbackStub *>(this);
    }

    inline const ICMonitoredStub *toMonitoredStub() const {
        JS_ASSERT(isMonitored());
        return reinterpret_cast<const ICMonitoredStub *>(this);
    }

    inline ICMonitoredStub *toMonitoredStub() {
        JS_ASSERT(isMonitored());
        return reinterpret_cast<ICMonitoredStub *>(this);
    }

    inline const ICMonitoredFallbackStub *toMonitoredFallbackStub() const {
        JS_ASSERT(isMonitoredFallback());
        return reinterpret_cast<const ICMonitoredFallbackStub *>(this);
    }

    inline ICMonitoredFallbackStub *toMonitoredFallbackStub() {
        JS_ASSERT(isMonitoredFallback());
        return reinterpret_cast<ICMonitoredFallbackStub *>(this);
    }

    inline const ICUpdatedStub *toUpdatedStub() const {
        JS_ASSERT(isUpdated());
        return reinterpret_cast<const ICUpdatedStub *>(this);
    }

    inline ICUpdatedStub *toUpdatedStub() {
        JS_ASSERT(isUpdated());
        return reinterpret_cast<ICUpdatedStub *>(this);
    }

#define KIND_METHODS(kindName)   \
    inline bool is##kindName() const { return kind() == kindName; } \
    inline const IC##kindName *to##kindName() const { \
        JS_ASSERT(is##kindName()); \
        return reinterpret_cast<const IC##kindName *>(this); \
    } \
    inline IC##kindName *to##kindName() { \
        JS_ASSERT(is##kindName()); \
        return reinterpret_cast<IC##kindName *>(this); \
    }
    IC_STUB_KIND_LIST(KIND_METHODS)
#undef KIND_METHODS

    inline ICStub *next() const {
        return next_;
    }

    inline bool hasNext() const {
        return next_ != NULL;
    }

    inline void setNext(ICStub *stub) {
        next_ = stub;
    }

    inline ICStub **addressOfNext() {
        return &next_;
    }

    inline IonCode *ionCode() {
        return IonCode::FromExecutable(stubCode_);
    }

    inline uint8_t *rawStubCode() const {
        return stubCode_;
    }

    // This method is not valid on TypeUpdate stub chains!
    inline ICFallbackStub *getChainFallback() {
        ICStub *lastStub = this;
        while (lastStub->next_)
            lastStub = lastStub->next_;
        JS_ASSERT(lastStub->isFallback());
        return lastStub->toFallbackStub();
    }

    inline ICStubConstIterator beginHere() {
        return ICStubConstIterator::StartingAt(this);
    }

    static inline size_t offsetOfNext() {
        return offsetof(ICStub, next_);
    }

    static inline size_t offsetOfStubCode() {
        return offsetof(ICStub, stubCode_);
    }

    static inline size_t offsetOfExtra() {
        return offsetof(ICStub, extra_);
    }

    static bool CanMakeCalls(ICStub::Kind kind) {
        JS_ASSERT(IsValidKind(kind));
        switch (kind) {
          case Call_Fallback:
          case Call_Scripted:
          case Call_AnyScripted:
          case Call_Native:
          case Call_ScriptedApplyArguments:
          case UseCount_Fallback:
          case GetProp_CallScripted:
          case GetProp_CallNative:
          case GetProp_CallDOMProxyNative:
          case GetProp_CallDOMProxyWithGenerationNative:
          case GetProp_DOMProxyShadowed:
          case SetProp_CallScripted:
          case SetProp_CallNative:
          case RetSub_Fallback:
            return true;
          default:
            return false;
        }
    }

    // Optimized stubs get purged on GC.  But some stubs can be active on the
    // stack during GC - specifically the ones that can make calls.  To ensure
    // that these do not get purged, all stubs that can make calls are allocated
    // in the fallback stub space.
    bool allocatedInFallbackSpace() const {
        JS_ASSERT(next());
        return CanMakeCalls(kind());
    }
};

class ICFallbackStub : public ICStub
{
    friend class ICStubConstIterator;
  protected:
    // Fallback stubs need these fields to easily add new stubs to
    // the linked list of stubs for an IC.

    // The IC entry for this linked list of stubs.
    ICEntry *icEntry_;

    // The number of stubs kept in the IC entry.
    uint32_t numOptimizedStubs_;

    // A pointer to the location stub pointer that needs to be
    // changed to add a new "last" stub immediately before the fallback
    // stub.  This'll start out pointing to the icEntry's "firstStub_"
    // field, and as new stubs are addd, it'll point to the current
    // last stub's "next_" field.
    ICStub **lastStubPtrAddr_;

    ICFallbackStub(Kind kind, IonCode *stubCode)
      : ICStub(kind, ICStub::Fallback, stubCode),
        icEntry_(NULL),
        numOptimizedStubs_(0),
        lastStubPtrAddr_(NULL) {}

    ICFallbackStub(Kind kind, Trait trait, IonCode *stubCode)
      : ICStub(kind, trait, stubCode),
        icEntry_(NULL),
        numOptimizedStubs_(0),
        lastStubPtrAddr_(NULL)
    {
        JS_ASSERT(trait == ICStub::Fallback ||
                  trait == ICStub::MonitoredFallback);
    }

  public:
    inline ICEntry *icEntry() const {
        return icEntry_;
    }

    inline size_t numOptimizedStubs() const {
        return (size_t) numOptimizedStubs_;
    }

    // The icEntry and lastStubPtrAddr_ fields can't be initialized when the stub is
    // created since the stub is created at compile time, and we won't know the IC entry
    // address until after compile when the BaselineScript is created.  This method
    // allows these fields to be fixed up at that point.
    void fixupICEntry(ICEntry *icEntry) {
        JS_ASSERT(icEntry_ == NULL);
        JS_ASSERT(lastStubPtrAddr_ == NULL);
        icEntry_ = icEntry;
        lastStubPtrAddr_ = icEntry_->addressOfFirstStub();
    }

    // Add a new stub to the IC chain terminated by this fallback stub.
    void addNewStub(ICStub *stub) {
        JS_ASSERT(*lastStubPtrAddr_ == this);
        JS_ASSERT(stub->next() == NULL);
        stub->setNext(this);
        *lastStubPtrAddr_ = stub;
        lastStubPtrAddr_ = stub->addressOfNext();
        numOptimizedStubs_++;
    }

    ICStubConstIterator beginChainConst() const {
        return ICStubConstIterator(icEntry_->firstStub());
    }

    ICStubIterator beginChain() {
        return ICStubIterator(this);
    }

    bool hasStub(ICStub::Kind kind) const {
        for (ICStubConstIterator iter = beginChainConst(); !iter.atEnd(); iter++) {
            if (iter->kind() == kind)
                return true;
        }
        return false;
    }

    unsigned numStubsWithKind(ICStub::Kind kind) const {
        unsigned count = 0;
        for (ICStubConstIterator iter = beginChainConst(); !iter.atEnd(); iter++) {
            if (iter->kind() == kind)
                count++;
        }
        return count;
    }

    void unlinkStub(Zone *zone, ICStub *prev, ICStub *stub);
    void unlinkStubsWithKind(JSContext *cx, ICStub::Kind kind);
};

// Monitored stubs are IC stubs that feed a single resulting value out to a
// type monitor operation.
class ICMonitoredStub : public ICStub
{
  protected:
    // Pointer to the start of the type monitoring stub chain.
    ICStub *firstMonitorStub_;

    ICMonitoredStub(Kind kind, IonCode *stubCode, ICStub *firstMonitorStub);

  public:
    inline void updateFirstMonitorStub(ICStub *monitorStub) {
        // This should only be called once: when the first optimized monitor stub
        // is added to the type monitor IC chain.
        JS_ASSERT(firstMonitorStub_ && firstMonitorStub_->isTypeMonitor_Fallback());
        firstMonitorStub_ = monitorStub;
    }
    inline void resetFirstMonitorStub(ICStub *monitorFallback) {
        JS_ASSERT(monitorFallback->isTypeMonitor_Fallback());
        firstMonitorStub_ = monitorFallback;
    }
    inline ICStub *firstMonitorStub() const {
        return firstMonitorStub_;
    }

    static inline size_t offsetOfFirstMonitorStub() {
        return offsetof(ICMonitoredStub, firstMonitorStub_);
    }
};

// Monitored fallback stubs - as the name implies.
class ICMonitoredFallbackStub : public ICFallbackStub
{
  protected:
    // Pointer to the fallback monitor stub.
    ICTypeMonitor_Fallback *fallbackMonitorStub_;

    ICMonitoredFallbackStub(Kind kind, IonCode *stubCode)
      : ICFallbackStub(kind, ICStub::MonitoredFallback, stubCode),
        fallbackMonitorStub_(NULL) {}

  public:
    bool initMonitoringChain(JSContext *cx, ICStubSpace *space);
    bool addMonitorStubForValue(JSContext *cx, HandleScript script, HandleValue val);

    inline ICTypeMonitor_Fallback *fallbackMonitorStub() const {
        return fallbackMonitorStub_;
    }

    static inline size_t offsetOfFallbackMonitorStub() {
        return offsetof(ICMonitoredFallbackStub, fallbackMonitorStub_);
    }
};

// Updated stubs are IC stubs that use a TypeUpdate IC to track
// the status of heap typesets that need to be updated.
class ICUpdatedStub : public ICStub
{
  protected:
    // Pointer to the start of the type updating stub chain.
    ICStub *firstUpdateStub_;

    static const uint32_t MAX_OPTIMIZED_STUBS = 8;
    uint32_t numOptimizedStubs_;

    ICUpdatedStub(Kind kind, IonCode *stubCode)
      : ICStub(kind, ICStub::Updated, stubCode),
        firstUpdateStub_(NULL),
        numOptimizedStubs_(0)
    {}

  public:
    bool initUpdatingChain(JSContext *cx, ICStubSpace *space);

    bool addUpdateStubForValue(JSContext *cx, HandleScript script, HandleObject obj, HandleId id,
                               HandleValue val);

    void addOptimizedUpdateStub(ICStub *stub) {
        if (firstUpdateStub_->isTypeUpdate_Fallback()) {
            stub->setNext(firstUpdateStub_);
            firstUpdateStub_ = stub;
        } else {
            ICStub *iter = firstUpdateStub_;
            JS_ASSERT(iter->next() != NULL);
            while (!iter->next()->isTypeUpdate_Fallback())
                iter = iter->next();
            JS_ASSERT(iter->next()->next() == NULL);
            stub->setNext(iter->next());
            iter->setNext(stub);
        }

        numOptimizedStubs_++;
    }

    inline ICStub *firstUpdateStub() const {
        return firstUpdateStub_;
    }

    bool hasTypeUpdateStub(ICStub::Kind kind) {
        ICStub *stub = firstUpdateStub_;
        do {
            if (stub->kind() == kind)
                return true;

            stub = stub->next();
        } while (stub);

        return false;
    }

    inline uint32_t numOptimizedStubs() const {
        return numOptimizedStubs_;
    }

    static inline size_t offsetOfFirstUpdateStub() {
        return offsetof(ICUpdatedStub, firstUpdateStub_);
    }
};

// Base class for stubcode compilers.
class ICStubCompiler
{
    // Prevent GC in the middle of stub compilation.
    js::gc::AutoSuppressGC suppressGC;

    mozilla::DebugOnly<bool> entersStubFrame_;

  protected:
    JSContext *cx;
    ICStub::Kind kind;

    // By default the stubcode key is just the kind.
    virtual int32_t getKey() const {
        return static_cast<int32_t>(kind);
    }

    virtual bool generateStubCode(MacroAssembler &masm) = 0;
    virtual bool postGenerateStubCode(MacroAssembler &masm, Handle<IonCode *> genCode) {
        return true;
    }
    IonCode *getStubCode();

    ICStubCompiler(JSContext *cx, ICStub::Kind kind)
      : suppressGC(cx), entersStubFrame_(false), cx(cx), kind(kind)
    {}

    // Emits a tail call to a VMFunction wrapper.
    bool tailCallVM(const VMFunction &fun, MacroAssembler &masm);

    // Emits a normal (non-tail) call to a VMFunction wrapper.
    bool callVM(const VMFunction &fun, MacroAssembler &masm);

    // Emits a call to a type-update IC, assuming that the value to be
    // checked is already in R0.
    bool callTypeUpdateIC(MacroAssembler &masm, uint32_t objectOffset);

    // A stub frame is used when a stub wants to call into the VM without
    // performing a tail call. This is required for the return address
    // to pc mapping to work.
    void enterStubFrame(MacroAssembler &masm, Register scratch);
    void leaveStubFrame(MacroAssembler &masm, bool calledIntoIon = false);

    // Some stubs need to emit SPS profiler updates.  This emits the guarding
    // jitcode for those stubs.  If profiling is not enabled, jumps to the
    // given label.
    void guardProfilingEnabled(MacroAssembler &masm, Register scratch, Label *skip);

    inline GeneralRegisterSet availableGeneralRegs(size_t numInputs) const {
        GeneralRegisterSet regs(GeneralRegisterSet::All());
        JS_ASSERT(!regs.has(BaselineStackReg));

#ifdef JS_CPU_ARM
        JS_ASSERT(!regs.has(BaselineTailCallReg));
#elif defined(JS_CPU_MIPS)
        JS_ASSERT(!regs.has(BaselineTailCallReg));
        JS_ASSERT(!regs.has(BaselineSecondScratchReg));
#endif

        regs.take(BaselineFrameReg);
        regs.take(BaselineStubReg);

#ifdef JS_CPU_X64
        regs.take(ExtractTemp0);
        regs.take(ExtractTemp1);
#endif

        switch (numInputs) {
          case 0:
            break;
          case 1:
            regs.take(R0);
            break;
          case 2:
            regs.take(R0);
            regs.take(R1);
            break;
          default:
            JS_NOT_REACHED("Invalid numInputs");
        }

        return regs;
    }

#ifdef JSGC_GENERATIONAL
    inline bool emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, Register scratch,
                                         GeneralRegisterSet saveRegs);
#endif

  public:
    virtual ICStub *getStub(ICStubSpace *space) = 0;

    ICStubSpace *getStubSpace(JSScript *script) {
        if (ICStub::CanMakeCalls(kind))
            return script->baselineScript()->fallbackStubSpace();
        return script->compartment()->ionCompartment()->optimizedStubSpace();
    }
};

// Base class for stub compilers that can generate multiple stubcodes.
// These compilers need access to the JSOp they are compiling for.
class ICMultiStubCompiler : public ICStubCompiler
{
  protected:
    JSOp op;

    // Stub keys for multi-stub kinds are composed of both the kind
    // and the op they are compiled for.
    virtual int32_t getKey() const {
        return static_cast<int32_t>(kind) | (static_cast<int32_t>(op) << 16);
    }

    ICMultiStubCompiler(JSContext *cx, ICStub::Kind kind, JSOp op)
      : ICStubCompiler(cx, kind), op(op) {}
};

// UseCount_Fallback

// A UseCount IC chain has only the fallback stub.
class ICUseCount_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICUseCount_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::UseCount_Fallback, stubCode)
    { }

  public:
    static inline ICUseCount_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICUseCount_Fallback>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::UseCount_Fallback)
        { }

        ICUseCount_Fallback *getStub(ICStubSpace *space) {
            return ICUseCount_Fallback::New(space, getStubCode());
        }
    };
};

// Profiler_Fallback

class ICProfiler_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICProfiler_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::Profiler_Fallback, stubCode)
    { }

  public:
    static inline ICProfiler_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICProfiler_Fallback>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::Profiler_Fallback)
        { }

        ICProfiler_Fallback *getStub(ICStubSpace *space) {
            return ICProfiler_Fallback::New(space, getStubCode());
        }
    };
};

// Profiler_PushFunction

class ICProfiler_PushFunction : public ICStub
{
    friend class ICStubSpace;

  protected:
    const char *str_;
    HeapPtrScript script_;

    ICProfiler_PushFunction(IonCode *stubCode, const char *str, HandleScript script);

  public:
    static inline ICProfiler_PushFunction *New(ICStubSpace *space, IonCode *code,
                                               const char *str, HandleScript script)
    {
        if (!code)
            return NULL;
        return space->allocate<ICProfiler_PushFunction>(code, str, script);
    }

    HeapPtrScript &script() {
        return script_;
    }

    static size_t offsetOfStr() {
        return offsetof(ICProfiler_PushFunction, str_);
    }
    static size_t offsetOfScript() {
        return offsetof(ICProfiler_PushFunction, script_);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        const char *str_;
        RootedScript script_;
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, const char *str, HandleScript script)
          : ICStubCompiler(cx, ICStub::Profiler_PushFunction),
            str_(str),
            script_(cx, script)
        { }

        ICProfiler_PushFunction *getStub(ICStubSpace *space) {
            return ICProfiler_PushFunction::New(space, getStubCode(), str_, script_);
        }
    };
};


// TypeCheckPrimitiveSetStub
//   Base class for IC stubs (TypeUpdate or TypeMonitor) that check that a given
//   value's type falls within a set of primitive types.

class TypeCheckPrimitiveSetStub : public ICStub
{
    friend class ICStubSpace;
  protected:
    inline static uint16_t TypeToFlag(JSValueType type) {
        return 1u << static_cast<unsigned>(type);
    }

    inline static uint16_t ValidFlags() {
        return ((TypeToFlag(JSVAL_TYPE_OBJECT) << 1) - 1) & ~TypeToFlag(JSVAL_TYPE_MAGIC);
    }

    TypeCheckPrimitiveSetStub(Kind kind, IonCode *stubCode, uint16_t flags)
        : ICStub(kind, stubCode)
    {
        JS_ASSERT(kind == TypeMonitor_PrimitiveSet || kind == TypeUpdate_PrimitiveSet);
        JS_ASSERT(flags && !(flags & ~ValidFlags()));
        extra_ = flags;
    }

    TypeCheckPrimitiveSetStub *updateTypesAndCode(uint16_t flags, IonCode *code) {
        JS_ASSERT(flags && !(flags & ~ValidFlags()));
        if (!code)
            return NULL;
        extra_ = flags;
        updateCode(code);
        return this;
    }

  public:
    uint16_t typeFlags() const {
        return extra_;
    }

    bool containsType(JSValueType type) const {
        JS_ASSERT(type <= JSVAL_TYPE_OBJECT);
        JS_ASSERT(type != JSVAL_TYPE_MAGIC);
        return extra_ & TypeToFlag(type);
    }

    ICTypeMonitor_PrimitiveSet *toMonitorStub() {
        return toTypeMonitor_PrimitiveSet();
    }

    ICTypeUpdate_PrimitiveSet *toUpdateStub() {
        return toTypeUpdate_PrimitiveSet();
    }

    class Compiler : public ICStubCompiler {
      protected:
        TypeCheckPrimitiveSetStub *existingStub_;
        uint16_t flags_;

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(flags_) << 16);
        }

      public:
        Compiler(JSContext *cx, Kind kind, TypeCheckPrimitiveSetStub *existingStub,
                 JSValueType type)
          : ICStubCompiler(cx, kind),
            existingStub_(existingStub),
            flags_((existingStub ? existingStub->typeFlags() : 0) | TypeToFlag(type))
        {
            JS_ASSERT_IF(existingStub_, flags_ != existingStub_->typeFlags());
        }

        TypeCheckPrimitiveSetStub *updateStub() {
            JS_ASSERT(existingStub_);
            return existingStub_->updateTypesAndCode(flags_, getStubCode());
        }
    };
};

// TypeMonitor

// The TypeMonitor fallback stub is not always a regular fallback stub. When
// used for monitoring the values pushed by a bytecode it doesn't hold a
// pointer to the IC entry, but rather back to the main fallback stub for the
// IC (from which a pointer to the IC entry can be retrieved). When monitoring
// the types of 'this', arguments or other values with no associated IC, there
// is no main fallback stub, and the IC entry is referenced directly.
class ICTypeMonitor_Fallback : public ICStub
{
    friend class ICStubSpace;

    static const uint32_t MAX_OPTIMIZED_STUBS = 8;

    // Pointer to the main fallback stub for the IC or to the main IC entry,
    // depending on hasFallbackStub.
    union {
        ICMonitoredFallbackStub *mainFallbackStub_;
        ICEntry *icEntry_;
    };

    // Pointer to the first monitor stub.
    ICStub *firstMonitorStub_;

    // Address of the last monitor stub's field pointing to this
    // fallback monitor stub.  This will get updated when new
    // monitor stubs are created and added.
    ICStub **lastMonitorStubPtrAddr_;

    // Count of optimized type monitor stubs in this chain.
    uint32_t numOptimizedMonitorStubs_ : 8;

    // Whether this has a fallback stub referring to the IC entry.
    bool hasFallbackStub_ : 1;

    // Index of 'this' or argument which is being monitored, or BYTECODE_INDEX
    // if this is monitoring the types of values pushed at some bytecode.
    uint32_t argumentIndex_ : 23;

    static const uint32_t BYTECODE_INDEX = (1 << 23) - 1;

    ICTypeMonitor_Fallback(IonCode *stubCode, ICMonitoredFallbackStub *mainFallbackStub,
                           uint32_t argumentIndex)
      : ICStub(ICStub::TypeMonitor_Fallback, stubCode),
        mainFallbackStub_(mainFallbackStub),
        firstMonitorStub_(thisFromCtor()),
        lastMonitorStubPtrAddr_(NULL),
        numOptimizedMonitorStubs_(0),
        hasFallbackStub_(mainFallbackStub != NULL),
        argumentIndex_(argumentIndex)
    { }

    ICTypeMonitor_Fallback *thisFromCtor() {
        return this;
    }

    void addOptimizedMonitorStub(ICStub *stub) {
        stub->setNext(this);

        JS_ASSERT((lastMonitorStubPtrAddr_ != NULL) ==
                  (numOptimizedMonitorStubs_ || !hasFallbackStub_));

        if (lastMonitorStubPtrAddr_)
            *lastMonitorStubPtrAddr_ = stub;

        if (numOptimizedMonitorStubs_ == 0) {
            JS_ASSERT(firstMonitorStub_ == this);
            firstMonitorStub_ = stub;
        } else {
            JS_ASSERT(firstMonitorStub_ != NULL);
        }

        lastMonitorStubPtrAddr_ = stub->addressOfNext();
        numOptimizedMonitorStubs_++;
    }

  public:
    static inline ICTypeMonitor_Fallback *New(
        ICStubSpace *space, IonCode *code, ICMonitoredFallbackStub *mainFbStub,
        uint32_t argumentIndex)
    {
        if (!code)
            return NULL;
        return space->allocate<ICTypeMonitor_Fallback>(code, mainFbStub, argumentIndex);
    }

    bool hasStub(ICStub::Kind kind) {
        ICStub *stub = firstMonitorStub_;
        do {
            if (stub->kind() == kind)
                return true;

            stub = stub->next();
        } while (stub);

        return false;
    }

    inline ICFallbackStub *mainFallbackStub() const {
        JS_ASSERT(hasFallbackStub_);
        return mainFallbackStub_;
    }

    inline ICEntry *icEntry() const {
        return hasFallbackStub_ ? mainFallbackStub()->icEntry() : icEntry_;
    }

    inline ICStub *firstMonitorStub() const {
        return firstMonitorStub_;
    }

    static inline size_t offsetOfFirstMonitorStub() {
        return offsetof(ICTypeMonitor_Fallback, firstMonitorStub_);
    }

    inline uint32_t numOptimizedMonitorStubs() const {
        return numOptimizedMonitorStubs_;
    }

    inline bool monitorsThis() const {
        return argumentIndex_ == 0;
    }

    inline bool monitorsArgument(uint32_t *pargument) const {
        if (argumentIndex_ > 0 && argumentIndex_ < BYTECODE_INDEX) {
            *pargument = argumentIndex_ - 1;
            return true;
        }
        return false;
    }

    inline bool monitorsBytecode() const {
        return argumentIndex_ == BYTECODE_INDEX;
    }

    // Fixup the IC entry as for a normal fallback stub, for this/arguments.
    void fixupICEntry(ICEntry *icEntry) {
        JS_ASSERT(!hasFallbackStub_);
        JS_ASSERT(icEntry_ == NULL);
        JS_ASSERT(lastMonitorStubPtrAddr_ == NULL);
        icEntry_ = icEntry;
        lastMonitorStubPtrAddr_ = icEntry_->addressOfFirstStub();
    }

    // Create a new monitor stub for the type of the given value, and
    // add it to this chain.
    bool addMonitorStubForValue(JSContext *cx, HandleScript script, HandleValue val);

    void resetMonitorStubChain(Zone *zone);

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
        ICMonitoredFallbackStub *mainFallbackStub_;
        uint32_t argumentIndex_;

      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, ICMonitoredFallbackStub *mainFallbackStub)
          : ICStubCompiler(cx, ICStub::TypeMonitor_Fallback),
            mainFallbackStub_(mainFallbackStub),
            argumentIndex_(BYTECODE_INDEX)
        { }

        Compiler(JSContext *cx, uint32_t argumentIndex)
          : ICStubCompiler(cx, ICStub::TypeMonitor_Fallback),
            mainFallbackStub_(NULL),
            argumentIndex_(argumentIndex)
        { }

        ICTypeMonitor_Fallback *getStub(ICStubSpace *space) {
            return ICTypeMonitor_Fallback::New(space, getStubCode(), mainFallbackStub_,
                                               argumentIndex_);
        }
    };
};

class ICTypeMonitor_PrimitiveSet : public TypeCheckPrimitiveSetStub
{
    friend class ICStubSpace;

    ICTypeMonitor_PrimitiveSet(IonCode *stubCode, uint16_t flags)
        : TypeCheckPrimitiveSetStub(TypeMonitor_PrimitiveSet, stubCode, flags)
    {}

  public:
    static inline ICTypeMonitor_PrimitiveSet *New(ICStubSpace *space, IonCode *code,
                                                  uint16_t flags)
    {
        if (!code)
            return NULL;
        return space->allocate<ICTypeMonitor_PrimitiveSet>(code, flags);
    }

    class Compiler : public TypeCheckPrimitiveSetStub::Compiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, ICTypeMonitor_PrimitiveSet *existingStub, JSValueType type)
          : TypeCheckPrimitiveSetStub::Compiler(cx, TypeMonitor_PrimitiveSet, existingStub, type)
        {}

        ICTypeMonitor_PrimitiveSet *updateStub() {
            TypeCheckPrimitiveSetStub *stub =
                this->TypeCheckPrimitiveSetStub::Compiler::updateStub();
            if (!stub)
                return NULL;
            return stub->toMonitorStub();
        }

        ICTypeMonitor_PrimitiveSet *getStub(ICStubSpace *space) {
            JS_ASSERT(!existingStub_);
            return ICTypeMonitor_PrimitiveSet::New(space, getStubCode(), flags_);
        }
    };
};

class ICTypeMonitor_SingleObject : public ICStub
{
    friend class ICStubSpace;

    HeapPtrObject obj_;

    ICTypeMonitor_SingleObject(IonCode *stubCode, HandleObject obj);

  public:
    static inline ICTypeMonitor_SingleObject *New(
            ICStubSpace *space, IonCode *code, HandleObject obj)
    {
        if (!code)
            return NULL;
        return space->allocate<ICTypeMonitor_SingleObject>(code, obj);
    }

    HeapPtrObject &object() {
        return obj_;
    }

    static size_t offsetOfObject() {
        return offsetof(ICTypeMonitor_SingleObject, obj_);
    }

    class Compiler : public ICStubCompiler {
      protected:
        HandleObject obj_;
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, HandleObject obj)
          : ICStubCompiler(cx, TypeMonitor_SingleObject),
            obj_(obj)
        { }

        ICTypeMonitor_SingleObject *getStub(ICStubSpace *space) {
            return ICTypeMonitor_SingleObject::New(space, getStubCode(), obj_);
        }
    };
};

class ICTypeMonitor_TypeObject : public ICStub
{
    friend class ICStubSpace;

    HeapPtrTypeObject type_;

    ICTypeMonitor_TypeObject(IonCode *stubCode, HandleTypeObject type);

  public:
    static inline ICTypeMonitor_TypeObject *New(
            ICStubSpace *space, IonCode *code, HandleTypeObject type)
    {
        if (!code)
            return NULL;
        return space->allocate<ICTypeMonitor_TypeObject>(code, type);
    }

    HeapPtrTypeObject &type() {
        return type_;
    }

    static size_t offsetOfType() {
        return offsetof(ICTypeMonitor_TypeObject, type_);
    }

    class Compiler : public ICStubCompiler {
      protected:
        HandleTypeObject type_;
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, HandleTypeObject type)
          : ICStubCompiler(cx, TypeMonitor_TypeObject),
            type_(type)
        { }

        ICTypeMonitor_TypeObject *getStub(ICStubSpace *space) {
            return ICTypeMonitor_TypeObject::New(space, getStubCode(), type_);
        }
    };
};

// TypeUpdate

extern const VMFunction DoTypeUpdateFallbackInfo;

// The TypeUpdate fallback is not a regular fallback, since it just
// forwards to a different entry point in the main fallback stub.
class ICTypeUpdate_Fallback : public ICStub
{
    friend class ICStubSpace;

    ICTypeUpdate_Fallback(IonCode *stubCode)
      : ICStub(ICStub::TypeUpdate_Fallback, stubCode)
    {}

  public:
    static inline ICTypeUpdate_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICTypeUpdate_Fallback>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::TypeUpdate_Fallback)
        { }

        ICTypeUpdate_Fallback *getStub(ICStubSpace *space) {
            return ICTypeUpdate_Fallback::New(space, getStubCode());
        }
    };
};

class ICTypeUpdate_PrimitiveSet : public TypeCheckPrimitiveSetStub
{
    friend class ICStubSpace;

    ICTypeUpdate_PrimitiveSet(IonCode *stubCode, uint16_t flags)
        : TypeCheckPrimitiveSetStub(TypeUpdate_PrimitiveSet, stubCode, flags)
    {}

  public:
    static inline ICTypeUpdate_PrimitiveSet *New(ICStubSpace *space, IonCode *code,
                                                 uint16_t flags)
    {
        if (!code)
            return NULL;
        return space->allocate<ICTypeUpdate_PrimitiveSet>(code, flags);
    }

    class Compiler : public TypeCheckPrimitiveSetStub::Compiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, ICTypeUpdate_PrimitiveSet *existingStub, JSValueType type)
          : TypeCheckPrimitiveSetStub::Compiler(cx, TypeUpdate_PrimitiveSet, existingStub, type)
        {}

        ICTypeUpdate_PrimitiveSet *updateStub() {
            TypeCheckPrimitiveSetStub *stub =
                this->TypeCheckPrimitiveSetStub::Compiler::updateStub();
            if (!stub)
                return NULL;
            return stub->toUpdateStub();
        }

        ICTypeUpdate_PrimitiveSet *getStub(ICStubSpace *space) {
            JS_ASSERT(!existingStub_);
            return ICTypeUpdate_PrimitiveSet::New(space, getStubCode(), flags_);
        }
    };
};

// Type update stub to handle a singleton object.
class ICTypeUpdate_SingleObject : public ICStub
{
    friend class ICStubSpace;

    HeapPtrObject obj_;

    ICTypeUpdate_SingleObject(IonCode *stubCode, HandleObject obj);

  public:
    static inline ICTypeUpdate_SingleObject *New(ICStubSpace *space, IonCode *code,
                                                 HandleObject obj)
    {
        if (!code)
            return NULL;
        return space->allocate<ICTypeUpdate_SingleObject>(code, obj);
    }

    HeapPtrObject &object() {
        return obj_;
    }

    static size_t offsetOfObject() {
        return offsetof(ICTypeUpdate_SingleObject, obj_);
    }

    class Compiler : public ICStubCompiler {
      protected:
        HandleObject obj_;
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, HandleObject obj)
          : ICStubCompiler(cx, TypeUpdate_SingleObject),
            obj_(obj)
        { }

        ICTypeUpdate_SingleObject *getStub(ICStubSpace *space) {
            return ICTypeUpdate_SingleObject::New(space, getStubCode(), obj_);
        }
    };
};

// Type update stub to handle a single TypeObject.
class ICTypeUpdate_TypeObject : public ICStub
{
    friend class ICStubSpace;

    HeapPtrTypeObject type_;

    ICTypeUpdate_TypeObject(IonCode *stubCode, HandleTypeObject type);

  public:
    static inline ICTypeUpdate_TypeObject *New(ICStubSpace *space, IonCode *code,
                                               HandleTypeObject type)
    {
        if (!code)
            return NULL;
        return space->allocate<ICTypeUpdate_TypeObject>(code, type);
    }

    HeapPtrTypeObject &type() {
        return type_;
    }

    static size_t offsetOfType() {
        return offsetof(ICTypeUpdate_TypeObject, type_);
    }

    class Compiler : public ICStubCompiler {
      protected:
        HandleTypeObject type_;
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, HandleTypeObject type)
          : ICStubCompiler(cx, TypeUpdate_TypeObject),
            type_(type)
        { }

        ICTypeUpdate_TypeObject *getStub(ICStubSpace *space) {
            return ICTypeUpdate_TypeObject::New(space, getStubCode(), type_);
        }
    };
};

// This
//      JSOP_THIS

class ICThis_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICThis_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::This_Fallback, stubCode) {}

  public:
    static inline ICThis_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICThis_Fallback>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::This_Fallback) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICThis_Fallback::New(space, getStubCode());
        }
    };
};

class ICNewArray_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICNewArray_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::NewArray_Fallback, stubCode)
    {}

  public:
    static inline ICNewArray_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICNewArray_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::NewArray_Fallback)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICNewArray_Fallback::New(space, getStubCode());
        }
    };
};

class ICNewObject_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICNewObject_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::NewObject_Fallback, stubCode)
    {}

  public:
    static inline ICNewObject_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICNewObject_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::NewObject_Fallback)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICNewObject_Fallback::New(space, getStubCode());
        }
    };
};

// Compare
//      JSOP_LT
//      JSOP_GT

class ICCompare_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICCompare_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::Compare_Fallback, stubCode) {}

  public:
    static const uint32_t MAX_OPTIMIZED_STUBS = 8;

    static inline ICCompare_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICCompare_Fallback>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::Compare_Fallback) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICCompare_Fallback::New(space, getStubCode());
        }
    };
};

class ICCompare_Int32 : public ICStub
{
    friend class ICStubSpace;

    ICCompare_Int32(IonCode *stubCode)
      : ICStub(ICStub::Compare_Int32, stubCode) {}

  public:
    static inline ICCompare_Int32 *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICCompare_Int32>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICMultiStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, JSOp op)
          : ICMultiStubCompiler(cx, ICStub::Compare_Int32, op) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICCompare_Int32::New(space, getStubCode());
        }
    };
};

class ICCompare_Double : public ICStub
{
    friend class ICStubSpace;

    ICCompare_Double(IonCode *stubCode)
      : ICStub(ICStub::Compare_Double, stubCode)
    {}

  public:
    static inline ICCompare_Double *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICCompare_Double>(code);
    }

    class Compiler : public ICMultiStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, JSOp op)
          : ICMultiStubCompiler(cx, ICStub::Compare_Double, op)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICCompare_Double::New(space, getStubCode());
        }
    };
};

class ICCompare_NumberWithUndefined : public ICStub
{
    friend class ICStubSpace;

    ICCompare_NumberWithUndefined(IonCode *stubCode, bool lhsIsUndefined)
      : ICStub(ICStub::Compare_NumberWithUndefined, stubCode)
    {
        extra_ = lhsIsUndefined;
    }

  public:
    static inline ICCompare_NumberWithUndefined *New(ICStubSpace *space, IonCode *code, bool lhsIsUndefined) {
        if (!code)
            return NULL;
        return space->allocate<ICCompare_NumberWithUndefined>(code, lhsIsUndefined);
    }

    bool lhsIsUndefined() {
        return extra_;
    }

    class Compiler : public ICMultiStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

        bool lhsIsUndefined;

      public:
        Compiler(JSContext *cx, JSOp op, bool lhsIsUndefined)
          : ICMultiStubCompiler(cx, ICStub::Compare_NumberWithUndefined, op),
            lhsIsUndefined(lhsIsUndefined)
        {}

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind)
                 | (static_cast<int32_t>(op) << 16)
                 | (static_cast<int32_t>(lhsIsUndefined) << 24);
        }

        ICStub *getStub(ICStubSpace *space) {
            return ICCompare_NumberWithUndefined::New(space, getStubCode(), lhsIsUndefined);
        }
    };
};

class ICCompare_String : public ICStub
{
    friend class ICStubSpace;

    ICCompare_String(IonCode *stubCode)
      : ICStub(ICStub::Compare_String, stubCode)
    {}

  public:
    static inline ICCompare_String *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICCompare_String>(code);
    }

    class Compiler : public ICMultiStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, JSOp op)
          : ICMultiStubCompiler(cx, ICStub::Compare_String, op)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICCompare_String::New(space, getStubCode());
        }
    };
};

class ICCompare_Boolean : public ICStub
{
    friend class ICStubSpace;

    ICCompare_Boolean(IonCode *stubCode)
      : ICStub(ICStub::Compare_Boolean, stubCode)
    {}

  public:
    static inline ICCompare_Boolean *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICCompare_Boolean>(code);
    }

    class Compiler : public ICMultiStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, JSOp op)
          : ICMultiStubCompiler(cx, ICStub::Compare_Boolean, op)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICCompare_Boolean::New(space, getStubCode());
        }
    };
};

class ICCompare_Object : public ICStub
{
    friend class ICStubSpace;

    ICCompare_Object(IonCode *stubCode)
      : ICStub(ICStub::Compare_Object, stubCode)
    {}

  public:
    static inline ICCompare_Object *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICCompare_Object>(code);
    }

    class Compiler : public ICMultiStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, JSOp op)
          : ICMultiStubCompiler(cx, ICStub::Compare_Object, op)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICCompare_Object::New(space, getStubCode());
        }
    };
};

class ICCompare_ObjectWithUndefined : public ICStub
{
    friend class ICStubSpace;

    ICCompare_ObjectWithUndefined(IonCode *stubCode)
      : ICStub(ICStub::Compare_ObjectWithUndefined, stubCode)
    {}

  public:
    static inline ICCompare_ObjectWithUndefined *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICCompare_ObjectWithUndefined>(code);
    }

    class Compiler : public ICMultiStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

        bool lhsIsUndefined;
        bool compareWithNull;

      public:
        Compiler(JSContext *cx, JSOp op, bool lhsIsUndefined, bool compareWithNull)
          : ICMultiStubCompiler(cx, ICStub::Compare_ObjectWithUndefined, op),
            lhsIsUndefined(lhsIsUndefined),
            compareWithNull(compareWithNull)
        {}

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind)
                 | (static_cast<int32_t>(op) << 16)
                 | (static_cast<int32_t>(lhsIsUndefined) << 24)
                 | (static_cast<int32_t>(compareWithNull) << 25);
        }

        ICStub *getStub(ICStubSpace *space) {
            return ICCompare_ObjectWithUndefined::New(space, getStubCode());
        }
    };
};

class ICCompare_Int32WithBoolean : public ICStub
{
    friend class ICStubSpace;

    ICCompare_Int32WithBoolean(IonCode *stubCode, bool lhsIsInt32)
      : ICStub(ICStub::Compare_Int32WithBoolean, stubCode)
    {
        extra_ = lhsIsInt32;
    }

  public:
    static inline ICCompare_Int32WithBoolean *New(ICStubSpace *space, IonCode *code,
                                                  bool lhsIsInt32)
    {
        if (!code)
            return NULL;
        return space->allocate<ICCompare_Int32WithBoolean>(code, lhsIsInt32);
    }

    bool lhsIsInt32() const {
        return extra_;
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        JSOp op_;
        bool lhsIsInt32_;
        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return (static_cast<int32_t>(kind) | (static_cast<int32_t>(op_) << 16) |
                    (static_cast<int32_t>(lhsIsInt32_) << 24));
        }

      public:
        Compiler(JSContext *cx, JSOp op, bool lhsIsInt32)
          : ICStubCompiler(cx, ICStub::Compare_Int32WithBoolean),
            op_(op),
            lhsIsInt32_(lhsIsInt32)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICCompare_Int32WithBoolean::New(space, getStubCode(), lhsIsInt32_);
        }
    };
};

// ToBool
//      JSOP_IFNE

class ICToBool_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICToBool_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::ToBool_Fallback, stubCode) {}

  public:
    static const uint32_t MAX_OPTIMIZED_STUBS = 8;

    static inline ICToBool_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICToBool_Fallback>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::ToBool_Fallback) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICToBool_Fallback::New(space, getStubCode());
        }
    };
};

class ICToBool_Int32 : public ICStub
{
    friend class ICStubSpace;

    ICToBool_Int32(IonCode *stubCode)
      : ICStub(ICStub::ToBool_Int32, stubCode) {}

  public:
    static inline ICToBool_Int32 *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICToBool_Int32>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::ToBool_Int32) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICToBool_Int32::New(space, getStubCode());
        }
    };
};

class ICToBool_String : public ICStub
{
    friend class ICStubSpace;

    ICToBool_String(IonCode *stubCode)
      : ICStub(ICStub::ToBool_String, stubCode) {}

  public:
    static inline ICToBool_String *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICToBool_String>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::ToBool_String) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICToBool_String::New(space, getStubCode());
        }
    };
};

class ICToBool_NullUndefined : public ICStub
{
    friend class ICStubSpace;

    ICToBool_NullUndefined(IonCode *stubCode)
      : ICStub(ICStub::ToBool_NullUndefined, stubCode) {}

  public:
    static inline ICToBool_NullUndefined *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICToBool_NullUndefined>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::ToBool_NullUndefined) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICToBool_NullUndefined::New(space, getStubCode());
        }
    };
};

class ICToBool_Double : public ICStub
{
    friend class ICStubSpace;

    ICToBool_Double(IonCode *stubCode)
      : ICStub(ICStub::ToBool_Double, stubCode) {}

  public:
    static inline ICToBool_Double *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICToBool_Double>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::ToBool_Double) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICToBool_Double::New(space, getStubCode());
        }
    };
};

class ICToBool_Object : public ICStub
{
    friend class ICStubSpace;

    ICToBool_Object(IonCode *stubCode)
      : ICStub(ICStub::ToBool_Object, stubCode) {}

  public:
    static inline ICToBool_Object *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICToBool_Object>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::ToBool_Object) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICToBool_Object::New(space, getStubCode());
        }
    };
};

// ToNumber
//     JSOP_POS

class ICToNumber_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICToNumber_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::ToNumber_Fallback, stubCode) {}

  public:
    static inline ICToNumber_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICToNumber_Fallback>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::ToNumber_Fallback) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICToNumber_Fallback::New(space, getStubCode());
        }
    };
};

// BinaryArith
//      JSOP_ADD
//      JSOP_BITAND, JSOP_BITXOR, JSOP_BITOR
//      JSOP_LSH, JSOP_RSH, JSOP_URSH

class ICBinaryArith_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICBinaryArith_Fallback(IonCode *stubCode)
      : ICFallbackStub(BinaryArith_Fallback, stubCode)
    {
        extra_ = 0;
    }

  public:
    static const uint32_t MAX_OPTIMIZED_STUBS = 8;

    static inline ICBinaryArith_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICBinaryArith_Fallback>(code);
    }

    bool sawDoubleResult() {
        return extra_;
    }
    void setSawDoubleResult() {
        extra_ = 1;
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::BinaryArith_Fallback) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICBinaryArith_Fallback::New(space, getStubCode());
        }
    };
};

class ICBinaryArith_Int32 : public ICStub
{
    friend class ICStubSpace;

    ICBinaryArith_Int32(IonCode *stubCode, bool allowDouble)
      : ICStub(BinaryArith_Int32, stubCode)
    {
        extra_ = allowDouble;
    }

  public:
    static inline ICBinaryArith_Int32 *New(ICStubSpace *space, IonCode *code, bool allowDouble) {
        if (!code)
            return NULL;
        return space->allocate<ICBinaryArith_Int32>(code, allowDouble);
    }
    bool allowDouble() const {
        return extra_;
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        JSOp op_;
        bool allowDouble_;

        bool generateStubCode(MacroAssembler &masm);

        // Stub keys shift-stubs need to encode the kind, the JSOp and if we allow doubles.
        virtual int32_t getKey() const {
            return (static_cast<int32_t>(kind) | (static_cast<int32_t>(op_) << 16) |
                    (static_cast<int32_t>(allowDouble_) << 24));
        }

      public:
        Compiler(JSContext *cx, JSOp op, bool allowDouble)
          : ICStubCompiler(cx, ICStub::BinaryArith_Int32),
            op_(op), allowDouble_(allowDouble) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICBinaryArith_Int32::New(space, getStubCode(), allowDouble_);
        }
    };
};

class ICBinaryArith_StringConcat : public ICStub
{
    friend class ICStubSpace;

    ICBinaryArith_StringConcat(IonCode *stubCode)
      : ICStub(BinaryArith_StringConcat, stubCode)
    {}

  public:
    static inline ICBinaryArith_StringConcat *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICBinaryArith_StringConcat>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::BinaryArith_StringConcat)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICBinaryArith_StringConcat::New(space, getStubCode());
        }
    };
};

class ICBinaryArith_StringObjectConcat : public ICStub
{
    friend class ICStubSpace;

    ICBinaryArith_StringObjectConcat(IonCode *stubCode, bool lhsIsString)
      : ICStub(BinaryArith_StringObjectConcat, stubCode)
    {
        extra_ = lhsIsString;
    }

  public:
    static inline ICBinaryArith_StringObjectConcat *New(ICStubSpace *space, IonCode *code,
                                                        bool lhsIsString) {
        if (!code)
            return NULL;
        return space->allocate<ICBinaryArith_StringObjectConcat>(code, lhsIsString);
    }

    bool lhsIsString() const {
        return extra_;
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool lhsIsString_;
        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(lhsIsString_) << 16);
        }

      public:
        Compiler(JSContext *cx, bool lhsIsString)
          : ICStubCompiler(cx, ICStub::BinaryArith_StringObjectConcat),
            lhsIsString_(lhsIsString)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICBinaryArith_StringObjectConcat::New(space, getStubCode(), lhsIsString_);
        }
    };
};

class ICBinaryArith_Double : public ICStub
{
    friend class ICStubSpace;

    ICBinaryArith_Double(IonCode *stubCode)
      : ICStub(BinaryArith_Double, stubCode)
    {}

  public:
    static inline ICBinaryArith_Double *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICBinaryArith_Double>(code);
    }

    class Compiler : public ICMultiStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, JSOp op)
          : ICMultiStubCompiler(cx, ICStub::BinaryArith_Double, op)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICBinaryArith_Double::New(space, getStubCode());
        }
    };
};

class ICBinaryArith_BooleanWithInt32 : public ICStub
{
    friend class ICStubSpace;

    ICBinaryArith_BooleanWithInt32(IonCode *stubCode, bool lhsIsBool, bool rhsIsBool)
      : ICStub(BinaryArith_BooleanWithInt32, stubCode)
    {
        JS_ASSERT(lhsIsBool || rhsIsBool);
        extra_ = 0;
        if (lhsIsBool)
            extra_ |= 1;
        if (rhsIsBool)
            extra_ |= 2;
    }

  public:
    static inline ICBinaryArith_BooleanWithInt32 *New(ICStubSpace *space, IonCode *code,
                                                      bool lhsIsBool, bool rhsIsBool) {
        if (!code)
            return NULL;
        return space->allocate<ICBinaryArith_BooleanWithInt32>(code, lhsIsBool, rhsIsBool);
    }

    bool lhsIsBoolean() const {
        return extra_ & 1;
    }

    bool rhsIsBoolean() const {
        return extra_ & 2;
    }

    class Compiler : public ICStubCompiler {
      protected:
        JSOp op_;
        bool lhsIsBool_;
        bool rhsIsBool_;
        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(op_) << 16) |
                   (static_cast<int32_t>(lhsIsBool_) << 24) |
                   (static_cast<int32_t>(rhsIsBool_) << 25);
        }

      public:
        Compiler(JSContext *cx, JSOp op, bool lhsIsBool, bool rhsIsBool)
          : ICStubCompiler(cx, ICStub::BinaryArith_BooleanWithInt32),
            op_(op), lhsIsBool_(lhsIsBool), rhsIsBool_(rhsIsBool)
        {
            JS_ASSERT(op_ == JSOP_ADD || op_ == JSOP_SUB || op_ == JSOP_BITOR ||
                      op_ == JSOP_BITAND || op_ == JSOP_BITXOR);
            JS_ASSERT(lhsIsBool_ || rhsIsBool_);
        }

        ICStub *getStub(ICStubSpace *space) {
            return ICBinaryArith_BooleanWithInt32::New(space, getStubCode(),
                                                       lhsIsBool_, rhsIsBool_);
        }
    };
};

class ICBinaryArith_DoubleWithInt32 : public ICStub
{
    friend class ICStubSpace;

    ICBinaryArith_DoubleWithInt32(IonCode *stubCode, bool lhsIsDouble)
      : ICStub(BinaryArith_DoubleWithInt32, stubCode)
    {
        extra_ = lhsIsDouble;
    }

  public:
    static inline ICBinaryArith_DoubleWithInt32 *New(ICStubSpace *space, IonCode *code,
                                                     bool lhsIsDouble) {
        if (!code)
            return NULL;
        return space->allocate<ICBinaryArith_DoubleWithInt32>(code, lhsIsDouble);
    }

    bool lhsIsDouble() const {
        return extra_;
    }

    class Compiler : public ICMultiStubCompiler {
      protected:
        bool lhsIsDouble_;
        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(op) << 16) |
                   (static_cast<int32_t>(lhsIsDouble_) << 24);
        }

      public:
        Compiler(JSContext *cx, JSOp op, bool lhsIsDouble)
          : ICMultiStubCompiler(cx, ICStub::BinaryArith_DoubleWithInt32, op),
            lhsIsDouble_(lhsIsDouble)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICBinaryArith_DoubleWithInt32::New(space, getStubCode(), lhsIsDouble_);
        }
    };
};

// UnaryArith
//     JSOP_BITNOT
//     JSOP_NEG

class ICUnaryArith_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICUnaryArith_Fallback(IonCode *stubCode)
      : ICFallbackStub(UnaryArith_Fallback, stubCode)
    {
        extra_ = 0;
    }

  public:
    static const uint32_t MAX_OPTIMIZED_STUBS = 8;

    static inline ICUnaryArith_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICUnaryArith_Fallback>(code);
    }

    bool sawDoubleResult() {
        return extra_;
    }
    void setSawDoubleResult() {
        extra_ = 1;
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::UnaryArith_Fallback)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICUnaryArith_Fallback::New(space, getStubCode());
        }
    };
};

class ICUnaryArith_Int32 : public ICStub
{
    friend class ICStubSpace;

    ICUnaryArith_Int32(IonCode *stubCode)
      : ICStub(UnaryArith_Int32, stubCode)
    {}

  public:
    static inline ICUnaryArith_Int32 *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICUnaryArith_Int32>(code);
    }

    class Compiler : public ICMultiStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, JSOp op)
          : ICMultiStubCompiler(cx, ICStub::UnaryArith_Int32, op)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICUnaryArith_Int32::New(space, getStubCode());
        }
    };
};

class ICUnaryArith_Double : public ICStub
{
    friend class ICStubSpace;

    ICUnaryArith_Double(IonCode *stubCode)
      : ICStub(UnaryArith_Double, stubCode)
    {}

  public:
    static inline ICUnaryArith_Double *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICUnaryArith_Double>(code);
    }

    class Compiler : public ICMultiStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, JSOp op)
          : ICMultiStubCompiler(cx, ICStub::UnaryArith_Double, op)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICUnaryArith_Double::New(space, getStubCode());
        }
    };
};

// GetElem
//      JSOP_GETELEM

class ICGetElem_Fallback : public ICMonitoredFallbackStub
{
    friend class ICStubSpace;

    ICGetElem_Fallback(IonCode *stubCode)
      : ICMonitoredFallbackStub(ICStub::GetElem_Fallback, stubCode)
    { }

    static const uint16_t EXTRA_NON_NATIVE = 0x1;
    static const uint16_t EXTRA_NEGATIVE_INDEX = 0x2;

  public:
    static const uint32_t MAX_OPTIMIZED_STUBS = 16;

    static inline ICGetElem_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICGetElem_Fallback>(code);
    }

    void noteNonNativeAccess() {
        extra_ |= EXTRA_NON_NATIVE;
    }
    bool hasNonNativeAccess() const {
        return extra_ & EXTRA_NON_NATIVE;
    }

    void noteNegativeIndex() {
        extra_ |= EXTRA_NEGATIVE_INDEX;
    }
    bool hasNegativeIndex() const {
        return extra_ & EXTRA_NEGATIVE_INDEX;
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::GetElem_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            ICGetElem_Fallback *stub = ICGetElem_Fallback::New(space, getStubCode());
            if (!stub)
                return NULL;
            if (!stub->initMonitoringChain(cx, space))
                return NULL;
            return stub;
        }
    };
};

class ICGetElemNativeStub : public ICMonitoredStub
{
    HeapPtrShape shape_;
    HeapValue idval_;
    uint32_t offset_;

  protected:
    ICGetElemNativeStub(ICStub::Kind kind, IonCode *stubCode, ICStub *firstMonitorStub,
                        HandleShape shape, HandleValue idval,
                        bool isFixedSlot, uint32_t offset);

    ~ICGetElemNativeStub();

  public:
    HeapPtrShape &shape() {
        return shape_;
    }
    static size_t offsetOfShape() {
        return offsetof(ICGetElemNativeStub, shape_);
    }

    HeapValue &idval() {
        return idval_;
    }
    static size_t offsetOfIdval() {
        return offsetof(ICGetElemNativeStub, idval_);
    }

    uint32_t offset() const {
        return offset_;
    }
    static size_t offsetOfOffset() {
        return offsetof(ICGetElemNativeStub, offset_);
    }

    bool isFixedSlot() const {
        return extra_;
    }
};

class ICGetElem_Native : public ICGetElemNativeStub
{
    friend class ICStubSpace;
    ICGetElem_Native(IonCode *stubCode, ICStub *firstMonitorStub,
                     HandleShape shape, HandleValue idval,
                     bool isFixedSlot, uint32_t offset)
      : ICGetElemNativeStub(ICStub::GetElem_Native, stubCode, firstMonitorStub, shape, idval,
                            isFixedSlot, offset)
    {}

  public:
    static inline ICGetElem_Native *New(ICStubSpace *space, IonCode *code,
                                        ICStub *firstMonitorStub,
                                        HandleShape shape, HandleValue idval,
                                        bool isFixedSlot, uint32_t offset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetElem_Native>(code, firstMonitorStub, shape, idval,
                                                 isFixedSlot, offset);
    }
};

class ICGetElem_NativePrototype : public ICGetElemNativeStub
{
    friend class ICStubSpace;
    HeapPtrObject holder_;
    HeapPtrShape holderShape_;

    ICGetElem_NativePrototype(IonCode *stubCode, ICStub *firstMonitorStub,
                              HandleShape shape, HandleValue idval,
                              bool isFixedSlot, uint32_t offset,
                              HandleObject holder, HandleShape holderShape);

  public:
    static inline ICGetElem_NativePrototype *New(ICStubSpace *space, IonCode *code,
                                                 ICStub *firstMonitorStub,
                                                 HandleShape shape, HandleValue idval,
                                                 bool isFixedSlot, uint32_t offset,
                                                 HandleObject holder, HandleShape holderShape)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetElem_NativePrototype>(code, firstMonitorStub, shape, idval,
                                                          isFixedSlot, offset, holder, holderShape);
    }

    HeapPtrObject &holder() {
        return holder_;
    }
    static size_t offsetOfHolder() {
        return offsetof(ICGetElem_NativePrototype, holder_);
    }

    HeapPtrShape &holderShape() {
        return holderShape_;
    }
    static size_t offsetOfHolderShape() {
        return offsetof(ICGetElem_NativePrototype, holderShape_);
    }
};

// Compiler for GetElem_Native and GetElem_NativePrototype stubs.
class ICGetElemNativeCompiler : public ICStubCompiler
{
    ICStub *firstMonitorStub_;
    HandleObject obj_;
    HandleObject holder_;
    HandleValue idval_;
    bool isFixedSlot_;
    uint32_t offset_;

    bool generateStubCode(MacroAssembler &masm);

  protected:
    virtual int32_t getKey() const {
        return static_cast<int32_t>(kind) | (static_cast<int32_t>(isFixedSlot_) << 16);
    }

  public:
    ICGetElemNativeCompiler(JSContext *cx, ICStub::Kind kind, ICStub *firstMonitorStub,
                            HandleObject obj, HandleObject holder, HandleValue idval,
                            bool isFixedSlot, uint32_t offset)
      : ICStubCompiler(cx, kind),
        firstMonitorStub_(firstMonitorStub),
        obj_(obj),
        holder_(holder),
        idval_(idval),
        isFixedSlot_(isFixedSlot),
        offset_(offset)
    {}

    ICStub *getStub(ICStubSpace *space) {
        RootedShape shape(cx, obj_->lastProperty());
        if (kind == ICStub::GetElem_Native) {
            JS_ASSERT(obj_ == holder_);
            return ICGetElem_Native::New(space, getStubCode(), firstMonitorStub_, shape, idval_,
                                         isFixedSlot_, offset_);
        }

        JS_ASSERT(obj_ != holder_);
        JS_ASSERT(kind == ICStub::GetElem_NativePrototype);
        RootedShape holderShape(cx, holder_->lastProperty());
        return ICGetElem_NativePrototype::New(space, getStubCode(), firstMonitorStub_, shape,
                                              idval_, isFixedSlot_, offset_, holder_, holderShape);
    }
};

class ICGetElem_String : public ICStub
{
    friend class ICStubSpace;

    ICGetElem_String(IonCode *stubCode)
      : ICStub(ICStub::GetElem_String, stubCode) {}

  public:
    static inline ICGetElem_String *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICGetElem_String>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::GetElem_String) {}

        ICStub *getStub(ICStubSpace *space) {
            return ICGetElem_String::New(space, getStubCode());
        }
    };
};

class ICGetElem_Dense : public ICMonitoredStub
{
    friend class ICStubSpace;

    HeapPtrShape shape_;

    ICGetElem_Dense(IonCode *stubCode, ICStub *firstMonitorStub, HandleShape shape);

  public:
    static inline ICGetElem_Dense *New(ICStubSpace *space, IonCode *code,
                                       ICStub *firstMonitorStub, HandleShape shape)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetElem_Dense>(code, firstMonitorStub, shape);
    }

    static size_t offsetOfShape() {
        return offsetof(ICGetElem_Dense, shape_);
    }

    HeapPtrShape &shape() {
        return shape_;
    }

    class Compiler : public ICStubCompiler {
      ICStub *firstMonitorStub_;
      RootedShape shape_;

      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, ICStub *firstMonitorStub, Shape *shape)
          : ICStubCompiler(cx, ICStub::GetElem_Dense),
            firstMonitorStub_(firstMonitorStub),
            shape_(cx, shape)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICGetElem_Dense::New(space, getStubCode(), firstMonitorStub_, shape_);
        }
    };
};

class ICGetElem_TypedArray : public ICStub
{
    friend class ICStubSpace;

  protected: // Protected to silence Clang warning.
    HeapPtrShape shape_;

    ICGetElem_TypedArray(IonCode *stubCode, HandleShape shape, uint32_t type);

  public:
    static inline ICGetElem_TypedArray *New(ICStubSpace *space, IonCode *code,
                                            HandleShape shape, uint32_t type)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetElem_TypedArray>(code, shape, type);
    }

    static size_t offsetOfShape() {
        return offsetof(ICGetElem_TypedArray, shape_);
    }

    HeapPtrShape &shape() {
        return shape_;
    }

    class Compiler : public ICStubCompiler {
      RootedShape shape_;
      uint32_t type_;

      protected:
        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(type_) << 16);
        }

      public:
        Compiler(JSContext *cx, Shape *shape, uint32_t type)
          : ICStubCompiler(cx, ICStub::GetElem_TypedArray),
            shape_(cx, shape),
            type_(type)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICGetElem_TypedArray::New(space, getStubCode(), shape_, type_);
        }
    };
};

class ICGetElem_Arguments : public ICMonitoredStub
{
    friend class ICStubSpace;
  public:
    enum Which { Normal, Strict, Magic };

  private:
    ICGetElem_Arguments(IonCode *stubCode, ICStub *firstMonitorStub, Which which)
      : ICMonitoredStub(ICStub::GetElem_Arguments, stubCode, firstMonitorStub)
    {
        extra_ = static_cast<uint16_t>(which);
    }

  public:
    static inline ICGetElem_Arguments *New(ICStubSpace *space, IonCode *code,
                                           ICStub *firstMonitorStub, Which which)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetElem_Arguments>(code, firstMonitorStub, which);
    }

    Which which() const {
        return static_cast<Which>(extra_);
    }

    class Compiler : public ICStubCompiler {
      ICStub *firstMonitorStub_;
      Which which_;

      protected:
        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(which_) << 16);
        }

      public:
        Compiler(JSContext *cx, ICStub *firstMonitorStub, Which which)
          : ICStubCompiler(cx, ICStub::GetElem_Arguments),
            firstMonitorStub_(firstMonitorStub),
            which_(which)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICGetElem_Arguments::New(space, getStubCode(), firstMonitorStub_, which_);
        }
    };
};

// SetElem
//      JSOP_SETELEM
//      JSOP_INITELEM

class ICSetElem_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICSetElem_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::SetElem_Fallback, stubCode)
    { }

  public:
    static const uint32_t MAX_OPTIMIZED_STUBS = 8;

    static inline ICSetElem_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICSetElem_Fallback>(code);
    }

    // Compiler for this stub kind.
    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::SetElem_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICSetElem_Fallback::New(space, getStubCode());
        }
    };
};

class ICSetElem_Dense : public ICUpdatedStub
{
    friend class ICStubSpace;

    HeapPtrShape shape_;
    HeapPtrTypeObject type_;

    ICSetElem_Dense(IonCode *stubCode, HandleShape shape, HandleTypeObject type);

  public:
    static inline ICSetElem_Dense *New(ICStubSpace *space, IonCode *code, HandleShape shape,
                                       HandleTypeObject type) {
        if (!code)
            return NULL;
        return space->allocate<ICSetElem_Dense>(code, shape, type);
    }

    static size_t offsetOfShape() {
        return offsetof(ICSetElem_Dense, shape_);
    }
    static size_t offsetOfType() {
        return offsetof(ICSetElem_Dense, type_);
    }

    HeapPtrShape &shape() {
        return shape_;
    }
    HeapPtrTypeObject &type() {
        return type_;
    }

    class Compiler : public ICStubCompiler {
        RootedShape shape_;

        // Compiler is only live on stack during compilation, it should
        // outlive any RootedTypeObject it's passed.  So it can just
        // use the handle.
        HandleTypeObject type_;

        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, Shape *shape, HandleTypeObject type)
          : ICStubCompiler(cx, ICStub::SetElem_Dense),
            shape_(cx, shape),
            type_(type)
        {}

        ICUpdatedStub *getStub(ICStubSpace *space) {
            ICSetElem_Dense *stub = ICSetElem_Dense::New(space, getStubCode(), shape_, type_);
            if (!stub || !stub->initUpdatingChain(cx, space))
                return NULL;
            return stub;
        }
    };
};

template <size_t ProtoChainDepth> class ICSetElem_DenseAddImpl;

class ICSetElem_DenseAdd : public ICUpdatedStub
{
    friend class ICStubSpace;

  public:
    static const size_t MAX_PROTO_CHAIN_DEPTH = 4;

  protected:
    HeapPtrTypeObject type_;

    ICSetElem_DenseAdd(IonCode *stubCode, types::TypeObject *type, size_t protoChainDepth);

  public:
    static size_t offsetOfType() {
        return offsetof(ICSetElem_DenseAdd, type_);
    }

    HeapPtrTypeObject &type() {
        return type_;
    }
    size_t protoChainDepth() const {
        return extra_;
    }

    template <size_t ProtoChainDepth>
    ICSetElem_DenseAddImpl<ProtoChainDepth> *toImplUnchecked() {
        return static_cast<ICSetElem_DenseAddImpl<ProtoChainDepth> *>(this);
    }

    template <size_t ProtoChainDepth>
    ICSetElem_DenseAddImpl<ProtoChainDepth> *toImpl() {
        JS_ASSERT(ProtoChainDepth == protoChainDepth());
        return toImplUnchecked<ProtoChainDepth>();
    }
};

template <size_t ProtoChainDepth>
class ICSetElem_DenseAddImpl : public ICSetElem_DenseAdd
{
    friend class ICStubSpace;

    static const size_t NumShapes = ProtoChainDepth + 1;
    HeapPtrShape shapes_[NumShapes];

    ICSetElem_DenseAddImpl(IonCode *stubCode, types::TypeObject *type,
                           const AutoShapeVector *shapes)
      : ICSetElem_DenseAdd(stubCode, type, ProtoChainDepth)
    {
        JS_ASSERT(shapes->length() == NumShapes);
        for (size_t i = 0; i < NumShapes; i++)
            shapes_[i].init((*shapes)[i]);
    }

  public:
    static inline ICSetElem_DenseAddImpl *New(ICStubSpace *space, IonCode *code,
                                              types::TypeObject *type,
                                              const AutoShapeVector *shapes)
    {
        if (!code)
            return NULL;
        return space->allocate<ICSetElem_DenseAddImpl<ProtoChainDepth> >(code, type, shapes);
    }

    void traceShapes(JSTracer *trc) {
        for (size_t i = 0; i < NumShapes; i++)
            MarkShape(trc, &shapes_[i], "baseline-setelem-denseadd-stub-shape");
    }
    Shape *shape(size_t i) const {
        JS_ASSERT(i < NumShapes);
        return shapes_[i];
    }
    static size_t offsetOfShape(size_t idx) {
        return offsetof(ICSetElem_DenseAddImpl, shapes_) + idx * sizeof(HeapPtrShape);
    }
};

class ICSetElemDenseAddCompiler : public ICStubCompiler {
    RootedObject obj_;
    size_t protoChainDepth_;

    bool generateStubCode(MacroAssembler &masm);

  protected:
    virtual int32_t getKey() const {
        return static_cast<int32_t>(kind) | (static_cast<int32_t>(protoChainDepth_) << 16);
    }

  public:
    ICSetElemDenseAddCompiler(JSContext *cx, HandleObject obj, size_t protoChainDepth)
        : ICStubCompiler(cx, ICStub::SetElem_DenseAdd),
          obj_(cx, obj),
          protoChainDepth_(protoChainDepth)
    {}

    template <size_t ProtoChainDepth>
    ICUpdatedStub *getStubSpecific(ICStubSpace *space, const AutoShapeVector *shapes);

    ICUpdatedStub *getStub(ICStubSpace *space);
};

class ICSetElem_TypedArray : public ICStub
{
    friend class ICStubSpace;

  protected: // Protected to silence Clang warning.
    HeapPtrShape shape_;

    ICSetElem_TypedArray(IonCode *stubCode, HandleShape shape, uint32_t type,
                         bool expectOutOfBounds);

  public:
    static inline ICSetElem_TypedArray *New(ICStubSpace *space, IonCode *code,
                                            HandleShape shape, uint32_t type,
                                            bool expectOutOfBounds)
    {
        if (!code)
            return NULL;
        return space->allocate<ICSetElem_TypedArray>(code, shape, type, expectOutOfBounds);
    }

    uint32_t type() const {
        return extra_ & 0xff;
    }

    bool expectOutOfBounds() const {
        return (extra_ >> 8) & 1;
    }

    static size_t offsetOfShape() {
        return offsetof(ICSetElem_TypedArray, shape_);
    }

    HeapPtrShape &shape() {
        return shape_;
    }

    class Compiler : public ICStubCompiler {
        RootedShape shape_;
        uint32_t type_;
        bool expectOutOfBounds_;

      protected:
        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(type_) << 16) |
                   (static_cast<int32_t>(expectOutOfBounds_) << 24);
        }

      public:
        Compiler(JSContext *cx, Shape *shape, uint32_t type, bool expectOutOfBounds)
          : ICStubCompiler(cx, ICStub::SetElem_TypedArray),
            shape_(cx, shape),
            type_(type),
            expectOutOfBounds_(expectOutOfBounds)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICSetElem_TypedArray::New(space, getStubCode(), shape_, type_,
                                             expectOutOfBounds_);
        }
    };
};

// In
//      JSOP_IN
class ICIn_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICIn_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::In_Fallback, stubCode)
    { }

  public:
    static inline ICIn_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICIn_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::In_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICIn_Fallback::New(space, getStubCode());
        }
    };
};

// GetName
//      JSOP_NAME
//      JSOP_CALLNAME
//      JSOP_GETGNAME
//      JSOP_CALLGNAME
class ICGetName_Fallback : public ICMonitoredFallbackStub
{
    friend class ICStubSpace;

    ICGetName_Fallback(IonCode *stubCode)
      : ICMonitoredFallbackStub(ICStub::GetName_Fallback, stubCode)
    { }

  public:
    static const uint32_t MAX_OPTIMIZED_STUBS = 8;

    static inline ICGetName_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICGetName_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::GetName_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            ICGetName_Fallback *stub = ICGetName_Fallback::New(space, getStubCode());
            if (!stub || !stub->initMonitoringChain(cx, space))
                return NULL;
            return stub;
        }
    };
};

// Optimized GETGNAME/CALLGNAME stub.
class ICGetName_Global : public ICMonitoredStub
{
    friend class ICStubSpace;

  protected: // Protected to silence Clang warning.
    HeapPtrShape shape_;
    uint32_t slot_;

    ICGetName_Global(IonCode *stubCode, ICStub *firstMonitorStub, HandleShape shape, uint32_t slot);

  public:
    static inline ICGetName_Global *New(ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
                                        HandleShape shape, uint32_t slot)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetName_Global>(code, firstMonitorStub, shape, slot);
    }

    HeapPtrShape &shape() {
        return shape_;
    }
    static size_t offsetOfShape() {
        return offsetof(ICGetName_Global, shape_);
    }
    static size_t offsetOfSlot() {
        return offsetof(ICGetName_Global, slot_);
    }

    class Compiler : public ICStubCompiler {
        ICStub *firstMonitorStub_;
        RootedShape shape_;
        uint32_t slot_;

      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, ICStub *firstMonitorStub, Shape *shape, uint32_t slot)
          : ICStubCompiler(cx, ICStub::GetName_Global),
            firstMonitorStub_(firstMonitorStub),
            shape_(cx, shape),
            slot_(slot)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICGetName_Global::New(space, getStubCode(), firstMonitorStub_, shape_, slot_);
        }
    };
};

// Optimized GETNAME/CALLNAME stub, making a variable number of hops to get an
// 'own' property off some scope object. Unlike GETPROP on an object's
// prototype, there is no teleporting optimization to take advantage of and
// shape checks are required all along the scope chain.
template <size_t NumHops>
class ICGetName_Scope : public ICMonitoredStub
{
    friend class ICStubSpace;

    static const size_t MAX_HOPS = 6;

    HeapPtrShape shapes_[NumHops + 1];
    uint32_t offset_;

    ICGetName_Scope(IonCode *stubCode, ICStub *firstMonitorStub,
                    AutoShapeVector *shapes, uint32_t offset);

    static Kind GetStubKind() {
        return (Kind) (GetName_Scope0 + NumHops);
    }

  public:
    static inline ICGetName_Scope *New(ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
                                       AutoShapeVector *shapes, uint32_t offset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetName_Scope<NumHops> >(code, firstMonitorStub, shapes, offset);
    }

    void traceScopes(JSTracer *trc) {
        for (size_t i = 0; i < NumHops + 1; i++)
            MarkShape(trc, &shapes_[i], "baseline-scope-stub-shape");
    }

    static size_t offsetOfShape(size_t index) {
        JS_ASSERT(index <= NumHops);
        return offsetof(ICGetName_Scope, shapes_) + (index * sizeof(HeapPtrShape));
    }
    static size_t offsetOfOffset() {
        return offsetof(ICGetName_Scope, offset_);
    }

    class Compiler : public ICStubCompiler {
        ICStub *firstMonitorStub_;
        AutoShapeVector *shapes_;
        bool isFixedSlot_;
        uint32_t offset_;

      protected:
        bool generateStubCode(MacroAssembler &masm);

      protected:
        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(isFixedSlot_) << 16);
        }

      public:
        Compiler(JSContext *cx, ICStub *firstMonitorStub,
                 AutoShapeVector *shapes, bool isFixedSlot, uint32_t offset)
          : ICStubCompiler(cx, GetStubKind()),
            firstMonitorStub_(firstMonitorStub),
            shapes_(shapes),
            isFixedSlot_(isFixedSlot),
            offset_(offset)
        {
        }

        ICStub *getStub(ICStubSpace *space) {
            return ICGetName_Scope::New(space, getStubCode(), firstMonitorStub_, shapes_, offset_);
        }
    };
};

// BindName
//      JSOP_BINDNAME
class ICBindName_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICBindName_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::BindName_Fallback, stubCode)
    { }

  public:
    static inline ICBindName_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICBindName_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::BindName_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICBindName_Fallback::New(space, getStubCode());
        }
    };
};

// GetIntrinsic
//      JSOP_GETINTRINSIC
//      JSOP_CALLINTRINSIC
class ICGetIntrinsic_Fallback : public ICMonitoredFallbackStub
{
    friend class ICStubSpace;

    ICGetIntrinsic_Fallback(IonCode *stubCode)
      : ICMonitoredFallbackStub(ICStub::GetIntrinsic_Fallback, stubCode)
    { }

  public:
    static inline ICGetIntrinsic_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICGetIntrinsic_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::GetIntrinsic_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            ICGetIntrinsic_Fallback *stub = ICGetIntrinsic_Fallback::New(space, getStubCode());
            if (!stub || !stub->initMonitoringChain(cx, space))
                return NULL;
            return stub;
        }
    };
};

// Stub that loads the constant result of a GETINTRINSIC operation.
class ICGetIntrinsic_Constant : public ICStub
{
    friend class ICStubSpace;

    HeapValue value_;

    ICGetIntrinsic_Constant(IonCode *stubCode, HandleValue value);
    ~ICGetIntrinsic_Constant();

  public:
    static inline ICGetIntrinsic_Constant *New(ICStubSpace *space, IonCode *code,
                                               HandleValue value)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetIntrinsic_Constant>(code, value);
    }

    HeapValue &value() {
        return value_;
    }
    static size_t offsetOfValue() {
        return offsetof(ICGetIntrinsic_Constant, value_);
    }

    class Compiler : public ICStubCompiler {
        bool generateStubCode(MacroAssembler &masm);

        HandleValue value_;

      public:
        Compiler(JSContext *cx, HandleValue value)
          : ICStubCompiler(cx, ICStub::GetIntrinsic_Constant),
            value_(value)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICGetIntrinsic_Constant::New(space, getStubCode(), value_);
        }
    };
};

class ICGetProp_Fallback : public ICMonitoredFallbackStub
{
    friend class ICStubSpace;

    ICGetProp_Fallback(IonCode *stubCode)
      : ICMonitoredFallbackStub(ICStub::GetProp_Fallback, stubCode)
    { }

  public:
    static const uint32_t MAX_OPTIMIZED_STUBS = 8;

    static inline ICGetProp_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_Fallback>(code);
    }

    static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0;
    static const size_t ACCESSED_GETTER_BIT = 1;

    void noteUnoptimizableAccess() {
        extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT);
    }
    bool hadUnoptimizableAccess() const {
        return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT);
    }

    void noteAccessedGetter() {
        extra_ |= (1u << ACCESSED_GETTER_BIT);
    }
    bool hasAccessedGetter() const {
        return extra_ & (1u << ACCESSED_GETTER_BIT);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::GetProp_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            ICGetProp_Fallback *stub = ICGetProp_Fallback::New(space, getStubCode());
            if (!stub || !stub->initMonitoringChain(cx, space))
                return NULL;
            return stub;
        }
    };
};

// Stub for accessing a dense array's length.
class ICGetProp_ArrayLength : public ICStub
{
    friend class ICStubSpace;

    ICGetProp_ArrayLength(IonCode *stubCode)
      : ICStub(GetProp_ArrayLength, stubCode)
    {}

  public:
    static inline ICGetProp_ArrayLength *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_ArrayLength>(code);
    }

    class Compiler : public ICStubCompiler {
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::GetProp_ArrayLength)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICGetProp_ArrayLength::New(space, getStubCode());
        }
    };
};

// Stub for accessing a typed array's length.
class ICGetProp_TypedArrayLength : public ICStub
{
    friend class ICStubSpace;

    ICGetProp_TypedArrayLength(IonCode *stubCode)
      : ICStub(GetProp_TypedArrayLength, stubCode)
    {}

  public:
    static inline ICGetProp_TypedArrayLength *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_TypedArrayLength>(code);
    }

    class Compiler : public ICStubCompiler {
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::GetProp_TypedArrayLength)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICGetProp_TypedArrayLength::New(space, getStubCode());
        }
    };
};

// Stub for accessing a string's length.
class ICGetProp_String : public ICMonitoredStub
{
    friend class ICStubSpace;

  protected: // Protected to silence Clang warning.
    // Shape of String.prototype to check for.
    HeapPtrShape stringProtoShape_;

    // Fixed or dynamic slot offset.
    uint32_t offset_;

    ICGetProp_String(IonCode *stubCode, ICStub *firstMonitorStub,
                     HandleShape stringProtoShape, uint32_t offset);

  public:
    static inline ICGetProp_String *New(ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
                                        HandleShape stringProtoShape, uint32_t offset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_String>(code, firstMonitorStub, stringProtoShape, offset);
    }

    HeapPtrShape &stringProtoShape() {
        return stringProtoShape_;
    }
    static size_t offsetOfStringProtoShape() {
        return offsetof(ICGetProp_String, stringProtoShape_);
    }

    static size_t offsetOfOffset() {
        return offsetof(ICGetProp_String, offset_);
    }

    class Compiler : public ICStubCompiler {
        ICStub *firstMonitorStub_;
        RootedObject stringPrototype_;
        bool isFixedSlot_;
        uint32_t offset_;

        bool generateStubCode(MacroAssembler &masm);

      protected:
        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(isFixedSlot_) << 16);
        }

      public:
        Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleObject stringPrototype,
                 bool isFixedSlot, uint32_t offset)
          : ICStubCompiler(cx, ICStub::GetProp_String),
            firstMonitorStub_(firstMonitorStub),
            stringPrototype_(cx, stringPrototype),
            isFixedSlot_(isFixedSlot),
            offset_(offset)
        {}

        ICStub *getStub(ICStubSpace *space) {
            RootedShape stringProtoShape(cx, stringPrototype_->lastProperty());
            return ICGetProp_String::New(space, getStubCode(), firstMonitorStub_,
                                         stringProtoShape, offset_);
        }
    };
};

// Stub for accessing a string's length.
class ICGetProp_StringLength : public ICStub
{
    friend class ICStubSpace;

    ICGetProp_StringLength(IonCode *stubCode)
      : ICStub(GetProp_StringLength, stubCode)
    {}

  public:
    static inline ICGetProp_StringLength *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_StringLength>(code);
    }

    class Compiler : public ICStubCompiler {
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::GetProp_StringLength)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICGetProp_StringLength::New(space, getStubCode());
        }
    };
};

// Base class for GetProp_Native and GetProp_NativePrototype stubs.
class ICGetPropNativeStub : public ICMonitoredStub
{
    // Object shape (lastProperty).
    HeapPtrShape shape_;

    // Fixed or dynamic slot offset.
    uint32_t offset_;

  protected:
    ICGetPropNativeStub(ICStub::Kind kind, IonCode *stubCode, ICStub *firstMonitorStub,
                        HandleShape shape, uint32_t offset);

  public:
    HeapPtrShape &shape() {
        return shape_;
    }
    uint32_t offset() const {
        return offset_;
    }
    static size_t offsetOfShape() {
        return offsetof(ICGetPropNativeStub, shape_);
    }
    static size_t offsetOfOffset() {
        return offsetof(ICGetPropNativeStub, offset_);
    }
};

// Stub for accessing an own property on a native object.
class ICGetProp_Native : public ICGetPropNativeStub
{
    friend class ICStubSpace;

    ICGetProp_Native(IonCode *stubCode, ICStub *firstMonitorStub, HandleShape shape,
                     uint32_t offset)
      : ICGetPropNativeStub(GetProp_Native, stubCode, firstMonitorStub, shape, offset)
    {}

  public:
    static inline ICGetProp_Native *New(ICStubSpace *space, IonCode *code,
                                        ICStub *firstMonitorStub, HandleShape shape,
                                        uint32_t offset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_Native>(code, firstMonitorStub, shape, offset);
    }
};

// Stub for accessing a property on a native object's prototype. Note that due to
// the shape teleporting optimization, we only have to guard on the object's shape
// and the holder's shape.
class ICGetProp_NativePrototype : public ICGetPropNativeStub
{
    friend class ICStubSpace;

  protected:
    // Holder and its shape.
    HeapPtrObject holder_;
    HeapPtrShape holderShape_;

    ICGetProp_NativePrototype(IonCode *stubCode, ICStub *firstMonitorStub, HandleShape shape,
                              uint32_t offset, HandleObject holder, HandleShape holderShape);

  public:
    static inline ICGetProp_NativePrototype *New(ICStubSpace *space, IonCode *code,
                                                 ICStub *firstMonitorStub, HandleShape shape,
                                                 uint32_t offset, HandleObject holder,
                                                 HandleShape holderShape)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_NativePrototype>(code, firstMonitorStub, shape, offset,
                                                          holder, holderShape);
    }

  public:
    HeapPtrObject &holder() {
        return holder_;
    }
    HeapPtrShape &holderShape() {
        return holderShape_;
    }
    static size_t offsetOfHolder() {
        return offsetof(ICGetProp_NativePrototype, holder_);
    }
    static size_t offsetOfHolderShape() {
        return offsetof(ICGetProp_NativePrototype, holderShape_);
    }
};


// Compiler for GetProp_Native and GetProp_NativePrototype stubs.
class ICGetPropNativeCompiler : public ICStubCompiler
{
    ICStub *firstMonitorStub_;
    HandleObject obj_;
    HandleObject holder_;
    bool isFixedSlot_;
    uint32_t offset_;

    bool generateStubCode(MacroAssembler &masm);

  protected:
    virtual int32_t getKey() const {
        return static_cast<int32_t>(kind) | (static_cast<int32_t>(isFixedSlot_) << 16);
    }

  public:
    ICGetPropNativeCompiler(JSContext *cx, ICStub::Kind kind, ICStub *firstMonitorStub,
                            HandleObject obj, HandleObject holder, bool isFixedSlot,
                            uint32_t offset)
      : ICStubCompiler(cx, kind),
        firstMonitorStub_(firstMonitorStub),
        obj_(obj),
        holder_(holder),
        isFixedSlot_(isFixedSlot),
        offset_(offset)
    {}

    ICStub *getStub(ICStubSpace *space) {
        RootedShape shape(cx, obj_->lastProperty());
        if (kind == ICStub::GetProp_Native) {
            JS_ASSERT(obj_ == holder_);
            return ICGetProp_Native::New(space, getStubCode(), firstMonitorStub_, shape, offset_);
        }

        JS_ASSERT(obj_ != holder_);
        JS_ASSERT(kind == ICStub::GetProp_NativePrototype);
        RootedShape holderShape(cx, holder_->lastProperty());
        return ICGetProp_NativePrototype::New(space, getStubCode(), firstMonitorStub_, shape,
                                              offset_, holder_, holderShape);
    }
};

// Stub for calling a getter (native or scripted) on a native object.
class ICGetPropCallGetter : public ICMonitoredStub
{
    friend class ICStubSpace;

  protected:
    // Object shape (lastProperty).
    HeapPtrShape shape_;

    // Holder and shape.
    HeapPtrObject holder_;
    HeapPtrShape holderShape_;

    // Function to call.
    HeapPtrFunction getter_;

    // PC offset of call
    uint32_t pcOffset_;

    ICGetPropCallGetter(Kind kind, IonCode *stubCode, ICStub *firstMonitorStub,
                         HandleShape shape, HandleObject holder, HandleShape holderShape,
                         HandleFunction getter, uint32_t pcOffset);

  public:
    HeapPtrShape &shape() {
        return shape_;
    }
    HeapPtrObject &holder() {
        return holder_;
    }
    HeapPtrShape &holderShape() {
        return holderShape_;
    }
    HeapPtrFunction &getter() {
        return getter_;
    }

    static size_t offsetOfShape() {
        return offsetof(ICGetPropCallGetter, shape_);
    }
    static size_t offsetOfHolder() {
        return offsetof(ICGetPropCallGetter, holder_);
    }
    static size_t offsetOfHolderShape() {
        return offsetof(ICGetPropCallGetter, holderShape_);
    }
    static size_t offsetOfGetter() {
        return offsetof(ICGetPropCallGetter, getter_);
    }
    static size_t offsetOfPCOffset() {
        return offsetof(ICGetPropCallGetter, pcOffset_);
    }

    class Compiler : public ICStubCompiler {
      protected:
        ICStub *firstMonitorStub_;
        RootedObject obj_;
        RootedObject holder_;
        RootedFunction getter_;
        uint32_t pcOffset_;

      public:
        Compiler(JSContext *cx, ICStub::Kind kind, ICStub *firstMonitorStub, HandleObject obj,
                 HandleObject holder, HandleFunction getter, uint32_t pcOffset)
          : ICStubCompiler(cx, kind),
            firstMonitorStub_(firstMonitorStub),
            obj_(cx, obj),
            holder_(cx, holder),
            getter_(cx, getter),
            pcOffset_(pcOffset)
        {
            JS_ASSERT(kind == ICStub::GetProp_CallScripted || kind == ICStub::GetProp_CallNative);
        }
    };
};

// Stub for calling a scripted getter on a native object.
class ICGetProp_CallScripted : public ICGetPropCallGetter
{
    friend class ICStubSpace;

  protected:
    ICGetProp_CallScripted(IonCode *stubCode, ICStub *firstMonitorStub,
                           HandleShape shape, HandleObject holder, HandleShape holderShape,
                           HandleFunction getter, uint32_t pcOffset)
      : ICGetPropCallGetter(GetProp_CallScripted, stubCode, firstMonitorStub,
                            shape, holder, holderShape, getter, pcOffset)
    {}

  public:
    static inline ICGetProp_CallScripted *New(
                ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
                HandleShape shape, HandleObject holder, HandleShape holderShape,
                HandleFunction getter, uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_CallScripted>(code, firstMonitorStub,
                                                       shape, holder, holderShape, getter,
                                                       pcOffset);
    }

    class Compiler : public ICGetPropCallGetter::Compiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleObject obj,
                 HandleObject holder, HandleFunction getter, uint32_t pcOffset)
          : ICGetPropCallGetter::Compiler(cx, ICStub::GetProp_CallScripted, firstMonitorStub,
                                          obj, holder, getter, pcOffset)
        {}

        ICStub *getStub(ICStubSpace *space) {
            RootedShape shape(cx, obj_->lastProperty());
            RootedShape holderShape(cx, holder_->lastProperty());
            return ICGetProp_CallScripted::New(space, getStubCode(), firstMonitorStub_, shape,
                                               holder_, holderShape, getter_, pcOffset_);
        }
    };
};

// Stub for calling a native getter on a native object.
class ICGetProp_CallNative : public ICGetPropCallGetter
{
    friend class ICStubSpace;

  protected:
    ICGetProp_CallNative(IonCode *stubCode, ICStub *firstMonitorStub,
                         HandleShape shape, HandleObject holder, HandleShape holderShape,
                         HandleFunction getter, uint32_t pcOffset)
      : ICGetPropCallGetter(GetProp_CallNative, stubCode, firstMonitorStub,
                            shape, holder, holderShape, getter, pcOffset)
    {}

  public:
    static inline ICGetProp_CallNative *New(
                ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
                HandleShape shape, HandleObject holder, HandleShape holderShape,
                HandleFunction getter, uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_CallNative>(code, firstMonitorStub,
                                                     shape, holder, holderShape, getter,
                                                     pcOffset);
    }

    class Compiler : public ICGetPropCallGetter::Compiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleObject obj,
                 HandleObject holder, HandleFunction getter, uint32_t pcOffset)
          : ICGetPropCallGetter::Compiler(cx, ICStub::GetProp_CallNative, firstMonitorStub,
                                          obj, holder, getter, pcOffset)
        {}

        ICStub *getStub(ICStubSpace *space) {
            RootedShape shape(cx, obj_->lastProperty());
            RootedShape holderShape(cx, holder_->lastProperty());
            return ICGetProp_CallNative::New(space, getStubCode(), firstMonitorStub_, shape,
                                               holder_, holderShape, getter_, pcOffset_);
        }
    };
};

class ICGetPropCallDOMProxyNativeStub : public ICMonitoredStub
{
  friend class ICStubSpace;
  protected:
    // Shape of the DOMProxy
    HeapPtrShape shape_;

    // Proxy handler to check against.
    BaseProxyHandler *proxyHandler_;

    // Object shape of expected expando object. (NULL if no expando object should be there)
    HeapPtrShape expandoShape_;

    // Holder and its shape.
    HeapPtrObject holder_;
    HeapPtrShape holderShape_;

    // Function to call.
    HeapPtrFunction getter_;

    // PC offset of call
    uint32_t pcOffset_;

    ICGetPropCallDOMProxyNativeStub(ICStub::Kind kind, IonCode *stubCode,
                                    ICStub *firstMonitorStub, HandleShape shape,
                                    BaseProxyHandler *proxyHandler, HandleShape expandoShape,
                                    HandleObject holder, HandleShape holderShape,
                                    HandleFunction getter, uint32_t pcOffset);

  public:
    HeapPtrShape &shape() {
        return shape_;
    }
    HeapPtrShape &expandoShape() {
        return expandoShape_;
    }
    HeapPtrObject &holder() {
        return holder_;
    }
    HeapPtrShape &holderShape() {
        return holderShape_;
    }
    HeapPtrFunction &getter() {
        return getter_;
    }
    uint32_t pcOffset() const {
        return pcOffset_;
    }

    static size_t offsetOfShape() {
        return offsetof(ICGetPropCallDOMProxyNativeStub, shape_);
    }
    static size_t offsetOfProxyHandler() {
        return offsetof(ICGetPropCallDOMProxyNativeStub, proxyHandler_);
    }
    static size_t offsetOfExpandoShape() {
        return offsetof(ICGetPropCallDOMProxyNativeStub, expandoShape_);
    }
    static size_t offsetOfHolder() {
        return offsetof(ICGetPropCallDOMProxyNativeStub, holder_);
    }
    static size_t offsetOfHolderShape() {
        return offsetof(ICGetPropCallDOMProxyNativeStub, holderShape_);
    }
    static size_t offsetOfGetter() {
        return offsetof(ICGetPropCallDOMProxyNativeStub, getter_);
    }
    static size_t offsetOfPCOffset() {
        return offsetof(ICGetPropCallDOMProxyNativeStub, pcOffset_);
    }
};

class ICGetProp_CallDOMProxyNative : public ICGetPropCallDOMProxyNativeStub
{
    friend class ICStubSpace;
    ICGetProp_CallDOMProxyNative(IonCode *stubCode, ICStub *firstMonitorStub, HandleShape shape,
                                 BaseProxyHandler *proxyHandler, HandleShape expandoShape,
                                 HandleObject holder, HandleShape holderShape,
                                 HandleFunction getter, uint32_t pcOffset)
      : ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyNative, stubCode,
                                        firstMonitorStub, shape, proxyHandler, expandoShape,
                                        holder, holderShape, getter, pcOffset)
    {}

  public:
    static inline ICGetProp_CallDOMProxyNative *New(
            ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
            HandleShape shape, BaseProxyHandler *proxyHandler,
            HandleShape expandoShape, HandleObject holder, HandleShape holderShape,
            HandleFunction getter, uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_CallDOMProxyNative>(code, firstMonitorStub, shape,
                                                   proxyHandler, expandoShape, holder,
                                                   holderShape, getter, pcOffset);
    }
};

class ICGetProp_CallDOMProxyWithGenerationNative : public ICGetPropCallDOMProxyNativeStub
{
  protected:
    ExpandoAndGeneration *expandoAndGeneration_;
    uint32_t generation_;

  public:
    ICGetProp_CallDOMProxyWithGenerationNative(IonCode *stubCode, ICStub *firstMonitorStub,
                                               HandleShape shape, BaseProxyHandler *proxyHandler,
                                               ExpandoAndGeneration *expandoAndGeneration,
                                               uint32_t generation, HandleShape expandoShape,
                                               HandleObject holder, HandleShape holderShape,
                                               HandleFunction getter, uint32_t pcOffset)
      : ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyWithGenerationNative,
                                        stubCode, firstMonitorStub, shape, proxyHandler,
                                        expandoShape, holder, holderShape, getter, pcOffset),
        expandoAndGeneration_(expandoAndGeneration),
        generation_(generation)
    {
    }

    static inline ICGetProp_CallDOMProxyWithGenerationNative *New(
            ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
            HandleShape shape, BaseProxyHandler *proxyHandler,
            ExpandoAndGeneration *expandoAndGeneration, uint32_t generation,
            HandleShape expandoShape, HandleObject holder, HandleShape holderShape,
            HandleFunction getter, uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_CallDOMProxyWithGenerationNative>(code, firstMonitorStub,
                                                   shape, proxyHandler, expandoAndGeneration,
                                                   generation, expandoShape, holder, holderShape,
                                                   getter, pcOffset);
    }

    void *expandoAndGeneration() const {
        return expandoAndGeneration_;
    }
    uint32_t generation() const {
        return generation_;
    }

    void setGeneration(uint32_t value) {
        generation_ = value;
    }

    static size_t offsetOfInternalStruct() {
        return offsetof(ICGetProp_CallDOMProxyWithGenerationNative, expandoAndGeneration_);
    }
    static size_t offsetOfGeneration() {
        return offsetof(ICGetProp_CallDOMProxyWithGenerationNative, generation_);
    }
};

class ICGetPropCallDOMProxyNativeCompiler : public ICStubCompiler {
    ICStub *firstMonitorStub_;
    RootedObject obj_;
    RootedObject holder_;
    RootedFunction getter_;
    uint32_t pcOffset_;

    bool generateStubCode(MacroAssembler &masm, Address* internalStructAddr,
                          Address* generationAddr);
    bool generateStubCode(MacroAssembler &masm);

  public:
    ICGetPropCallDOMProxyNativeCompiler(JSContext *cx, ICStub::Kind kind,
                                        ICStub *firstMonitorStub, HandleObject obj,
                                        HandleObject holder, HandleFunction getter,
                                        uint32_t pcOffset);

    ICStub *getStub(ICStubSpace *space);
};

class ICGetProp_DOMProxyShadowed : public ICMonitoredStub
{
  friend class ICStubSpace;
  protected:
    HeapPtrShape shape_;
    BaseProxyHandler *proxyHandler_;
    HeapPtrPropertyName name_;
    uint32_t pcOffset_;

    ICGetProp_DOMProxyShadowed(IonCode *stubCode, ICStub *firstMonitorStub, HandleShape shape,
                               BaseProxyHandler *proxyHandler, HandlePropertyName name,
                               uint32_t pcOffset);

  public:
    static inline ICGetProp_DOMProxyShadowed *New(ICStubSpace *space, IonCode *code,
                                                  ICStub *firstMonitorStub, HandleShape shape,
                                                  BaseProxyHandler *proxyHandler,
                                                  HandlePropertyName name, uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_DOMProxyShadowed>(code, firstMonitorStub, shape,
                                                           proxyHandler, name, pcOffset);
    }

    HeapPtrShape &shape() {
        return shape_;
    }
    HeapPtrPropertyName &name() {
        return name_;
    }

    static size_t offsetOfShape() {
        return offsetof(ICGetProp_DOMProxyShadowed, shape_);
    }
    static size_t offsetOfProxyHandler() {
        return offsetof(ICGetProp_DOMProxyShadowed, proxyHandler_);
    }
    static size_t offsetOfName() {
        return offsetof(ICGetProp_DOMProxyShadowed, name_);
    }
    static size_t offsetOfPCOffset() {
        return offsetof(ICGetProp_DOMProxyShadowed, pcOffset_);
    }

    class Compiler : public ICStubCompiler {
        ICStub *firstMonitorStub_;
        RootedObject obj_;
        RootedPropertyName name_;
        uint32_t pcOffset_;

        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleObject obj, HandlePropertyName name,
                 uint32_t pcOffset)
          : ICStubCompiler(cx, ICStub::GetProp_CallNative),
            firstMonitorStub_(firstMonitorStub),
            obj_(cx, obj),
            name_(cx, name),
            pcOffset_(pcOffset)
        {}

        ICStub *getStub(ICStubSpace *space);
    };
};

class ICGetProp_ArgumentsLength : public ICStub
{
  friend class ICStubSpace;
  public:
    enum Which { Normal, Strict, Magic };

  protected:
    ICGetProp_ArgumentsLength(IonCode *stubCode)
      : ICStub(ICStub::GetProp_ArgumentsLength, stubCode)
    { }

  public:
    static inline ICGetProp_ArgumentsLength *New(ICStubSpace *space, IonCode *code)
    {
        if (!code)
            return NULL;
        return space->allocate<ICGetProp_ArgumentsLength>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        Which which_;

        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(which_) << 16);
        }

      public:
        Compiler(JSContext *cx, Which which)
          : ICStubCompiler(cx, ICStub::GetProp_ArgumentsLength),
            which_(which)
        {}

        ICStub *getStub(ICStubSpace *space) {
            return ICGetProp_ArgumentsLength::New(space, getStubCode());
        }
    };
};

// SetProp
//     JSOP_SETPROP
//     JSOP_SETNAME
//     JSOP_SETGNAME
//     JSOP_INITPROP

class ICSetProp_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICSetProp_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::SetProp_Fallback, stubCode)
    { }

  public:
    static const uint32_t MAX_OPTIMIZED_STUBS = 8;

    static inline ICSetProp_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICSetProp_Fallback>(code);
    }

    static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0;
    void noteUnoptimizableAccess() {
        extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT);
    }
    bool hadUnoptimizableAccess() const {
        return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::SetProp_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICSetProp_Fallback::New(space, getStubCode());
        }
    };
};

// Optimized SETPROP/SETGNAME/SETNAME stub.
class ICSetProp_Native : public ICUpdatedStub
{
    friend class ICStubSpace;

  protected: // Protected to silence Clang warning.
    HeapPtrTypeObject type_;
    HeapPtrShape shape_;
    uint32_t offset_;

    ICSetProp_Native(IonCode *stubCode, HandleTypeObject type, HandleShape shape, uint32_t offset);

  public:
    static inline ICSetProp_Native *New(ICStubSpace *space, IonCode *code, HandleTypeObject type,
                                        HandleShape shape, uint32_t offset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICSetProp_Native>(code, type, shape, offset);
    }
    HeapPtrTypeObject &type() {
        return type_;
    }
    HeapPtrShape &shape() {
        return shape_;
    }
    static size_t offsetOfType() {
        return offsetof(ICSetProp_Native, type_);
    }
    static size_t offsetOfShape() {
        return offsetof(ICSetProp_Native, shape_);
    }
    static size_t offsetOfOffset() {
        return offsetof(ICSetProp_Native, offset_);
    }

    class Compiler : public ICStubCompiler {
        RootedObject obj_;
        bool isFixedSlot_;
        uint32_t offset_;

      protected:
        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(isFixedSlot_) << 16);
        }

        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, HandleObject obj, bool isFixedSlot, uint32_t offset)
          : ICStubCompiler(cx, ICStub::SetProp_Native),
            obj_(cx, obj),
            isFixedSlot_(isFixedSlot),
            offset_(offset)
        {}

        ICUpdatedStub *getStub(ICStubSpace *space);
    };
};


template <size_t ProtoChainDepth> class ICSetProp_NativeAddImpl;

class ICSetProp_NativeAdd : public ICUpdatedStub
{
  public:
    static const size_t MAX_PROTO_CHAIN_DEPTH = 4;

  protected: // Protected to silence Clang warning.
    HeapPtrTypeObject type_;
    HeapPtrShape newShape_;
    uint32_t offset_;

    ICSetProp_NativeAdd(IonCode *stubCode, HandleTypeObject type, size_t protoChainDepth,
                        HandleShape newShape, uint32_t offset);

  public:
    size_t protoChainDepth() const {
        return extra_;
    }
    HeapPtrTypeObject &type() {
        return type_;
    }
    HeapPtrShape &newShape() {
        return newShape_;
    }

    template <size_t ProtoChainDepth>
    ICSetProp_NativeAddImpl<ProtoChainDepth> *toImpl() {
        JS_ASSERT(ProtoChainDepth == protoChainDepth());
        return static_cast<ICSetProp_NativeAddImpl<ProtoChainDepth> *>(this);
    }

    static size_t offsetOfType() {
        return offsetof(ICSetProp_NativeAdd, type_);
    }
    static size_t offsetOfNewShape() {
        return offsetof(ICSetProp_NativeAdd, newShape_);
    }
    static size_t offsetOfOffset() {
        return offsetof(ICSetProp_NativeAdd, offset_);
    }
};

template <size_t ProtoChainDepth>
class ICSetProp_NativeAddImpl : public ICSetProp_NativeAdd
{
    friend class ICStubSpace;

    static const size_t NumShapes = ProtoChainDepth + 1;
    HeapPtrShape shapes_[NumShapes];

    ICSetProp_NativeAddImpl(IonCode *stubCode, HandleTypeObject type,
                            const AutoShapeVector *shapes,
                            HandleShape newShape, uint32_t offset);

  public:
    static inline ICSetProp_NativeAddImpl *New(
            ICStubSpace *space, IonCode *code, HandleTypeObject type,
            const AutoShapeVector *shapes, HandleShape newShape, uint32_t offset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICSetProp_NativeAddImpl<ProtoChainDepth> >(
                            code, type, shapes, newShape, offset);
    }

    void traceShapes(JSTracer *trc) {
        for (size_t i = 0; i < NumShapes; i++)
            MarkShape(trc, &shapes_[i], "baseline-setpropnativeadd-stub-shape");
    }

    static size_t offsetOfShape(size_t idx) {
        return offsetof(ICSetProp_NativeAddImpl, shapes_) + (idx * sizeof(HeapPtrShape));
    }
};

class ICSetPropNativeAddCompiler : public ICStubCompiler {
    RootedObject obj_;
    RootedShape oldShape_;
    size_t protoChainDepth_;
    bool isFixedSlot_;
    uint32_t offset_;

  protected:
    virtual int32_t getKey() const {
        return static_cast<int32_t>(kind) | (static_cast<int32_t>(isFixedSlot_) << 16) |
               (static_cast<int32_t>(protoChainDepth_) << 20);
    }

    bool generateStubCode(MacroAssembler &masm);

  public:
    ICSetPropNativeAddCompiler(JSContext *cx, HandleObject obj, HandleShape oldShape,
                               size_t protoChainDepth, bool isFixedSlot, uint32_t offset);

    template <size_t ProtoChainDepth>
    ICUpdatedStub *getStubSpecific(ICStubSpace *space, const AutoShapeVector *shapes)
    {
        RootedTypeObject type(cx, obj_->getType(cx));
        RootedShape newShape(cx, obj_->lastProperty());

        return ICSetProp_NativeAddImpl<ProtoChainDepth>::New(
                    space, getStubCode(), type, shapes, newShape, offset_);
    }

    ICUpdatedStub *getStub(ICStubSpace *space);
};

// Base stub for calling a setters on a native object.
class ICSetPropCallSetter : public ICStub
{
    friend class ICStubSpace;

  protected:
    // Object shape (lastProperty).
    HeapPtrShape shape_;

    // Holder and shape.
    HeapPtrObject holder_;
    HeapPtrShape holderShape_;

    // Function to call.
    HeapPtrFunction setter_;

    // PC of call, for profiler
    uint32_t pcOffset_;

    ICSetPropCallSetter(Kind kind, IonCode *stubCode, HandleShape shape, HandleObject holder,
                        HandleShape holderShape, HandleFunction setter, uint32_t pcOffset);

  public:
    HeapPtrShape &shape() {
        return shape_;
    }
    HeapPtrObject &holder() {
        return holder_;
    }
    HeapPtrShape &holderShape() {
        return holderShape_;
    }
    HeapPtrFunction &setter() {
        return setter_;
    }

    static size_t offsetOfShape() {
        return offsetof(ICSetPropCallSetter, shape_);
    }
    static size_t offsetOfHolder() {
        return offsetof(ICSetPropCallSetter, holder_);
    }
    static size_t offsetOfHolderShape() {
        return offsetof(ICSetPropCallSetter, holderShape_);
    }
    static size_t offsetOfSetter() {
        return offsetof(ICSetPropCallSetter, setter_);
    }
    static size_t offsetOfPCOffset() {
        return offsetof(ICSetPropCallSetter, pcOffset_);
    }

    class Compiler : public ICStubCompiler {
      protected:
        RootedObject obj_;
        RootedObject holder_;
        RootedFunction setter_;
        uint32_t pcOffset_;

      public:
        Compiler(JSContext *cx, ICStub::Kind kind, HandleObject obj, HandleObject holder,
                 HandleFunction setter, uint32_t pcOffset)
          : ICStubCompiler(cx, kind),
            obj_(cx, obj),
            holder_(cx, holder),
            setter_(cx, setter),
            pcOffset_(pcOffset)
        {
            JS_ASSERT(kind == ICStub::SetProp_CallScripted || kind == ICStub::SetProp_CallNative);
        }
    };
};

// Stub for calling a scripted setter on a native object.
class ICSetProp_CallScripted : public ICSetPropCallSetter
{
    friend class ICStubSpace;

  protected:
    ICSetProp_CallScripted(IonCode *stubCode, HandleShape shape, HandleObject holder,
                           HandleShape holderShape, HandleFunction setter, uint32_t pcOffset)
      : ICSetPropCallSetter(SetProp_CallScripted, stubCode, shape, holder, holderShape,
                            setter, pcOffset)
    {}

  public:
    static inline ICSetProp_CallScripted *New(ICStubSpace *space, IonCode *code,
                                              HandleShape shape, HandleObject holder,
                                              HandleShape holderShape, HandleFunction setter,
                                              uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICSetProp_CallScripted>(code, shape, holder, holderShape, setter,
                                                       pcOffset);
    }

    class Compiler : public ICSetPropCallSetter::Compiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, HandleObject obj, HandleObject holder, HandleFunction setter,
                 uint32_t pcOffset)
          : ICSetPropCallSetter::Compiler(cx, ICStub::SetProp_CallScripted,
                                          obj, holder, setter, pcOffset)
        {}

        ICStub *getStub(ICStubSpace *space) {
            RootedShape shape(cx, obj_->lastProperty());
            RootedShape holderShape(cx, holder_->lastProperty());
            return ICSetProp_CallScripted::New(space, getStubCode(), shape, holder_, holderShape,
                                               setter_, pcOffset_);
        }
    };
};

// Stub for calling a native setter on a native object.
class ICSetProp_CallNative : public ICSetPropCallSetter
{
    friend class ICStubSpace;

  protected:
    ICSetProp_CallNative(IonCode *stubCode, HandleShape shape, HandleObject holder,
                           HandleShape holderShape, HandleFunction setter, uint32_t pcOffset)
      : ICSetPropCallSetter(SetProp_CallNative, stubCode, shape, holder, holderShape,
                            setter, pcOffset)
    {}

  public:
    static inline ICSetProp_CallNative *New(ICStubSpace *space, IonCode *code,
                                            HandleShape shape, HandleObject holder,
                                            HandleShape holderShape, HandleFunction setter,
                                            uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICSetProp_CallNative>(code, shape, holder, holderShape, setter,
                                                     pcOffset);
    }

    class Compiler : public ICSetPropCallSetter::Compiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, HandleObject obj, HandleObject holder, HandleFunction setter,
                 uint32_t pcOffset)
          : ICSetPropCallSetter::Compiler(cx, ICStub::SetProp_CallNative,
                                          obj, holder, setter, pcOffset)
        {}

        ICStub *getStub(ICStubSpace *space) {
            RootedShape shape(cx, obj_->lastProperty());
            RootedShape holderShape(cx, holder_->lastProperty());
            return ICSetProp_CallNative::New(space, getStubCode(), shape, holder_, holderShape,
                                               setter_, pcOffset_);
        }
    };
};

// Call
//      JSOP_CALL
//      JSOP_FUNAPPLY
//      JSOP_FUNCALL
//      JSOP_NEW

class ICCallStubCompiler : public ICStubCompiler
{
  protected:
    ICCallStubCompiler(JSContext *cx, ICStub::Kind kind)
      : ICStubCompiler(cx, kind)
    { }

    void pushCallArguments(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg);
    Register guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg,
                           bool checkNative, Label *failure);
    void pushCallerArguments(MacroAssembler &masm, GeneralRegisterSet regs);
};

class ICCall_Fallback : public ICMonitoredFallbackStub
{
    friend class ICStubSpace;
  public:
    static const unsigned CONSTRUCTING_FLAG = 0x0001;

    static const uint32_t MAX_OPTIMIZED_STUBS = 16;
    static const uint32_t MAX_SCRIPTED_STUBS = 7;
    static const uint32_t MAX_NATIVE_STUBS = 7;
  private:

    ICCall_Fallback(IonCode *stubCode, bool isConstructing)
      : ICMonitoredFallbackStub(ICStub::Call_Fallback, stubCode)
    {
        extra_ = 0;
        if (isConstructing)
            extra_ |= CONSTRUCTING_FLAG;
    }

  public:

    static inline ICCall_Fallback *New(ICStubSpace *space, IonCode *code, bool isConstructing)
    {
        if (!code)
            return NULL;
        return space->allocate<ICCall_Fallback>(code, isConstructing);
    }

    bool isConstructing() const {
        return extra_ & CONSTRUCTING_FLAG;
    }

    unsigned scriptedStubCount() const {
        return numStubsWithKind(Call_Scripted);
    }
    bool scriptedStubsAreGeneralized() const {
        return hasStub(Call_AnyScripted);
    }

    unsigned nativeStubCount() const {
        return numStubsWithKind(Call_Native);
    }
    bool nativeStubsAreGeneralized() const {
        // Return hasStub(Call_AnyNative) after Call_AnyNative stub is added.
        return false;
    }

    // Compiler for this stub kind.
    class Compiler : public ICCallStubCompiler {
      protected:
        bool isConstructing_;
        uint32_t returnOffset_;
        bool generateStubCode(MacroAssembler &masm);
        bool postGenerateStubCode(MacroAssembler &masm, Handle<IonCode *> code);

      public:
        Compiler(JSContext *cx, bool isConstructing)
          : ICCallStubCompiler(cx, ICStub::Call_Fallback),
            isConstructing_(isConstructing)
        { }

        ICStub *getStub(ICStubSpace *space) {
            ICCall_Fallback *stub = ICCall_Fallback::New(space, getStubCode(), isConstructing_);
            if (!stub || !stub->initMonitoringChain(cx, space))
                return NULL;
            return stub;
        }
    };
};

class ICCall_Scripted : public ICMonitoredStub
{
    friend class ICStubSpace;

  protected:
    HeapPtrScript calleeScript_;
    uint32_t pcOffset_;

    ICCall_Scripted(IonCode *stubCode, ICStub *firstMonitorStub, HandleScript calleeScript,
                    uint32_t pcOffset);

  public:
    static inline ICCall_Scripted *New(
            ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub, HandleScript calleeScript,
            uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICCall_Scripted>(code, firstMonitorStub, calleeScript, pcOffset);
    }

    HeapPtrScript &calleeScript() {
        return calleeScript_;
    }

    static size_t offsetOfCalleeScript() {
        return offsetof(ICCall_Scripted, calleeScript_);
    }
    static size_t offsetOfPCOffset() {
        return offsetof(ICCall_Scripted, pcOffset_);
    }
};

class ICCall_AnyScripted : public ICMonitoredStub
{
    friend class ICStubSpace;

  protected:
    uint32_t pcOffset_;

    ICCall_AnyScripted(IonCode *stubCode, ICStub *firstMonitorStub, uint32_t pcOffset)
      : ICMonitoredStub(ICStub::Call_AnyScripted, stubCode, firstMonitorStub),
        pcOffset_(pcOffset)
    { }

  public:
    static inline ICCall_AnyScripted *New(ICStubSpace *space, IonCode *code,
                                          ICStub *firstMonitorStub, uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICCall_AnyScripted>(code, firstMonitorStub, pcOffset);
    }

    static size_t offsetOfPCOffset() {
        return offsetof(ICCall_AnyScripted, pcOffset_);
    }
};

// Compiler for Call_Scripted and Call_AnyScripted stubs.
class ICCallScriptedCompiler : public ICCallStubCompiler {
  protected:
    ICStub *firstMonitorStub_;
    bool isConstructing_;
    RootedScript calleeScript_;
    uint32_t pcOffset_;
    bool generateStubCode(MacroAssembler &masm);

    virtual int32_t getKey() const {
        return static_cast<int32_t>(kind) | (static_cast<int32_t>(isConstructing_) << 16);
    }

  public:
    ICCallScriptedCompiler(JSContext *cx, ICStub *firstMonitorStub, HandleScript calleeScript,
                            bool isConstructing, uint32_t pcOffset)
      : ICCallStubCompiler(cx, ICStub::Call_Scripted),
        firstMonitorStub_(firstMonitorStub),
        isConstructing_(isConstructing),
        calleeScript_(cx, calleeScript),
        pcOffset_(pcOffset)
    { }

    ICCallScriptedCompiler(JSContext *cx, ICStub *firstMonitorStub, bool isConstructing,
                           uint32_t pcOffset)
      : ICCallStubCompiler(cx, ICStub::Call_AnyScripted),
        firstMonitorStub_(firstMonitorStub),
        isConstructing_(isConstructing),
        calleeScript_(cx, NULL),
        pcOffset_(pcOffset)
    { }

    ICStub *getStub(ICStubSpace *space) {
        if (calleeScript_) {
            return ICCall_Scripted::New(space, getStubCode(), firstMonitorStub_, calleeScript_,
                                        pcOffset_);
        }
        return ICCall_AnyScripted::New(space, getStubCode(), firstMonitorStub_, pcOffset_);
    }
};

class ICCall_Native : public ICMonitoredStub
{
    friend class ICStubSpace;

  protected:
    HeapPtrFunction callee_;
    uint32_t pcOffset_;

    ICCall_Native(IonCode *stubCode, ICStub *firstMonitorStub, HandleFunction callee,
                  uint32_t pcOffset);

  public:
    static inline ICCall_Native *New(ICStubSpace *space, IonCode *code, ICStub *firstMonitorStub,
                                     HandleFunction callee, uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICCall_Native>(code, firstMonitorStub, callee, pcOffset);
    }

    HeapPtrFunction &callee() {
        return callee_;
    }

    static size_t offsetOfCallee() {
        return offsetof(ICCall_Native, callee_);
    }
    static size_t offsetOfPCOffset() {
        return offsetof(ICCall_Native, pcOffset_);
    }

    // Compiler for this stub kind.
    class Compiler : public ICCallStubCompiler {
      protected:
        ICStub *firstMonitorStub_;
        bool isConstructing_;
        RootedFunction callee_;
        uint32_t pcOffset_;
        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(isConstructing_) << 16);
        }

      public:
        Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleFunction callee,
                 bool isConstructing, uint32_t pcOffset)
          : ICCallStubCompiler(cx, ICStub::Call_Native),
            firstMonitorStub_(firstMonitorStub),
            isConstructing_(isConstructing),
            callee_(cx, callee),
            pcOffset_(pcOffset)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICCall_Native::New(space, getStubCode(), firstMonitorStub_, callee_, pcOffset_);
        }
    };
};

class ICCall_ScriptedApplyArguments : public ICMonitoredStub
{
    friend class ICStubSpace;

  protected:
    uint32_t pcOffset_;

    ICCall_ScriptedApplyArguments(IonCode *stubCode, ICStub *firstMonitorStub, uint32_t pcOffset)
      : ICMonitoredStub(ICStub::Call_ScriptedApplyArguments, stubCode, firstMonitorStub),
        pcOffset_(pcOffset)
    {}

  public:
    static inline ICCall_ScriptedApplyArguments *New(ICStubSpace *space, IonCode *code,
                                                     ICStub *firstMonitorStub, uint32_t pcOffset)
    {
        if (!code)
            return NULL;
        return space->allocate<ICCall_ScriptedApplyArguments>(code, firstMonitorStub, pcOffset);
    }

    static size_t offsetOfPCOffset() {
        return offsetof(ICCall_ScriptedApplyArguments, pcOffset_);
    }

    // Compiler for this stub kind.
    class Compiler : public ICCallStubCompiler {
      protected:
        ICStub *firstMonitorStub_;
        uint32_t pcOffset_;
        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind);
        }

      public:
        Compiler(JSContext *cx, ICStub *firstMonitorStub, uint32_t pcOffset)
          : ICCallStubCompiler(cx, ICStub::Call_ScriptedApplyArguments),
            firstMonitorStub_(firstMonitorStub),
            pcOffset_(pcOffset)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICCall_ScriptedApplyArguments::New(space, getStubCode(), firstMonitorStub_,
                                                      pcOffset_);
        }
    };
};

// Stub for performing a TableSwitch, updating the IC's return address to jump
// to whatever point the switch is branching to.
class ICTableSwitch : public ICStub
{
    friend class ICStubSpace;

  protected: // Protected to silence Clang warning.
    void **table_;
    int32_t min_;
    int32_t length_;
    void *defaultTarget_;

    ICTableSwitch(IonCode *stubCode, void **table,
                  int32_t min, int32_t length, void *defaultTarget)
      : ICStub(TableSwitch, stubCode), table_(table),
        min_(min), length_(length), defaultTarget_(defaultTarget)
    {}

  public:
    static inline ICTableSwitch *New(ICStubSpace *space, IonCode *code, void **table,
                                     int32_t min, int32_t length, void *defaultTarget) {
        if (!code)
            return NULL;
        return space->allocate<ICTableSwitch>(code, table, min, length, defaultTarget);
    }

    void fixupJumpTable(HandleScript script, BaselineScript *baseline);

    class Compiler : public ICStubCompiler {
        bool generateStubCode(MacroAssembler &masm);

        jsbytecode *pc_;

      public:
        Compiler(JSContext *cx, jsbytecode *pc)
          : ICStubCompiler(cx, ICStub::TableSwitch), pc_(pc)
        {}

        ICStub *getStub(ICStubSpace *space);
    };
};

// IC for constructing an iterator from an input value.
class ICIteratorNew_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICIteratorNew_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::IteratorNew_Fallback, stubCode)
    { }

  public:
    static inline ICIteratorNew_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICIteratorNew_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::IteratorNew_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICIteratorNew_Fallback::New(space, getStubCode());
        }
    };
};

// IC for testing if there are more values in an iterator.
class ICIteratorMore_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICIteratorMore_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::IteratorMore_Fallback, stubCode)
    { }

  public:
    static inline ICIteratorMore_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICIteratorMore_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::IteratorMore_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICIteratorMore_Fallback::New(space, getStubCode());
        }
    };
};

// IC for testing if there are more values in a native iterator.
class ICIteratorMore_Native : public ICStub
{
    friend class ICStubSpace;

    ICIteratorMore_Native(IonCode *stubCode)
      : ICStub(ICStub::IteratorMore_Native, stubCode)
    { }

  public:
    static inline ICIteratorMore_Native *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICIteratorMore_Native>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::IteratorMore_Native)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICIteratorMore_Native::New(space, getStubCode());
        }
    };
};

// IC for getting the next value in an iterator.
class ICIteratorNext_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICIteratorNext_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::IteratorNext_Fallback, stubCode)
    { }

  public:
    static inline ICIteratorNext_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICIteratorNext_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::IteratorNext_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICIteratorNext_Fallback::New(space, getStubCode());
        }
    };
};

// IC for getting the next value in a native iterator.
class ICIteratorNext_Native : public ICStub
{
    friend class ICStubSpace;

    ICIteratorNext_Native(IonCode *stubCode)
      : ICStub(ICStub::IteratorNext_Native, stubCode)
    { }

  public:
    static inline ICIteratorNext_Native *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICIteratorNext_Native>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::IteratorNext_Native)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICIteratorNext_Native::New(space, getStubCode());
        }
    };
};

// IC for closing an iterator.
class ICIteratorClose_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICIteratorClose_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::IteratorClose_Fallback, stubCode)
    { }

  public:
    static inline ICIteratorClose_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICIteratorClose_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::IteratorClose_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICIteratorClose_Fallback::New(space, getStubCode());
        }
    };
};

// InstanceOf
//      JSOP_INSTANCEOF
class ICInstanceOf_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICInstanceOf_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::InstanceOf_Fallback, stubCode)
    { }

  public:
    static inline ICInstanceOf_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICInstanceOf_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::InstanceOf_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICInstanceOf_Fallback::New(space, getStubCode());
        }
    };
};

// TypeOf
//      JSOP_TYPEOF
//      JSOP_TYPEOFEXPR
class ICTypeOf_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICTypeOf_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::TypeOf_Fallback, stubCode)
    { }

  public:
    static inline ICTypeOf_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICTypeOf_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::TypeOf_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICTypeOf_Fallback::New(space, getStubCode());
        }
    };
};

class ICTypeOf_Typed : public ICFallbackStub
{
    friend class ICStubSpace;

    ICTypeOf_Typed(IonCode *stubCode, JSType type)
      : ICFallbackStub(ICStub::TypeOf_Typed, stubCode)
    {
        extra_ = uint16_t(type);
        JS_ASSERT(JSType(extra_) == type);
    }

  public:
    static inline ICTypeOf_Typed *New(ICStubSpace *space, IonCode *code, JSType type) {
        if (!code)
            return NULL;
        return space->allocate<ICTypeOf_Typed>(code, type);
    }

    JSType type() const {
        return JSType(extra_);
    }

    class Compiler : public ICStubCompiler {
      protected:
        JSType type_;
        RootedString typeString_;
        bool generateStubCode(MacroAssembler &masm);

        virtual int32_t getKey() const {
            return static_cast<int32_t>(kind) | (static_cast<int32_t>(type_) << 16);
        }

      public:
        Compiler(JSContext *cx, JSType type, HandleString string)
          : ICStubCompiler(cx, ICStub::TypeOf_Typed),
            type_(type),
            typeString_(cx, string)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICTypeOf_Typed::New(space, getStubCode(), type_);
        }
    };
};

// Rest
//      JSOP_REST
class ICRest_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICRest_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::Rest_Fallback, stubCode)
    { }

  public:
    static inline ICRest_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICRest_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::Rest_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICRest_Fallback::New(space, getStubCode());
        }
    };
};

// Stub for JSOP_RETSUB ("returning" from a |finally| block).
class ICRetSub_Fallback : public ICFallbackStub
{
    friend class ICStubSpace;

    ICRetSub_Fallback(IonCode *stubCode)
      : ICFallbackStub(ICStub::RetSub_Fallback, stubCode)
    { }

  public:
    static const uint32_t MAX_OPTIMIZED_STUBS = 8;

    static inline ICRetSub_Fallback *New(ICStubSpace *space, IonCode *code) {
        if (!code)
            return NULL;
        return space->allocate<ICRetSub_Fallback>(code);
    }

    class Compiler : public ICStubCompiler {
      protected:
        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx)
          : ICStubCompiler(cx, ICStub::RetSub_Fallback)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICRetSub_Fallback::New(space, getStubCode());
        }
    };
};

// Optimized JSOP_RETSUB stub. Every stub maps a single pc offset to its
// native code address.
class ICRetSub_Resume : public ICStub
{
    friend class ICStubSpace;

  protected:
    uint32_t pcOffset_;
    uint8_t *addr_;

    ICRetSub_Resume(IonCode *stubCode, uint32_t pcOffset, uint8_t *addr)
      : ICStub(ICStub::RetSub_Resume, stubCode),
        pcOffset_(pcOffset),
        addr_(addr)
    { }

  public:
    static ICRetSub_Resume *New(ICStubSpace *space, IonCode *code, uint32_t pcOffset,
                                uint8_t *addr) {
        if (!code)
            return NULL;
        return space->allocate<ICRetSub_Resume>(code, pcOffset, addr);
    }

    static size_t offsetOfPCOffset() {
        return offsetof(ICRetSub_Resume, pcOffset_);
    }
    static size_t offsetOfAddr() {
        return offsetof(ICRetSub_Resume, addr_);
    }

    class Compiler : public ICStubCompiler {
        uint32_t pcOffset_;
        uint8_t *addr_;

        bool generateStubCode(MacroAssembler &masm);

      public:
        Compiler(JSContext *cx, uint32_t pcOffset, uint8_t *addr)
          : ICStubCompiler(cx, ICStub::RetSub_Resume),
            pcOffset_(pcOffset),
            addr_(addr)
        { }

        ICStub *getStub(ICStubSpace *space) {
            return ICRetSub_Resume::New(space, getStubCode(), pcOffset_, addr_);
        }
    };
};

} // namespace jit
} // namespace js

#endif // JS_ION

#endif /* jit_BaselineIC_h */
