| Index: Source/platform/heap/Handle.h
|
| diff --git a/Source/platform/heap/Handle.h b/Source/platform/heap/Handle.h
|
| index 0c59bfab4bd1bad578193852bd3bbc4d160f6214..62c7734053274e02f73723c59bfffb6f39cc9841 100644
|
| --- a/Source/platform/heap/Handle.h
|
| +++ b/Source/platform/heap/Handle.h
|
| @@ -150,207 +150,6 @@ private:
|
| friend class ThreadState;
|
| };
|
|
|
| -
|
| -const int wrapperPersistentsPerRegion = 256;
|
| -const size_t wrapperPersistentOffsetMask = ~static_cast<size_t>(3);
|
| -const size_t wrapperPersistentLiveBitMask = 1;
|
| -
|
| -class WrapperPersistentNode {
|
| - WTF_MAKE_NONCOPYABLE(WrapperPersistentNode);
|
| -public:
|
| - bool isAlive() { return m_regionOffset & wrapperPersistentLiveBitMask; }
|
| -
|
| - WrapperPersistentRegion* region()
|
| - {
|
| - return reinterpret_cast<WrapperPersistentRegion*>(
|
| - reinterpret_cast<Address>(this) - (m_regionOffset & wrapperPersistentOffsetMask));
|
| - }
|
| -
|
| - virtual ~WrapperPersistentNode()
|
| - {
|
| - m_regionOffset &= ~wrapperPersistentLiveBitMask;
|
| - }
|
| -
|
| - virtual void trace(Visitor* visitor) { }
|
| -
|
| -protected:
|
| - WrapperPersistentNode() : m_raw(0), m_regionOffset(0) { }
|
| -
|
| - explicit WrapperPersistentNode(void* raw)
|
| - {
|
| - // When the constructor is called the slot should have been taken (takeSlot)
|
| - // as part of allocating the memory (via operator new). Hence the m_raw
|
| - // pointer should be 0.
|
| - ASSERT(!m_raw);
|
| - m_raw = raw;
|
| - // The m_regionOffset should always be set as an offset to the containing
|
| - // region. However it should not have the live bit set when the constructor
|
| - // is called.
|
| - ASSERT(m_regionOffset);
|
| - ASSERT(!isAlive());
|
| - m_regionOffset |= wrapperPersistentLiveBitMask;
|
| - }
|
| -
|
| -private:
|
| - void initSlot(size_t regionOffset, WrapperPersistentNode* nextFree)
|
| - {
|
| - ASSERT(!m_raw);
|
| - ASSERT(!m_regionOffset);
|
| - ASSERT(!(regionOffset & ~wrapperPersistentOffsetMask));
|
| - m_raw = nextFree;
|
| - m_regionOffset = regionOffset;
|
| - }
|
| -
|
| - WrapperPersistentNode* takeSlot()
|
| - {
|
| - // The slot should not be alive at the point where it is allocated.
|
| - ASSERT(!isAlive());
|
| - WrapperPersistentNode* nextFree = reinterpret_cast<WrapperPersistentNode*>(m_raw);
|
| - m_raw = 0;
|
| - return nextFree;
|
| - }
|
| -
|
| - WrapperPersistentNode* freeSlot(WrapperPersistentNode* nextFree)
|
| - {
|
| - // When the slot is freed the destructor should already have cleared the live bit.
|
| - ASSERT(!isAlive());
|
| - m_raw = nextFree;
|
| - return this;
|
| - }
|
| -
|
| -protected:
|
| - // m_raw is used both to point to the object when the WrapperPersistentNode is used/alive
|
| - // and to point to the next free wrapperPersistentNode in the region when the node is
|
| - // unused/dead.
|
| - void* m_raw;
|
| -
|
| - // The m_regionOffset field is an offset from this node to the base of the containing
|
| - // WrapperPersistentRegion.
|
| - size_t m_regionOffset;
|
| -
|
| - friend class WrapperPersistentRegion;
|
| -};
|
| -
|
| -template<typename T>
|
| -class WrapperPersistent FINAL : public WrapperPersistentNode {
|
| -public:
|
| - WrapperPersistent() : WrapperPersistentNode(0) { }
|
| - WrapperPersistent(std::nullptr_t) : WrapperPersistentNode(0) { }
|
| - WrapperPersistent(T* raw) : WrapperPersistentNode(raw) { }
|
| - WrapperPersistent(T& raw) : WrapperPersistentNode(&raw) { }
|
| -
|
| - void* operator new(size_t);
|
| - void operator delete(void*);
|
| -
|
| - virtual void trace(Visitor* visitor)
|
| - {
|
| - ASSERT(isAlive());
|
| - visitor->mark(static_cast<T*>(m_raw));
|
| - }
|
| -};
|
| -
|
| -class PLATFORM_EXPORT WrapperPersistentRegion {
|
| - WTF_MAKE_NONCOPYABLE(WrapperPersistentRegion);
|
| -public:
|
| - WrapperPersistentRegion()
|
| - {
|
| - WrapperPersistentNode* nextFree = 0;
|
| - for (int i = wrapperPersistentsPerRegion - 1; i >= 0; --i) {
|
| - size_t regionOffset = reinterpret_cast<Address>(&m_entries[i]) - reinterpret_cast<Address>(this);
|
| - // Setup the free slot with an offset to the containing region's base and a pointer to the next
|
| - // free slot in the region.
|
| - m_entries[i].initSlot(regionOffset, nextFree);
|
| - nextFree = &m_entries[i];
|
| - }
|
| - m_prev = 0;
|
| - m_next = 0;
|
| - m_freeHead = nextFree;
|
| - m_count = 0;
|
| - }
|
| -
|
| - void* allocate()
|
| - {
|
| - if (!m_freeHead) {
|
| - ASSERT(m_count == wrapperPersistentsPerRegion);
|
| - return 0;
|
| - }
|
| - // We have a free persistent slot in this region.
|
| - WrapperPersistentNode* freeSlot = m_freeHead;
|
| - // Take the slot and advance m_freeHead to the next free slot.
|
| - m_freeHead = freeSlot->takeSlot();
|
| - ASSERT(m_count < wrapperPersistentsPerRegion);
|
| - m_count++;
|
| - return reinterpret_cast<void*>(freeSlot);
|
| - }
|
| -
|
| - void free(WrapperPersistentNode* object)
|
| - {
|
| - ASSERT(object);
|
| - ASSERT(!object->isAlive());
|
| - m_freeHead = object->freeSlot(m_freeHead);
|
| - ASSERT(m_count > 0);
|
| - m_count--;
|
| - if (!m_count)
|
| - ThreadState::current()->freeWrapperPersistentRegion(this);
|
| - }
|
| -
|
| - bool removeIfNotLast(WrapperPersistentRegion** headPtr);
|
| - static void insertHead(WrapperPersistentRegion** headPtr, WrapperPersistentRegion* newHead);
|
| - static WrapperPersistentRegion* removeHead(WrapperPersistentRegion** headPtr);
|
| - static void* outOfLineAllocate(ThreadState*, WrapperPersistentRegion*);
|
| - static void trace(WrapperPersistentRegion* head, Visitor* visitor)
|
| - {
|
| - for (WrapperPersistentRegion* current = head; current; current = current->m_next)
|
| - current->traceRegion(visitor);
|
| - }
|
| -
|
| -private:
|
| - void traceRegion(Visitor* visitor)
|
| - {
|
| - size_t live = 0;
|
| -
|
| -#ifdef NDEBUG
|
| - for (int i = 0; i < wrapperPersistentsPerRegion && live < m_count; ++i) {
|
| -#else
|
| - // In DEBUG mode we scan all entries to validate we only have m_count
|
| - // live entries.
|
| - for (int i = 0; i < wrapperPersistentsPerRegion; ++i) {
|
| -#endif
|
| - if (m_entries[i].isAlive()) {
|
| - m_entries[i].trace(visitor);
|
| - live++;
|
| - }
|
| - }
|
| - ASSERT(live == m_count);
|
| - }
|
| -
|
| - WrapperPersistentRegion* m_prev;
|
| - WrapperPersistentRegion* m_next;
|
| - WrapperPersistentNode* m_freeHead;
|
| - size_t m_count;
|
| - WrapperPersistentNode m_entries[wrapperPersistentsPerRegion];
|
| -};
|
| -
|
| -template<typename T>
|
| -void* WrapperPersistent<T>::operator new(size_t size)
|
| -{
|
| - ASSERT(size == sizeof(WrapperPersistent<T>));
|
| - ThreadState* state = ThreadState::current();
|
| - WrapperPersistentRegion* region = state->wrapperRoots();
|
| - ASSERT(region);
|
| - void* persistent = region->allocate();
|
| - if (!persistent)
|
| - return WrapperPersistentRegion::outOfLineAllocate(state, region);
|
| - return persistent;
|
| -}
|
| -
|
| -template<typename T>
|
| -void WrapperPersistent<T>::operator delete(void* object)
|
| -{
|
| - WrapperPersistentNode* persistent = static_cast<WrapperPersistentNode*>(object);
|
| - persistent->region()->free(persistent);
|
| -}
|
| -
|
| // RootsAccessor for Persistent that provides access to thread-local list
|
| // of persistent handles. Can only be used to create handles that
|
| // are constructed and destructed on the same thread.
|
|
|