]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - heap/MarkedSpace.cpp
JavaScriptCore-1097.3.tar.gz
[apple/javascriptcore.git] / heap / MarkedSpace.cpp
index 77f6e523aa6f7cbacc03de8c7d89d336cb5d1f64..405ed571a08bfa4e52d43e63fdb4911226e9eb82 100644 (file)
@@ -22,8 +22,6 @@
 #include "MarkedSpace.h"
 
 #include "JSGlobalObject.h"
-#include "JSCell.h"
-#include "JSGlobalData.h"
 #include "JSLock.h"
 #include "JSObject.h"
 #include "ScopeChain.h"
@@ -32,136 +30,142 @@ namespace JSC {
 
 class Structure;
 
-MarkedSpace::MarkedSpace(JSGlobalData* globalData)
-    : m_waterMark(0)
-    , m_highWaterMark(0)
-    , m_globalData(globalData)
+MarkedSpace::MarkedSpace(Heap* heap)
+    : m_heap(heap)
 {
-    for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
-        sizeClassFor(cellSize).cellSize = cellSize;
+    for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
+        allocatorFor(cellSize).init(heap, this, cellSize, false);
+        destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
+    }
 
-    for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep)
-        sizeClassFor(cellSize).cellSize = cellSize;
+    for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
+        allocatorFor(cellSize).init(heap, this, cellSize, false);
+        destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
+    }
 }
 
-void MarkedSpace::destroy()
+void MarkedSpace::resetAllocators()
 {
-    clearMarks();
-    shrink();
-    ASSERT(!size());
+    for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
+        allocatorFor(cellSize).reset();
+        destructorAllocatorFor(cellSize).reset();
+    }
+
+    for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
+        allocatorFor(cellSize).reset();
+        destructorAllocatorFor(cellSize).reset();
+    }
 }
 
-MarkedBlock* MarkedSpace::allocateBlock(SizeClass& sizeClass)
+void MarkedSpace::canonicalizeCellLivenessData()
 {
-    MarkedBlock* block = MarkedBlock::create(globalData(), sizeClass.cellSize);
-    sizeClass.blockList.append(block);
-    sizeClass.nextBlock = block;
-    m_blocks.add(block);
+    for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
+        allocatorFor(cellSize).zapFreeList();
+        destructorAllocatorFor(cellSize).zapFreeList();
+    }
 
-    return block;
+    for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
+        allocatorFor(cellSize).zapFreeList();
+        destructorAllocatorFor(cellSize).zapFreeList();
+    }
 }
 
-void MarkedSpace::freeBlocks(DoublyLinkedList<MarkedBlock>& blocks)
+bool MarkedSpace::isPagedOut(double deadline)
 {
-    MarkedBlock* next;
-    for (MarkedBlock* block = blocks.head(); block; block = next) {
-        next = block->next();
+    for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
+        if (allocatorFor(cellSize).isPagedOut(deadline) || destructorAllocatorFor(cellSize).isPagedOut(deadline))
+            return true;
+    }
 
-        blocks.remove(block);
-        m_blocks.remove(block);
-        MarkedBlock::destroy(block);
+    for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
+        if (allocatorFor(cellSize).isPagedOut(deadline) || destructorAllocatorFor(cellSize).isPagedOut(deadline))
+            return true;
     }
+
+    return false;
 }
 
-void* MarkedSpace::allocateFromSizeClass(SizeClass& sizeClass)
+void MarkedSpace::freeBlocks(MarkedBlock* head)
 {
-    for (MarkedBlock*& block = sizeClass.nextBlock ; block; block = block->next()) {
-        if (void* result = block->allocate())
-            return result;
+    MarkedBlock* next;
+    for (MarkedBlock* block = head; block; block = next) {
+        next = static_cast<MarkedBlock*>(block->next());
+        
+        m_blocks.remove(block);
+        block->sweep();
 
-        m_waterMark += block->capacity();
+        m_heap->blockAllocator().deallocate(block);
     }
+}
 
-    if (m_waterMark < m_highWaterMark)
-        return allocateBlock(sizeClass)->allocate();
+class TakeIfUnmarked {
+public:
+    typedef MarkedBlock* ReturnType;
+    
+    TakeIfUnmarked(MarkedSpace*);
+    void operator()(MarkedBlock*);
+    ReturnType returnValue();
+    
+private:
+    MarkedSpace* m_markedSpace;
+    DoublyLinkedList<MarkedBlock> m_empties;
+};
 
-    return 0;
+inline TakeIfUnmarked::TakeIfUnmarked(MarkedSpace* newSpace)
+    : m_markedSpace(newSpace)
+{
 }
 
-void MarkedSpace::shrink()
+inline void TakeIfUnmarked::operator()(MarkedBlock* block)
 {
-    // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
-    DoublyLinkedList<MarkedBlock> empties;
-
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it) {
-        MarkedBlock* block = *it;
-        if (block->isEmpty()) {
-            SizeClass& sizeClass = sizeClassFor(block->cellSize());
-            sizeClass.blockList.remove(block);
-            sizeClass.nextBlock = sizeClass.blockList.head();
-            empties.append(block);
-        }
-    }
+    if (!block->markCountIsZero())
+        return;
     
-    freeBlocks(empties);
-    ASSERT(empties.isEmpty());
+    m_markedSpace->allocatorFor(block).removeBlock(block);
+    m_empties.append(block);
 }
 
-void MarkedSpace::clearMarks()
+inline TakeIfUnmarked::ReturnType TakeIfUnmarked::returnValue()
 {
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        (*it)->clearMarks();
+    return m_empties.head();
 }
 
-void MarkedSpace::sweep()
+void MarkedSpace::shrink()
 {
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        (*it)->sweep();
+    // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
+    TakeIfUnmarked takeIfUnmarked(this);
+    freeBlocks(forEachBlock(takeIfUnmarked));
 }
 
-size_t MarkedSpace::objectCount() const
-{
-    size_t result = 0;
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        result += (*it)->markCount();
-    return result;
-}
+#if ENABLE(GGC)
+class GatherDirtyCells {
+    WTF_MAKE_NONCOPYABLE(GatherDirtyCells);
+public:
+    typedef void* ReturnType;
+    
+    explicit GatherDirtyCells(MarkedBlock::DirtyCellVector*);
+    void operator()(MarkedBlock*);
+    ReturnType returnValue() { return 0; }
+    
+private:
+    MarkedBlock::DirtyCellVector* m_dirtyCells;
+};
 
-size_t MarkedSpace::size() const
+inline GatherDirtyCells::GatherDirtyCells(MarkedBlock::DirtyCellVector* dirtyCells)
+    : m_dirtyCells(dirtyCells)
 {
-    size_t result = 0;
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        result += (*it)->size();
-    return result;
 }
 
-size_t MarkedSpace::capacity() const
+inline void GatherDirtyCells::operator()(MarkedBlock* block)
 {
-    size_t result = 0;
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        result += (*it)->capacity();
-    return result;
+    block->gatherDirtyCells(*m_dirtyCells);
 }
 
-void MarkedSpace::reset()
+void MarkedSpace::gatherDirtyCells(MarkedBlock::DirtyCellVector& dirtyCells)
 {
-    m_waterMark = 0;
-
-    for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
-        sizeClassFor(cellSize).reset();
-
-    for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep)
-        sizeClassFor(cellSize).reset();
-
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        (*it)->reset();
+    GatherDirtyCells gatherDirtyCells(&dirtyCells);
+    forEachBlock(gatherDirtyCells);
 }
+#endif
 
 } // namespace JSC