| Index: Source/platform/heap/Handle.h
 | 
| diff --git a/Source/platform/heap/Handle.h b/Source/platform/heap/Handle.h
 | 
| index 7de70a60203e4ebc1eead19f8fcf6d947e0bbdfc..a95426684b0ffd7ad8cce17444a2859c59c36b93 100644
 | 
| --- a/Source/platform/heap/Handle.h
 | 
| +++ b/Source/platform/heap/Handle.h
 | 
| @@ -150,199 +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 {
 | 
| -    ALLOW_ONLY_INLINE_ALLOCATION();
 | 
| -    WTF_MAKE_NONCOPYABLE(WrapperPersistentNode);
 | 
| -public:
 | 
| -    bool isAlive() { return m_regionOffset & wrapperPersistentLiveBitMask; }
 | 
| -
 | 
| -    WrapperPersistentRegion* region()
 | 
| -    {
 | 
| -        return reinterpret_cast<WrapperPersistentRegion*>(
 | 
| -            reinterpret_cast<Address>(this) - regionOffset());
 | 
| -    }
 | 
| -
 | 
| -    virtual void trace(Visitor* visitor) { }
 | 
| -
 | 
| -    static inline void destroy(const WrapperPersistentNode*);
 | 
| -
 | 
| -protected:
 | 
| -    WrapperPersistentNode() : m_raw(0), m_regionOffset(0) { }
 | 
| -    WrapperPersistentNode(void *raw, size_t regionOffset) : m_raw(raw), m_regionOffset(regionOffset) { }
 | 
| -
 | 
| -private:
 | 
| -    size_t regionOffset() { return m_regionOffset & wrapperPersistentOffsetMask; }
 | 
| -
 | 
| -    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)
 | 
| -    {
 | 
| -        m_regionOffset &= ~wrapperPersistentLiveBitMask;
 | 
| -        m_raw = nextFree;
 | 
| -        return this;
 | 
| -    }
 | 
| -
 | 
| -    // Don't allow delete being called on wrapper persistent nodes. We
 | 
| -    // do use placement new to initialize the slot with the right vtable. See
 | 
| -    // WrapperPersistent<T> below.
 | 
| -    void operator delete(void*);
 | 
| -
 | 
| -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 encodes liveness of the slot as well as being 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 {
 | 
| -    ALLOW_ONLY_INLINE_ALLOCATION();
 | 
| -public:
 | 
| -    static WrapperPersistent<T>* create(T* raw);
 | 
| -
 | 
| -    virtual void trace(Visitor* visitor) override
 | 
| -    {
 | 
| -        ASSERT(isAlive());
 | 
| -        visitor->mark(static_cast<T*>(m_raw));
 | 
| -    }
 | 
| -
 | 
| -private:
 | 
| -    WrapperPersistent() { }
 | 
| -
 | 
| -    // We need to use a constructor to initialize the allocated slot since it
 | 
| -    // has a vtable which must be set to the WrapperPersistent<T> type.
 | 
| -    WrapperPersistent(T* raw, size_t regionOffset) : WrapperPersistentNode(raw, regionOffset) { }
 | 
| -
 | 
| -    // Don't allow delete being called on wrapper persistents.
 | 
| -    void operator delete(void*);
 | 
| -};
 | 
| -
 | 
| -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.
 | 
| -            ASSERT(!(regionOffset & ~wrapperPersistentOffsetMask));
 | 
| -            new (&m_entries[i]) WrapperPersistentNode(nextFree, regionOffset);
 | 
| -            nextFree = &m_entries[i];
 | 
| -        }
 | 
| -        m_prev = 0;
 | 
| -        m_next = 0;
 | 
| -        m_freeHead = nextFree;
 | 
| -        m_count = 0;
 | 
| -    }
 | 
| -
 | 
| -    Address 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<Address>(freeSlot);
 | 
| -    }
 | 
| -
 | 
| -    void free(WrapperPersistentNode* object)
 | 
| -    {
 | 
| -        ASSERT(object);
 | 
| -        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 Address 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>
 | 
| -WrapperPersistent<T>* WrapperPersistent<T>::create(T* raw)
 | 
| -{
 | 
| -    ThreadState* state = ThreadState::current();
 | 
| -    WrapperPersistentRegion* region = state->wrapperRoots();
 | 
| -    ASSERT(region);
 | 
| -    Address persistentSlot = region->allocate();
 | 
| -    if (!persistentSlot)
 | 
| -        persistentSlot = WrapperPersistentRegion::outOfLineAllocate(state, ®ion);
 | 
| -    ASSERT(persistentSlot);
 | 
| -    ASSERT(!reinterpret_cast<WrapperPersistentNode*>(persistentSlot)->isAlive());
 | 
| -
 | 
| -    size_t regionOffset = persistentSlot - reinterpret_cast<Address>(region);
 | 
| -    regionOffset |= wrapperPersistentLiveBitMask;
 | 
| -
 | 
| -    // We use placement new to call the constructor to ensure that we setup the
 | 
| -    // vtable correctly.
 | 
| -    return new (persistentSlot) WrapperPersistent<T>(raw, regionOffset);
 | 
| -}
 | 
| -
 | 
| -void WrapperPersistentNode::destroy(const WrapperPersistentNode* node)
 | 
| -{
 | 
| -    WrapperPersistentNode* persistent = const_cast<WrapperPersistentNode*>(node);
 | 
| -    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.
 | 
| 
 |