/*
 * Copyright (C) 2016-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 "JITWorklist.h"

#if ENABLE(JIT)

#include "JIT.h"
#include "JSCInlines.h"
#include "VMInlines.h"

namespace JSC {

class JITWorklist::Plan : public ThreadSafeRefCounted<JITWorklist::Plan> {
public:
    Plan(CodeBlock* codeBlock, unsigned loopOSREntryBytecodeOffset)
        : m_codeBlock(codeBlock)
        , m_jit(codeBlock->vm(), codeBlock, loopOSREntryBytecodeOffset)
    {
        m_jit.doMainThreadPreparationBeforeCompile();
    }
    
    void compileInThread()
    {
        m_jit.compileWithoutLinking(JITCompilationCanFail);
        
        LockHolder locker(m_lock);
        m_isFinishedCompiling = true;
    }
    
    void finalize()
    {
        CompilationResult result = m_jit.link();
        switch (result) {
        case CompilationFailed:
            CODEBLOCK_LOG_EVENT(m_codeBlock, "delayJITCompile", ("compilation failed"));
            if (Options::verboseOSR())
                dataLogF("    JIT compilation failed.\n");
            m_codeBlock->dontJITAnytimeSoon();
            m_codeBlock->m_didFailJITCompilation = true;
            return;
        case CompilationSuccessful:
            if (Options::verboseOSR())
                dataLogF("    JIT compilation successful.\n");
            m_codeBlock->ownerExecutable()->installCode(m_codeBlock);
            m_codeBlock->jitSoon();
            return;
        default:
            RELEASE_ASSERT_NOT_REACHED();
            return;
        }
    }
    
    CodeBlock* codeBlock() { return m_codeBlock; }
    VM& vm() { return m_codeBlock->vm(); }
    
    bool isFinishedCompiling()
    {
        LockHolder locker(m_lock);
        return m_isFinishedCompiling;
    }
    
    static void compileNow(CodeBlock* codeBlock, unsigned loopOSREntryBytecodeOffset)
    {
        Plan plan(codeBlock, loopOSREntryBytecodeOffset);
        plan.compileInThread();
        plan.finalize();
    }
    
private:
    CodeBlock* m_codeBlock;
    JIT m_jit;
    Lock m_lock;
    bool m_isFinishedCompiling { false };
};

class JITWorklist::Thread : public AutomaticThread {
public:
    Thread(const AbstractLocker& locker, JITWorklist& worklist)
        : AutomaticThread(locker, worklist.m_lock, worklist.m_condition.copyRef())
        , m_worklist(worklist)
    {
        m_worklist.m_numAvailableThreads++;
    }

    const char* name() const override
    {
#if OS(LINUX)
        return "JITWorker";
#else
        return "JIT Worklist Helper Thread";
#endif
    }
    
protected:
    PollResult poll(const AbstractLocker&) override
    {
        RELEASE_ASSERT(m_worklist.m_numAvailableThreads);
        
        if (m_worklist.m_queue.isEmpty())
            return PollResult::Wait;
        
        m_myPlans = WTFMove(m_worklist.m_queue);
        m_worklist.m_numAvailableThreads--;
        return PollResult::Work;
    }
    
    WorkResult work() override
    {
        RELEASE_ASSERT(!m_myPlans.isEmpty());
        
        for (RefPtr<Plan>& plan : m_myPlans) {
            plan->compileInThread();
            plan = nullptr;
            
            // Make sure that the main thread realizes that we just compiled something. Notifying
            // a condition is basically free if nobody is waiting.
            LockHolder locker(*m_worklist.m_lock);
            m_worklist.m_condition->notifyAll(locker);
        }
        
        m_myPlans.clear();
        
        LockHolder locker(*m_worklist.m_lock);
        m_worklist.m_numAvailableThreads++;
        return WorkResult::Continue;
    }
    
private:
    JITWorklist& m_worklist;
    Plans m_myPlans;
};

JITWorklist::JITWorklist()
    : m_lock(Box<Lock>::create())
    , m_condition(AutomaticThreadCondition::create())
{
    LockHolder locker(*m_lock);
    m_thread = new Thread(locker, *this);
}

JITWorklist::~JITWorklist()
{
    UNREACHABLE_FOR_PLATFORM();
}

bool JITWorklist::completeAllForVM(VM& vm)
{
    bool result = false;
    DeferGC deferGC(vm.heap);
    for (;;) {
        Vector<RefPtr<Plan>, 32> myPlans;
        {
            LockHolder locker(*m_lock);
            for (;;) {
                bool didFindUnfinishedPlan = false;
                m_plans.removeAllMatching(
                    [&] (RefPtr<Plan>& plan) {
                        if (&plan->vm() != &vm)
                            return false;
                        if (!plan->isFinishedCompiling()) {
                            didFindUnfinishedPlan = true;
                            return false;
                        }
                        myPlans.append(WTFMove(plan));
                        return true;
                    });
                
                // If we found plans then we should finalize them now.
                if (!myPlans.isEmpty())
                    break;
                
                // If we don't find plans, then we're either done or we need to wait, depending on
                // whether we found some unfinished plans.
                if (!didFindUnfinishedPlan)
                    return result;
                
                m_condition->wait(*m_lock);
            }
        }
        
        RELEASE_ASSERT(!myPlans.isEmpty());
        result = true;
        finalizePlans(myPlans);
    }
}

void JITWorklist::poll(VM& vm)
{
    DeferGC deferGC(vm.heap);
    Plans myPlans;
    {
        LockHolder locker(*m_lock);
        m_plans.removeAllMatching(
            [&] (RefPtr<Plan>& plan) {
                if (&plan->vm() != &vm)
                    return false;
                if (!plan->isFinishedCompiling())
                    return false;
                myPlans.append(WTFMove(plan));
                return true;
            });
    }
    
    finalizePlans(myPlans);
}

void JITWorklist::compileLater(CodeBlock* codeBlock, unsigned loopOSREntryBytecodeOffset)
{
    DeferGC deferGC(codeBlock->vm().heap);
    RELEASE_ASSERT(codeBlock->jitType() == JITType::InterpreterThunk);
    
    if (codeBlock->m_didFailJITCompilation) {
        codeBlock->dontJITAnytimeSoon();
        return;
    }
    
    if (!Options::useConcurrentJIT()) {
        Plan::compileNow(codeBlock, loopOSREntryBytecodeOffset);
        return;
    }
    
    codeBlock->jitSoon();

    {
        LockHolder locker(*m_lock);
        
        if (m_planned.contains(codeBlock))
            return;
        
        if (m_numAvailableThreads) {
            m_planned.add(codeBlock);
            RefPtr<Plan> plan = adoptRef(new Plan(codeBlock, loopOSREntryBytecodeOffset));
            m_plans.append(plan);
            m_queue.append(plan);
            m_condition->notifyAll(locker);
            return;
        }
    }

    // Compiling on the main thread if the helper thread isn't available is a defense against this
    // pathology:
    //
    // 1) Do something that is allowed to take a while, like load a giant piece of initialization
    //    code. This plans the compile of the init code, but doesn't finish it. It will take a
    //    while.
    //
    // 2) Do something that is supposed to be quick. Now all baseline compiles, and so all DFG and
    //    FTL compiles, of everything is blocked on the long-running baseline compile of that
    //    initialization code.
    //
    // The single-threaded concurrent JIT has this tendency to convoy everything while at the same
    // time postponing when it happens, which means that the convoy delays are less predictable.
    // This works around the issue. If the concurrent JIT thread is convoyed, we revert to main
    // thread compiles. This is probably not as good as if we had multiple JIT threads. Maybe we
    // can do that someday.
    Plan::compileNow(codeBlock, loopOSREntryBytecodeOffset);
}

void JITWorklist::compileNow(CodeBlock* codeBlock, unsigned loopOSREntryBytecodeOffset)
{
    VM& vm = codeBlock->vm();
    DeferGC deferGC(vm.heap);
    if (codeBlock->jitType() != JITType::InterpreterThunk)
        return;
    
    bool isPlanned;
    {
        LockHolder locker(*m_lock);
        isPlanned = m_planned.contains(codeBlock);
    }
    
    if (isPlanned) {
        RELEASE_ASSERT(Options::useConcurrentJIT());
        // This is expensive, but probably good enough.
        completeAllForVM(vm);
    }
    
    // Now it might be compiled!
    if (codeBlock->jitType() != JITType::InterpreterThunk)
        return;
    
    // We do this in case we had previously attempted, and then failed, to compile with the
    // baseline JIT.
    codeBlock->resetJITData();
    
    // OK, just compile it.
    JIT::compile(vm, codeBlock, JITCompilationMustSucceed, loopOSREntryBytecodeOffset);
    codeBlock->ownerExecutable()->installCode(codeBlock);
}

void JITWorklist::finalizePlans(Plans& myPlans)
{
    for (RefPtr<Plan>& plan : myPlans) {
        plan->finalize();
        
        LockHolder locker(*m_lock);
        m_planned.remove(plan->codeBlock());
    }
}

static JITWorklist* theGlobalJITWorklist { nullptr };

JITWorklist* JITWorklist::existingGlobalWorklistOrNull()
{
    return theGlobalJITWorklist;
}

JITWorklist& JITWorklist::ensureGlobalWorklist()
{
    static std::once_flag once;
    std::call_once(
        once,
        [] {
            auto* worklist = new JITWorklist();
            WTF::storeStoreFence();
            theGlobalJITWorklist = worklist;
        });
    return *theGlobalJITWorklist;
}

} // namespace JSC

#endif // ENABLE(JIT)

