diff options
Diffstat (limited to 'Source/JavaScriptCore/heap/CopiedSpace.cpp')
-rw-r--r-- | Source/JavaScriptCore/heap/CopiedSpace.cpp | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp index bf87a305c..cedafee3a 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.cpp +++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp @@ -28,6 +28,7 @@ #include "CopiedSpaceInlineMethods.h" #include "GCActivityCallback.h" +#include "Options.h" namespace JSC { @@ -36,6 +37,7 @@ CopiedSpace::CopiedSpace(Heap* heap) , m_toSpace(0) , m_fromSpace(0) , m_inCopyingPhase(false) + , m_shouldDoCopyPhase(false) , m_numberOfLoanedBlocks(0) { m_toSpaceLock.Init(); @@ -50,7 +52,7 @@ CopiedSpace::~CopiedSpace() m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_fromSpace->removeHead())); while (!m_oversizeBlocks.isEmpty()) - CopiedBlock::destroy(m_oversizeBlocks.removeHead()).deallocate(); + m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(m_oversizeBlocks.removeHead())); } void CopiedSpace::init() @@ -79,15 +81,7 @@ CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr) { ASSERT(isOversize(bytes)); - size_t blockSize = WTF::roundUpToMultipleOf(WTF::pageSize(), sizeof(CopiedBlock) + bytes); - - PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, WTF::pageSize(), OSAllocator::JSGCHeapPages); - if (!static_cast<bool>(allocation)) { - *outPtr = 0; - return false; - } - - CopiedBlock* block = CopiedBlock::create(allocation); + CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocateCustomSize(sizeof(CopiedBlock) + bytes, WTF::pageSize())); m_oversizeBlocks.push(block); m_blockFilter.add(reinterpret_cast<Bits>(block)); m_blockSet.add(block); @@ -97,7 +91,7 @@ CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr) *outPtr = allocator.forceAllocate(bytes); allocator.resetCurrentBlock(); - m_heap->didAllocate(blockSize); + m_heap->didAllocate(block->region()->blockSize()); return true; } @@ -145,22 +139,25 @@ CheckedBoolean CopiedSpace::tryReallocateOversize(void** ptr, size_t oldSize, si CopiedBlock* oldBlock = oversizeBlockFor(oldPtr); m_oversizeBlocks.remove(oldBlock); m_blockSet.remove(oldBlock); - CopiedBlock::destroy(oldBlock).deallocate(); + m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(oldBlock)); } *ptr = newPtr; return true; } -void CopiedSpace::doneFillingBlock(CopiedBlock* block) +void CopiedSpace::doneFillingBlock(CopiedBlock* block, CopiedBlock** exchange) { ASSERT(m_inCopyingPhase); + if (exchange) + *exchange = allocateBlockForCopyingPhase(); + if (!block) return; if (!block->dataSize()) { - recycleBlock(block); + recycleBorrowedBlock(block); return; } @@ -182,6 +179,38 @@ void CopiedSpace::doneFillingBlock(CopiedBlock* block) } } +void CopiedSpace::startedCopying() +{ + std::swap(m_fromSpace, m_toSpace); + + m_blockFilter.reset(); + m_allocator.resetCurrentBlock(); + + CopiedBlock* next = 0; + size_t totalLiveBytes = 0; + size_t totalUsableBytes = 0; + for (CopiedBlock* block = m_fromSpace->head(); block; block = next) { + next = block->next(); + if (!block->isPinned() && block->canBeRecycled()) { + recycleEvacuatedBlock(block); + continue; + } + totalLiveBytes += block->liveBytes(); + totalUsableBytes += block->payloadCapacity(); + } + + double markedSpaceBytes = m_heap->objectSpace().capacity(); + double totalFragmentation = ((double)totalLiveBytes + markedSpaceBytes) / ((double)totalUsableBytes + markedSpaceBytes); + m_shouldDoCopyPhase = totalFragmentation <= Options::minHeapUtilization(); + if (!m_shouldDoCopyPhase) + return; + + ASSERT(m_shouldDoCopyPhase); + ASSERT(!m_inCopyingPhase); + ASSERT(!m_numberOfLoanedBlocks); + m_inCopyingPhase = true; +} + void CopiedSpace::doneCopying() { { @@ -190,12 +219,13 @@ void CopiedSpace::doneCopying() m_loanedBlocksCondition.wait(m_loanedBlocksLock); } - ASSERT(m_inCopyingPhase); + ASSERT(m_inCopyingPhase == m_shouldDoCopyPhase); m_inCopyingPhase = false; + while (!m_fromSpace->isEmpty()) { CopiedBlock* block = m_fromSpace->removeHead(); - if (block->m_isPinned) { - block->m_isPinned = false; + if (block->isPinned() || !m_shouldDoCopyPhase) { + block->didSurviveGC(); // We don't add the block to the blockSet because it was never removed. ASSERT(m_blockSet.contains(block)); m_blockFilter.add(reinterpret_cast<Bits>(block)); @@ -210,13 +240,13 @@ void CopiedSpace::doneCopying() CopiedBlock* curr = m_oversizeBlocks.head(); while (curr) { CopiedBlock* next = curr->next(); - if (!curr->m_isPinned) { + if (!curr->isPinned()) { m_oversizeBlocks.remove(curr); m_blockSet.remove(curr); - CopiedBlock::destroy(curr).deallocate(); + m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(curr)); } else { m_blockFilter.add(reinterpret_cast<Bits>(curr)); - curr->m_isPinned = false; + curr->didSurviveGC(); } curr = next; } @@ -225,6 +255,8 @@ void CopiedSpace::doneCopying() allocateBlock(); else m_allocator.setCurrentBlock(m_toSpace->head()); + + m_shouldDoCopyPhase = false; } size_t CopiedSpace::size() |