]>
git.saurik.com Git - apple/javascriptcore.git/blob - heap/CopiedBlock.h
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "BlockAllocator.h"
30 #include "CopyWorkList.h"
31 #include "HeapBlock.h"
32 #include "JSCJSValue.h"
34 #include <wtf/Atomics.h>
35 #include <wtf/OwnPtr.h>
36 #include <wtf/PassOwnPtr.h>
42 class CopiedBlock
: public HeapBlock
<CopiedBlock
> {
43 friend class CopiedSpace
;
44 friend class CopiedAllocator
;
46 static CopiedBlock
* create(DeadBlock
*);
47 static CopiedBlock
* createNoZeroFill(DeadBlock
*);
57 bool shouldReportLiveBytes(SpinLockHolder
&, JSCell
* owner
);
58 void reportLiveBytes(SpinLockHolder
&, JSCell
*, CopyToken
, unsigned);
59 void reportLiveBytesDuringCopying(unsigned);
61 void didEvacuateBytes(unsigned);
62 bool shouldEvacuate();
65 // The payload is the region of the block that is usable for allocations.
68 size_t payloadCapacity();
70 // The data is the region of the block that has been used for allocations.
75 // The wilderness is the region of the block that is usable for allocations
76 // but has not been so used.
78 char* wildernessEnd();
79 size_t wildernessSize();
84 static const size_t blockSize
= 32 * KB
;
87 CopyWorkList
& workList();
88 SpinLock
& workListLock() { return m_workListLock
; }
92 void zeroFillWilderness(); // Can be called at any time to zero-fill to the end of the block.
94 void checkConsistency();
96 SpinLock m_workListLock
;
97 OwnPtr
<CopyWorkList
> m_workList
;
102 unsigned m_liveBytes
;
104 unsigned m_liveObjects
;
108 inline CopiedBlock
* CopiedBlock::createNoZeroFill(DeadBlock
* block
)
110 Region
* region
= block
->region();
111 return new(NotNull
, block
) CopiedBlock(region
);
114 inline CopiedBlock
* CopiedBlock::create(DeadBlock
* block
)
116 CopiedBlock
* newBlock
= createNoZeroFill(block
);
117 newBlock
->zeroFillWilderness();
121 inline void CopiedBlock::zeroFillWilderness()
124 memset(wilderness(), 0, wildernessSize());
127 JSValue
* limit
= reinterpret_cast_ptr
<JSValue
*>(wildernessEnd());
128 for (JSValue
* currentValue
= reinterpret_cast_ptr
<JSValue
*>(wilderness()); currentValue
< limit
; currentValue
++)
129 *currentValue
= emptyValue
;
133 inline CopiedBlock::CopiedBlock(Region
* region
)
134 : HeapBlock
<CopiedBlock
>(region
)
135 , m_remaining(payloadCapacity())
143 m_workListLock
.Init();
144 ASSERT(is8ByteAligned(reinterpret_cast<void*>(m_remaining
)));
147 inline void CopiedBlock::didSurviveGC()
160 inline void CopiedBlock::didEvacuateBytes(unsigned bytes
)
162 ASSERT(m_liveBytes
>= bytes
);
163 ASSERT(m_liveObjects
);
165 m_liveBytes
-= bytes
;
172 inline bool CopiedBlock::canBeRecycled()
178 inline bool CopiedBlock::shouldEvacuate()
181 return static_cast<double>(m_liveBytes
) / static_cast<double>(payloadCapacity()) <= Options::minCopiedBlockUtilization();
184 inline void CopiedBlock::pin()
191 inline bool CopiedBlock::isPinned()
196 inline bool CopiedBlock::isOld()
201 inline void CopiedBlock::didPromote()
206 inline bool CopiedBlock::isOversize()
208 return region()->isCustomSize();
211 inline unsigned CopiedBlock::liveBytes()
217 inline char* CopiedBlock::payload()
219 return reinterpret_cast<char*>(this) + ((sizeof(CopiedBlock
) + 7) & ~7);
222 inline char* CopiedBlock::payloadEnd()
224 return reinterpret_cast<char*>(this) + region()->blockSize();
227 inline size_t CopiedBlock::payloadCapacity()
229 return payloadEnd() - payload();
232 inline char* CopiedBlock::data()
237 inline char* CopiedBlock::dataEnd()
239 return payloadEnd() - m_remaining
;
242 inline size_t CopiedBlock::dataSize()
244 return dataEnd() - data();
247 inline char* CopiedBlock::wilderness()
252 inline char* CopiedBlock::wildernessEnd()
257 inline size_t CopiedBlock::wildernessSize()
259 return wildernessEnd() - wilderness();
262 inline size_t CopiedBlock::size()
267 inline size_t CopiedBlock::capacity()
269 return region()->blockSize();
272 inline bool CopiedBlock::hasWorkList()
277 inline CopyWorkList
& CopiedBlock::workList()
282 inline void CopiedBlock::checkConsistency()
284 ASSERT(!!m_liveBytes
== !!m_liveObjects
);