]>
Commit | Line | Data |
---|---|---|
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 | ||
29 | namespace JSC { | |
30 | ||
31 | class Structure; | |
32 | ||
6fe7ccc8 A |
33 | MarkedSpace::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 | 47 | void 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 | 60 | void 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 | 73 | bool 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 | 88 | void 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 |
101 | class TakeIfUnmarked { |
102 | public: | |
103 | typedef MarkedBlock* ReturnType; | |
104 | ||
105 | TakeIfUnmarked(MarkedSpace*); | |
106 | void operator()(MarkedBlock*); | |
107 | ReturnType returnValue(); | |
108 | ||
109 | private: | |
110 | MarkedSpace* m_markedSpace; | |
111 | DoublyLinkedList<MarkedBlock> m_empties; | |
112 | }; | |
14957cd0 | 113 | |
6fe7ccc8 A |
114 | inline TakeIfUnmarked::TakeIfUnmarked(MarkedSpace* newSpace) |
115 | : m_markedSpace(newSpace) | |
116 | { | |
14957cd0 A |
117 | } |
118 | ||
6fe7ccc8 | 119 | inline 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 | 128 | inline TakeIfUnmarked::ReturnType TakeIfUnmarked::returnValue() |
14957cd0 | 129 | { |
6fe7ccc8 | 130 | return m_empties.head(); |
14957cd0 A |
131 | } |
132 | ||
6fe7ccc8 | 133 | void 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) |
141 | class GatherDirtyCells { | |
142 | WTF_MAKE_NONCOPYABLE(GatherDirtyCells); | |
143 | public: | |
144 | typedef void* ReturnType; | |
145 | ||
146 | explicit GatherDirtyCells(MarkedBlock::DirtyCellVector*); | |
147 | void operator()(MarkedBlock*); | |
148 | ReturnType returnValue() { return 0; } | |
149 | ||
150 | private: | |
151 | MarkedBlock::DirtyCellVector* m_dirtyCells; | |
152 | }; | |
14957cd0 | 153 | |
6fe7ccc8 A |
154 | inline GatherDirtyCells::GatherDirtyCells(MarkedBlock::DirtyCellVector* dirtyCells) |
155 | : m_dirtyCells(dirtyCells) | |
14957cd0 | 156 | { |
14957cd0 A |
157 | } |
158 | ||
6fe7ccc8 | 159 | inline void GatherDirtyCells::operator()(MarkedBlock* block) |
14957cd0 | 160 | { |
6fe7ccc8 | 161 | block->gatherDirtyCells(*m_dirtyCells); |
14957cd0 A |
162 | } |
163 | ||
6fe7ccc8 | 164 | void 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 |