diff options
Diffstat (limited to 'Source/JavaScriptCore/heap/GCIncomingRefCounted.h')
-rw-r--r-- | Source/JavaScriptCore/heap/GCIncomingRefCounted.h | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/heap/GCIncomingRefCounted.h b/Source/JavaScriptCore/heap/GCIncomingRefCounted.h new file mode 100644 index 000000000..3854d0a14 --- /dev/null +++ b/Source/JavaScriptCore/heap/GCIncomingRefCounted.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GCIncomingRefCounted_h +#define GCIncomingRefCounted_h + +#include <wtf/DeferrableRefCounted.h> +#include <wtf/Vector.h> + +namespace JSC { + +class JSCell; + +// A C-heap-allocated object that may have additional reference counts +// due to incoming references from the heap, which are tracked in +// reverse: the object knows its incoming references. Such objects also +// have the invariant that they don't have references back into the GC +// heap. + +template<typename T> +class GCIncomingRefCounted : public DeferrableRefCounted<T> { +public: + GCIncomingRefCounted() + : m_encodedPointer(0) + { + } + + ~GCIncomingRefCounted() + { + if (hasVectorOfCells()) + delete vectorOfCells(); + } + + size_t numberOfIncomingReferences() const + { + if (!hasAnyIncoming()) + return 0; + if (hasSingleton()) + return 1; + return vectorOfCells()->size(); + } + + JSCell* incomingReferenceAt(size_t index) const + { + ASSERT(hasAnyIncoming()); + if (hasSingleton()) { + ASSERT(!index); + return singleton(); + } + return vectorOfCells()->at(index); + } + + // It's generally not a good idea to call this directly, since if this + // returns true, you're supposed to add this object to the GC's list. + // Call GCIncomingRefCountedSet::addReference() instead. + bool addIncomingReference(JSCell*); + + // A filter function returns true if we wish to keep the incoming + // reference, and false if we don't. This may delete the object, + // and if it does so, this returns true. In general, you don't want + // to use this with a filter function that can return false unless + // you're also walking the GC's list. + template<typename FilterFunctionType> + bool filterIncomingReferences(FilterFunctionType&); + +private: + static uintptr_t singletonFlag() { return 1; } + + bool hasVectorOfCells() const { return !(m_encodedPointer & singletonFlag()); } + bool hasAnyIncoming() const { return !!m_encodedPointer; } + bool hasSingleton() const { return hasAnyIncoming() && !hasVectorOfCells(); } + + JSCell* singleton() const + { + ASSERT(hasSingleton()); + return bitwise_cast<JSCell*>(m_encodedPointer & ~singletonFlag()); + } + + Vector<JSCell*>* vectorOfCells() const + { + ASSERT(hasVectorOfCells()); + return bitwise_cast<Vector<JSCell*>*>(m_encodedPointer); + } + + // Singleton flag is set: this is a JSCell*. + // Singleton flag not set: this is a pointer to a vector of cells. + uintptr_t m_encodedPointer; +}; + +} // namespace JSC + +#endif // GCIncomingRefCounted_h + |