]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - heap/MarkedAllocator.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / heap / MarkedAllocator.h
index 8b3620f08858ad1e62b3453b87523f12ba44ae07..161af480f974c90c7664fa1f77b7685fea6c39e5 100644 (file)
@@ -15,96 +15,134 @@ class SpeculativeJIT;
 }
 
 class MarkedAllocator {
-    friend class JIT;
-    friend class DFG::SpeculativeJIT;
+    friend class LLIntOffsetsExtractor;
 
 public:
+    static ptrdiff_t offsetOfFreeListHead();
+
     MarkedAllocator();
+    void lastChanceToFinalize();
     void reset();
-    void zapFreeList();
+    void stopAllocating();
+    void resumeAllocating();
     size_t cellSize() { return m_cellSize; }
-    bool cellsNeedDestruction() { return m_cellsNeedDestruction; }
-    void* allocate();
+    bool needsDestruction() { return m_needsDestruction; }
+    void* allocate(size_t);
     Heap* heap() { return m_heap; }
+    MarkedBlock* takeLastActiveBlock()
+    {
+        MarkedBlock* block = m_lastActiveBlock;
+        m_lastActiveBlock = 0;
+        return block;
+    }
     
     template<typename Functor> void forEachBlock(Functor&);
     
     void addBlock(MarkedBlock*);
     void removeBlock(MarkedBlock*);
-    void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction);
+    void init(Heap*, MarkedSpace*, size_t cellSize, bool needsDestruction);
 
     bool isPagedOut(double deadline);
    
 private:
-    friend class LLIntOffsetsExtractor;
-    
-    JS_EXPORT_PRIVATE void* allocateSlowCase();
-    void* tryAllocate();
-    void* tryAllocateHelper();
-    MarkedBlock* allocateBlock();
+    JS_EXPORT_PRIVATE void* allocateSlowCase(size_t);
+    void* tryAllocate(size_t);
+    void* tryAllocateHelper(size_t);
+    void* tryPopFreeList(size_t);
+    MarkedBlock* allocateBlock(size_t);
+    ALWAYS_INLINE void doTestCollectionsIfNeeded();
     
     MarkedBlock::FreeList m_freeList;
     MarkedBlock* m_currentBlock;
-    DoublyLinkedList<HeapBlock> m_blockList;
+    MarkedBlock* m_lastActiveBlock;
+    MarkedBlock* m_nextBlockToSweep;
+    DoublyLinkedList<MarkedBlock> m_blockList;
+    DoublyLinkedList<MarkedBlock> m_retiredBlocks;
     size_t m_cellSize;
-    bool m_cellsNeedDestruction;
+    bool m_needsDestruction { false };
     Heap* m_heap;
     MarkedSpace* m_markedSpace;
 };
 
+inline ptrdiff_t MarkedAllocator::offsetOfFreeListHead()
+{
+    return OBJECT_OFFSETOF(MarkedAllocator, m_freeList) + OBJECT_OFFSETOF(MarkedBlock::FreeList, head);
+}
+
 inline MarkedAllocator::MarkedAllocator()
     : m_currentBlock(0)
+    , m_lastActiveBlock(0)
+    , m_nextBlockToSweep(0)
     , m_cellSize(0)
-    , m_cellsNeedDestruction(true)
     , m_heap(0)
     , m_markedSpace(0)
 {
 }
 
-inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction)
+inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool needsDestruction)
 {
     m_heap = heap;
     m_markedSpace = markedSpace;
     m_cellSize = cellSize;
-    m_cellsNeedDestruction = cellsNeedDestruction;
+    m_needsDestruction = needsDestruction;
 }
 
-inline void* MarkedAllocator::allocate()
+inline void* MarkedAllocator::allocate(size_t bytes)
 {
     MarkedBlock::FreeCell* head = m_freeList.head;
-    // This is a light-weight fast path to cover the most common case.
-    if (UNLIKELY(!head))
-        return allocateSlowCase();
+    if (UNLIKELY(!head)) {
+        void* result = allocateSlowCase(bytes);
+#ifndef NDEBUG
+        memset(result, 0xCD, bytes);
+#endif
+        return result;
+    }
     
     m_freeList.head = head->next;
+#ifndef NDEBUG
+    memset(head, 0xCD, bytes);
+#endif
     return head;
 }
 
-inline void MarkedAllocator::reset()
-{
-    m_currentBlock = static_cast<MarkedBlock*>(m_blockList.head());
-}
-
-inline void MarkedAllocator::zapFreeList()
+inline void MarkedAllocator::stopAllocating()
 {
+    ASSERT(!m_lastActiveBlock);
     if (!m_currentBlock) {
         ASSERT(!m_freeList.head);
         return;
     }
     
-    m_currentBlock->zapFreeList(m_freeList);
+    m_currentBlock->stopAllocating(m_freeList);
+    m_lastActiveBlock = m_currentBlock;
+    m_currentBlock = 0;
     m_freeList = MarkedBlock::FreeList();
 }
 
+inline void MarkedAllocator::resumeAllocating()
+{
+    if (!m_lastActiveBlock)
+        return;
+
+    m_freeList = m_lastActiveBlock->resumeAllocating();
+    m_currentBlock = m_lastActiveBlock;
+    m_lastActiveBlock = 0;
+}
+
 template <typename Functor> inline void MarkedAllocator::forEachBlock(Functor& functor)
 {
-    HeapBlock* next;
-    for (HeapBlock* block = m_blockList.head(); block; block = next) {
+    MarkedBlock* next;
+    for (MarkedBlock* block = m_blockList.head(); block; block = next) {
+        next = block->next();
+        functor(block);
+    }
+
+    for (MarkedBlock* block = m_retiredBlocks.head(); block; block = next) {
         next = block->next();
-        functor(static_cast<MarkedBlock*>(block));
+        functor(block);
     }
 }
-    
+
 } // namespace JSC
 
 #endif