/*
 *  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 Heap_h
#define Heap_h

#include "BlockAllocator.h"
#include "CopyVisitor.h"
#include "DFGCodeBlocks.h"
#include "GCThreadSharedData.h"
#include "HandleSet.h"
#include "HandleStack.h"
#include "JITStubRoutineSet.h"
#include "MarkedAllocator.h"
#include "MarkedBlock.h"
#include "MarkedBlockSet.h"
#include "MarkedSpace.h"
#include "Options.h"
#include "SlotVisitor.h"
#include "WeakHandleOwner.h"
#include "WriteBarrierSupport.h"
#include <wtf/CurrentTime.h>
#include <wtf/HashCountedSet.h>
#include <wtf/HashSet.h>

#define COLLECT_ON_EVERY_ALLOCATION 0

namespace JSC {

    class CopiedSpace;
    class CodeBlock;
    class ExecutableBase;
    class GCActivityCallback;
    class GCAwareJITStubRoutine;
    class GlobalCodeBlock;
    class Heap;
    class HeapRootVisitor;
    class IncrementalSweeper;
    class JITStubRoutine;
    class JSCell;
    class JSGlobalData;
    class JSStack;
    class JSValue;
    class LiveObjectIterator;
    class LLIntOffsetsExtractor;
    class MarkedArgumentBuffer;
    class WeakGCHandlePool;
    class SlotVisitor;

    typedef std::pair<JSValue, WTF::String> ValueStringPair;
    typedef HashCountedSet<JSCell*> ProtectCountSet;
    typedef HashCountedSet<const char*> TypeCountSet;

    enum OperationInProgress { NoOperation, Allocation, Collection };

    enum HeapType { SmallHeap, LargeHeap };

    class Heap {
        WTF_MAKE_NONCOPYABLE(Heap);
    public:
        friend class JIT;
        friend class GCThreadSharedData;
        static Heap* heap(const JSValue); // 0 for immediate values
        static Heap* heap(const JSCell*);

        // This constant determines how many blocks we iterate between checks of our 
        // deadline when calling Heap::isPagedOut. Decreasing it will cause us to detect 
        // overstepping our deadline more quickly, while increasing it will cause 
        // our scan to run faster. 
        static const unsigned s_timeCheckResolution = 16;

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

        static bool isWriteBarrierEnabled();
        static void writeBarrier(const JSCell*, JSValue);
        static void writeBarrier(const JSCell*, JSCell*);
        static uint8_t* addressOfCardFor(JSCell*);

        Heap(JSGlobalData*, HeapType);
        ~Heap();
        JS_EXPORT_PRIVATE void lastChanceToFinalize();

        JSGlobalData* globalData() const { return m_globalData; }
        MarkedSpace& objectSpace() { return m_objectSpace; }
        MachineThreads& machineThreads() { return m_machineThreads; }

        JS_EXPORT_PRIVATE GCActivityCallback* activityCallback();
        JS_EXPORT_PRIVATE void setActivityCallback(GCActivityCallback*);
        JS_EXPORT_PRIVATE void setGarbageCollectionTimerEnabled(bool);

        JS_EXPORT_PRIVATE IncrementalSweeper* sweeper();

        // true if an allocation or collection is in progress
        inline bool isBusy();
        
        MarkedAllocator& firstAllocatorWithoutDestructors() { return m_objectSpace.firstAllocator(); }
        MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); }
        MarkedAllocator& allocatorForObjectWithNormalDestructor(size_t bytes) { return m_objectSpace.normalDestructorAllocatorFor(bytes); }
        MarkedAllocator& allocatorForObjectWithImmortalStructureDestructor(size_t bytes) { return m_objectSpace.immortalStructureDestructorAllocatorFor(bytes); }
        CopiedAllocator& storageAllocator() { return m_storageSpace.allocator(); }
        CheckedBoolean tryAllocateStorage(size_t, void**);
        CheckedBoolean tryReallocateStorage(void**, size_t, size_t);

        typedef void (*Finalizer)(JSCell*);
        JS_EXPORT_PRIVATE void addFinalizer(JSCell*, Finalizer);
        void addCompiledCode(ExecutableBase*);

        void notifyIsSafeToCollect() { m_isSafeToCollect = true; }
        bool isSafeToCollect() const { return m_isSafeToCollect; }

        JS_EXPORT_PRIVATE void collectAllGarbage();
        enum SweepToggle { DoNotSweep, DoSweep };
        bool shouldCollect();
        void collect(SweepToggle);

        void reportExtraMemoryCost(size_t cost);
        JS_EXPORT_PRIVATE void reportAbandonedObjectGraph();

        JS_EXPORT_PRIVATE void protect(JSValue);
        JS_EXPORT_PRIVATE bool unprotect(JSValue); // True when the protect count drops to 0.
        
        void jettisonDFGCodeBlock(PassOwnPtr<CodeBlock>);

        JS_EXPORT_PRIVATE size_t size();
        JS_EXPORT_PRIVATE size_t capacity();
        JS_EXPORT_PRIVATE size_t objectCount();
        JS_EXPORT_PRIVATE size_t globalObjectCount();
        JS_EXPORT_PRIVATE size_t protectedObjectCount();
        JS_EXPORT_PRIVATE size_t protectedGlobalObjectCount();
        JS_EXPORT_PRIVATE PassOwnPtr<TypeCountSet> protectedObjectTypeCounts();
        JS_EXPORT_PRIVATE PassOwnPtr<TypeCountSet> objectTypeCounts();
        void showStatistics();

        void pushTempSortVector(Vector<ValueStringPair>*);
        void popTempSortVector(Vector<ValueStringPair>*);
    
        HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = adoptPtr(new HashSet<MarkedArgumentBuffer*>); return *m_markListSet; }
        
        template<typename Functor> typename Functor::ReturnType forEachProtectedCell(Functor&);
        template<typename Functor> typename Functor::ReturnType forEachProtectedCell();

        HandleSet* handleSet() { return &m_handleSet; }
        HandleStack* handleStack() { return &m_handleStack; }

        void getConservativeRegisterRoots(HashSet<JSCell*>& roots);

        double lastGCLength() { return m_lastGCLength; }
        void increaseLastGCLength(double amount) { m_lastGCLength += amount; }

        JS_EXPORT_PRIVATE void deleteAllCompiledCode();

        void didAllocate(size_t);
        void didAbandon(size_t);

        bool isPagedOut(double deadline);
        void didStartVMShutdown();
        
#if ENABLE(JIT)
        const JITStubRoutineSet& jitStubRoutines() { return m_jitStubRoutines; }
#endif

    private:
        friend class CodeBlock;
        friend class CopiedBlock;
        friend class GCAwareJITStubRoutine;
        friend class JITStubRoutine;
        friend class LLIntOffsetsExtractor;
        friend class MarkedSpace;
        friend class MarkedAllocator;
        friend class MarkedBlock;
        friend class CopiedSpace;
        friend class CopyVisitor;
        friend class SlotVisitor;
        friend class IncrementalSweeper;
        friend class HeapStatistics;
        friend class WeakSet;
        template<typename T> friend void* allocateCell(Heap&);
        template<typename T> friend void* allocateCell(Heap&, size_t);

        void* allocateWithImmortalStructureDestructor(size_t); // For use with special objects whose Structures never die.
        void* allocateWithNormalDestructor(size_t); // For use with objects that inherit directly or indirectly from JSDestructibleObject.
        void* allocateWithoutDestructor(size_t); // For use with objects without destructors.

        static const size_t minExtraCost = 256;
        static const size_t maxExtraCost = 1024 * 1024;
        
        class FinalizerOwner : public WeakHandleOwner {
            virtual void finalize(Handle<Unknown>, void* context);
        };

        JS_EXPORT_PRIVATE bool isValidAllocation(size_t);
        JS_EXPORT_PRIVATE void reportExtraMemoryCostSlowCase(size_t);

        void markRoots(bool fullGC);
        void markProtectedObjects(HeapRootVisitor&);
        void markTempSortVectors(HeapRootVisitor&);
        void copyBackingStores();
        void harvestWeakReferences();
        void finalizeUnconditionalFinalizers();
        void deleteUnmarkedCompiledCode();
        void zombifyDeadObjects();
        void markDeadObjects();

        JSStack& stack();
        BlockAllocator& blockAllocator();

        const HeapType m_heapType;
        const size_t m_ramSize;
        const size_t m_minBytesPerCycle;
        size_t m_sizeAfterLastCollect;

        size_t m_bytesAllocatedLimit;
        size_t m_bytesAllocated;
        size_t m_bytesAbandoned;
#if defined (__LB_SHELL__) || OS(STARBOARD)
        double m_lastCollectTime;
#endif

        OperationInProgress m_operationInProgress;
        BlockAllocator m_blockAllocator;
        MarkedSpace m_objectSpace;
        CopiedSpace m_storageSpace;

#if ENABLE(SIMPLE_HEAP_PROFILING)
        VTableSpectrum m_destroyedTypeCounts;
#endif

        ProtectCountSet m_protectedValues;
        Vector<Vector<ValueStringPair>* > m_tempSortingVectors;
        OwnPtr<HashSet<MarkedArgumentBuffer*> > m_markListSet;

        MachineThreads m_machineThreads;
        
        GCThreadSharedData m_sharedData;
        SlotVisitor m_slotVisitor;
        CopyVisitor m_copyVisitor;

        HandleSet m_handleSet;
        HandleStack m_handleStack;
        DFGCodeBlocks m_dfgCodeBlocks;
#if ENABLE(JIT)
        JITStubRoutineSet m_jitStubRoutines;
#endif
        FinalizerOwner m_finalizerOwner;
        
        bool m_isSafeToCollect;

        JSGlobalData* m_globalData;
        double m_lastGCLength;
        double m_lastCodeDiscardTime;

        DoublyLinkedList<ExecutableBase> m_compiledCode;
        
        GCActivityCallback* m_activityCallback;
        IncrementalSweeper* m_sweeper;
        Vector<MarkedBlock*> m_blockSnapshot;
    };

    struct MarkedBlockSnapshotFunctor : public MarkedBlock::VoidFunctor {
        MarkedBlockSnapshotFunctor(Vector<MarkedBlock*>& blocks) 
            : m_index(0) 
            , m_blocks(blocks)
        {
        }
    
        void operator()(MarkedBlock* block) { m_blocks[m_index++] = block; }
    
        size_t m_index;
        Vector<MarkedBlock*>& m_blocks;
    };

    inline bool Heap::shouldCollect()
    {
#if defined (__LB_SHELL__) || OS(STARBOARD)
        // m_bytesAllocated is a coarse measure of how
        // much has been allocated since the last collect().
        // It's only incremented by certain large allocations.
        // We try to collect quite frequently.
        // But no more than once per minute.
        if (!(m_isSafeToCollect &&
            m_operationInProgress == NoOperation)) {
            return false;
        }

        if (m_bytesAllocated >= 4096 * 1024) {
            return true;
        } else if (m_bytesAllocated >= 1024 * 1024 &&
            (WTF::currentTime() - m_lastCollectTime > 60.0f)) {
            return true;
        } else {
            return false;
        }
#else
        if (Options::gcMaxHeapSize())
            return m_bytesAllocated > Options::gcMaxHeapSize() && m_isSafeToCollect && m_operationInProgress == NoOperation;
#if ENABLE(GGC)
        return m_objectSpace.nurseryWaterMark() >= m_minBytesPerCycle && m_isSafeToCollect && m_operationInProgress == NoOperation;
#else
        return m_bytesAllocated > m_bytesAllocatedLimit && m_isSafeToCollect && m_operationInProgress == NoOperation;
#endif
#endif
    }

    bool Heap::isBusy()
    {
        return m_operationInProgress != NoOperation;
    }

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

    inline Heap* Heap::heap(const JSValue v)
    {
        if (!v.isCell())
            return 0;
        return heap(v.asCell());
    }

    inline bool Heap::isLive(const void* cell)
    {
        return MarkedBlock::blockFor(cell)->isLiveCell(cell);
    }

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

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

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

    inline bool Heap::isWriteBarrierEnabled()
    {
#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
        return true;
#else
        return false;
#endif
    }

#if ENABLE(GGC)
    inline uint8_t* Heap::addressOfCardFor(JSCell* cell)
    {
        return MarkedBlock::blockFor(cell)->addressOfCardFor(cell);
    }

    inline void Heap::writeBarrier(const JSCell* owner, JSCell*)
    {
        WriteBarrierCounters::countWriteBarrier();
        MarkedBlock* block = MarkedBlock::blockFor(owner);
        if (block->isMarked(owner))
            block->setDirtyObject(owner);
    }

    inline void Heap::writeBarrier(const JSCell* owner, JSValue value)
    {
        if (!value)
            return;
        if (!value.isCell())
            return;
        writeBarrier(owner, value.asCell());
    }
#else

    inline void Heap::writeBarrier(const JSCell*, JSCell*)
    {
        WriteBarrierCounters::countWriteBarrier();
    }

    inline void Heap::writeBarrier(const JSCell*, JSValue)
    {
        WriteBarrierCounters::countWriteBarrier();
    }
#endif

    inline void Heap::reportExtraMemoryCost(size_t cost)
    {
        if (cost > minExtraCost) 
            reportExtraMemoryCostSlowCase(cost);
    }

    template<typename Functor> inline typename Functor::ReturnType Heap::forEachProtectedCell(Functor& functor)
    {
        ProtectCountSet::iterator end = m_protectedValues.end();
        for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
            functor(it->key);
        m_handleSet.forEachStrongHandle(functor, m_protectedValues);

        return functor.returnValue();
    }

    template<typename Functor> inline typename Functor::ReturnType Heap::forEachProtectedCell()
    {
        Functor functor;
        return forEachProtectedCell(functor);
    }

    inline void* Heap::allocateWithNormalDestructor(size_t bytes)
    {
        ASSERT(isValidAllocation(bytes));
        return m_objectSpace.allocateWithNormalDestructor(bytes);
    }
    
    inline void* Heap::allocateWithImmortalStructureDestructor(size_t bytes)
    {
        ASSERT(isValidAllocation(bytes));
        return m_objectSpace.allocateWithImmortalStructureDestructor(bytes);
    }
    
    inline void* Heap::allocateWithoutDestructor(size_t bytes)
    {
        ASSERT(isValidAllocation(bytes));
        return m_objectSpace.allocateWithoutDestructor(bytes);
    }
   
    inline CheckedBoolean Heap::tryAllocateStorage(size_t bytes, void** outPtr)
    {
        return m_storageSpace.tryAllocate(bytes, outPtr);
    }
    
    inline CheckedBoolean Heap::tryReallocateStorage(void** ptr, size_t oldSize, size_t newSize)
    {
        return m_storageSpace.tryReallocate(ptr, oldSize, newSize);
    }

    inline BlockAllocator& Heap::blockAllocator()
    {
        return m_blockAllocator;
    }

} // namespace JSC

#endif // Heap_h
