• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "JSCell.h"
25 #include "JSGlobalData.h"
26 #include "JSLock.h"
27 #include "JSObject.h"
28 #include "ScopeChain.h"
29 
30 namespace JSC {
31 
32 class Structure;
33 
MarkedSpace(JSGlobalData * globalData)34 MarkedSpace::MarkedSpace(JSGlobalData* globalData)
35     : m_waterMark(0)
36     , m_highWaterMark(0)
37     , m_globalData(globalData)
38 {
39     for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
40         sizeClassFor(cellSize).cellSize = cellSize;
41 
42     for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep)
43         sizeClassFor(cellSize).cellSize = cellSize;
44 }
45 
destroy()46 void MarkedSpace::destroy()
47 {
48     clearMarks();
49     shrink();
50     ASSERT(!size());
51 }
52 
allocateBlock(SizeClass & sizeClass)53 MarkedBlock* MarkedSpace::allocateBlock(SizeClass& sizeClass)
54 {
55     MarkedBlock* block = MarkedBlock::create(globalData(), sizeClass.cellSize);
56     sizeClass.blockList.append(block);
57     sizeClass.nextBlock = block;
58     m_blocks.add(block);
59 
60     return block;
61 }
62 
freeBlocks(DoublyLinkedList<MarkedBlock> & blocks)63 void MarkedSpace::freeBlocks(DoublyLinkedList<MarkedBlock>& blocks)
64 {
65     MarkedBlock* next;
66     for (MarkedBlock* block = blocks.head(); block; block = next) {
67         next = block->next();
68 
69         blocks.remove(block);
70         m_blocks.remove(block);
71         MarkedBlock::destroy(block);
72     }
73 }
74 
allocateFromSizeClass(SizeClass & sizeClass)75 void* MarkedSpace::allocateFromSizeClass(SizeClass& sizeClass)
76 {
77     for (MarkedBlock*& block = sizeClass.nextBlock ; block; block = block->next()) {
78         if (void* result = block->allocate())
79             return result;
80 
81         m_waterMark += block->capacity();
82     }
83 
84     if (m_waterMark < m_highWaterMark)
85         return allocateBlock(sizeClass)->allocate();
86 
87     return 0;
88 }
89 
shrink()90 void MarkedSpace::shrink()
91 {
92     // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
93     DoublyLinkedList<MarkedBlock> empties;
94 
95     BlockIterator end = m_blocks.end();
96     for (BlockIterator it = m_blocks.begin(); it != end; ++it) {
97         MarkedBlock* block = *it;
98         if (block->isEmpty()) {
99             SizeClass& sizeClass = sizeClassFor(block->cellSize());
100             sizeClass.blockList.remove(block);
101             sizeClass.nextBlock = sizeClass.blockList.head();
102             empties.append(block);
103         }
104     }
105 
106     freeBlocks(empties);
107     ASSERT(empties.isEmpty());
108 }
109 
clearMarks()110 void MarkedSpace::clearMarks()
111 {
112     BlockIterator end = m_blocks.end();
113     for (BlockIterator it = m_blocks.begin(); it != end; ++it)
114         (*it)->clearMarks();
115 }
116 
sweep()117 void MarkedSpace::sweep()
118 {
119     BlockIterator end = m_blocks.end();
120     for (BlockIterator it = m_blocks.begin(); it != end; ++it)
121         (*it)->sweep();
122 }
123 
objectCount() const124 size_t MarkedSpace::objectCount() const
125 {
126     size_t result = 0;
127     BlockIterator end = m_blocks.end();
128     for (BlockIterator it = m_blocks.begin(); it != end; ++it)
129         result += (*it)->markCount();
130     return result;
131 }
132 
size() const133 size_t MarkedSpace::size() const
134 {
135     size_t result = 0;
136     BlockIterator end = m_blocks.end();
137     for (BlockIterator it = m_blocks.begin(); it != end; ++it)
138         result += (*it)->size();
139     return result;
140 }
141 
capacity() const142 size_t MarkedSpace::capacity() const
143 {
144     size_t result = 0;
145     BlockIterator end = m_blocks.end();
146     for (BlockIterator it = m_blocks.begin(); it != end; ++it)
147         result += (*it)->capacity();
148     return result;
149 }
150 
reset()151 void MarkedSpace::reset()
152 {
153     m_waterMark = 0;
154 
155     for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
156         sizeClassFor(cellSize).reset();
157 
158     for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep)
159         sizeClassFor(cellSize).reset();
160 
161     BlockIterator end = m_blocks.end();
162     for (BlockIterator it = m_blocks.begin(); it != end; ++it)
163         (*it)->reset();
164 }
165 
166 } // namespace JSC
167