]> git.saurik.com Git - apple/javascriptcore.git/blame - heap/HeapInlines.h
JavaScriptCore-7600.1.4.13.1.tar.gz
[apple/javascriptcore.git] / heap / HeapInlines.h
CommitLineData
81345200
A
1/*
2 * Copyright (C) 2014 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. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef HeapInlines_h
27#define HeapInlines_h
28
29#include "Heap.h"
30#include "JSCell.h"
31#include "Structure.h"
32
33namespace JSC {
34
35inline bool Heap::shouldCollect()
36{
37 if (isDeferred())
38 return false;
39 if (Options::gcMaxHeapSize())
40 return m_bytesAllocatedThisCycle > Options::gcMaxHeapSize() && m_isSafeToCollect && m_operationInProgress == NoOperation;
41 return m_bytesAllocatedThisCycle > m_maxEdenSize && m_isSafeToCollect && m_operationInProgress == NoOperation;
42}
43
44inline bool Heap::isBusy()
45{
46 return m_operationInProgress != NoOperation;
47}
48
49inline bool Heap::isCollecting()
50{
51 return m_operationInProgress == FullCollection || m_operationInProgress == EdenCollection;
52}
53
54inline Heap* Heap::heap(const JSCell* cell)
55{
56 return MarkedBlock::blockFor(cell)->heap();
57}
58
59inline Heap* Heap::heap(const JSValue v)
60{
61 if (!v.isCell())
62 return 0;
63 return heap(v.asCell());
64}
65
66inline bool Heap::isLive(const void* cell)
67{
68 return MarkedBlock::blockFor(cell)->isLiveCell(cell);
69}
70
71inline bool Heap::isRemembered(const void* ptr)
72{
73 const JSCell* cell = static_cast<const JSCell*>(ptr);
74 ASSERT(cell);
75 ASSERT(!Options::enableConcurrentJIT() || !isCompilationThread());
76 ASSERT(MarkedBlock::blockFor(cell)->isRemembered(cell) == cell->isRemembered());
77 return cell->isRemembered();
78}
79
80inline bool Heap::isMarked(const void* cell)
81{
82 return MarkedBlock::blockFor(cell)->isMarked(cell);
83}
84
85inline bool Heap::testAndSetMarked(const void* cell)
86{
87 return MarkedBlock::blockFor(cell)->testAndSetMarked(cell);
88}
89
90inline void Heap::setMarked(const void* cell)
91{
92 MarkedBlock::blockFor(cell)->setMarked(cell);
93}
94
95inline bool Heap::isWriteBarrierEnabled()
96{
97#if ENABLE(WRITE_BARRIER_PROFILING) || ENABLE(GGC)
98 return true;
99#else
100 return false;
101#endif
102}
103
104inline void Heap::writeBarrier(const JSCell* from, JSValue to)
105{
106#if ENABLE(WRITE_BARRIER_PROFILING)
107 WriteBarrierCounters::countWriteBarrier();
108#endif
109#if ENABLE(GGC)
110 if (!to.isCell())
111 return;
112 writeBarrier(from, to.asCell());
113#else
114 UNUSED_PARAM(from);
115 UNUSED_PARAM(to);
116#endif
117}
118
119inline void Heap::writeBarrier(const JSCell* from, JSCell* to)
120{
121#if ENABLE(WRITE_BARRIER_PROFILING)
122 WriteBarrierCounters::countWriteBarrier();
123#endif
124#if ENABLE(GGC)
125 if (!from || !from->isMarked()) {
126 ASSERT(!from || !isMarked(from));
127 return;
128 }
129 if (!to || to->isMarked()) {
130 ASSERT(!to || isMarked(to));
131 return;
132 }
133 addToRememberedSet(from);
134#else
135 UNUSED_PARAM(from);
136 UNUSED_PARAM(to);
137#endif
138}
139
140inline void Heap::writeBarrier(const JSCell* from)
141{
142#if ENABLE(GGC)
143 ASSERT_GC_OBJECT_LOOKS_VALID(const_cast<JSCell*>(from));
144 if (!from || !from->isMarked()) {
145 ASSERT(!from || !isMarked(from));
146 return;
147 }
148 ASSERT(isMarked(from));
149 addToRememberedSet(from);
150#else
151 UNUSED_PARAM(from);
152#endif
153}
154
155inline void Heap::reportExtraMemoryCost(size_t cost)
156{
157 if (cost > minExtraCost)
158 reportExtraMemoryCostSlowCase(cost);
159}
160
161template<typename Functor> inline typename Functor::ReturnType Heap::forEachProtectedCell(Functor& functor)
162{
163 for (auto& pair : m_protectedValues)
164 functor(pair.key);
165 m_handleSet.forEachStrongHandle(functor, m_protectedValues);
166
167 return functor.returnValue();
168}
169
170template<typename Functor> inline typename Functor::ReturnType Heap::forEachProtectedCell()
171{
172 Functor functor;
173 return forEachProtectedCell(functor);
174}
175
176template<typename Functor> inline void Heap::forEachCodeBlock(Functor& functor)
177{
178 return m_codeBlocks.iterate<Functor>(functor);
179}
180
181inline void* Heap::allocateWithNormalDestructor(size_t bytes)
182{
183#if ENABLE(ALLOCATION_LOGGING)
184 dataLogF("JSC GC allocating %lu bytes with normal destructor.\n", bytes);
185#endif
186 ASSERT(isValidAllocation(bytes));
187 return m_objectSpace.allocateWithNormalDestructor(bytes);
188}
189
190inline void* Heap::allocateWithImmortalStructureDestructor(size_t bytes)
191{
192#if ENABLE(ALLOCATION_LOGGING)
193 dataLogF("JSC GC allocating %lu bytes with immortal structure destructor.\n", bytes);
194#endif
195 ASSERT(isValidAllocation(bytes));
196 return m_objectSpace.allocateWithImmortalStructureDestructor(bytes);
197}
198
199inline void* Heap::allocateWithoutDestructor(size_t bytes)
200{
201#if ENABLE(ALLOCATION_LOGGING)
202 dataLogF("JSC GC allocating %lu bytes without destructor.\n", bytes);
203#endif
204 ASSERT(isValidAllocation(bytes));
205 return m_objectSpace.allocateWithoutDestructor(bytes);
206}
207
208inline CheckedBoolean Heap::tryAllocateStorage(JSCell* intendedOwner, size_t bytes, void** outPtr)
209{
210 CheckedBoolean result = m_storageSpace.tryAllocate(bytes, outPtr);
211#if ENABLE(ALLOCATION_LOGGING)
212 dataLogF("JSC GC allocating %lu bytes of storage for %p: %p.\n", bytes, intendedOwner, *outPtr);
213#else
214 UNUSED_PARAM(intendedOwner);
215#endif
216 return result;
217}
218
219inline CheckedBoolean Heap::tryReallocateStorage(JSCell* intendedOwner, void** ptr, size_t oldSize, size_t newSize)
220{
221#if ENABLE(ALLOCATION_LOGGING)
222 void* oldPtr = *ptr;
223#endif
224 CheckedBoolean result = m_storageSpace.tryReallocate(ptr, oldSize, newSize);
225#if ENABLE(ALLOCATION_LOGGING)
226 dataLogF("JSC GC reallocating %lu -> %lu bytes of storage for %p: %p -> %p.\n", oldSize, newSize, intendedOwner, oldPtr, *ptr);
227#else
228 UNUSED_PARAM(intendedOwner);
229#endif
230 return result;
231}
232
233inline void Heap::ascribeOwner(JSCell* intendedOwner, void* storage)
234{
235#if ENABLE(ALLOCATION_LOGGING)
236 dataLogF("JSC GC ascribing %p as owner of storage %p.\n", intendedOwner, storage);
237#else
238 UNUSED_PARAM(intendedOwner);
239 UNUSED_PARAM(storage);
240#endif
241}
242
243inline BlockAllocator& Heap::blockAllocator()
244{
245 return m_blockAllocator;
246}
247
248#if USE(CF)
249template <typename T>
250inline void Heap::releaseSoon(RetainPtr<T>&& object)
251{
252 m_objectSpace.releaseSoon(WTF::move(object));
253}
254#endif
255
256inline void Heap::incrementDeferralDepth()
257{
258 RELEASE_ASSERT(m_deferralDepth < 100); // Sanity check to make sure this doesn't get ridiculous.
259 m_deferralDepth++;
260}
261
262inline void Heap::decrementDeferralDepth()
263{
264 RELEASE_ASSERT(m_deferralDepth >= 1);
265 m_deferralDepth--;
266}
267
268inline bool Heap::collectIfNecessaryOrDefer()
269{
270 if (isDeferred())
271 return false;
272
273 if (!shouldCollect())
274 return false;
275
276 collect();
277 return true;
278}
279
280inline void Heap::decrementDeferralDepthAndGCIfNeeded()
281{
282 decrementDeferralDepth();
283 collectIfNecessaryOrDefer();
284}
285
286inline HashSet<MarkedArgumentBuffer*>& Heap::markListSet()
287{
288 if (!m_markListSet)
289 m_markListSet = adoptPtr(new HashSet<MarkedArgumentBuffer*>);
290 return *m_markListSet;
291}
292
293} // namespace JSC
294
295#endif // HeapInlines_h