1/*
2 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5 *
6 *  This library is free software; you can redistribute it and/or
7 *  modify it under the terms of the GNU Lesser General Public
8 *  License as published by the Free Software Foundation; either
9 *  version 2 of the License, or (at your option) any later version.
10 *
11 *  This library is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 *  Lesser General Public License for more details.
15 *
16 *  You should have received a copy of the GNU Lesser General Public
17 *  License along with this library; if not, write to the Free Software
18 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19 *
20 */
21
22#ifndef Heap_h
23#define Heap_h
24
25#include "HandleHeap.h"
26#include "HandleStack.h"
27#include "MarkStack.h"
28#include "MarkedSpace.h"
29#include <wtf/Forward.h>
30#include <wtf/HashCountedSet.h>
31#include <wtf/HashSet.h>
32
33namespace JSC {
34
35    class GCActivityCallback;
36    class GlobalCodeBlock;
37    class HeapRootMarker;
38    class JSCell;
39    class JSGlobalData;
40    class JSValue;
41    class LiveObjectIterator;
42    class MarkStack;
43    class MarkedArgumentBuffer;
44    class RegisterFile;
45    class UString;
46    class WeakGCHandlePool;
47
48    typedef std::pair<JSValue, UString> ValueStringPair;
49    typedef HashCountedSet<JSCell*> ProtectCountSet;
50    typedef HashCountedSet<const char*> TypeCountSet;
51
52    enum OperationInProgress { NoOperation, Allocation, Collection };
53
54    class Heap {
55        WTF_MAKE_NONCOPYABLE(Heap);
56    public:
57        static Heap* heap(JSValue); // 0 for immediate values
58        static Heap* heap(JSCell*);
59
60        static bool isMarked(const JSCell*);
61        static bool testAndSetMarked(const JSCell*);
62        static void setMarked(JSCell*);
63
64        Heap(JSGlobalData*);
65        ~Heap();
66        void destroy(); // JSGlobalData must call destroy() before ~Heap().
67
68        JSGlobalData* globalData() const { return m_globalData; }
69        MarkedSpace& markedSpace() { return m_markedSpace; }
70        MachineThreads& machineThreads() { return m_machineThreads; }
71
72        GCActivityCallback* activityCallback();
73        void setActivityCallback(PassOwnPtr<GCActivityCallback>);
74
75        bool isBusy(); // true if an allocation or collection is in progress
76        void* allocate(size_t);
77        void collectAllGarbage();
78
79        void reportExtraMemoryCost(size_t cost);
80
81        void protect(JSValue);
82        bool unprotect(JSValue); // True when the protect count drops to 0.
83
84        bool contains(void*);
85
86        size_t size() const;
87        size_t capacity() const;
88        size_t objectCount() const;
89        size_t globalObjectCount();
90        size_t protectedObjectCount();
91        size_t protectedGlobalObjectCount();
92        PassOwnPtr<TypeCountSet> protectedObjectTypeCounts();
93        PassOwnPtr<TypeCountSet> objectTypeCounts();
94
95        void pushTempSortVector(Vector<ValueStringPair>*);
96        void popTempSortVector(Vector<ValueStringPair>*);
97
98        HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
99
100        template <typename Functor> void forEach(Functor&);
101
102        HandleSlot allocateGlobalHandle() { return m_handleHeap.allocate(); }
103        HandleSlot allocateLocalHandle() { return m_handleStack.push(); }
104
105        HandleStack* handleStack() { return &m_handleStack; }
106
107    private:
108        friend class JSGlobalData;
109
110        static const size_t minExtraCost = 256;
111        static const size_t maxExtraCost = 1024 * 1024;
112
113        void* allocateSlowCase(size_t);
114        void reportExtraMemoryCostSlowCase(size_t);
115
116        void markRoots();
117        void markProtectedObjects(HeapRootMarker&);
118        void markTempSortVectors(HeapRootMarker&);
119
120        enum SweepToggle { DoNotSweep, DoSweep };
121        void reset(SweepToggle);
122
123        RegisterFile& registerFile();
124
125        OperationInProgress m_operationInProgress;
126        MarkedSpace m_markedSpace;
127
128        ProtectCountSet m_protectedValues;
129        Vector<Vector<ValueStringPair>* > m_tempSortingVectors;
130
131        HashSet<MarkedArgumentBuffer*>* m_markListSet;
132
133        OwnPtr<GCActivityCallback> m_activityCallback;
134
135        JSGlobalData* m_globalData;
136
137        MachineThreads m_machineThreads;
138        MarkStack m_markStack;
139        HandleHeap m_handleHeap;
140        HandleStack m_handleStack;
141
142        size_t m_extraCost;
143    };
144
145    inline bool Heap::isMarked(const JSCell* cell)
146    {
147        return MarkedSpace::isMarked(cell);
148    }
149
150    inline bool Heap::testAndSetMarked(const JSCell* cell)
151    {
152        return MarkedSpace::testAndSetMarked(cell);
153    }
154
155    inline void Heap::setMarked(JSCell* cell)
156    {
157        MarkedSpace::setMarked(cell);
158    }
159
160    inline bool Heap::contains(void* p)
161    {
162        return m_markedSpace.contains(p);
163    }
164
165    inline void Heap::reportExtraMemoryCost(size_t cost)
166    {
167        if (cost > minExtraCost)
168            reportExtraMemoryCostSlowCase(cost);
169    }
170
171    template <typename Functor> inline void Heap::forEach(Functor& functor)
172    {
173        m_markedSpace.forEach(functor);
174    }
175
176} // namespace JSC
177
178#endif // Heap_h
179