X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/1df5f87f1309a8daa30dabdee855f48ae40d14ab..6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174:/heap/MarkedAllocator.cpp diff --git a/heap/MarkedAllocator.cpp b/heap/MarkedAllocator.cpp new file mode 100644 index 0000000..2135e99 --- /dev/null +++ b/heap/MarkedAllocator.cpp @@ -0,0 +1,123 @@ +#include "config.h" +#include "MarkedAllocator.h" + +#include "GCActivityCallback.h" +#include "Heap.h" +#include "JSGlobalData.h" +#include + +namespace JSC { + +bool MarkedAllocator::isPagedOut(double deadline) +{ + unsigned itersSinceLastTimeCheck = 0; + HeapBlock* block = m_blockList.head(); + while (block) { + block = block->next(); + ++itersSinceLastTimeCheck; + if (itersSinceLastTimeCheck >= Heap::s_timeCheckResolution) { + double currentTime = WTF::monotonicallyIncreasingTime(); + if (currentTime > deadline) + return true; + itersSinceLastTimeCheck = 0; + } + } + + return false; +} + +inline void* MarkedAllocator::tryAllocateHelper() +{ + if (!m_freeList.head) { + for (MarkedBlock*& block = m_currentBlock; block; block = static_cast(block->next())) { + m_freeList = block->sweep(MarkedBlock::SweepToFreeList); + if (m_freeList.head) + break; + block->didConsumeFreeList(); + } + + if (!m_freeList.head) + return 0; + } + + MarkedBlock::FreeCell* head = m_freeList.head; + m_freeList.head = head->next; + ASSERT(head); + return head; +} + +inline void* MarkedAllocator::tryAllocate() +{ + ASSERT(!m_heap->isBusy()); + m_heap->m_operationInProgress = Allocation; + void* result = tryAllocateHelper(); + m_heap->m_operationInProgress = NoOperation; + return result; +} + +void* MarkedAllocator::allocateSlowCase() +{ + ASSERT(m_heap->globalData()->apiLock().currentThreadIsHoldingLock()); +#if COLLECT_ON_EVERY_ALLOCATION + m_heap->collectAllGarbage(); + ASSERT(m_heap->m_operationInProgress == NoOperation); +#endif + + ASSERT(!m_freeList.head); + m_heap->didAllocate(m_freeList.bytes); + + void* result = tryAllocate(); + + if (LIKELY(result != 0)) + return result; + + if (m_heap->shouldCollect()) { + m_heap->collect(Heap::DoNotSweep); + + result = tryAllocate(); + if (result) + return result; + } + + ASSERT(!m_heap->shouldCollect()); + + MarkedBlock* block = allocateBlock(); + ASSERT(block); + addBlock(block); + + result = tryAllocate(); + ASSERT(result); + return result; +} + +MarkedBlock* MarkedAllocator::allocateBlock() +{ + MarkedBlock* block = static_cast(m_heap->blockAllocator().allocate()); + if (block) + block = MarkedBlock::recycle(block, m_heap, m_cellSize, m_cellsNeedDestruction); + else + block = MarkedBlock::create(m_heap, m_cellSize, m_cellsNeedDestruction); + + m_markedSpace->didAddBlock(block); + + return block; +} + +void MarkedAllocator::addBlock(MarkedBlock* block) +{ + ASSERT(!m_currentBlock); + ASSERT(!m_freeList.head); + + m_blockList.append(block); + m_currentBlock = block; + m_freeList = block->sweep(MarkedBlock::SweepToFreeList); +} + +void MarkedAllocator::removeBlock(MarkedBlock* block) +{ + if (m_currentBlock == block) + m_currentBlock = 0; + m_blockList.remove(block); +} + +} // namespace JSC