/*
 * 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"

namespace JSC { namespace DFG {

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

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;
    }
    
    StructureSet::OutOfLineList* list = m_set.list();
    for (unsigned i = list->m_length; i--;) {
        if (!list->list()[i]->dfgShouldWatch()) {
            makeTop();
            return;
        }
    }
}

void StructureAbstractValue::observeTransition(Structure* from, Structure* 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;
    
    StructureSet 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(Structure* structure)
{
    if (isTop())
        return false;
    
    if (!m_set.add(structure))
        return false;
    
    if (m_set.size() > polymorphismLimit)
        makeTop();
    
    return true;
}

bool StructureAbstractValue::merge(const StructureSet& 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 StructureSet& other)
{
    if (!m_set.merge(other))
        return false;
    
    if (m_set.size() > polymorphismLimit)
        makeTop();
    
    return true;
}

void StructureAbstractValue::filter(const StructureSet& 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 StructureSet&), 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(
        [&] (Structure* structure) {
            return !!(speculationFromStructure(structure) & type);
        });
}

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

bool StructureAbstractValue::isSubsetOf(const StructureSet& 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 StructureSet& other) const
{
    if (isInfinite())
        return true;
    
    return m_set.isSupersetOf(other);
}

bool StructureAbstractValue::overlaps(const StructureSet& 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::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, context));
}

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

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

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)

