]> git.saurik.com Git - apple/javascriptcore.git/blame - heap/MarkedSpace.cpp
JavaScriptCore-1097.3.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
24#include "JSGlobalObject.h"
14957cd0
A
25#include "JSLock.h"
26#include "JSObject.h"
27#include "ScopeChain.h"
28
29namespace JSC {
30
31class Structure;
32
6fe7ccc8
A
33MarkedSpace::MarkedSpace(Heap* heap)
34 : m_heap(heap)
14957cd0 35{
6fe7ccc8
A
36 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
37 allocatorFor(cellSize).init(heap, this, cellSize, false);
38 destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
39 }
14957cd0 40
6fe7ccc8
A
41 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
42 allocatorFor(cellSize).init(heap, this, cellSize, false);
43 destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
44 }
14957cd0
A
45}
46
6fe7ccc8 47void MarkedSpace::resetAllocators()
14957cd0 48{
6fe7ccc8
A
49 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
50 allocatorFor(cellSize).reset();
51 destructorAllocatorFor(cellSize).reset();
52 }
53
54 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
55 allocatorFor(cellSize).reset();
56 destructorAllocatorFor(cellSize).reset();
57 }
14957cd0
A
58}
59
6fe7ccc8 60void MarkedSpace::canonicalizeCellLivenessData()
14957cd0 61{
6fe7ccc8
A
62 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
63 allocatorFor(cellSize).zapFreeList();
64 destructorAllocatorFor(cellSize).zapFreeList();
65 }
14957cd0 66
6fe7ccc8
A
67 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
68 allocatorFor(cellSize).zapFreeList();
69 destructorAllocatorFor(cellSize).zapFreeList();
70 }
14957cd0
A
71}
72
6fe7ccc8 73bool MarkedSpace::isPagedOut(double deadline)
14957cd0 74{
6fe7ccc8
A
75 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
76 if (allocatorFor(cellSize).isPagedOut(deadline) || destructorAllocatorFor(cellSize).isPagedOut(deadline))
77 return true;
78 }
14957cd0 79
6fe7ccc8
A
80 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
81 if (allocatorFor(cellSize).isPagedOut(deadline) || destructorAllocatorFor(cellSize).isPagedOut(deadline))
82 return true;
14957cd0 83 }
6fe7ccc8
A
84
85 return false;
14957cd0
A
86}
87
6fe7ccc8 88void MarkedSpace::freeBlocks(MarkedBlock* head)
14957cd0 89{
6fe7ccc8
A
90 MarkedBlock* next;
91 for (MarkedBlock* block = head; block; block = next) {
92 next = static_cast<MarkedBlock*>(block->next());
93
94 m_blocks.remove(block);
95 block->sweep();
14957cd0 96
6fe7ccc8 97 m_heap->blockAllocator().deallocate(block);
14957cd0 98 }
6fe7ccc8 99}
14957cd0 100
6fe7ccc8
A
101class TakeIfUnmarked {
102public:
103 typedef MarkedBlock* ReturnType;
104
105 TakeIfUnmarked(MarkedSpace*);
106 void operator()(MarkedBlock*);
107 ReturnType returnValue();
108
109private:
110 MarkedSpace* m_markedSpace;
111 DoublyLinkedList<MarkedBlock> m_empties;
112};
14957cd0 113
6fe7ccc8
A
114inline TakeIfUnmarked::TakeIfUnmarked(MarkedSpace* newSpace)
115 : m_markedSpace(newSpace)
116{
14957cd0
A
117}
118
6fe7ccc8 119inline void TakeIfUnmarked::operator()(MarkedBlock* block)
14957cd0 120{
6fe7ccc8
A
121 if (!block->markCountIsZero())
122 return;
14957cd0 123
6fe7ccc8
A
124 m_markedSpace->allocatorFor(block).removeBlock(block);
125 m_empties.append(block);
14957cd0
A
126}
127
6fe7ccc8 128inline TakeIfUnmarked::ReturnType TakeIfUnmarked::returnValue()
14957cd0 129{
6fe7ccc8 130 return m_empties.head();
14957cd0
A
131}
132
6fe7ccc8 133void MarkedSpace::shrink()
14957cd0 134{
6fe7ccc8
A
135 // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
136 TakeIfUnmarked takeIfUnmarked(this);
137 freeBlocks(forEachBlock(takeIfUnmarked));
14957cd0
A
138}
139
6fe7ccc8
A
140#if ENABLE(GGC)
141class GatherDirtyCells {
142 WTF_MAKE_NONCOPYABLE(GatherDirtyCells);
143public:
144 typedef void* ReturnType;
145
146 explicit GatherDirtyCells(MarkedBlock::DirtyCellVector*);
147 void operator()(MarkedBlock*);
148 ReturnType returnValue() { return 0; }
149
150private:
151 MarkedBlock::DirtyCellVector* m_dirtyCells;
152};
14957cd0 153
6fe7ccc8
A
154inline GatherDirtyCells::GatherDirtyCells(MarkedBlock::DirtyCellVector* dirtyCells)
155 : m_dirtyCells(dirtyCells)
14957cd0 156{
14957cd0
A
157}
158
6fe7ccc8 159inline void GatherDirtyCells::operator()(MarkedBlock* block)
14957cd0 160{
6fe7ccc8 161 block->gatherDirtyCells(*m_dirtyCells);
14957cd0
A
162}
163
6fe7ccc8 164void MarkedSpace::gatherDirtyCells(MarkedBlock::DirtyCellVector& dirtyCells)
14957cd0 165{
6fe7ccc8
A
166 GatherDirtyCells gatherDirtyCells(&dirtyCells);
167 forEachBlock(gatherDirtyCells);
14957cd0 168}
6fe7ccc8 169#endif
14957cd0
A
170
171} // namespace JSC