/*
 * Copyright (C) 2012-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. 
 */

#include "config.h"
#include "CallLinkStatus.h"

#include "BytecodeStructs.h"
#include "CallLinkInfo.h"
#include "CodeBlock.h"
#include "JSCInlines.h"
#include <wtf/CommaPrinter.h>
#include <wtf/ListDump.h>

namespace JSC {

namespace CallLinkStatusInternal {
static constexpr bool verbose = false;
}

CallLinkStatus::CallLinkStatus(JSValue value)
    : m_couldTakeSlowPath(false)
    , m_isProved(false)
{
    if (!value || !value.isCell()) {
        m_couldTakeSlowPath = true;
        return;
    }
    
    m_variants.append(CallVariant(value.asCell()));
}

CallLinkStatus CallLinkStatus::computeFor(
    CodeBlock* profiledBlock, BytecodeIndex bytecodeIndex, const ICStatusMap& map,
    ExitSiteData exitSiteData)
{
    ConcurrentJSLocker locker(profiledBlock->m_lock);
    
    UNUSED_PARAM(profiledBlock);
    UNUSED_PARAM(bytecodeIndex);
    UNUSED_PARAM(map);
    UNUSED_PARAM(exitSiteData);
#if ENABLE(DFG_JIT)
    CallLinkInfo* callLinkInfo = map.get(CodeOrigin(bytecodeIndex)).callLinkInfo;
    if (!callLinkInfo)
        return CallLinkStatus();
    // doneLocation is nullptr when it is tied to LLInt (not Baseline).
    if (!callLinkInfo->doneLocation()) {
        if (exitSiteData.takesSlowPath)
            return takesSlowPath();
#if ENABLE(DFG_JIT)
        if (profiledBlock->unlinkedCodeBlock()->hasExitSite(DFG::FrequentExitSite(bytecodeIndex, BadConstantValue))) {
            // We could force this to be a closure call, but instead we'll just assume that it
            // takes slow path.
            return takesSlowPath();
        }
#endif
    }
    
    return computeFor(locker, profiledBlock, *callLinkInfo, exitSiteData);
#else
    return CallLinkStatus();
#endif
}

CallLinkStatus CallLinkStatus::computeFor(
    CodeBlock* profiledBlock, BytecodeIndex bytecodeIndex, const ICStatusMap& map)
{
    return computeFor(profiledBlock, bytecodeIndex, map, computeExitSiteData(profiledBlock, bytecodeIndex));
}

CallLinkStatus::ExitSiteData CallLinkStatus::computeExitSiteData(CodeBlock* profiledBlock, BytecodeIndex bytecodeIndex)
{
    ExitSiteData exitSiteData;
#if ENABLE(DFG_JIT)
    UnlinkedCodeBlock* codeBlock = profiledBlock->unlinkedCodeBlock();
    ConcurrentJSLocker locker(codeBlock->m_lock);

    auto takesSlowPath = [&] (ExitingInlineKind inlineKind) -> ExitFlag {
        return ExitFlag(
            codeBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadType, ExitFromAnything, inlineKind))
            || codeBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadExecutable, ExitFromAnything, inlineKind)),
            inlineKind);
    };
    
    auto badFunction = [&] (ExitingInlineKind inlineKind) -> ExitFlag {
        return ExitFlag(codeBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadConstantValue, ExitFromAnything, inlineKind)), inlineKind);
    };
    
    exitSiteData.takesSlowPath |= takesSlowPath(ExitFromNotInlined);
    exitSiteData.takesSlowPath |= takesSlowPath(ExitFromInlined);
    exitSiteData.badFunction |= badFunction(ExitFromNotInlined);
    exitSiteData.badFunction |= badFunction(ExitFromInlined);
#else
    UNUSED_PARAM(profiledBlock);
    UNUSED_PARAM(bytecodeIndex);
#endif
    
    return exitSiteData;
}

#if ENABLE(JIT)
CallLinkStatus CallLinkStatus::computeFor(
    const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, CallLinkInfo& callLinkInfo)
{
    // We don't really need this, but anytime we have to debug this code, it becomes indispensable.
    UNUSED_PARAM(profiledBlock);
    
    CallLinkStatus result = computeFromCallLinkInfo(locker, callLinkInfo);
    result.m_maxArgumentCountIncludingThis = callLinkInfo.maxArgumentCountIncludingThis();
    return result;
}

CallLinkStatus CallLinkStatus::computeFromCallLinkInfo(
    const ConcurrentJSLocker&, CallLinkInfo& callLinkInfo)
{
    // We cannot tell you anything about direct calls.
    if (callLinkInfo.isDirect())
        return CallLinkStatus();
    
    if (callLinkInfo.clearedByGC() || callLinkInfo.clearedByVirtual())
        return takesSlowPath();
    
    // Note that despite requiring that the locker is held, this code is racy with respect
    // to the CallLinkInfo: it may get cleared while this code runs! This is because
    // CallLinkInfo::unlink() may be called from a different CodeBlock than the one that owns
    // the CallLinkInfo and currently we save space by not having CallLinkInfos know who owns
    // them. So, there is no way for either the caller of CallLinkInfo::unlock() or unlock()
    // itself to figure out which lock to lock.
    //
    // Fortunately, that doesn't matter. The only things we ask of CallLinkInfo - the slow
    // path count, the stub, and the target - can all be asked racily. Stubs and targets can
    // only be deleted at next GC, so if we load a non-null one, then it must contain data
    // that is still marginally valid (i.e. the pointers ain't stale). This kind of raciness
    // is probably OK for now.
    
    // PolymorphicCallStubRoutine is a GCAwareJITStubRoutine, so if non-null, it will stay alive
    // until next GC even if the CallLinkInfo is concurrently cleared. Also, the variants list is
    // never mutated after the PolymorphicCallStubRoutine is instantiated. We have some conservative
    // fencing in place to make sure that we see the variants list after construction.
    if (PolymorphicCallStubRoutine* stub = callLinkInfo.stub()) {
        WTF::dependentLoadLoadFence();
        
        if (!stub->hasEdges()) {
            // This means we have an FTL profile, which has incomplete information.
            //
            // It's not clear if takesSlowPath() or CallLinkStatus() are appropriate here, but I
            // think that takesSlowPath() is a narrow winner.
            //
            // Either way, this is telling us that the FTL had been led to believe that it's
            // profitable not to inline anything.
            return takesSlowPath();
        }
        
        CallEdgeList edges = stub->edges();
        
        // Now that we've loaded the edges list, there are no further concurrency concerns. We will
        // just manipulate and prune this list to our liking - mostly removing entries that are too
        // infrequent and ensuring that it's sorted in descending order of frequency.
        
        RELEASE_ASSERT(edges.size());
        
        std::sort(
            edges.begin(), edges.end(),
            [] (CallEdge a, CallEdge b) {
                return a.count() > b.count();
            });
        RELEASE_ASSERT(edges.first().count() >= edges.last().count());
        
        double totalCallsToKnown = 0;
        double totalCallsToUnknown = callLinkInfo.slowPathCount();
        CallVariantList variants;
        for (size_t i = 0; i < edges.size(); ++i) {
            CallEdge edge = edges[i];
            // If the call is at the tail of the distribution, then we don't optimize it and we
            // treat it as if it was a call to something unknown. We define the tail as being either
            // a call that doesn't belong to the N most frequent callees (N =
            // maxPolymorphicCallVariantsForInlining) or that has a total call count that is too
            // small.
            if (i >= Options::maxPolymorphicCallVariantsForInlining()
                || edge.count() < Options::frequentCallThreshold())
                totalCallsToUnknown += edge.count();
            else {
                totalCallsToKnown += edge.count();
                variants.append(edge.callee());
            }
        }
        
        // Bail if we didn't find any calls that qualified.
        RELEASE_ASSERT(!!totalCallsToKnown == !!variants.size());
        if (variants.isEmpty())
            return takesSlowPath();
        
        // We require that the distribution of callees is skewed towards a handful of common ones.
        if (totalCallsToKnown / totalCallsToUnknown < Options::minimumCallToKnownRate())
            return takesSlowPath();
        
        RELEASE_ASSERT(totalCallsToKnown);
        RELEASE_ASSERT(variants.size());
        
        CallLinkStatus result;
        result.m_variants = variants;
        result.m_couldTakeSlowPath = !!totalCallsToUnknown;
        result.m_isBasedOnStub = true;
        return result;
    }
    
    CallLinkStatus result;
    
    if (JSObject* target = callLinkInfo.lastSeenCallee()) {
        CallVariant variant(target);
        if (callLinkInfo.hasSeenClosure())
            variant = variant.despecifiedClosure();
        result.m_variants.append(variant);
    }
    
    result.m_couldTakeSlowPath = !!callLinkInfo.slowPathCount();

    return result;
}

CallLinkStatus CallLinkStatus::computeFor(
    const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, CallLinkInfo& callLinkInfo,
    ExitSiteData exitSiteData, ExitingInlineKind inlineKind)
{
    CallLinkStatus result = computeFor(locker, profiledBlock, callLinkInfo);
    result.accountForExits(exitSiteData, inlineKind);
    return result;
}

void CallLinkStatus::accountForExits(ExitSiteData exitSiteData, ExitingInlineKind inlineKind)
{
    if (exitSiteData.badFunction.isSet(inlineKind)) {
        if (isBasedOnStub()) {
            // If we have a polymorphic stub, then having an exit site is not quite so useful. In
            // most cases, the information in the stub has higher fidelity.
            makeClosureCall();
        } else {
            // We might not have a polymorphic stub for any number of reasons. When this happens, we
            // are in less certain territory, so exit sites mean a lot.
            m_couldTakeSlowPath = true;
        }
    }
    
    if (exitSiteData.takesSlowPath.isSet(inlineKind))
        m_couldTakeSlowPath = true;
}

CallLinkStatus CallLinkStatus::computeFor(
    CodeBlock* profiledBlock, CodeOrigin codeOrigin,
    const ICStatusMap& baselineMap, const ICStatusContextStack& optimizedStack)
{
    if (CallLinkStatusInternal::verbose)
        dataLog("Figuring out call profiling for ", codeOrigin, "\n");
    ExitSiteData exitSiteData = computeExitSiteData(profiledBlock, codeOrigin.bytecodeIndex());
    if (CallLinkStatusInternal::verbose) {
        dataLog("takesSlowPath = ", exitSiteData.takesSlowPath, "\n");
        dataLog("badFunction = ", exitSiteData.badFunction, "\n");
    }
    
    for (const ICStatusContext* context : optimizedStack) {
        if (CallLinkStatusInternal::verbose)
            dataLog("Examining status in ", pointerDump(context->optimizedCodeBlock), "\n");
        ICStatus status = context->get(codeOrigin);
        
        // If we have both a CallLinkStatus and a callLinkInfo for the same origin, then it means
        // one of two things:
        //
        // 1) We initially thought that we'd be able to inline this call so we recorded a status
        //    but then we realized that it was pointless and gave up and emitted a normal call
        //    anyway.
        //
        // 2) We did a polymorphic call inline that had a slow path case.
        //
        // In the first case, it's essential that we use the callLinkInfo, since the status may
        // be polymorphic but the link info benefits from polyvariant profiling.
        //
        // In the second case, it's essential that we use the status, since the callLinkInfo
        // corresponds to the slow case.
        //
        // It would be annoying to distinguish those two cases. However, we know that:
        //
        // If the first case happens in the FTL, then it means that even with polyvariant
        // profiling, we failed to do anything useful. That suggests that in the FTL, it's OK to
        // prioritize the status. That status will again tell us to not do anything useful.
        //
        // The second case only happens in the FTL.
        //
        // Therefore, we prefer the status in the FTL and the info in the DFG.
        //
        // Luckily, this case doesn't matter for the other ICStatuses, since they never do the
        // fast-path-slow-path control-flow-diamond style of IC inlining. It's either all fast
        // path or it's a full IC. So, for them, if there is an IC status then it means case (1).
        
        bool checkStatusFirst = context->optimizedCodeBlock->jitType() == JITType::FTLJIT;
        
        auto bless = [&] (CallLinkStatus& result) {
            if (!context->isInlined(codeOrigin))
                result.merge(computeFor(profiledBlock, codeOrigin.bytecodeIndex(), baselineMap, exitSiteData));
        };
        
        auto checkInfo = [&] () -> CallLinkStatus {
            if (!status.callLinkInfo)
                return CallLinkStatus();
            
            dataLogLnIf(CallLinkStatusInternal::verbose, "Have CallLinkInfo with CodeOrigin = ", codeOrigin, "\n");
            CallLinkStatus result;
            {
                ConcurrentJSLocker locker(context->optimizedCodeBlock->m_lock);
                result = computeFor(
                    locker, context->optimizedCodeBlock, *status.callLinkInfo, exitSiteData,
                    context->inlineKind(codeOrigin));
                if (CallLinkStatusInternal::verbose)
                    dataLog("Got result: ", result, "\n");
            }
            bless(result);
            return result;
        };
        
        auto checkStatus = [&] () -> CallLinkStatus {
            if (!status.callStatus)
                return CallLinkStatus();
            CallLinkStatus result = *status.callStatus;
            if (CallLinkStatusInternal::verbose)
                dataLog("Have callStatus: ", result, "\n");
            result.accountForExits(exitSiteData, context->inlineKind(codeOrigin));
            bless(result);
            return result;
        };
        
        if (checkStatusFirst) {
            if (CallLinkStatus result = checkStatus())
                return result;
            if (CallLinkStatus result = checkInfo())
                return result;
            continue;
        }
        
        if (CallLinkStatus result = checkInfo())
            return result;
        if (CallLinkStatus result = checkStatus())
            return result;
    }
    
    return computeFor(profiledBlock, codeOrigin.bytecodeIndex(), baselineMap, exitSiteData);
}
#endif

void CallLinkStatus::setProvenConstantCallee(CallVariant variant)
{
    m_variants = CallVariantList{ variant };
    m_couldTakeSlowPath = false;
    m_isProved = true;
}

bool CallLinkStatus::isClosureCall() const
{
    for (unsigned i = m_variants.size(); i--;) {
        if (m_variants[i].isClosureCall())
            return true;
    }
    return false;
}

void CallLinkStatus::makeClosureCall()
{
    m_variants = despecifiedVariantList(m_variants);
}

bool CallLinkStatus::finalize(VM& vm)
{
    for (CallVariant& variant : m_variants) {
        if (!variant.finalize(vm))
            return false;
    }
    return true;
}

void CallLinkStatus::merge(const CallLinkStatus& other)
{
    m_couldTakeSlowPath |= other.m_couldTakeSlowPath;
    
    for (const CallVariant& otherVariant : other.m_variants) {
        bool found = false;
        for (CallVariant& thisVariant : m_variants) {
            if (thisVariant.merge(otherVariant)) {
                found = true;
                break;
            }
        }
        if (!found)
            m_variants.append(otherVariant);
    }
}

void CallLinkStatus::filter(JSValue value)
{
    m_variants.removeAllMatching(
        [&] (CallVariant& variant) -> bool {
            variant.filter(value);
            return !variant;
        });
}

void CallLinkStatus::dump(PrintStream& out) const
{
    if (!isSet()) {
        out.print("Not Set");
        return;
    }
    
    CommaPrinter comma;
    
    if (m_isProved)
        out.print(comma, "Statically Proved");
    
    if (m_couldTakeSlowPath)
        out.print(comma, "Could Take Slow Path");
    
    if (m_isBasedOnStub)
        out.print(comma, "Based On Stub");
    
    if (!m_variants.isEmpty())
        out.print(comma, listDump(m_variants));
    
    if (m_maxArgumentCountIncludingThis)
        out.print(comma, "maxArgumentCountIncludingThis = ", m_maxArgumentCountIncludingThis);
}

} // namespace JSC

