/*
 * Copyright (C) 2009 University of Szeged
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#if ENABLE(ASSEMBLER)

#include "AssemblerBuffer.h"
#include <wtf/SegmentedVector.h>

#define ASSEMBLER_HAS_CONSTANT_POOL 1

namespace JSC {

/*
    On a constant pool 4 or 8 bytes data can be stored. The values can be
    constants or addresses. The addresses should be 32 or 64 bits. The constants
    should be double-precisions float or integer numbers which are hard to be
    encoded as few machine instructions.

    TODO: The pool is desinged to handle both 32 and 64 bits values, but
    currently only the 4 bytes constants are implemented and tested.

    The AssemblerBuffer can contain multiple constant pools. Each pool is inserted
    into the instruction stream - protected by a jump instruction from the
    execution flow.

    The flush mechanism is called when no space remain to insert the next instruction
    into the pool. Three values are used to determine when the constant pool itself
    have to be inserted into the instruction stream (Assembler Buffer):

    - maxPoolSize: size of the constant pool in bytes, this value cannot be
        larger than the maximum offset of a PC relative memory load

    - barrierSize: size of jump instruction in bytes which protects the
        constant pool from execution

    - maxInstructionSize: maximum length of a machine instruction in bytes

    There are some callbacks which solve the target architecture specific
    address handling:

    - TYPE patchConstantPoolLoad(TYPE load, int value):
        patch the 'load' instruction with the index of the constant in the
        constant pool and return the patched instruction.

    - void patchConstantPoolLoad(void* loadAddr, void* constPoolAddr):
        patch the a PC relative load instruction at 'loadAddr' address with the
        final relative offset. The offset can be computed with help of
        'constPoolAddr' (the address of the constant pool) and index of the
        constant (which is stored previously in the load instruction itself).

    - TYPE placeConstantPoolBarrier(int size):
        return with a constant pool barrier instruction which jumps over the
        constant pool.

    The 'put*WithConstant*' functions should be used to place a data into the
    constant pool.
*/

template <int maxPoolSize, int barrierSize, int maxInstructionSize, class AssemblerType>
class AssemblerBufferWithConstantPool : public AssemblerBuffer {
    typedef SegmentedVector<uint32_t, 512> LoadOffsets;
    using AssemblerBuffer::putIntegral;
    using AssemblerBuffer::putIntegralUnchecked;
public:
    typedef struct {
        short high;
        short low;
    } TwoShorts;

    enum {
        UniqueConst,
        ReusableConst,
        UnusedEntry,
    };

    AssemblerBufferWithConstantPool()
        : AssemblerBuffer()
        , m_numConsts(0)
        , m_maxDistance(maxPoolSize)
        , m_lastConstDelta(0)
    {
        m_pool = static_cast<uint32_t*>(fastMalloc(maxPoolSize));
        m_mask = static_cast<char*>(fastMalloc(maxPoolSize / sizeof(uint32_t)));
    }

    ~AssemblerBufferWithConstantPool()
    {
        fastFree(m_mask);
        fastFree(m_pool);
    }

    void ensureSpace(int space)
    {
        flushIfNoSpaceFor(space);
        AssemblerBuffer::ensureSpace(space);
    }

    void ensureSpace(int insnSpace, int constSpace)
    {
        flushIfNoSpaceFor(insnSpace, constSpace);
        AssemblerBuffer::ensureSpace(insnSpace);
    }

    void ensureSpaceForAnyInstruction(int amount = 1)
    {
        flushIfNoSpaceFor(amount * maxInstructionSize, amount * sizeof(uint64_t));
    }

    bool isAligned(int alignment)
    {
        flushIfNoSpaceFor(alignment);
        return AssemblerBuffer::isAligned(alignment);
    }

    void putByteUnchecked(int value)
    {
        AssemblerBuffer::putByteUnchecked(value);
        correctDeltas(1);
    }

    void putByte(int value)
    {
        flushIfNoSpaceFor(1);
        AssemblerBuffer::putByte(value);
        correctDeltas(1);
    }

    void putShortUnchecked(int value)
    {
        AssemblerBuffer::putShortUnchecked(value);
        correctDeltas(2);
    }

    void putShort(int value)
    {
        flushIfNoSpaceFor(2);
        AssemblerBuffer::putShort(value);
        correctDeltas(2);
    }

    void putIntUnchecked(int value)
    {
        AssemblerBuffer::putIntUnchecked(value);
        correctDeltas(4);
    }

    void putInt(int value)
    {
        flushIfNoSpaceFor(4);
        AssemblerBuffer::putInt(value);
        correctDeltas(4);
    }

    void putInt64Unchecked(int64_t value)
    {
        AssemblerBuffer::putInt64Unchecked(value);
        correctDeltas(8);
    }

    void putIntegral(TwoShorts value)
    {
        putIntegral(value.high);
        putIntegral(value.low);
    }

    void putIntegralUnchecked(TwoShorts value)
    {
        putIntegralUnchecked(value.high);
        putIntegralUnchecked(value.low);
    }

    void putShortWithConstantInt(uint16_t insn, uint32_t constant, bool isReusable = false)
    {
        putIntegralWithConstantInt(insn, constant, isReusable);
    }

    void putIntWithConstantInt(uint32_t insn, uint32_t constant, bool isReusable = false)
    {
        putIntegralWithConstantInt(insn, constant, isReusable);
    }

    // This flushing mechanism can be called after any unconditional jumps.
    void flushWithoutBarrier(bool isForced = false)
    {
        // Flush if constant pool is more than 60% full to avoid overuse of this function.
        if (isForced || 5 * static_cast<uint32_t>(m_numConsts) > 3 * maxPoolSize / sizeof(uint32_t))
            flushConstantPool(false);
    }

    uint32_t* poolAddress()
    {
        return m_pool;
    }

    int sizeOfConstantPool()
    {
        return m_numConsts;
    }

    void flushConstantPool(bool useBarrier = true)
    {
        if (!m_numConsts)
            return;
        int alignPool = (codeSize() + (useBarrier ? barrierSize : 0)) & (sizeof(uint64_t) - 1);

        if (alignPool)
            alignPool = sizeof(uint64_t) - alignPool;

        // Callback to protect the constant pool from execution
        if (useBarrier)
            putIntegral(AssemblerType::placeConstantPoolBarrier(m_numConsts * sizeof(uint32_t) + alignPool));

        if (alignPool) {
            if (alignPool & 1)
                AssemblerBuffer::putByte(AssemblerType::padForAlign8);
            if (alignPool & 2)
                AssemblerBuffer::putShort(AssemblerType::padForAlign16);
            if (alignPool & 4)
                AssemblerBuffer::putInt(AssemblerType::padForAlign32);
        }

        int constPoolOffset = codeSize();
        append(reinterpret_cast<char*>(m_pool), m_numConsts * sizeof(uint32_t));

        // Patch each PC relative load
        for (LoadOffsets::Iterator iter = m_loadOffsets.begin(); iter != m_loadOffsets.end(); ++iter) {
            void* loadAddr = reinterpret_cast<char*>(data()) + *iter;
            AssemblerType::patchConstantPoolLoad(loadAddr, reinterpret_cast<char*>(data()) + constPoolOffset);
        }

        m_loadOffsets.clear();
        m_numConsts = 0;
    }

private:
    void correctDeltas(int insnSize)
    {
        m_maxDistance -= insnSize;
        m_lastConstDelta -= insnSize;
        if (m_lastConstDelta < 0)
            m_lastConstDelta = 0;
    }

    void correctDeltas(int insnSize, int constSize)
    {
        correctDeltas(insnSize);

        m_maxDistance -= m_lastConstDelta;
        m_lastConstDelta = constSize;
    }

    template<typename IntegralType>
    void putIntegralWithConstantInt(IntegralType insn, uint32_t constant, bool isReusable)
    {
        if (!m_numConsts)
            m_maxDistance = maxPoolSize;
        flushIfNoSpaceFor(sizeof(IntegralType), 4);

        m_loadOffsets.append(codeSize());
        if (isReusable) {
            for (int i = 0; i < m_numConsts; ++i) {
                if (m_mask[i] == ReusableConst && m_pool[i] == constant) {
                    putIntegral(static_cast<IntegralType>(AssemblerType::patchConstantPoolLoad(insn, i)));
                    correctDeltas(sizeof(IntegralType));
                    return;
                }
            }
        }

        m_pool[m_numConsts] = constant;
        m_mask[m_numConsts] = static_cast<char>(isReusable ? ReusableConst : UniqueConst);

        putIntegral(static_cast<IntegralType>(AssemblerType::patchConstantPoolLoad(insn, m_numConsts)));
        ++m_numConsts;

        correctDeltas(sizeof(IntegralType), 4);
    }

    void flushIfNoSpaceFor(int nextInsnSize)
    {
        if (m_numConsts == 0)
            return;
        int lastConstDelta = m_lastConstDelta > nextInsnSize ? m_lastConstDelta - nextInsnSize : 0;
        if ((m_maxDistance < nextInsnSize + lastConstDelta + barrierSize + (int)sizeof(uint32_t)))
            flushConstantPool();
    }

    void flushIfNoSpaceFor(int nextInsnSize, int nextConstSize)
    {
        if (m_numConsts == 0)
            return;
        if ((m_maxDistance < nextInsnSize + m_lastConstDelta + nextConstSize + barrierSize + (int)sizeof(uint32_t)) ||
            (m_numConsts * sizeof(uint32_t) + nextConstSize >= maxPoolSize))
            flushConstantPool();
    }

    uint32_t* m_pool;
    char* m_mask;
    LoadOffsets m_loadOffsets;

    int m_numConsts;
    int m_maxDistance;
    int m_lastConstDelta;
};

} // namespace JSC

#endif // ENABLE(ASSEMBLER)
