/*
 * Copyright (C) 2015-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 "JSScope.h"
#include "VM.h"

namespace JSC {

template<typename JSCellType>
class InferredValue {
    WTF_MAKE_NONCOPYABLE(InferredValue);
    WTF_MAKE_NONMOVABLE(InferredValue);
public:
    // For the purpose of deciding whether or not to watch this variable, you only need
    // to inspect inferredValue(). If this returns something other than the empty
    // value, then it means that at all future safepoints, this watchpoint set will be
    // in one of these states:
    //
    //    IsWatched: in this case, the variable's value must still be the
    //        inferredValue.
    //
    //    IsInvalidated: in this case the variable's value may be anything but you'll
    //        either notice that it's invalidated and not install the watchpoint, or
    //        you will have been notified that the watchpoint was fired.
    JSCellType* inferredValue()
    {
        uintptr_t data = m_data;
        if (isFat(data))
            return fat(data)->inferredValue();
        return bitwise_cast<JSCellType*>(data & ValueMask);
    }

    explicit InferredValue()
        : m_data(encodeState(ClearWatchpoint))
    {
        ASSERT(inferredValue() == nullptr);
    }

    ~InferredValue()
    {
        if (isThin())
            return;
        freeFat();
    }

    // Fast way of getting the state, which only works from the main thread.
    WatchpointState stateOnJSThread() const
    {
        uintptr_t data = m_data;
        if (isFat(data))
            return fat(data)->stateOnJSThread();
        return decodeState(data);
    }

    // It is safe to call this from another thread. It may return a prior state,
    // but that should be fine since you should only perform actions based on the
    // state if you also add a watchpoint.
    WatchpointState state() const
    {
        uintptr_t data = m_data;
        if (isFat(data))
            return fat(data)->state();
        return decodeState(data);
    }

    // It is safe to call this from another thread. It may return false
    // even if the set actually had been invalidated, but that ought to happen
    // only in the case of races, and should be rare.
    bool hasBeenInvalidated() const
    {
        return state() == IsInvalidated;
    }
    
    // Like hasBeenInvalidated(), may be called from another thread.
    bool isStillValid() const
    {
        return !hasBeenInvalidated();
    }
    
    void add(Watchpoint*);
    
    void invalidate(VM& vm, const FireDetail& detail)
    {
        if (isFat())
            fat()->invalidate(vm, detail);
        else
            m_data = encodeState(IsInvalidated);
    }
    
    bool isBeingWatched() const
    {
        if (isFat())
            return fat()->isBeingWatched();
        return false;
    }

    void notifyWrite(VM& vm, JSCell* owner, JSCellType* value, const FireDetail& detail)
    {
        if (LIKELY(stateOnJSThread() == IsInvalidated))
            return;
        notifyWriteSlow(vm, owner, value, detail);
    }
    
    void notifyWrite(VM& vm, JSCell* owner, JSCellType* value, const char* reason)
    {
        if (LIKELY(stateOnJSThread() == IsInvalidated))
            return;
        notifyWriteSlow(vm, owner, value, reason);
    }
    
    void finalizeUnconditionally(VM&);

private:
    class InferredValueWatchpointSet final : public WatchpointSet {
    public:
        InferredValueWatchpointSet(WatchpointState state, JSCellType* value)
            : WatchpointSet(state)
            , m_value(value)
        {
        }

        JSCellType* inferredValue() const { return m_value; }

        void invalidate(VM& vm, const FireDetail& detail)
        {
            m_value = nullptr;
            WatchpointSet::invalidate(vm, detail);
        }

        void notifyWriteSlow(VM&, JSCell* owner, JSCellType*, const FireDetail&);

    private:
        JSCellType* m_value;
    };

    static constexpr uintptr_t IsThinFlag        = 1;
    static constexpr uintptr_t StateMask         = 6;
    static constexpr uintptr_t StateShift        = 1;
    static constexpr uintptr_t ValueMask         = ~static_cast<uintptr_t>(IsThinFlag | StateMask);
    
    static bool isThin(uintptr_t data) { return data & IsThinFlag; }
    static bool isFat(uintptr_t data) { return !isThin(data); }
    
    static WatchpointState decodeState(uintptr_t data)
    {
        ASSERT(isThin(data));
        return static_cast<WatchpointState>((data & StateMask) >> StateShift);
    }
    
    static uintptr_t encodeState(WatchpointState state)
    {
        return (static_cast<uintptr_t>(state) << StateShift) | IsThinFlag;
    }
    
    bool isThin() const { return isThin(m_data); }
    bool isFat() const { return isFat(m_data); };
    
    static InferredValueWatchpointSet* fat(uintptr_t data)
    {
        return bitwise_cast<InferredValueWatchpointSet*>(data);
    }
    
    InferredValueWatchpointSet* fat()
    {
        ASSERT(isFat());
        return fat(m_data);
    }
    
    const InferredValueWatchpointSet* fat() const
    {
        ASSERT(isFat());
        return fat(m_data);
    }
    
    InferredValueWatchpointSet* inflate()
    {
        if (LIKELY(isFat()))
            return fat();
        return inflateSlow();
    }

    InferredValueWatchpointSet* inflateSlow();
    void freeFat();

    void notifyWriteSlow(VM&, JSCell* owner, JSCellType*, const FireDetail&);
    void notifyWriteSlow(VM&, JSCell* owner, JSCellType*, const char* reason);
    
    uintptr_t m_data;
};

template<typename JSCellType>
void InferredValue<JSCellType>::InferredValueWatchpointSet::notifyWriteSlow(VM& vm, JSCell* owner, JSCellType* value, const FireDetail& detail)
{
    switch (state()) {
    case ClearWatchpoint:
        m_value = value;
        vm.heap.writeBarrier(owner, value);
        startWatching();
        return;

    case IsWatched:
        ASSERT(!!m_value);
        if (m_value == value)
            return;
        invalidate(vm, detail);
        return;

    case IsInvalidated:
        ASSERT_NOT_REACHED();
        return;
    }

    ASSERT_NOT_REACHED();
}

template<typename JSCellType>
void InferredValue<JSCellType>::notifyWriteSlow(VM& vm, JSCell* owner, JSCellType* value, const FireDetail& detail)
{
    uintptr_t data = m_data;
    if (isFat(data)) {
        fat(data)->notifyWriteSlow(vm, owner, value, detail);
        return;
    }

    switch (state()) {
    case ClearWatchpoint:
        ASSERT(decodeState(m_data) != IsInvalidated);
        m_data = (bitwise_cast<uintptr_t>(value) & ValueMask) | encodeState(IsWatched);
        vm.heap.writeBarrier(owner, value);
        return;

    case IsWatched:
        ASSERT(!!inferredValue());
        if (inferredValue() == value)
            return;
        invalidate(vm, detail);
        return;

    case IsInvalidated:
        ASSERT_NOT_REACHED();
        return;
    }

    ASSERT_NOT_REACHED();
}

template<typename JSCellType>
void InferredValue<JSCellType>::notifyWriteSlow(VM& vm, JSCell* owner, JSCellType* value, const char* reason)
{
    notifyWriteSlow(vm, owner, value, StringFireDetail(reason));
}

template<typename JSCellType>
void InferredValue<JSCellType>::add(Watchpoint* watchpoint)
{
    inflate()->add(watchpoint);
}

template<typename JSCellType>
auto InferredValue<JSCellType>::inflateSlow() -> InferredValueWatchpointSet*
{
    ASSERT(isThin());
    ASSERT(!isCompilationThread());
    uintptr_t data = m_data;
    InferredValueWatchpointSet* fat = adoptRef(new InferredValueWatchpointSet(decodeState(m_data), bitwise_cast<JSCellType*>(data & ValueMask))).leakRef();
    WTF::storeStoreFence();
    m_data = bitwise_cast<uintptr_t>(fat);
    return fat;
}

template<typename JSCellType>
void InferredValue<JSCellType>::freeFat()
{
    ASSERT(isFat());
    fat()->deref();
}

} // namespace JSC
