/*
 * Copyright (C) 2011-2019 Apple Inc. 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 APPLE INC. ``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 APPLE INC. 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

#include "BytecodeIndex.h"

#include <limits.h>
#include <wtf/HashMap.h>
#include <wtf/PrintStream.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>

namespace JSC {

class CodeBlock;
struct DumpContext;
struct InlineCallFrame;

class CodeOrigin {
public:
    CodeOrigin()
#if CPU(ADDRESS64)
        : m_compositeValue(buildCompositeValue(nullptr, BytecodeIndex()))
#else
        : m_inlineCallFrame(nullptr)
#endif
    {
    }

    CodeOrigin(WTF::HashTableDeletedValueType)
#if CPU(ADDRESS64)
        : m_compositeValue(buildCompositeValue(deletedMarker(), BytecodeIndex()))
#else
        : m_bytecodeIndex(WTF::HashTableDeletedValue)
        , m_inlineCallFrame(deletedMarker())
#endif
    {
    }
    
    explicit CodeOrigin(BytecodeIndex bytecodeIndex, InlineCallFrame* inlineCallFrame = nullptr)
#if CPU(ADDRESS64)
        : m_compositeValue(buildCompositeValue(inlineCallFrame, bytecodeIndex))
#else
        : m_bytecodeIndex(bytecodeIndex)
        , m_inlineCallFrame(inlineCallFrame)
#endif
    {
        ASSERT(!!bytecodeIndex);
#if CPU(ADDRESS64)
        ASSERT(!(bitwise_cast<uintptr_t>(inlineCallFrame) & ~s_maskCompositeValueForPointer));
#endif
    }
    
#if CPU(ADDRESS64)
    CodeOrigin& operator=(const CodeOrigin& other)
    {
        if (this != &other) {
            if (UNLIKELY(isOutOfLine()))
                delete outOfLineCodeOrigin();
            
            if (UNLIKELY(other.isOutOfLine()))
                m_compositeValue = buildCompositeValue(other.inlineCallFrame(), other.bytecodeIndex());
            else
                m_compositeValue = other.m_compositeValue;
        }
        return *this;
    }
    CodeOrigin& operator=(CodeOrigin&& other)
    {
        if (this != &other) {
            if (UNLIKELY(isOutOfLine()))
                delete outOfLineCodeOrigin();

            m_compositeValue = std::exchange(other.m_compositeValue, 0);
        }
        return *this;
    }

    CodeOrigin(const CodeOrigin& other)
    {
        // We don't use the member initializer list because it would not let us optimize the common case where there is no out-of-line storage
        // (in which case we don't have to extract the components of the composite value just to reassemble it).
        if (UNLIKELY(other.isOutOfLine()))
            m_compositeValue = buildCompositeValue(other.inlineCallFrame(), other.bytecodeIndex());
        else
            m_compositeValue = other.m_compositeValue;
    }
    CodeOrigin(CodeOrigin&& other)
        : m_compositeValue(std::exchange(other.m_compositeValue, 0))
    {
    }

    ~CodeOrigin()
    {
        if (UNLIKELY(isOutOfLine()))
            delete outOfLineCodeOrigin();
    }
#endif
    
    bool isSet() const
    {
#if CPU(ADDRESS64)
        return !(m_compositeValue & s_maskIsBytecodeIndexInvalid);
#else
        return !!m_bytecodeIndex;
#endif
    }
    explicit operator bool() const { return isSet(); }
    
    bool isHashTableDeletedValue() const
    {
#if CPU(ADDRESS64)
        return !isSet() && (m_compositeValue & s_maskCompositeValueForPointer);
#else
        return m_bytecodeIndex.isHashTableDeletedValue() && !!m_inlineCallFrame;
#endif
    }
    
    // The inline depth is the depth of the inline stack, so 1 = not inlined,
    // 2 = inlined one deep, etc.
    unsigned inlineDepth() const;
    
    // If the code origin corresponds to inlined code, gives you the heap object that
    // would have owned the code if it had not been inlined. Otherwise returns 0.
    CodeBlock* codeOriginOwner() const;
    
    int stackOffset() const;
    
    unsigned hash() const;
    bool operator==(const CodeOrigin& other) const;
    bool operator!=(const CodeOrigin& other) const { return !(*this == other); }
    
    // This checks if the two code origins correspond to the same stack trace snippets,
    // but ignore whether the InlineCallFrame's are identical.
    bool isApproximatelyEqualTo(const CodeOrigin& other, InlineCallFrame* terminal = nullptr) const;
    
    unsigned approximateHash(InlineCallFrame* terminal = nullptr) const;

    template <typename Function>
    void walkUpInlineStack(const Function&) const;

    inline bool inlineStackContainsActiveCheckpoint() const;
    
    // Get the inline stack. This is slow, and is intended for debugging only.
    Vector<CodeOrigin> inlineStack() const;
    
    JS_EXPORT_PRIVATE void dump(PrintStream&) const;
    void dumpInContext(PrintStream&, DumpContext*) const;

    BytecodeIndex bytecodeIndex() const
    {
#if CPU(ADDRESS64)
        if (!isSet())
            return BytecodeIndex();
        if (UNLIKELY(isOutOfLine()))
            return outOfLineCodeOrigin()->bytecodeIndex;
        return BytecodeIndex::fromBits(m_compositeValue >> (64 - s_freeBitsAtTop));
#else
        return m_bytecodeIndex;
#endif
    }

    InlineCallFrame* inlineCallFrame() const
    {
#if CPU(ADDRESS64)
        if (UNLIKELY(isOutOfLine()))
            return outOfLineCodeOrigin()->inlineCallFrame;
        return bitwise_cast<InlineCallFrame*>(m_compositeValue & s_maskCompositeValueForPointer);
#else
        return m_inlineCallFrame;
#endif
    }

private:
#if CPU(ADDRESS64)
    static constexpr uintptr_t s_maskIsOutOfLine = 1;
    static constexpr uintptr_t s_maskIsBytecodeIndexInvalid = 2;

    struct OutOfLineCodeOrigin {
        WTF_MAKE_FAST_ALLOCATED;
    public:
        InlineCallFrame* inlineCallFrame;
        BytecodeIndex bytecodeIndex;
        
        OutOfLineCodeOrigin(InlineCallFrame* inlineCallFrame, BytecodeIndex bytecodeIndex)
            : inlineCallFrame(inlineCallFrame)
            , bytecodeIndex(bytecodeIndex)
        {
        }
    };
    
    bool isOutOfLine() const
    {
        return m_compositeValue & s_maskIsOutOfLine;
    }
    OutOfLineCodeOrigin* outOfLineCodeOrigin() const
    {
        ASSERT(isOutOfLine());
        return bitwise_cast<OutOfLineCodeOrigin*>(m_compositeValue & s_maskCompositeValueForPointer);
    }
#endif

    static InlineCallFrame* deletedMarker()
    {
        auto value = static_cast<uintptr_t>(1 << 3);
#if CPU(ADDRESS64)
        ASSERT(value & s_maskCompositeValueForPointer);
        ASSERT(!(value & ~s_maskCompositeValueForPointer));
#endif
        return bitwise_cast<InlineCallFrame*>(value);
    }

#if CPU(ADDRESS64)
    static constexpr unsigned s_freeBitsAtTop = 64 - OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH);
    static constexpr uintptr_t s_maskCompositeValueForPointer = ((1ULL << OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH)) - 1) & ~(8ULL - 1);
    static uintptr_t buildCompositeValue(InlineCallFrame* inlineCallFrame, BytecodeIndex bytecodeIndex)
    {
        if (!bytecodeIndex)
            return bitwise_cast<uintptr_t>(inlineCallFrame) | s_maskIsBytecodeIndexInvalid;

        if (UNLIKELY(bytecodeIndex.asBits() >= 1 << s_freeBitsAtTop)) {
            auto* outOfLine = new OutOfLineCodeOrigin(inlineCallFrame, bytecodeIndex);
            return bitwise_cast<uintptr_t>(outOfLine) | s_maskIsOutOfLine;
        }

        uintptr_t encodedBytecodeIndex = static_cast<uintptr_t>(bytecodeIndex.asBits()) << (64 - s_freeBitsAtTop);
        ASSERT(!(encodedBytecodeIndex & bitwise_cast<uintptr_t>(inlineCallFrame)));
        return encodedBytecodeIndex | bitwise_cast<uintptr_t>(inlineCallFrame);
    }

    // The bottom bit indicates whether to look at an out-of-line implementation (because of a bytecode index which is too big for us to store).
    // The next bit indicates whether this is an invalid bytecode (which depending on the InlineCallFrame* can either indicate an unset CodeOrigin,
    // or a deletion marker for a hash table).
    // The next bit is free
    // The next 64-s_freeBitsAtTop-3 are the InlineCallFrame* or the OutOfLineCodeOrigin*
    // Finally the last s_freeBitsAtTop are the bytecodeIndex if it is inline
    uintptr_t m_compositeValue;
#else
    BytecodeIndex m_bytecodeIndex;
    InlineCallFrame* m_inlineCallFrame;
#endif
};

inline unsigned CodeOrigin::hash() const
{
    return WTF::IntHash<unsigned>::hash(bytecodeIndex().asBits()) +
        WTF::PtrHash<InlineCallFrame*>::hash(inlineCallFrame());
}

inline bool CodeOrigin::operator==(const CodeOrigin& other) const
{
#if CPU(ADDRESS64)
    if (m_compositeValue == other.m_compositeValue)
        return true;
#endif
    return bytecodeIndex() == other.bytecodeIndex()
        && inlineCallFrame() == other.inlineCallFrame();
}

struct CodeOriginHash {
    static unsigned hash(const CodeOrigin& key) { return key.hash(); }
    static bool equal(const CodeOrigin& a, const CodeOrigin& b) { return a == b; }
    static constexpr bool safeToCompareToEmptyOrDeleted = true;
};

struct CodeOriginApproximateHash {
    static unsigned hash(const CodeOrigin& key) { return key.approximateHash(); }
    static bool equal(const CodeOrigin& a, const CodeOrigin& b) { return a.isApproximatelyEqualTo(b); }
    static constexpr bool safeToCompareToEmptyOrDeleted = true;
};

} // namespace JSC

namespace WTF {

template<typename T> struct DefaultHash;
template<> struct DefaultHash<JSC::CodeOrigin> {
    typedef JSC::CodeOriginHash Hash;
};

template<typename T> struct HashTraits;
template<> struct HashTraits<JSC::CodeOrigin> : SimpleClassHashTraits<JSC::CodeOrigin> {
    static constexpr bool emptyValueIsZero = false;
};

} // namespace WTF
