]> git.saurik.com Git - apple/javascriptcore.git/blame - heap/MarkedSpace.cpp
JavaScriptCore-1218.33.tar.gz
[apple/javascriptcore.git] / heap / MarkedSpace.cpp
CommitLineData
14957cd0
A
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21#include "config.h"
22#include "MarkedSpace.h"
23
93a37866 24#include "IncrementalSweeper.h"
14957cd0 25#include "JSGlobalObject.h"
14957cd0
A
26#include "JSLock.h"
27#include "JSObject.h"
93a37866 28
14957cd0
A
29
30namespace JSC {
31
32class Structure;
33
93a37866
A
34class Free {
35public:
36 typedef MarkedBlock* ReturnType;
37
38 enum FreeMode { FreeOrShrink, FreeAll };
39
40 Free(FreeMode, MarkedSpace*);
41 void operator()(MarkedBlock*);
42 ReturnType returnValue();
43
44private:
45 FreeMode m_freeMode;
46 MarkedSpace* m_markedSpace;
47 DoublyLinkedList<MarkedBlock> m_blocks;
48};
49
50inline Free::Free(FreeMode freeMode, MarkedSpace* newSpace)
51 : m_freeMode(freeMode)
52 , m_markedSpace(newSpace)
53{
54}
55
56inline void Free::operator()(MarkedBlock* block)
57{
58 if (m_freeMode == FreeOrShrink)
59 m_markedSpace->freeOrShrinkBlock(block);
60 else
61 m_markedSpace->freeBlock(block);
62}
63
64inline Free::ReturnType Free::returnValue()
65{
66 return m_blocks.head();
67}
68
69struct VisitWeakSet : MarkedBlock::VoidFunctor {
70 VisitWeakSet(HeapRootVisitor& heapRootVisitor) : m_heapRootVisitor(heapRootVisitor) { }
71 void operator()(MarkedBlock* block) { block->visitWeakSet(m_heapRootVisitor); }
72private:
73 HeapRootVisitor& m_heapRootVisitor;
74};
75
76struct ReapWeakSet : MarkedBlock::VoidFunctor {
77 void operator()(MarkedBlock* block) { block->reapWeakSet(); }
78};
79
6fe7ccc8
A
80MarkedSpace::MarkedSpace(Heap* heap)
81 : m_heap(heap)
14957cd0 82{
6fe7ccc8 83 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
93a37866
A
84 allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None);
85 normalDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::Normal);
86 immortalStructureDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::ImmortalStructure);
6fe7ccc8 87 }
14957cd0 88
6fe7ccc8 89 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
93a37866
A
90 allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None);
91 normalDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::Normal);
92 immortalStructureDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::ImmortalStructure);
6fe7ccc8 93 }
93a37866
A
94
95 m_normalSpace.largeAllocator.init(heap, this, 0, MarkedBlock::None);
96 m_normalDestructorSpace.largeAllocator.init(heap, this, 0, MarkedBlock::Normal);
97 m_immortalStructureDestructorSpace.largeAllocator.init(heap, this, 0, MarkedBlock::ImmortalStructure);
98}
99
100MarkedSpace::~MarkedSpace()
101{
102 Free free(Free::FreeAll, this);
103 forEachBlock(free);
104}
105
106struct LastChanceToFinalize : MarkedBlock::VoidFunctor {
107 void operator()(MarkedBlock* block) { block->lastChanceToFinalize(); }
108};
109
110void MarkedSpace::lastChanceToFinalize()
111{
112 canonicalizeCellLivenessData();
113 forEachBlock<LastChanceToFinalize>();
114}
115
116void MarkedSpace::sweep()
117{
118 m_heap->sweeper()->willFinishSweeping();
119 forEachBlock<Sweep>();
14957cd0
A
120}
121
6fe7ccc8 122void MarkedSpace::resetAllocators()
14957cd0 123{
6fe7ccc8
A
124 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
125 allocatorFor(cellSize).reset();
93a37866
A
126 normalDestructorAllocatorFor(cellSize).reset();
127 immortalStructureDestructorAllocatorFor(cellSize).reset();
6fe7ccc8
A
128 }
129
130 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
131 allocatorFor(cellSize).reset();
93a37866
A
132 normalDestructorAllocatorFor(cellSize).reset();
133 immortalStructureDestructorAllocatorFor(cellSize).reset();
6fe7ccc8 134 }
93a37866
A
135
136 m_normalSpace.largeAllocator.reset();
137 m_normalDestructorSpace.largeAllocator.reset();
138 m_immortalStructureDestructorSpace.largeAllocator.reset();
139}
140
141void MarkedSpace::visitWeakSets(HeapRootVisitor& heapRootVisitor)
142{
143 VisitWeakSet visitWeakSet(heapRootVisitor);
144 forEachBlock(visitWeakSet);
145}
146
147void MarkedSpace::reapWeakSets()
148{
149 forEachBlock<ReapWeakSet>();
14957cd0
A
150}
151
6fe7ccc8 152void MarkedSpace::canonicalizeCellLivenessData()
14957cd0 153{
6fe7ccc8 154 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
93a37866
A
155 allocatorFor(cellSize).canonicalizeCellLivenessData();
156 normalDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData();
157 immortalStructureDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData();
6fe7ccc8 158 }
14957cd0 159
6fe7ccc8 160 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
93a37866
A
161 allocatorFor(cellSize).canonicalizeCellLivenessData();
162 normalDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData();
163 immortalStructureDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData();
6fe7ccc8 164 }
93a37866
A
165
166 m_normalSpace.largeAllocator.canonicalizeCellLivenessData();
167 m_normalDestructorSpace.largeAllocator.canonicalizeCellLivenessData();
168 m_immortalStructureDestructorSpace.largeAllocator.canonicalizeCellLivenessData();
14957cd0
A
169}
170
6fe7ccc8 171bool MarkedSpace::isPagedOut(double deadline)
14957cd0 172{
6fe7ccc8 173 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
93a37866
A
174 if (allocatorFor(cellSize).isPagedOut(deadline)
175 || normalDestructorAllocatorFor(cellSize).isPagedOut(deadline)
176 || immortalStructureDestructorAllocatorFor(cellSize).isPagedOut(deadline))
6fe7ccc8
A
177 return true;
178 }
14957cd0 179
6fe7ccc8 180 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
93a37866
A
181 if (allocatorFor(cellSize).isPagedOut(deadline)
182 || normalDestructorAllocatorFor(cellSize).isPagedOut(deadline)
183 || immortalStructureDestructorAllocatorFor(cellSize).isPagedOut(deadline))
6fe7ccc8 184 return true;
14957cd0 185 }
6fe7ccc8 186
93a37866
A
187 if (m_normalSpace.largeAllocator.isPagedOut(deadline)
188 || m_normalDestructorSpace.largeAllocator.isPagedOut(deadline)
189 || m_immortalStructureDestructorSpace.largeAllocator.isPagedOut(deadline))
190 return true;
191
6fe7ccc8 192 return false;
14957cd0
A
193}
194
93a37866 195void MarkedSpace::freeBlock(MarkedBlock* block)
14957cd0 196{
93a37866
A
197 block->allocator()->removeBlock(block);
198 m_blocks.remove(block);
199 if (block->capacity() == MarkedBlock::blockSize) {
200 m_heap->blockAllocator().deallocate(MarkedBlock::destroy(block));
201 return;
14957cd0 202 }
93a37866 203 m_heap->blockAllocator().deallocateCustomSize(MarkedBlock::destroy(block));
6fe7ccc8 204}
14957cd0 205
93a37866 206void MarkedSpace::freeOrShrinkBlock(MarkedBlock* block)
14957cd0 207{
93a37866
A
208 if (!block->isEmpty()) {
209 block->shrink();
6fe7ccc8 210 return;
93a37866 211 }
14957cd0 212
93a37866 213 freeBlock(block);
14957cd0
A
214}
215
93a37866
A
216struct Shrink : MarkedBlock::VoidFunctor {
217 void operator()(MarkedBlock* block) { block->shrink(); }
6fe7ccc8 218};
14957cd0 219
93a37866 220void MarkedSpace::shrink()
14957cd0 221{
93a37866
A
222 Free freeOrShrink(Free::FreeOrShrink, this);
223 forEachBlock(freeOrShrink);
14957cd0
A
224}
225
226} // namespace JSC