/*
 * Copyright (C) 2014, 2015 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 "DFGStructureAbstractValue.h"

#if ENABLE(DFG_JIT)

#include "DFGGraph.h"
#include "JSCJSValueInlines.h"

namespace JSC { namespace DFG {

#if ASSERT_ENABLED
void StructureAbstractValue::assertIsRegistered(Graph& graph) const
{
    if (isTop())
        return;
    
    for (unsigned i = size(); i--;)
        graph.assertIsRegistered(at(i).get());
}
#endif // ASSERT_ENABLED

void StructureAbstractValue::clobber()
{
    // The premise of this approach to clobbering is that anytime we introduce
    // a watchable structure into an abstract value, we watchpoint it. You can assert
    // that this holds by calling assertIsWatched().
        
    if (isTop())
        return;

    setClobbered(true);
        
    if (m_set.isThin()) {
        if (!m_set.singleEntry())
            return;
        if (!m_set.singleEntry()->dfgShouldWatch())
            makeTopWhenThin();
        return;
    }
    
    RegisteredStructureSet::OutOfLineList* list = m_set.list();
    for (unsigned i = list->m_length; i--;) {
        if (!list->list()[i]->dfgShouldWatch()) {
            makeTop();
            return;
        }
    }
}

void StructureAbstractValue::observeTransition(RegisteredStructure from, RegisteredStructure to)
{
    ASSERT(!from->dfgShouldWatch());

    if (isTop())
        return;
    
    if (!m_set.contains(from))
        return;
    
    if (!m_set.add(to))
        return;
    
    if (m_set.size() > polymorphismLimit)
        makeTop();
}

void StructureAbstractValue::observeTransitions(const TransitionVector& vector)
{
    if (isTop())
        return;
    
    RegisteredStructureSet newStructures;
    for (unsigned i = vector.size(); i--;) {
        ASSERT(!vector[i].previous->dfgShouldWatch());

        if (!m_set.contains(vector[i].previous))
            continue;
        
        newStructures.add(vector[i].next);
    }
    
    if (!m_set.merge(newStructures))
        return;
    
    if (m_set.size() > polymorphismLimit)
        makeTop();
}

bool StructureAbstractValue::add(RegisteredStructure structure)
{
    if (isTop())
        return false;
    
    if (!m_set.add(structure))
        return false;
    
    if (m_set.size() > polymorphismLimit)
        makeTop();
    
    return true;
}

bool StructureAbstractValue::merge(const RegisteredStructureSet& other)
{
    if (isTop())
        return false;
    
    return mergeNotTop(other);
}

bool StructureAbstractValue::mergeSlow(const StructureAbstractValue& other)
{
    // It isn't immediately obvious that the code below is doing the right thing, so let's go
    // through it.
    //
    // This not clobbered, other not clobbered: Clearly, we don't want to make anything clobbered
    // since we just have two sets and we are merging them. mergeNotTop() can handle this just
    // fine.
    //
    // This clobbered, other clobbered: Clobbered means that we have a set of things, plus we
    // temporarily have the set of all things but the latter will go away once we hit the next
    // invalidation point. This allows us to merge two clobbered sets the natural way. For now
    // the set will still be TOP (and so we keep the clobbered bit set), but we know that after
    // invalidation, we will have the union of the this and other.
    //
    // This clobbered, other not clobbered: It's safe to merge in other for both before and after
    // invalidation, so long as we leave the clobbered bit set. Before invalidation this has no
    // effect since the set will still appear to have all things in it. The way to think about
    // what invalidation would do is imagine if we had a set A that was clobbered and a set B
    // that wasn't and we considered the following two cases. Note that we expect A to be the
    // same at the end in both cases:
    //
    //            A.merge(B)                             InvalidationPoint
    //            InvalidationPoint                      A.merge(B)
    //
    // The fact that we expect A to be the same in both cases means that we want to merge other
    // into this but keep the clobbered bit.
    //
    // This not clobbered, other clobbered: This is just the converse of the previous case. We
    // want to merge other into this and set the clobbered bit.
    
    bool changed = false;
    
    if (!isClobbered() && other.isClobbered()) {
        setClobbered(true);
        changed = true;
    }
    
    changed |= mergeNotTop(other.m_set);
    
    return changed;
}

bool StructureAbstractValue::mergeNotTop(const RegisteredStructureSet& other)
{
    if (!m_set.merge(other))
        return false;
    
    if (m_set.size() > polymorphismLimit)
        makeTop();
    
    return true;
}

void StructureAbstractValue::filter(const RegisteredStructureSet& other)
{
    if (isTop()) {
        m_set = other;
        return;
    }
    
    if (isClobbered()) {
        // We have two choices here:
        //
        // Do nothing: It's legal to keep our set intact, which would essentially mean that for
        // now, our set would behave like TOP but after the next invalidation point it wold be
        // a finite set again. This may be a good choice if 'other' is much bigger than our
        // m_set.
        //
        // Replace m_set with other and clear the clobber bit: This is also legal, and means that
        // we're no longer clobbered. This is usually better because it immediately gives us a
        // smaller set.
        //
        // This scenario should come up rarely. We usually don't do anything to an abstract value
        // after it is clobbered. But we apply some heuristics.
        
        if (other.size() > m_set.size() + clobberedSupremacyThreshold)
            return; // Keep the clobbered set.
        
        m_set = other;
        setClobbered(false);
        return;
    }
    
    m_set.filter(other);
}

void StructureAbstractValue::filter(const StructureAbstractValue& other)
{
    if (other.isTop())
        return;
    
    if (other.isClobbered()) {
        if (isTop())
            return;
        
        if (!isClobbered()) {
            // See justification in filter(const RegisteredStructureSet&), above. An unclobbered set is
            // almost always better.
            if (m_set.size() > other.m_set.size() + clobberedSupremacyThreshold)
                *this = other; // Keep the clobbered set.
            return;
        }

        m_set.filter(other.m_set);
        return;
    }
    
    filter(other.m_set);
}

void StructureAbstractValue::filterSlow(SpeculatedType type)
{
    if (!(type & SpecCell)) {
        clear();
        return;
    }
    
    ASSERT(!isTop());
    
    m_set.genericFilter(
        [&] (RegisteredStructure structure) {
            return !!(speculationFromStructure(structure.get()) & type);
        });
}

void StructureAbstractValue::filterClassInfoSlow(const ClassInfo* classInfo)
{
    ASSERT(!isTop());
    m_set.genericFilter(
        [&] (RegisteredStructure structure) {
            return structure->classInfoForCells()->isSubClassOf(classInfo);
        });
}

bool StructureAbstractValue::contains(RegisteredStructure structure) const
{
    if (isInfinite())
        return true;
    
    return m_set.contains(structure);
}

bool StructureAbstractValue::contains(Structure* structure) const
{
    if (isInfinite())
        return true;
    
    return m_set.toStructureSet().contains(structure);
}

bool StructureAbstractValue::isSubsetOf(const RegisteredStructureSet& other) const
{
    if (isInfinite())
        return false;
    
    return m_set.isSubsetOf(other);
}

bool StructureAbstractValue::isSubsetOf(const StructureAbstractValue& other) const
{
    if (isTop())
        return false;
    
    if (other.isTop())
        return true;
    
    if (isClobbered() == other.isClobbered())
        return m_set.isSubsetOf(other.m_set);
    
    // Here it gets tricky. If in doubt, return false!
    
    if (isClobbered())
        return false; // A clobbered set is never a subset of an unclobbered set.
    
    // An unclobbered set is currently a subset of a clobbered set, but it may not be so after
    // invalidation.
    return m_set.isSubsetOf(other.m_set);
}

bool StructureAbstractValue::isSupersetOf(const RegisteredStructureSet& other) const
{
    if (isInfinite())
        return true;
    
    return m_set.isSupersetOf(other);
}

bool StructureAbstractValue::overlaps(const RegisteredStructureSet& other) const
{
    if (isInfinite())
        return true;
    
    return m_set.overlaps(other);
}

bool StructureAbstractValue::overlaps(const StructureAbstractValue& other) const
{
    if (other.isInfinite())
        return true;
    
    return overlaps(other.m_set);
}

bool StructureAbstractValue::isSubClassOf(const ClassInfo* classInfo) const
{
    if (isInfinite())
        return false;

    // Note that this function returns true if the structure set is empty.
    for (const RegisteredStructure structure : m_set) {
        if (!structure->classInfoForCells()->isSubClassOf(classInfo))
            return false;
    }
    return true;
}

bool StructureAbstractValue::isNotSubClassOf(const ClassInfo* classInfo) const
{
    if (isInfinite())
        return false;

    // Note that this function returns true if the structure set is empty.
    for (const RegisteredStructure structure : m_set) {
        if (structure->classInfoForCells()->isSubClassOf(classInfo))
            return false;
    }
    return true;
}

bool StructureAbstractValue::equalsSlow(const StructureAbstractValue& other) const
{
    ASSERT(m_set.m_pointer != other.m_set.m_pointer);
    ASSERT(!isTop());
    ASSERT(!other.isTop());
    
    return m_set == other.m_set
        && isClobbered() == other.isClobbered();
}

void StructureAbstractValue::dumpInContext(PrintStream& out, DumpContext* context) const
{
    if (isClobbered())
        out.print("Clobbered:");
    
    if (isTop())
        out.print("TOP");
    else
        out.print(inContext(m_set.toStructureSet(), context));
}

void StructureAbstractValue::dump(PrintStream& out) const
{
    dumpInContext(out, nullptr);
}

void StructureAbstractValue::validateReferences(const TrackedReferences& trackedReferences) const
{
    if (isTop())
        return;
    m_set.validateReferences(trackedReferences);
}

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)

