/* -*- 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_IonCode_h
#define jit_IonCode_h

#include "mozilla/Atomics.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/PodOperations.h"

#include "jstypes.h"

#include "gc/Heap.h"
#include "jit/ExecutableAllocator.h"
#include "jit/ICStubSpace.h"
#include "jit/IonOptimizationLevels.h"
#include "jit/IonTypes.h"
#include "js/UbiNode.h"
#include "vm/TraceLogging.h"
#include "vm/TypeInference.h"

namespace js {
namespace jit {

class MacroAssembler;
class PatchableBackedge;
class IonBuilder;
class IonICEntry;

typedef Vector<JSObject*, 4, JitAllocPolicy> ObjectVector;

class JitCode : public gc::TenuredCell
{
  protected:
    uint8_t* code_;
    ExecutablePool* pool_;
    uint32_t bufferSize_;             // Total buffer size. Does not include headerSize_.
    uint32_t insnSize_;               // Instruction stream size.
    uint32_t dataSize_;               // Size of the read-only data area.
    uint32_t jumpRelocTableBytes_;    // Size of the jump relocation table.
    uint32_t dataRelocTableBytes_;    // Size of the data relocation table.
    uint32_t preBarrierTableBytes_;   // Size of the prebarrier table.
    uint8_t headerSize_ : 5;          // Number of bytes allocated before codeStart.
    uint8_t kind_ : 3;                // jit::CodeKind, for the memory reporters.
    bool invalidated_ : 1;            // Whether the code object has been invalidated.
                                      // This is necessary to prevent GC tracing.
    bool hasBytecodeMap_ : 1;         // Whether the code object has been registered with
                                      // native=>bytecode mapping tables.

#if JS_BITS_PER_WORD == 32
    // Ensure JitCode is gc::Cell aligned.
    uint32_t padding_;
#endif

    JitCode()
      : code_(nullptr),
        pool_(nullptr)
    { }
    JitCode(uint8_t* code, uint32_t bufferSize, uint32_t headerSize, ExecutablePool* pool,
            CodeKind kind)
      : code_(code),
        pool_(pool),
        bufferSize_(bufferSize),
        insnSize_(0),
        dataSize_(0),
        jumpRelocTableBytes_(0),
        dataRelocTableBytes_(0),
        preBarrierTableBytes_(0),
        headerSize_(headerSize),
        kind_(kind),
        invalidated_(false),
        hasBytecodeMap_(false)
    {
        MOZ_ASSERT(CodeKind(kind_) == kind);
        MOZ_ASSERT(headerSize_ == headerSize);
    }

    uint32_t dataOffset() const {
        return insnSize_;
    }
    uint32_t jumpRelocTableOffset() const {
        return dataOffset() + dataSize_;
    }
    uint32_t dataRelocTableOffset() const {
        return jumpRelocTableOffset() + jumpRelocTableBytes_;
    }
    uint32_t preBarrierTableOffset() const {
        return dataRelocTableOffset() + dataRelocTableBytes_;
    }

  public:
    uint8_t* raw() const {
        return code_;
    }
    uint8_t* rawEnd() const {
        return code_ + insnSize_;
    }
    bool containsNativePC(const void* addr) const {
        const uint8_t* addr_u8 = (const uint8_t*) addr;
        return raw() <= addr_u8 && addr_u8 < rawEnd();
    }
    size_t instructionsSize() const {
        return insnSize_;
    }
    size_t bufferSize() const {
        return bufferSize_;
    }
    size_t headerSize() const {
        return headerSize_;
    }

    void traceChildren(JSTracer* trc);
    void finalize(FreeOp* fop);
    void fixupAfterMovingGC() {}
    void setInvalidated() {
        invalidated_ = true;
    }

    void setHasBytecodeMap() {
        hasBytecodeMap_ = true;
    }

    void togglePreBarriers(bool enabled);

    // If this JitCode object has been, effectively, corrupted due to
    // invalidation patching, then we have to remember this so we don't try and
    // trace relocation entries that may now be corrupt.
    bool invalidated() const {
        return !!invalidated_;
    }

    template <typename T> T as() const {
        return JS_DATA_TO_FUNC_PTR(T, raw());
    }

    void copyFrom(MacroAssembler& masm);

    static JitCode* FromExecutable(uint8_t* buffer) {
        JitCode* code = *(JitCode**)(buffer - sizeof(JitCode*));
        MOZ_ASSERT(code->raw() == buffer);
        return code;
    }

    static size_t offsetOfCode() {
        return offsetof(JitCode, code_);
    }

    uint8_t* jumpRelocTable() {
        return code_ + jumpRelocTableOffset();
    }

    // Allocates a new JitCode object which will be managed by the GC. If no
    // object can be allocated, nullptr is returned. On failure, |pool| is
    // automatically released, so the code may be freed.
    template <AllowGC allowGC>
    static JitCode* New(JSContext* cx, uint8_t* code, uint32_t bufferSize, uint32_t headerSize,
                        ExecutablePool* pool, CodeKind kind);

  public:
    static inline ThingRootKind rootKind() { return THING_ROOT_JIT_CODE; }
};

class SnapshotWriter;
class RecoverWriter;
class SafepointWriter;
class SafepointIndex;
class OsiIndex;
class IonCache;
struct PatchableBackedgeInfo;
struct CacheLocation;

// An IonScript attaches Ion-generated information to a JSScript.
struct IonScript
{
  private:
    // Code pointer containing the actual method.
    PreBarrieredJitCode method_;

    // Deoptimization table used by this method.
    PreBarrieredJitCode deoptTable_;

    // Entrypoint for OSR, or nullptr.
    jsbytecode* osrPc_;

    // Offset to OSR entrypoint from method_->raw(), or 0.
    uint32_t osrEntryOffset_;

    // Offset to entrypoint skipping type arg check from method_->raw().
    uint32_t skipArgCheckEntryOffset_;

    // Offset of the invalidation epilogue (which pushes this IonScript
    // and calls the invalidation thunk).
    uint32_t invalidateEpilogueOffset_;

    // The offset immediately after the IonScript immediate.
    // NOTE: technically a constant delta from
    // |invalidateEpilogueOffset_|, so we could hard-code this
    // per-platform if we want.
    uint32_t invalidateEpilogueDataOffset_;

    // Number of times this script bailed out without invalidation.
    uint32_t numBailouts_;

    // Flag set if IonScript was compiled with profiling enabled.
    bool hasProfilingInstrumentation_;

    // Flag for if this script is getting recompiled.
    uint32_t recompiling_;

    // Any kind of data needed by the runtime, these can be either cache
    // information or profiling info.
    uint32_t runtimeData_;
    uint32_t runtimeSize_;

    // State for polymorphic caches in the compiled code. All caches are stored
    // in the runtimeData buffer and indexed by the cacheIndex which give a
    // relative offset in the runtimeData array.
    uint32_t cacheIndex_;
    uint32_t cacheEntries_;

    // Map code displacement to safepoint / OSI-patch-delta.
    uint32_t safepointIndexOffset_;
    uint32_t safepointIndexEntries_;

    // Offset to and length of the safepoint table in bytes.
    uint32_t safepointsStart_;
    uint32_t safepointsSize_;

    // Number of bytes this function reserves on the stack.
    uint32_t frameSlots_;

    // Number of bytes used passed in as formal arguments or |this|.
    uint32_t argumentSlots_;

    // Frame size is the value that can be added to the StackPointer along
    // with the frame prefix to get a valid JitFrameLayout.
    uint32_t frameSize_;

    // Table mapping bailout IDs to snapshot offsets.
    uint32_t bailoutTable_;
    uint32_t bailoutEntries_;

    // Map OSI-point displacement to snapshot.
    uint32_t osiIndexOffset_;
    uint32_t osiIndexEntries_;

    // Offset from the start of the code buffer to its snapshot buffer.
    uint32_t snapshots_;
    uint32_t snapshotsListSize_;
    uint32_t snapshotsRVATableSize_;

    // List of instructions needed to recover stack frames.
    uint32_t recovers_;
    uint32_t recoversSize_;

    // Constant table for constants stored in snapshots.
    uint32_t constantTable_;
    uint32_t constantEntries_;

    // List of patchable backedges which are threaded into the runtime's list.
    uint32_t backedgeList_;
    uint32_t backedgeEntries_;

    // List of entries to the shared stub.
    uint32_t sharedStubList_;
    uint32_t sharedStubEntries_;

    // Number of references from invalidation records.
    uint32_t invalidationCount_;

    // Identifier of the compilation which produced this code.
    RecompileInfo recompileInfo_;

    // The optimization level this script was compiled in.
    OptimizationLevel optimizationLevel_;

    // Number of times we tried to enter this script via OSR but failed due to
    // a LOOPENTRY pc other than osrPc_.
    uint32_t osrPcMismatchCounter_;

    // Allocated space for fallback stubs.
    FallbackICStubSpace fallbackStubSpace_;

    // The tracelogger event used to log the start/stop of this IonScript.
    TraceLoggerEvent traceLoggerScriptEvent_;

  private:
    inline uint8_t* bottomBuffer() {
        return reinterpret_cast<uint8_t*>(this);
    }
    inline const uint8_t* bottomBuffer() const {
        return reinterpret_cast<const uint8_t*>(this);
    }

  public:

    SnapshotOffset* bailoutTable() {
        return (SnapshotOffset*) &bottomBuffer()[bailoutTable_];
    }
    PreBarrieredValue* constants() {
        return (PreBarrieredValue*) &bottomBuffer()[constantTable_];
    }
    const SafepointIndex* safepointIndices() const {
        return const_cast<IonScript*>(this)->safepointIndices();
    }
    SafepointIndex* safepointIndices() {
        return (SafepointIndex*) &bottomBuffer()[safepointIndexOffset_];
    }
    const OsiIndex* osiIndices() const {
        return const_cast<IonScript*>(this)->osiIndices();
    }
    OsiIndex* osiIndices() {
        return (OsiIndex*) &bottomBuffer()[osiIndexOffset_];
    }
    uint32_t* cacheIndex() {
        return (uint32_t*) &bottomBuffer()[cacheIndex_];
    }
    uint8_t* runtimeData() {
        return  &bottomBuffer()[runtimeData_];
    }
    PatchableBackedge* backedgeList() {
        return (PatchableBackedge*) &bottomBuffer()[backedgeList_];
    }

  private:
    void trace(JSTracer* trc);

  public:
    // Do not call directly, use IonScript::New. This is public for cx->new_.
    IonScript();

    static IonScript* New(JSContext* cx, RecompileInfo recompileInfo,
                          uint32_t frameSlots, uint32_t argumentSlots, uint32_t frameSize,
                          size_t snapshotsListSize, size_t snapshotsRVATableSize,
                          size_t recoversSize, size_t bailoutEntries,
                          size_t constants, size_t safepointIndexEntries,
                          size_t osiIndexEntries, size_t cacheEntries,
                          size_t runtimeSize, size_t safepointsSize,
                          size_t backedgeEntries, size_t sharedStubEntries,
                          OptimizationLevel optimizationLevel);
    static void Trace(JSTracer* trc, IonScript* script);
    static void Destroy(FreeOp* fop, IonScript* script);

    static inline size_t offsetOfMethod() {
        return offsetof(IonScript, method_);
    }
    static inline size_t offsetOfOsrEntryOffset() {
        return offsetof(IonScript, osrEntryOffset_);
    }
    static inline size_t offsetOfSkipArgCheckEntryOffset() {
        return offsetof(IonScript, skipArgCheckEntryOffset_);
    }
    static inline size_t offsetOfInvalidationCount() {
        return offsetof(IonScript, invalidationCount_);
    }
    static inline size_t offsetOfRecompiling() {
        return offsetof(IonScript, recompiling_);
    }

  public:
    JitCode* method() const {
        return method_;
    }
    void setMethod(JitCode* code) {
        MOZ_ASSERT(!invalidated());
        method_ = code;
    }
    void setDeoptTable(JitCode* code) {
        deoptTable_ = code;
    }
    void setOsrPc(jsbytecode* osrPc) {
        osrPc_ = osrPc;
    }
    jsbytecode* osrPc() const {
        return osrPc_;
    }
    void setOsrEntryOffset(uint32_t offset) {
        MOZ_ASSERT(!osrEntryOffset_);
        osrEntryOffset_ = offset;
    }
    uint32_t osrEntryOffset() const {
        return osrEntryOffset_;
    }
    void setSkipArgCheckEntryOffset(uint32_t offset) {
        MOZ_ASSERT(!skipArgCheckEntryOffset_);
        skipArgCheckEntryOffset_ = offset;
    }
    uint32_t getSkipArgCheckEntryOffset() const {
        return skipArgCheckEntryOffset_;
    }
    bool containsCodeAddress(uint8_t* addr) const {
        return method()->raw() <= addr && addr <= method()->raw() + method()->instructionsSize();
    }
    bool containsReturnAddress(uint8_t* addr) const {
        // This accounts for an off by one error caused by the return address of a
        // bailout sitting outside the range of the containing function.
        return method()->raw() <= addr && addr <= method()->raw() + method()->instructionsSize();
    }
    void setInvalidationEpilogueOffset(uint32_t offset) {
        MOZ_ASSERT(!invalidateEpilogueOffset_);
        invalidateEpilogueOffset_ = offset;
    }
    uint32_t invalidateEpilogueOffset() const {
        MOZ_ASSERT(invalidateEpilogueOffset_);
        return invalidateEpilogueOffset_;
    }
    void setInvalidationEpilogueDataOffset(uint32_t offset) {
        MOZ_ASSERT(!invalidateEpilogueDataOffset_);
        invalidateEpilogueDataOffset_ = offset;
    }
    uint32_t invalidateEpilogueDataOffset() const {
        MOZ_ASSERT(invalidateEpilogueDataOffset_);
        return invalidateEpilogueDataOffset_;
    }
    void incNumBailouts() {
        numBailouts_++;
    }
    uint32_t numBailouts() const {
        return numBailouts_;
    }
    bool bailoutExpected() const {
        return numBailouts_ > 0;
    }
    void setHasProfilingInstrumentation() {
        hasProfilingInstrumentation_ = true;
    }
    void clearHasProfilingInstrumentation() {
        hasProfilingInstrumentation_ = false;
    }
    bool hasProfilingInstrumentation() const {
        return hasProfilingInstrumentation_;
    }
    void setTraceLoggerEvent(TraceLoggerEvent& event) {
        traceLoggerScriptEvent_ = event;
    }
    const uint8_t* snapshots() const {
        return reinterpret_cast<const uint8_t*>(this) + snapshots_;
    }
    size_t snapshotsListSize() const {
        return snapshotsListSize_;
    }
    size_t snapshotsRVATableSize() const {
        return snapshotsRVATableSize_;
    }
    const uint8_t* recovers() const {
        return reinterpret_cast<const uint8_t*>(this) + recovers_;
    }
    size_t recoversSize() const {
        return recoversSize_;
    }
    const uint8_t* safepoints() const {
        return reinterpret_cast<const uint8_t*>(this) + safepointsStart_;
    }
    size_t safepointsSize() const {
        return safepointsSize_;
    }
    size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
        return mallocSizeOf(this);
    }
    PreBarrieredValue& getConstant(size_t index) {
        MOZ_ASSERT(index < numConstants());
        return constants()[index];
    }
    size_t numConstants() const {
        return constantEntries_;
    }
    uint32_t frameSlots() const {
        return frameSlots_;
    }
    uint32_t argumentSlots() const {
        return argumentSlots_;
    }
    uint32_t frameSize() const {
        return frameSize_;
    }
    SnapshotOffset bailoutToSnapshot(uint32_t bailoutId) {
        MOZ_ASSERT(bailoutId < bailoutEntries_);
        return bailoutTable()[bailoutId];
    }
    const SafepointIndex* getSafepointIndex(uint32_t disp) const;
    const SafepointIndex* getSafepointIndex(uint8_t* retAddr) const {
        MOZ_ASSERT(containsCodeAddress(retAddr));
        return getSafepointIndex(retAddr - method()->raw());
    }
    const OsiIndex* getOsiIndex(uint32_t disp) const;
    const OsiIndex* getOsiIndex(uint8_t* retAddr) const;
    inline IonCache& getCacheFromIndex(uint32_t index) {
        MOZ_ASSERT(index < cacheEntries_);
        uint32_t offset = cacheIndex()[index];
        return getCache(offset);
    }
    inline IonCache& getCache(uint32_t offset) {
        MOZ_ASSERT(offset < runtimeSize_);
        return *(IonCache*) &runtimeData()[offset];
    }
    size_t numCaches() const {
        return cacheEntries_;
    }
    IonICEntry* sharedStubList() {
        return (IonICEntry*) &bottomBuffer()[sharedStubList_];
    }
    size_t numSharedStubs() const {
        return sharedStubEntries_;
    }
    size_t runtimeSize() const {
        return runtimeSize_;
    }
    CacheLocation* getCacheLocs(uint32_t locIndex) {
        MOZ_ASSERT(locIndex < runtimeSize_);
        return (CacheLocation*) &runtimeData()[locIndex];
    }
    void toggleBarriers(bool enabled);
    void purgeCaches();
    void unlinkFromRuntime(FreeOp* fop);
    void copySnapshots(const SnapshotWriter* writer);
    void copyRecovers(const RecoverWriter* writer);
    void copyBailoutTable(const SnapshotOffset* table);
    void copyConstants(const Value* vp);
    void copySafepointIndices(const SafepointIndex* firstSafepointIndex, MacroAssembler& masm);
    void copyOsiIndices(const OsiIndex* firstOsiIndex, MacroAssembler& masm);
    void copyRuntimeData(const uint8_t* data);
    void copyCacheEntries(const uint32_t* caches, MacroAssembler& masm);
    void copySafepoints(const SafepointWriter* writer);
    void copyPatchableBackedges(JSContext* cx, JitCode* code,
                                PatchableBackedgeInfo* backedges,
                                MacroAssembler& masm);

    bool invalidated() const {
        return invalidationCount_ != 0;
    }

    // Invalidate the current compilation.
    bool invalidate(JSContext* cx, bool resetUses, const char* reason);

    size_t invalidationCount() const {
        return invalidationCount_;
    }
    void incrementInvalidationCount() {
        invalidationCount_++;
    }
    void decrementInvalidationCount(FreeOp* fop) {
        MOZ_ASSERT(invalidationCount_);
        invalidationCount_--;
        if (!invalidationCount_)
            Destroy(fop, this);
    }
    const RecompileInfo& recompileInfo() const {
        return recompileInfo_;
    }
    RecompileInfo& recompileInfoRef() {
        return recompileInfo_;
    }
    OptimizationLevel optimizationLevel() const {
        return optimizationLevel_;
    }
    uint32_t incrOsrPcMismatchCounter() {
        return ++osrPcMismatchCounter_;
    }
    void resetOsrPcMismatchCounter() {
        osrPcMismatchCounter_ = 0;
    }

    void setRecompiling() {
        recompiling_ = true;
    }

    bool isRecompiling() const {
        return recompiling_;
    }

    void clearRecompiling() {
        recompiling_ = false;
    }

    FallbackICStubSpace* fallbackStubSpace() {
        return &fallbackStubSpace_;
    }
    void adoptFallbackStubs(FallbackICStubSpace* stubSpace);
    void purgeOptimizedStubs(Zone* zone);

    enum ShouldIncreaseAge {
        IncreaseAge = true,
        KeepAge = false
    };

    static void writeBarrierPre(Zone* zone, IonScript* ionScript);
};

// Execution information for a basic block which may persist after the
// accompanying IonScript is destroyed, for use during profiling.
struct IonBlockCounts
{
  private:
    uint32_t id_;

    // Approximate bytecode in the outer (not inlined) script this block
    // was generated from.
    uint32_t offset_;

    // File and line of the inner script this block was generated from.
    char* description_;

    // ids for successors of this block.
    uint32_t numSuccessors_;
    uint32_t* successors_;

    // Hit count for this block.
    uint64_t hitCount_;

    // Text information about the code generated for this block.
    char* code_;

  public:

    bool init(uint32_t id, uint32_t offset, char* description, uint32_t numSuccessors) {
        id_ = id;
        offset_ = offset;
        description_ = description;
        numSuccessors_ = numSuccessors;
        if (numSuccessors) {
            successors_ = js_pod_calloc<uint32_t>(numSuccessors);
            if (!successors_)
                return false;
        }
        return true;
    }

    void destroy() {
        js_free(description_);
        js_free(successors_);
        js_free(code_);
    }

    uint32_t id() const {
        return id_;
    }

    uint32_t offset() const {
        return offset_;
    }

    const char* description() const {
        return description_;
    }

    size_t numSuccessors() const {
        return numSuccessors_;
    }

    void setSuccessor(size_t i, uint32_t id) {
        MOZ_ASSERT(i < numSuccessors_);
        successors_[i] = id;
    }

    uint32_t successor(size_t i) const {
        MOZ_ASSERT(i < numSuccessors_);
        return successors_[i];
    }

    uint64_t* addressOfHitCount() {
        return &hitCount_;
    }

    uint64_t hitCount() const {
        return hitCount_;
    }

    void setCode(const char* code) {
        char* ncode = js_pod_malloc<char>(strlen(code) + 1);
        if (ncode) {
            strcpy(ncode, code);
            code_ = ncode;
        }
    }

    const char* code() const {
        return code_;
    }
};

// Execution information for a compiled script which may persist after the
// IonScript is destroyed, for use during profiling.
struct IonScriptCounts
{
  private:
    // Any previous invalidated compilation(s) for the script.
    IonScriptCounts* previous_;

    // Information about basic blocks in this script.
    size_t numBlocks_;
    IonBlockCounts* blocks_;

  public:

    IonScriptCounts() {
        mozilla::PodZero(this);
    }

    ~IonScriptCounts() {
        for (size_t i = 0; i < numBlocks_; i++)
            blocks_[i].destroy();
        js_free(blocks_);
        // The list can be long in some corner cases (bug 1140084), so
        // unroll the recursion.
        IonScriptCounts* victims = previous_;
        while (victims) {
            IonScriptCounts* victim = victims;
            victims = victim->previous_;
            victim->previous_ = nullptr;
            js_delete(victim);
        }
    }

    bool init(size_t numBlocks) {
        blocks_ = js_pod_calloc<IonBlockCounts>(numBlocks);
        if (!blocks_)
            return false;

        numBlocks_ = numBlocks;
        return true;
    }

    size_t numBlocks() const {
        return numBlocks_;
    }

    IonBlockCounts& block(size_t i) {
        MOZ_ASSERT(i < numBlocks_);
        return blocks_[i];
    }

    void setPrevious(IonScriptCounts* previous) {
        previous_ = previous;
    }

    IonScriptCounts* previous() const {
        return previous_;
    }
};

struct VMFunction;

struct AutoFlushICache
{
  private:
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
    uintptr_t start_;
    uintptr_t stop_;
    const char* name_;
    bool inhibit_;
    AutoFlushICache* prev_;
#endif

  public:
    static void setRange(uintptr_t p, size_t len);
    static void flush(uintptr_t p, size_t len);
    static void setInhibit();
    ~AutoFlushICache();
    explicit AutoFlushICache(const char* nonce, bool inhibit=false);
};

} // namespace jit

namespace gc {

inline bool
IsMarked(const jit::VMFunction*)
{
    // VMFunction are only static objects which are used by WeakMaps as keys.
    // It is considered as a root object which is always marked.
    return true;
}

} // namespace gc

} // namespace js

// JS::ubi::Nodes can point to js::jit::JitCode instances; they're js::gc::Cell
// instances with no associated compartment.
namespace JS {
namespace ubi {
template<>
struct Concrete<js::jit::JitCode> : TracerConcrete<js::jit::JitCode> {
    CoarseType coarseType() const final { return CoarseType::Script; }

    Size size(mozilla::MallocSizeOf mallocSizeOf) const override {
        Size size = js::gc::Arena::thingSize(get().asTenured().getAllocKind());
        size += get().bufferSize();
        size += get().headerSize();
        return size;
    }

  protected:
    explicit Concrete(js::jit::JitCode *ptr) : TracerConcrete<js::jit::JitCode>(ptr) { }

  public:
    static void construct(void *storage, js::jit::JitCode *ptr) { new (storage) Concrete(ptr); }
};

} // namespace ubi
} // namespace JS

#endif /* jit_IonCode_h */
