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. |