/*
 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifndef MarkedSpace_h
#define MarkedSpace_h

#include "MachineStackMarker.h"
#include "MarkedBlock.h"
#include "PageAllocationAligned.h"
#include <wtf/Bitmap.h>
#include <wtf/DoublyLinkedList.h>
#include <wtf/FixedArray.h>
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>

#define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) < MarkedSpace::maxCellSize, class_fits_in_cell)

namespace JSC {

    class Heap;
    class JSCell;
    class JSGlobalData;
    class LiveObjectIterator;
    class MarkStack;
    class WeakGCHandle;

    class MarkedSpace {
        WTF_MAKE_NONCOPYABLE(MarkedSpace);
    public:
        // Currently public for use in assertions.
        static const size_t maxCellSize = 1024;

        static Heap* heap(JSCell*);

        static bool isMarked(const JSCell*);
        static bool testAndSetMarked(const JSCell*);
        static void setMarked(const JSCell*);

        MarkedSpace(JSGlobalData*);
        void destroy();

        JSGlobalData* globalData() { return m_globalData; }

        size_t highWaterMark() { return m_highWaterMark; }
        void setHighWaterMark(size_t highWaterMark) { m_highWaterMark = highWaterMark; }

        void* allocate(size_t);

        void clearMarks();
        void markRoots();
        void reset();
        void sweep();
        void shrink();

        size_t size() const;
        size_t capacity() const;
        size_t objectCount() const;

        bool contains(const void*);

        template<typename Functor> void forEach(Functor&);

    private:
        // [ 8, 16... 128 )
        static const size_t preciseStep = MarkedBlock::atomSize;
        static const size_t preciseCutoff = 128;
        static const size_t preciseCount = preciseCutoff / preciseStep - 1;

        // [ 128, 256... 1024 )
        static const size_t impreciseStep = preciseCutoff;
        static const size_t impreciseCutoff = maxCellSize;
        static const size_t impreciseCount = impreciseCutoff / impreciseStep - 1;

        typedef HashSet<MarkedBlock*>::iterator BlockIterator;

        struct SizeClass {
            SizeClass();
            void reset();

            MarkedBlock* nextBlock;
            DoublyLinkedList<MarkedBlock> blockList;
            size_t cellSize;
        };

        MarkedBlock* allocateBlock(SizeClass&);
        void freeBlocks(DoublyLinkedList<MarkedBlock>&);

        SizeClass& sizeClassFor(size_t);
        void* allocateFromSizeClass(SizeClass&);

        void clearMarks(MarkedBlock*);

        SizeClass m_preciseSizeClasses[preciseCount];
        SizeClass m_impreciseSizeClasses[impreciseCount];
        HashSet<MarkedBlock*> m_blocks;
        size_t m_waterMark;
        size_t m_highWaterMark;
        JSGlobalData* m_globalData;
    };

    inline Heap* MarkedSpace::heap(JSCell* cell)
    {
        return MarkedBlock::blockFor(cell)->heap();
    }

    inline bool MarkedSpace::isMarked(const JSCell* cell)
    {
        return MarkedBlock::blockFor(cell)->isMarked(cell);
    }

    inline bool MarkedSpace::testAndSetMarked(const JSCell* cell)
    {
        return MarkedBlock::blockFor(cell)->testAndSetMarked(cell);
    }

    inline void MarkedSpace::setMarked(const JSCell* cell)
    {
        MarkedBlock::blockFor(cell)->setMarked(cell);
    }

    inline bool MarkedSpace::contains(const void* x)
    {
        if (!MarkedBlock::isAtomAligned(x))
            return false;

        MarkedBlock* block = MarkedBlock::blockFor(x);
        if (!block || !m_blocks.contains(block))
            return false;

        return block->contains(x);
    }

    template <typename Functor> inline void MarkedSpace::forEach(Functor& functor)
    {
        BlockIterator end = m_blocks.end();
        for (BlockIterator it = m_blocks.begin(); it != end; ++it)
            (*it)->forEach(functor);
    }
    
    inline MarkedSpace::SizeClass::SizeClass()
        : nextBlock(0)
        , cellSize(0)
    {
    }

    inline void MarkedSpace::SizeClass::reset()
    {
        nextBlock = blockList.head();
    }

} // namespace JSC

#endif // MarkedSpace_h
