2 * Copyright (C) 2013 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.
26 #ifndef GCIncomingRefCounted_h
27 #define GCIncomingRefCounted_h
29 #include <wtf/DeferrableRefCounted.h>
30 #include <wtf/Vector.h>
36 // A C-heap-allocated object that may have additional reference counts
37 // due to incoming references from the heap, which are tracked in
38 // reverse: the object knows its incoming references. Such objects also
39 // have the invariant that they don't have references back into the GC
43 class GCIncomingRefCounted
: public DeferrableRefCounted
<T
> {
45 GCIncomingRefCounted()
50 ~GCIncomingRefCounted()
52 if (hasVectorOfCells())
53 delete vectorOfCells();
56 size_t numberOfIncomingReferences() const
58 if (!hasAnyIncoming())
62 return vectorOfCells()->size();
65 JSCell
* incomingReferenceAt(size_t index
) const
67 ASSERT(hasAnyIncoming());
72 return vectorOfCells()->at(index
);
75 // It's generally not a good idea to call this directly, since if this
76 // returns true, you're supposed to add this object to the GC's list.
77 // Call GCIncomingRefCountedSet::addReference() instead.
78 bool addIncomingReference(JSCell
*);
80 // A filter function returns true if we wish to keep the incoming
81 // reference, and false if we don't. This may delete the object,
82 // and if it does so, this returns true. In general, you don't want
83 // to use this with a filter function that can return false unless
84 // you're also walking the GC's list.
85 template<typename FilterFunctionType
>
86 bool filterIncomingReferences(FilterFunctionType
&);
89 static uintptr_t singletonFlag() { return 1; }
91 bool hasVectorOfCells() const { return !(m_encodedPointer
& singletonFlag()); }
92 bool hasAnyIncoming() const { return !!m_encodedPointer
; }
93 bool hasSingleton() const { return hasAnyIncoming() && !hasVectorOfCells(); }
95 JSCell
* singleton() const
97 ASSERT(hasSingleton());
98 return bitwise_cast
<JSCell
*>(m_encodedPointer
& ~singletonFlag());
101 Vector
<JSCell
*>* vectorOfCells() const
103 ASSERT(hasVectorOfCells());
104 return bitwise_cast
<Vector
<JSCell
*>*>(m_encodedPointer
);
107 // Singleton flag is set: this is a JSCell*.
108 // Singleton flag not set: this is a pointer to a vector of cells.
109 uintptr_t m_encodedPointer
;
114 #endif // GCIncomingRefCounted_h