/*
 * Copyright (C) 2020-2021 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 "DeleteByStatus.h"

#include "CacheableIdentifierInlines.h"
#include "CodeBlock.h"
#include "ICStatusUtils.h"
#include "PolymorphicAccess.h"
#include "StructureStubInfo.h"
#include <wtf/ListDump.h>

namespace JSC {

bool DeleteByStatus::appendVariant(const DeleteByIdVariant& variant)
{
    return appendICStatusVariant(m_variants, variant);
}

DeleteByStatus DeleteByStatus::computeForBaseline(CodeBlock* baselineBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex, ExitFlag didExit)
{
    ConcurrentJSLocker locker(baselineBlock->m_lock);

    DeleteByStatus result;

#if ENABLE(DFG_JIT)
    result = computeForStubInfoWithoutExitSiteFeedback(
        locker, baselineBlock, map.get(CodeOrigin(bytecodeIndex)).stubInfo);

    if (didExit)
        return result.slowVersion();
#else
    UNUSED_PARAM(map);
    UNUSED_PARAM(didExit);
    UNUSED_PARAM(bytecodeIndex);
#endif

    return result;
}

#if ENABLE(JIT)
DeleteByStatus::DeleteByStatus(StubInfoSummary summary, StructureStubInfo& stubInfo)
{
    switch (summary) {
    case StubInfoSummary::NoInformation:
        m_state = NoInformation;
        return;
    case StubInfoSummary::Simple:
    case StubInfoSummary::MakesCalls:
    case StubInfoSummary::TakesSlowPathAndMakesCalls:
        RELEASE_ASSERT_NOT_REACHED();
        return;
    case StubInfoSummary::TakesSlowPath:
        m_state = stubInfo.tookSlowPath ? ObservedTakesSlowPath : LikelyTakesSlowPath;
        return;
    }
    RELEASE_ASSERT_NOT_REACHED();
}

DeleteByStatus DeleteByStatus::computeForStubInfoWithoutExitSiteFeedback(
    const ConcurrentJSLocker&, CodeBlock* block, StructureStubInfo* stubInfo)
{
    StubInfoSummary summary = StructureStubInfo::summary(block->vm(), stubInfo);
    if (!isInlineable(summary))
        return DeleteByStatus(summary, *stubInfo);

    DeleteByStatus result;
    result.m_state = Simple;
    switch (stubInfo->cacheType()) {
    case CacheType::Unset:
        return DeleteByStatus(NoInformation);

    case CacheType::Stub: {
        PolymorphicAccess* list = stubInfo->u.stub;

        for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) {
            const AccessCase& access = list->at(listIndex);
            ASSERT(!access.viaProxy());

            Structure* structure = access.structure();
            ASSERT(structure);

            switch (access.type()) {
            case AccessCase::DeleteMiss:
            case AccessCase::DeleteNonConfigurable: {
                DeleteByIdVariant variant(access.identifier(), access.type() == AccessCase::DeleteMiss ? true : false, structure, nullptr, invalidOffset);
                if (!result.appendVariant(variant))
                    return DeleteByStatus(JSC::slowVersion(summary), *stubInfo);
                break;
            }
            case AccessCase::Delete: {
                PropertyOffset offset;
                Structure* newStructure = Structure::removePropertyTransitionFromExistingStructureConcurrently(structure, access.identifier().uid(), offset);
                if (!newStructure)
                    return DeleteByStatus(JSC::slowVersion(summary), *stubInfo);
                ASSERT_UNUSED(offset, offset == access.offset());                
                DeleteByIdVariant variant(access.identifier(), true, structure, newStructure, access.offset());

                if (!result.appendVariant(variant))
                    return DeleteByStatus(JSC::slowVersion(summary), *stubInfo);
                break;
            }
            default:
                ASSERT_NOT_REACHED();
                return DeleteByStatus(JSC::slowVersion(summary), *stubInfo);
            }
        }

        return result;
    }

    default:
        return DeleteByStatus(JSC::slowVersion(summary), *stubInfo);
    }

    RELEASE_ASSERT_NOT_REACHED();
    return DeleteByStatus();
}

DeleteByStatus DeleteByStatus::computeFor(
    CodeBlock* baselineBlock, ICStatusMap& baselineMap,
    ICStatusContextStack& contextStack, CodeOrigin codeOrigin)
{
    BytecodeIndex bytecodeIndex = codeOrigin.bytecodeIndex();
    ExitFlag didExit = hasBadCacheExitSite(baselineBlock, bytecodeIndex);

    for (ICStatusContext* context : contextStack) {
        ICStatus status = context->get(codeOrigin);

        auto bless = [&] (const DeleteByStatus& result) -> DeleteByStatus {
            if (!context->isInlined(codeOrigin)) {
                DeleteByStatus baselineResult = computeForBaseline(
                    baselineBlock, baselineMap, bytecodeIndex, didExit);
                baselineResult.merge(result);
                return baselineResult;
            }
            if (didExit.isSet(ExitFromInlined))
                return result.slowVersion();
            return result;
        };

        if (status.stubInfo) {
            DeleteByStatus result;
            {
                ConcurrentJSLocker locker(context->optimizedCodeBlock->m_lock);
                result = computeForStubInfoWithoutExitSiteFeedback(
                    locker, context->optimizedCodeBlock, status.stubInfo);
            }
            if (result.isSet())
                return bless(result);
        }

        if (status.deleteStatus)
            return bless(*status.deleteStatus);
    }

    return computeForBaseline(baselineBlock, baselineMap, bytecodeIndex, didExit);
}

#endif // ENABLE(JIT)

DeleteByStatus DeleteByStatus::slowVersion() const
{
    if (observedSlowPath())
        return DeleteByStatus(ObservedTakesSlowPath);
    return DeleteByStatus(LikelyTakesSlowPath);
}

void DeleteByStatus::merge(const DeleteByStatus& other)
{
    if (other.m_state == NoInformation)
        return;

    auto mergeSlow = [&] () {
        if (observedSlowPath() || other.observedSlowPath())
            *this = DeleteByStatus(ObservedTakesSlowPath);
        else
            *this = DeleteByStatus(LikelyTakesSlowPath);
    };

    switch (m_state) {
    case NoInformation:
        *this = other;
        return;

    case Simple:
        if (m_state != other.m_state)
            return mergeSlow();

        for (auto& otherVariant : other.m_variants) {
            if (!appendVariant(otherVariant))
                return mergeSlow();
        }
        return;

    case LikelyTakesSlowPath:
    case ObservedTakesSlowPath:
        return mergeSlow();
    }

    RELEASE_ASSERT_NOT_REACHED();
}

void DeleteByStatus::filter(const StructureSet& set)
{
    if (m_state != Simple)
        return;
    m_variants.removeAllMatching(
        [&] (auto& variant) -> bool {
            return !set.contains(variant.oldStructure());
        });
    if (m_variants.isEmpty())
        m_state = NoInformation;
}

CacheableIdentifier DeleteByStatus::singleIdentifier() const
{
    if (m_variants.isEmpty())
        return nullptr;

    CacheableIdentifier result = m_variants.first().identifier();
    if (!result)
        return nullptr;
    for (size_t i = 1; i < m_variants.size(); ++i) {
        CacheableIdentifier identifier = m_variants[i].identifier();
        if (!identifier)
            return nullptr;
        if (identifier != result)
            return nullptr;
    }
    return result;
}

template<typename Visitor>
void DeleteByStatus::visitAggregateImpl(Visitor& visitor)
{
    for (DeleteByIdVariant& variant : m_variants)
        variant.visitAggregate(visitor);
}

DEFINE_VISIT_AGGREGATE(DeleteByStatus);

template<typename Visitor>
void DeleteByStatus::markIfCheap(Visitor& visitor)
{
    for (DeleteByIdVariant& variant : m_variants)
        variant.markIfCheap(visitor);
}

template void DeleteByStatus::markIfCheap(AbstractSlotVisitor&);
template void DeleteByStatus::markIfCheap(SlotVisitor&);

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

void DeleteByStatus::dump(PrintStream& out) const
{
    out.print("(");
    switch (m_state) {
    case NoInformation:
        out.print("NoInformation");
        break;
    case Simple:
        out.print("Simple");
        break;
    case LikelyTakesSlowPath:
        out.print("LikelyTakesSlowPath");
        break;
    case ObservedTakesSlowPath:
        out.print("ObservedTakesSlowPath");
        break;
    }
    out.print(", ", listDump(m_variants), ")");
}

} // namespace JSC
