]> git.saurik.com Git - apple/javascriptcore.git/blame - heap/CopiedBlock.h
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / heap / CopiedBlock.h
CommitLineData
6fe7ccc8
A
1/*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef CopiedBlock_h
27#define CopiedBlock_h
28
93a37866
A
29#include "BlockAllocator.h"
30#include "CopyWorkList.h"
6fe7ccc8 31#include "HeapBlock.h"
93a37866
A
32#include "JSCJSValue.h"
33#include "Options.h"
34#include <wtf/Atomics.h>
35#include <wtf/OwnPtr.h>
36#include <wtf/PassOwnPtr.h>
6fe7ccc8
A
37
38namespace JSC {
39
40class CopiedSpace;
41
93a37866 42class CopiedBlock : public HeapBlock<CopiedBlock> {
6fe7ccc8
A
43 friend class CopiedSpace;
44 friend class CopiedAllocator;
45public:
93a37866
A
46 static CopiedBlock* create(DeadBlock*);
47 static CopiedBlock* createNoZeroFill(DeadBlock*);
48
49 void pin();
50 bool isPinned();
51
52 bool isOversize();
53
54 unsigned liveBytes();
55 void reportLiveBytes(JSCell*, unsigned);
56 void didSurviveGC();
57 void didEvacuateBytes(unsigned);
58 bool shouldEvacuate();
59 bool canBeRecycled();
6fe7ccc8 60
93a37866 61 // The payload is the region of the block that is usable for allocations.
6fe7ccc8 62 char* payload();
93a37866
A
63 char* payloadEnd();
64 size_t payloadCapacity();
65
66 // The data is the region of the block that has been used for allocations.
67 char* data();
68 char* dataEnd();
69 size_t dataSize();
70
71 // The wilderness is the region of the block that is usable for allocations
72 // but has not been so used.
73 char* wilderness();
74 char* wildernessEnd();
75 size_t wildernessSize();
76
6fe7ccc8
A
77 size_t size();
78 size_t capacity();
79
93a37866
A
80 static const size_t blockSize = 32 * KB;
81
82 bool hasWorkList();
83 CopyWorkList& workList();
84
6fe7ccc8 85private:
93a37866
A
86 CopiedBlock(Region*);
87 void zeroFillWilderness(); // Can be called at any time to zero-fill to the end of the block.
88
89#if ENABLE(PARALLEL_GC)
90 SpinLock m_workListLock;
91#endif
92 OwnPtr<CopyWorkList> m_workList;
93
94 size_t m_remaining;
6fe7ccc8 95 uintptr_t m_isPinned;
93a37866 96 unsigned m_liveBytes;
6fe7ccc8
A
97};
98
93a37866
A
99inline CopiedBlock* CopiedBlock::createNoZeroFill(DeadBlock* block)
100{
101 Region* region = block->region();
102 return new(NotNull, block) CopiedBlock(region);
103}
104
105inline CopiedBlock* CopiedBlock::create(DeadBlock* block)
106{
107 CopiedBlock* newBlock = createNoZeroFill(block);
108 newBlock->zeroFillWilderness();
109 return newBlock;
110}
111
112inline void CopiedBlock::zeroFillWilderness()
113{
114#if USE(JSVALUE64)
115 memset(wilderness(), 0, wildernessSize());
116#else
117 JSValue emptyValue;
118 JSValue* limit = reinterpret_cast_ptr<JSValue*>(wildernessEnd());
119 for (JSValue* currentValue = reinterpret_cast_ptr<JSValue*>(wilderness()); currentValue < limit; currentValue++)
120 *currentValue = emptyValue;
121#endif
122}
123
124inline CopiedBlock::CopiedBlock(Region* region)
125 : HeapBlock<CopiedBlock>(region)
126 , m_remaining(payloadCapacity())
127 , m_isPinned(false)
128 , m_liveBytes(0)
129{
130#if ENABLE(PARALLEL_GC)
131 m_workListLock.Init();
132#endif
133 ASSERT(is8ByteAligned(reinterpret_cast<void*>(m_remaining)));
134}
135
136inline void CopiedBlock::didSurviveGC()
137{
138 m_liveBytes = 0;
139 m_isPinned = false;
140 if (m_workList)
141 m_workList.clear();
142}
143
144inline void CopiedBlock::didEvacuateBytes(unsigned bytes)
145{
146 ASSERT(m_liveBytes >= bytes);
147 m_liveBytes -= bytes;
148}
149
150inline bool CopiedBlock::canBeRecycled()
151{
152 return !m_liveBytes;
153}
154
155inline bool CopiedBlock::shouldEvacuate()
156{
157 return static_cast<double>(m_liveBytes) / static_cast<double>(payloadCapacity()) <= Options::minCopiedBlockUtilization();
158}
159
160inline void CopiedBlock::pin()
161{
162 m_isPinned = true;
163 if (m_workList)
164 m_workList.clear();
165}
166
167inline bool CopiedBlock::isPinned()
168{
169 return m_isPinned;
170}
171
172inline bool CopiedBlock::isOversize()
173{
174 return region()->isCustomSize();
175}
176
177inline unsigned CopiedBlock::liveBytes()
178{
179 return m_liveBytes;
180}
181
6fe7ccc8
A
182inline char* CopiedBlock::payload()
183{
184 return reinterpret_cast<char*>(this) + ((sizeof(CopiedBlock) + 7) & ~7);
185}
186
93a37866
A
187inline char* CopiedBlock::payloadEnd()
188{
189 return reinterpret_cast<char*>(this) + region()->blockSize();
190}
191
192inline size_t CopiedBlock::payloadCapacity()
193{
194 return payloadEnd() - payload();
195}
196
197inline char* CopiedBlock::data()
198{
199 return payload();
200}
201
202inline char* CopiedBlock::dataEnd()
203{
204 return payloadEnd() - m_remaining;
205}
206
207inline size_t CopiedBlock::dataSize()
208{
209 return dataEnd() - data();
210}
211
212inline char* CopiedBlock::wilderness()
213{
214 return dataEnd();
215}
216
217inline char* CopiedBlock::wildernessEnd()
218{
219 return payloadEnd();
220}
221
222inline size_t CopiedBlock::wildernessSize()
223{
224 return wildernessEnd() - wilderness();
225}
226
6fe7ccc8
A
227inline size_t CopiedBlock::size()
228{
93a37866 229 return dataSize();
6fe7ccc8
A
230}
231
232inline size_t CopiedBlock::capacity()
233{
93a37866
A
234 return region()->blockSize();
235}
236
237inline bool CopiedBlock::hasWorkList()
238{
239 return !!m_workList;
240}
241
242inline CopyWorkList& CopiedBlock::workList()
243{
244 return *m_workList;
6fe7ccc8
A
245}
246
247} // namespace JSC
248
249#endif