void CopiedSpace::doneCopying() { { MutexLocker locker(m_loanedBlocksLock); while (m_numberOfLoanedBlocks > 0) m_loanedBlocksCondition.wait(m_loanedBlocksLock); } ASSERT(m_inCopyingPhase == m_shouldDoCopyPhase); m_inCopyingPhase = false; while (!m_fromSpace->isEmpty()) { CopiedBlock* block = m_fromSpace->removeHead(); // All non-pinned blocks in from-space should have been reclaimed as they were evacuated. ASSERT(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)); m_toSpace->push(block); } if (!m_toSpace->head()) allocateBlock(); else m_allocator.setCurrentBlock(m_toSpace->head()); m_shouldDoCopyPhase = false; }
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(); } CopiedBlock* block = m_oversizeBlocks.head(); while (block) { CopiedBlock* next = block->next(); if (block->isPinned()) { m_blockFilter.add(reinterpret_cast<Bits>(block)); totalLiveBytes += block->payloadCapacity(); totalUsableBytes += block->payloadCapacity(); block->didSurviveGC(); } else { m_oversizeBlocks.remove(block); m_blockSet.remove(block); m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(block)); } block = next; } 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; }