2 * Copyright (C) 2012 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. 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.
29 #include "HeapBlock.h"
30 #include "WeakHandleOwner.h"
32 #include <wtf/DoublyLinkedList.h>
33 #include <wtf/PageAllocation.h>
34 #include <wtf/StdLibExtras.h>
38 class HeapRootVisitor
;
40 class WeakHandleOwner
;
42 class WeakBlock
: public DoublyLinkedListNode
<WeakBlock
> {
44 friend class WTF::DoublyLinkedListNode
<WeakBlock
>;
45 static const size_t blockSize
= 4 * KB
;
59 static WeakBlock
* create();
60 static void destroy(WeakBlock
*);
62 static WeakImpl
* asWeakImpl(FreeCell
*);
65 const SweepResult
& sweepResult();
66 SweepResult
takeSweepResult();
68 void visitLiveWeakImpls(HeapRootVisitor
&);
69 void visitDeadWeakImpls(HeapRootVisitor
&);
74 static FreeCell
* asFreeCell(WeakImpl
*);
76 WeakBlock(PageAllocation
&);
77 WeakImpl
* firstWeakImpl();
78 void finalize(WeakImpl
*);
79 WeakImpl
* weakImpls();
80 size_t weakImplCount();
81 void addToFreeList(FreeCell
**, WeakImpl
*);
83 PageAllocation m_allocation
;
86 SweepResult m_sweepResult
;
89 inline WeakBlock::SweepResult::SweepResult()
96 inline bool WeakBlock::SweepResult::isNull() const
98 return blockIsFree
&& !freeList
; // This state is impossible, so we can use it to mean null.
101 inline WeakImpl
* WeakBlock::asWeakImpl(FreeCell
* freeCell
)
103 return reinterpret_cast<WeakImpl
*>(freeCell
);
106 inline WeakBlock::SweepResult
WeakBlock::takeSweepResult()
109 std::swap(tmp
, m_sweepResult
);
110 ASSERT(m_sweepResult
.isNull());
114 inline const WeakBlock::SweepResult
& WeakBlock::sweepResult()
116 return m_sweepResult
;
119 inline WeakBlock::FreeCell
* WeakBlock::asFreeCell(WeakImpl
* weakImpl
)
121 return reinterpret_cast<FreeCell
*>(weakImpl
);
124 inline void WeakBlock::finalize(WeakImpl
* weakImpl
)
126 ASSERT(weakImpl
->state() == WeakImpl::Dead
);
127 weakImpl
->setState(WeakImpl::Finalized
);
128 WeakHandleOwner
* weakHandleOwner
= weakImpl
->weakHandleOwner();
129 if (!weakHandleOwner
)
131 weakHandleOwner
->finalize(Handle
<Unknown
>::wrapSlot(&const_cast<JSValue
&>(weakImpl
->jsValue())), weakImpl
->context());
134 inline WeakImpl
* WeakBlock::weakImpls()
136 return reinterpret_cast<WeakImpl
*>(this) + ((sizeof(WeakBlock
) + sizeof(WeakImpl
) - 1) / sizeof(WeakImpl
));
139 inline size_t WeakBlock::weakImplCount()
141 return (blockSize
/ sizeof(WeakImpl
)) - ((sizeof(WeakBlock
) + sizeof(WeakImpl
) - 1) / sizeof(WeakImpl
));
144 inline void WeakBlock::addToFreeList(FreeCell
** freeList
, WeakImpl
* weakImpl
)
146 ASSERT(weakImpl
->state() == WeakImpl::Deallocated
);
147 FreeCell
* freeCell
= asFreeCell(weakImpl
);
148 ASSERT(!*freeList
|| ((char*)*freeList
> (char*)this && (char*)*freeList
< (char*)this + blockSize
));
149 ASSERT((char*)freeCell
> (char*)this && (char*)freeCell
< (char*)this + blockSize
);
150 freeCell
->next
= *freeList
;
151 *freeList
= freeCell
;
156 #endif // WeakBlock_h