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 <wtf/DoublyLinkedList.h>
30 #include "WeakHandleOwner.h"
32 #include <wtf/DoublyLinkedList.h>
33 #include <wtf/StdLibExtras.h>
37 class HeapRootVisitor
;
40 class WeakHandleOwner
;
42 class WeakBlock
: public DoublyLinkedListNode
<WeakBlock
> {
44 friend class WTF::DoublyLinkedListNode
<WeakBlock
>;
45 static const size_t blockSize
= 1 * KB
; // 1/16 of MarkedBlock size
54 bool blockIsFree
{ true };
55 bool blockIsLogicallyEmpty
{ true };
56 FreeCell
* freeList
{ nullptr };
59 static WeakBlock
* create(MarkedBlock
&);
60 static void destroy(WeakBlock
*);
62 static WeakImpl
* asWeakImpl(FreeCell
*);
65 bool isLogicallyEmptyButNotFree() const;
68 SweepResult
takeSweepResult();
70 void visit(HeapRootVisitor
&);
73 void lastChanceToFinalize();
74 void disconnectMarkedBlock() { m_markedBlock
= nullptr; }
77 static FreeCell
* asFreeCell(WeakImpl
*);
79 explicit WeakBlock(MarkedBlock
&);
80 WeakImpl
* firstWeakImpl();
81 void finalize(WeakImpl
*);
82 WeakImpl
* weakImpls();
83 size_t weakImplCount();
84 void addToFreeList(FreeCell
**, WeakImpl
*);
86 MarkedBlock
* m_markedBlock
;
89 SweepResult m_sweepResult
;
92 inline bool WeakBlock::SweepResult::isNull() const
94 return blockIsFree
&& !freeList
; // This state is impossible, so we can use it to mean null.
97 inline WeakImpl
* WeakBlock::asWeakImpl(FreeCell
* freeCell
)
99 return reinterpret_cast_ptr
<WeakImpl
*>(freeCell
);
102 inline WeakBlock::SweepResult
WeakBlock::takeSweepResult()
105 std::swap(tmp
, m_sweepResult
);
106 ASSERT(m_sweepResult
.isNull());
110 inline WeakBlock::FreeCell
* WeakBlock::asFreeCell(WeakImpl
* weakImpl
)
112 return reinterpret_cast_ptr
<FreeCell
*>(weakImpl
);
115 inline WeakImpl
* WeakBlock::weakImpls()
117 return reinterpret_cast_ptr
<WeakImpl
*>(this) + ((sizeof(WeakBlock
) + sizeof(WeakImpl
) - 1) / sizeof(WeakImpl
));
120 inline size_t WeakBlock::weakImplCount()
122 return (blockSize
/ sizeof(WeakImpl
)) - ((sizeof(WeakBlock
) + sizeof(WeakImpl
) - 1) / sizeof(WeakImpl
));
125 inline void WeakBlock::addToFreeList(FreeCell
** freeList
, WeakImpl
* weakImpl
)
127 ASSERT(weakImpl
->state() == WeakImpl::Deallocated
);
128 FreeCell
* freeCell
= asFreeCell(weakImpl
);
129 ASSERT(!*freeList
|| ((char*)*freeList
> (char*)this && (char*)*freeList
< (char*)this + blockSize
));
130 ASSERT((char*)freeCell
> (char*)this && (char*)freeCell
< (char*)this + blockSize
);
131 freeCell
->next
= *freeList
;
132 *freeList
= freeCell
;
135 inline bool WeakBlock::isEmpty()
137 return !m_sweepResult
.isNull() && m_sweepResult
.blockIsFree
;
140 inline bool WeakBlock::isLogicallyEmptyButNotFree() const
142 return !m_sweepResult
.isNull() && !m_sweepResult
.blockIsFree
&& m_sweepResult
.blockIsLogicallyEmpty
;
147 #endif // WeakBlock_h