X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/1df5f87f1309a8daa30dabdee855f48ae40d14ab..6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174:/heap/MarkedSpace.cpp diff --git a/heap/MarkedSpace.cpp b/heap/MarkedSpace.cpp index 77f6e52..405ed57 100644 --- a/heap/MarkedSpace.cpp +++ b/heap/MarkedSpace.cpp @@ -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& 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(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 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 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