]>
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 "CopyWorkList.h"
30 #include "JSCJSValue.h"
32 #include <wtf/Atomics.h>
33 #include <wtf/DoublyLinkedList.h>
34 #include <wtf/SpinLock.h>
40 class CopiedBlock
: public DoublyLinkedListNode
<CopiedBlock
> {
41 friend class WTF::DoublyLinkedListNode
<CopiedBlock
>;
42 friend class CopiedSpace
;
43 friend class CopiedAllocator
;
45 static CopiedBlock
* create(size_t = blockSize
);
46 static CopiedBlock
* createNoZeroFill(size_t = blockSize
);
47 static void destroy(CopiedBlock
*);
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();
101 SpinLock m_workListLock
;
102 std::unique_ptr
<CopyWorkList
> m_workList
;
107 unsigned m_liveBytes
;
109 unsigned m_liveObjects
;
113 inline CopiedBlock
* CopiedBlock::createNoZeroFill(size_t capacity
)
115 return new(NotNull
, fastAlignedMalloc(CopiedBlock::blockSize
, capacity
)) CopiedBlock(capacity
);
118 inline void CopiedBlock::destroy(CopiedBlock
* copiedBlock
)
120 copiedBlock
->~CopiedBlock();
121 fastAlignedFree(copiedBlock
);
124 inline CopiedBlock
* CopiedBlock::create(size_t capacity
)
126 CopiedBlock
* newBlock
= createNoZeroFill(capacity
);
127 newBlock
->zeroFillWilderness();
131 inline void CopiedBlock::zeroFillWilderness()
134 memset(wilderness(), 0, wildernessSize());
137 JSValue
* limit
= reinterpret_cast_ptr
<JSValue
*>(wildernessEnd());
138 for (JSValue
* currentValue
= reinterpret_cast_ptr
<JSValue
*>(wilderness()); currentValue
< limit
; currentValue
++)
139 *currentValue
= emptyValue
;
143 inline CopiedBlock::CopiedBlock(size_t capacity
)
144 : DoublyLinkedListNode
<CopiedBlock
>()
145 , m_capacity(capacity
)
146 , m_remaining(payloadCapacity())
154 ASSERT(is8ByteAligned(reinterpret_cast<void*>(m_remaining
)));
157 inline void CopiedBlock::didSurviveGC()
167 m_workList
= nullptr;
170 inline void CopiedBlock::didEvacuateBytes(unsigned bytes
)
172 ASSERT(m_liveBytes
>= bytes
);
173 ASSERT(m_liveObjects
);
175 m_liveBytes
-= bytes
;
182 inline bool CopiedBlock::canBeRecycled()
188 inline bool CopiedBlock::shouldEvacuate()
191 return static_cast<double>(m_liveBytes
) / static_cast<double>(payloadCapacity()) <= Options::minCopiedBlockUtilization();
194 inline void CopiedBlock::pin()
198 m_workList
= nullptr;
201 inline bool CopiedBlock::isPinned()
206 inline bool CopiedBlock::isOld()
211 inline void CopiedBlock::didPromote()
216 inline bool CopiedBlock::isOversize()
218 return m_capacity
!= blockSize
;
221 inline unsigned CopiedBlock::liveBytes()
227 inline char* CopiedBlock::payload()
229 return reinterpret_cast<char*>(this) + WTF::roundUpToMultipleOf
<sizeof(double)>(sizeof(CopiedBlock
));
232 inline char* CopiedBlock::payloadEnd()
234 return reinterpret_cast<char*>(this) + m_capacity
;
237 inline size_t CopiedBlock::payloadCapacity()
239 return payloadEnd() - payload();
242 inline char* CopiedBlock::data()
247 inline char* CopiedBlock::dataEnd()
249 return payloadEnd() - m_remaining
;
252 inline size_t CopiedBlock::dataSize()
254 return dataEnd() - data();
257 inline char* CopiedBlock::wilderness()
262 inline char* CopiedBlock::wildernessEnd()
267 inline size_t CopiedBlock::wildernessSize()
269 return wildernessEnd() - wilderness();
272 inline size_t CopiedBlock::size()
277 inline size_t CopiedBlock::capacity()
282 inline bool CopiedBlock::hasWorkList()
287 inline CopyWorkList
& CopiedBlock::workList()
292 inline void CopiedBlock::checkConsistency()
294 ASSERT(!!m_liveBytes
== !!m_liveObjects
);