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

#pragma once

#include <wtf/DeferrableRefCounted.h>
#include <wtf/Vector.h>

namespace JSC {

class JSCell;

// A C-heap-allocated object that may have additional reference counts
// due to incoming references from the heap, which are tracked in
// reverse: the object knows its incoming references. Such objects also
// have the invariant that they don't have references back into the GC
// heap.

template<typename T>
class GCIncomingRefCounted : public DeferrableRefCounted<T> {
public:
    GCIncomingRefCounted()
        : m_encodedPointer(0)
    {
    }
    
    ~GCIncomingRefCounted()
    {
        if (hasVectorOfCells())
            delete vectorOfCells();
    }
    
    size_t numberOfIncomingReferences() const
    {
        if (!hasAnyIncoming())
            return 0;
        if (hasSingleton())
            return 1;
        return vectorOfCells()->size();
    }
    
    JSCell* incomingReferenceAt(size_t index) const
    {
        ASSERT(hasAnyIncoming());
        if (hasSingleton()) {
            ASSERT(!index);
            return singleton();
        }
        return vectorOfCells()->at(index);
    }
    
    // It's generally not a good idea to call this directly, since if this
    // returns true, you're supposed to add this object to the GC's list.
    // Call GCIncomingRefCountedSet::addReference() instead.
    bool addIncomingReference(JSCell*);
    
    // A filter function returns true if we wish to keep the incoming
    // reference, and false if we don't. This may delete the object,
    // and if it does so, this returns true. In general, you don't want
    // to use this with a filter function that can return false unless
    // you're also walking the GC's list.
    template<typename FilterFunctionType>
    bool filterIncomingReferences(FilterFunctionType&);
    
private:
    static uintptr_t singletonFlag() { return 1; }
    
    bool hasVectorOfCells() const { return !(m_encodedPointer & singletonFlag()); }
    bool hasAnyIncoming() const { return !!m_encodedPointer; }
    bool hasSingleton() const { return hasAnyIncoming() && !hasVectorOfCells(); }
    
    JSCell* singleton() const
    {
        ASSERT(hasSingleton());
        return bitwise_cast<JSCell*>(m_encodedPointer & ~singletonFlag());
    }
    
    Vector<JSCell*>* vectorOfCells() const
    {
        ASSERT(hasVectorOfCells());
        return bitwise_cast<Vector<JSCell*>*>(m_encodedPointer);
    }
    
    // Singleton flag is set: this is a JSCell*.
    // Singleton flag not set: this is a pointer to a vector of cells.
    uintptr_t m_encodedPointer;
};

} // namespace JSC
