diff options
Diffstat (limited to 'Source/JavaScriptCore/heap')
19 files changed, 202 insertions, 104 deletions
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.cpp b/Source/JavaScriptCore/heap/BlockAllocator.cpp index fc4f8a4c6..690fd83c4 100644 --- a/Source/JavaScriptCore/heap/BlockAllocator.cpp +++ b/Source/JavaScriptCore/heap/BlockAllocator.cpp @@ -55,7 +55,7 @@ BlockAllocator::~BlockAllocator() void BlockAllocator::releaseFreeBlocks() { while (true) { - HeapBlock* block; + DeadBlock* block; { SpinLockHolder locker(&m_freeBlockLock); if (!m_numberOfFreeBlocks) @@ -70,7 +70,7 @@ void BlockAllocator::releaseFreeBlocks() if (!block) break; - block->m_allocation.deallocate(); + DeadBlock::destroy(block).deallocate(); } } @@ -121,7 +121,7 @@ void BlockAllocator::blockFreeingThreadMain() size_t desiredNumberOfFreeBlocks = currentNumberOfFreeBlocks / 2; while (!m_blockFreeingThreadShouldQuit) { - HeapBlock* block; + DeadBlock* block; { SpinLockHolder locker(&m_freeBlockLock); if (m_numberOfFreeBlocks <= desiredNumberOfFreeBlocks) @@ -136,7 +136,7 @@ void BlockAllocator::blockFreeingThreadMain() if (!block) break; - block->m_allocation.deallocate(); + DeadBlock::destroy(block).deallocate(); } } } diff --git a/Source/JavaScriptCore/heap/BlockAllocator.h b/Source/JavaScriptCore/heap/BlockAllocator.h index 7a99d2edd..042e65d92 100644 --- a/Source/JavaScriptCore/heap/BlockAllocator.h +++ b/Source/JavaScriptCore/heap/BlockAllocator.h @@ -38,6 +38,24 @@ namespace JSC { // Simple allocator to reduce VM cost by holding onto blocks of memory for // short periods of time and then freeing them on a secondary thread. +class DeadBlock : public HeapBlock<DeadBlock> { +public: + static DeadBlock* create(const PageAllocationAligned&); + +private: + DeadBlock(const PageAllocationAligned&); +}; + +inline DeadBlock::DeadBlock(const PageAllocationAligned& allocation) + : HeapBlock<DeadBlock>(allocation) +{ +} + +inline DeadBlock* DeadBlock::create(const PageAllocationAligned& allocation) +{ + return new(NotNull, allocation.base()) DeadBlock(allocation); +} + class BlockAllocator { public: BlockAllocator(); @@ -55,7 +73,7 @@ private: void releaseFreeBlocks(); - DoublyLinkedList<HeapBlock> m_freeBlocks; + DoublyLinkedList<DeadBlock> m_freeBlocks; size_t m_numberOfFreeBlocks; bool m_isCurrentlyAllocating; bool m_blockFreeingThreadShouldQuit; @@ -73,12 +91,12 @@ inline PageAllocationAligned BlockAllocator::allocate() if (m_numberOfFreeBlocks) { ASSERT(!m_freeBlocks.isEmpty()); m_numberOfFreeBlocks--; - return m_freeBlocks.removeHead()->m_allocation; + return DeadBlock::destroy(m_freeBlocks.removeHead()); } } ASSERT(m_freeBlocks.isEmpty()); - PageAllocationAligned allocation = PageAllocationAligned::allocate(HeapBlock::s_blockSize, HeapBlock::s_blockSize, OSAllocator::JSGCHeapPages); + PageAllocationAligned allocation = PageAllocationAligned::allocate(DeadBlock::s_blockSize, DeadBlock::s_blockSize, OSAllocator::JSGCHeapPages); if (!static_cast<bool>(allocation)) CRASH(); return allocation; @@ -87,8 +105,7 @@ inline PageAllocationAligned BlockAllocator::allocate() inline void BlockAllocator::deallocate(PageAllocationAligned allocation) { SpinLockHolder locker(&m_freeBlockLock); - HeapBlock* heapBlock = new(NotNull, allocation.base()) HeapBlock(allocation); - m_freeBlocks.push(heapBlock); + m_freeBlocks.push(DeadBlock::create(allocation)); m_numberOfFreeBlocks++; } diff --git a/Source/JavaScriptCore/heap/CopiedBlock.h b/Source/JavaScriptCore/heap/CopiedBlock.h index 6717a6835..ad5dbb46b 100644 --- a/Source/JavaScriptCore/heap/CopiedBlock.h +++ b/Source/JavaScriptCore/heap/CopiedBlock.h @@ -34,13 +34,12 @@ namespace JSC { class CopiedSpace; -class CopiedBlock : public HeapBlock { +class CopiedBlock : public HeapBlock<CopiedBlock> { friend class CopiedSpace; friend class CopiedAllocator; public: static CopiedBlock* create(const PageAllocationAligned&); static CopiedBlock* createNoZeroFill(const PageAllocationAligned&); - static PageAllocationAligned destroy(CopiedBlock*); // The payload is the region of the block that is usable for allocations. char* payload(); @@ -93,17 +92,8 @@ inline void CopiedBlock::zeroFillWilderness() #endif } -inline PageAllocationAligned CopiedBlock::destroy(CopiedBlock* block) -{ - PageAllocationAligned allocation; - swap(allocation, block->m_allocation); - - block->~CopiedBlock(); - return allocation; -} - inline CopiedBlock::CopiedBlock(const PageAllocationAligned& allocation) - : HeapBlock(allocation) + : HeapBlock<CopiedBlock>(allocation) , m_remaining(payloadCapacity()) , m_isPinned(false) { @@ -117,7 +107,7 @@ inline char* CopiedBlock::payload() inline char* CopiedBlock::payloadEnd() { - return reinterpret_cast<char*>(this) + m_allocation.size(); + return reinterpret_cast<char*>(this) + allocation().size(); } inline size_t CopiedBlock::payloadCapacity() @@ -162,7 +152,7 @@ inline size_t CopiedBlock::size() inline size_t CopiedBlock::capacity() { - return m_allocation.size(); + return allocation().size(); } } // namespace JSC diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp index 147dfa4b3..bf87a305c 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.cpp +++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp @@ -44,13 +44,13 @@ CopiedSpace::CopiedSpace(Heap* heap) CopiedSpace::~CopiedSpace() { while (!m_toSpace->isEmpty()) - m_heap->blockAllocator().deallocate(CopiedBlock::destroy(static_cast<CopiedBlock*>(m_toSpace->removeHead()))); + m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_toSpace->removeHead())); while (!m_fromSpace->isEmpty()) - m_heap->blockAllocator().deallocate(CopiedBlock::destroy(static_cast<CopiedBlock*>(m_fromSpace->removeHead()))); + m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_fromSpace->removeHead())); while (!m_oversizeBlocks.isEmpty()) - CopiedBlock::destroy(static_cast<CopiedBlock*>(m_oversizeBlocks.removeHead())).deallocate(); + CopiedBlock::destroy(m_oversizeBlocks.removeHead()).deallocate(); } void CopiedSpace::init() @@ -193,7 +193,7 @@ void CopiedSpace::doneCopying() ASSERT(m_inCopyingPhase); m_inCopyingPhase = false; while (!m_fromSpace->isEmpty()) { - CopiedBlock* block = static_cast<CopiedBlock*>(m_fromSpace->removeHead()); + CopiedBlock* block = m_fromSpace->removeHead(); if (block->m_isPinned) { block->m_isPinned = false; // We don't add the block to the blockSet because it was never removed. @@ -207,9 +207,9 @@ void CopiedSpace::doneCopying() m_heap->blockAllocator().deallocate(CopiedBlock::destroy(block)); } - CopiedBlock* curr = static_cast<CopiedBlock*>(m_oversizeBlocks.head()); + CopiedBlock* curr = m_oversizeBlocks.head(); while (curr) { - CopiedBlock* next = static_cast<CopiedBlock*>(curr->next()); + CopiedBlock* next = curr->next(); if (!curr->m_isPinned) { m_oversizeBlocks.remove(curr); m_blockSet.remove(curr); @@ -224,20 +224,20 @@ void CopiedSpace::doneCopying() if (!m_toSpace->head()) allocateBlock(); else - m_allocator.setCurrentBlock(static_cast<CopiedBlock*>(m_toSpace->head())); + m_allocator.setCurrentBlock(m_toSpace->head()); } size_t CopiedSpace::size() { size_t calculatedSize = 0; - for (CopiedBlock* block = static_cast<CopiedBlock*>(m_toSpace->head()); block; block = static_cast<CopiedBlock*>(block->next())) + for (CopiedBlock* block = m_toSpace->head(); block; block = block->next()) calculatedSize += block->size(); - for (CopiedBlock* block = static_cast<CopiedBlock*>(m_fromSpace->head()); block; block = static_cast<CopiedBlock*>(block->next())) + for (CopiedBlock* block = m_fromSpace->head(); block; block = block->next()) calculatedSize += block->size(); - for (CopiedBlock* block = static_cast<CopiedBlock*>(m_oversizeBlocks.head()); block; block = static_cast<CopiedBlock*>(block->next())) + for (CopiedBlock* block = m_oversizeBlocks.head(); block; block = block->next()) calculatedSize += block->size(); return calculatedSize; @@ -247,22 +247,22 @@ size_t CopiedSpace::capacity() { size_t calculatedCapacity = 0; - for (CopiedBlock* block = static_cast<CopiedBlock*>(m_toSpace->head()); block; block = static_cast<CopiedBlock*>(block->next())) + for (CopiedBlock* block = m_toSpace->head(); block; block = block->next()) calculatedCapacity += block->capacity(); - for (CopiedBlock* block = static_cast<CopiedBlock*>(m_fromSpace->head()); block; block = static_cast<CopiedBlock*>(block->next())) + for (CopiedBlock* block = m_fromSpace->head(); block; block = block->next()) calculatedCapacity += block->capacity(); - for (CopiedBlock* block = static_cast<CopiedBlock*>(m_oversizeBlocks.head()); block; block = static_cast<CopiedBlock*>(block->next())) + for (CopiedBlock* block = m_oversizeBlocks.head(); block; block = block->next()) calculatedCapacity += block->capacity(); return calculatedCapacity; } -static bool isBlockListPagedOut(double deadline, DoublyLinkedList<HeapBlock>* list) +static bool isBlockListPagedOut(double deadline, DoublyLinkedList<CopiedBlock>* list) { unsigned itersSinceLastTimeCheck = 0; - HeapBlock* current = list->head(); + CopiedBlock* current = list->head(); while (current) { current = current->next(); ++itersSinceLastTimeCheck; diff --git a/Source/JavaScriptCore/heap/CopiedSpace.h b/Source/JavaScriptCore/heap/CopiedSpace.h index be3a331e8..ec394ca8f 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.h +++ b/Source/JavaScriptCore/heap/CopiedSpace.h @@ -44,7 +44,6 @@ namespace JSC { class Heap; class CopiedBlock; -class HeapBlock; class CopiedSpace { friend class SlotVisitor; @@ -101,12 +100,12 @@ private: SpinLock m_toSpaceLock; - DoublyLinkedList<HeapBlock>* m_toSpace; - DoublyLinkedList<HeapBlock>* m_fromSpace; + DoublyLinkedList<CopiedBlock>* m_toSpace; + DoublyLinkedList<CopiedBlock>* m_fromSpace; - DoublyLinkedList<HeapBlock> m_blocks1; - DoublyLinkedList<HeapBlock> m_blocks2; - DoublyLinkedList<HeapBlock> m_oversizeBlocks; + DoublyLinkedList<CopiedBlock> m_blocks1; + DoublyLinkedList<CopiedBlock> m_blocks2; + DoublyLinkedList<CopiedBlock> m_oversizeBlocks; bool m_inCopyingPhase; @@ -116,7 +115,7 @@ private: static const size_t s_maxAllocationSize = 32 * KB; static const size_t s_initialBlockNum = 16; - static const size_t s_blockMask = ~(HeapBlock::s_blockSize - 1); + static const size_t s_blockMask = ~(CopiedBlock::s_blockSize - 1); }; } // namespace JSC diff --git a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h index e2af41ad8..790a302de 100644 --- a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h +++ b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h @@ -95,9 +95,7 @@ inline void CopiedSpace::pinIfNecessary(void* opaquePointer) inline void CopiedSpace::startedCopying() { - DoublyLinkedList<HeapBlock>* temp = m_fromSpace; - m_fromSpace = m_toSpace; - m_toSpace = temp; + std::swap(m_fromSpace, m_toSpace); m_blockFilter.reset(); m_allocator.resetCurrentBlock(); diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp index 377132765..669178804 100644 --- a/Source/JavaScriptCore/heap/Heap.cpp +++ b/Source/JavaScriptCore/heap/Heap.cpp @@ -830,4 +830,18 @@ void Heap::addCompiledCode(ExecutableBase* executable) m_compiledCode.append(executable); } +bool Heap::isSafeToSweepStructures() +{ + return !m_sweeper || m_sweeper->structuresCanBeSwept(); +} + +void Heap::didStartVMShutdown() +{ + m_activityCallback->didStartVMShutdown(); + m_activityCallback = 0; + m_sweeper->didStartVMShutdown(); + m_sweeper = 0; + lastChanceToFinalize(); +} + } // namespace JSC diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h index 595e937ce..f3474f2ea 100644 --- a/Source/JavaScriptCore/heap/Heap.h +++ b/Source/JavaScriptCore/heap/Heap.h @@ -168,6 +168,8 @@ namespace JSC { void didAbandon(size_t); bool isPagedOut(double deadline); + bool isSafeToSweepStructures(); + void didStartVMShutdown(); private: friend class CodeBlock; diff --git a/Source/JavaScriptCore/heap/HeapBlock.h b/Source/JavaScriptCore/heap/HeapBlock.h index 3cd3c6322..a63b7ebe1 100644 --- a/Source/JavaScriptCore/heap/HeapBlock.h +++ b/Source/JavaScriptCore/heap/HeapBlock.h @@ -34,22 +34,42 @@ namespace JSC { enum AllocationEffort { AllocationCanFail, AllocationMustSucceed }; -class HeapBlock : public DoublyLinkedListNode<HeapBlock> { +#if COMPILER(GCC) +#define CLASS_IF_GCC class +#else +#define CLASS_IF_GCC +#endif + +template<typename T> +class HeapBlock : public DoublyLinkedListNode<T> { + friend CLASS_IF_GCC DoublyLinkedListNode<T>; public: + static const size_t s_blockSize = 64 * KB; + + static PageAllocationAligned destroy(HeapBlock* block) + { + static_cast<T*>(block)->~T(); + + PageAllocationAligned allocation; + std::swap(allocation, block->m_allocation); + return allocation; + } + HeapBlock(const PageAllocationAligned& allocation) - : DoublyLinkedListNode<HeapBlock>() + : DoublyLinkedListNode<T>() + , m_allocation(allocation) , m_prev(0) , m_next(0) - , m_allocation(allocation) { ASSERT(m_allocation); } - HeapBlock* m_prev; - HeapBlock* m_next; + const PageAllocationAligned allocation() const { return m_allocation; } + +private: PageAllocationAligned m_allocation; - - static const size_t s_blockSize = 64 * KB; + T* m_prev; + T* m_next; }; } // namespace JSC diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp index 49222c545..f284d8b57 100644 --- a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp +++ b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp @@ -51,6 +51,7 @@ void IncrementalSweeper::doWork() IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop) : HeapTimer(heap->globalData(), runLoop) , m_currentBlockToSweepIndex(0) + , m_structuresCanBeSwept(false) { } @@ -72,12 +73,7 @@ void IncrementalSweeper::cancelTimer() void IncrementalSweeper::doSweep(double sweepBeginTime) { while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) { - MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++]; - if (!block->needsSweeping()) - continue; - - block->sweep(); - m_globalData->heap.objectSpace().freeOrShrinkBlock(block); + sweepNextBlock(); CFTimeInterval elapsedTime = WTF::monotonicallyIncreasingTime() - sweepBeginTime; if (elapsedTime < sweepTimeSlice) @@ -91,17 +87,48 @@ void IncrementalSweeper::doSweep(double sweepBeginTime) cancelTimer(); } +void IncrementalSweeper::sweepNextBlock() +{ + while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) { + MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++]; + if (block->onlyContainsStructures()) + m_structuresCanBeSwept = true; + else + ASSERT(!m_structuresCanBeSwept); + + if (!block->needsSweeping()) + continue; + + block->sweep(); + m_globalData->heap.objectSpace().freeOrShrinkBlock(block); + return; + } +} + void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>& blockSnapshot) { - WTF::copyToVector(blockSnapshot, m_blocksToSweep); + m_blocksToSweep.resize(blockSnapshot.size()); + CopyFunctor functor(m_blocksToSweep); + m_globalData->heap.objectSpace().forEachBlock(functor); m_currentBlockToSweepIndex = 0; + m_structuresCanBeSwept = false; scheduleTimer(); } +void IncrementalSweeper::willFinishSweeping() +{ + m_currentBlockToSweepIndex = 0; + m_structuresCanBeSwept = true; + m_blocksToSweep.clear(); + if (m_globalData) + cancelTimer(); +} + #else IncrementalSweeper::IncrementalSweeper(JSGlobalData* globalData) : HeapTimer(globalData) + , m_structuresCanBeSwept(false) { } @@ -116,8 +143,23 @@ IncrementalSweeper* IncrementalSweeper::create(Heap* heap) void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>&) { + m_structuresCanBeSwept = false; } - + +void IncrementalSweeper::willFinishSweeping() +{ + m_structuresCanBeSwept = true; +} + +void IncrementalSweeper::sweepNextBlock() +{ +} + #endif +bool IncrementalSweeper::structuresCanBeSwept() +{ + return m_structuresCanBeSwept; +} + } // namespace JSC diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.h b/Source/JavaScriptCore/heap/IncrementalSweeper.h index eedfa7f6f..c8005b071 100644 --- a/Source/JavaScriptCore/heap/IncrementalSweeper.h +++ b/Source/JavaScriptCore/heap/IncrementalSweeper.h @@ -36,12 +36,28 @@ namespace JSC { class Heap; - + +struct CopyFunctor : public MarkedBlock::VoidFunctor { + CopyFunctor(Vector<MarkedBlock*>& blocks) + : m_index(0) + , m_blocks(blocks) + { + } + + void operator()(MarkedBlock* block) { m_blocks[m_index++] = block; } + + size_t m_index; + Vector<MarkedBlock*>& m_blocks; +}; + class IncrementalSweeper : public HeapTimer { public: static IncrementalSweeper* create(Heap*); void startSweeping(const HashSet<MarkedBlock*>& blockSnapshot); virtual void doWork(); + void sweepNextBlock(); + bool structuresCanBeSwept(); + void willFinishSweeping(); private: #if USE(CF) @@ -58,6 +74,7 @@ private: IncrementalSweeper(JSGlobalData*); #endif + bool m_structuresCanBeSwept; }; } // namespace JSC diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp index 8e0c57b6a..537a34e48 100644 --- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp +++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp @@ -142,7 +142,7 @@ MachineThreads::MachineThreads(Heap* heap) MachineThreads::~MachineThreads() { if (m_threadSpecific) - ThreadSpecificKeyDelete(m_threadSpecific); + threadSpecificKeyDelete(m_threadSpecific); MutexLocker registeredThreadsLock(m_registeredThreadsMutex); for (Thread* t = m_registeredThreads; t;) { @@ -179,17 +179,17 @@ void MachineThreads::makeUsableFromMultipleThreads() if (m_threadSpecific) return; - ThreadSpecificKeyCreate(&m_threadSpecific, removeThread); + threadSpecificKeyCreate(&m_threadSpecific, removeThread); } void MachineThreads::addCurrentThread() { ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread()); - if (!m_threadSpecific || ThreadSpecificGet(m_threadSpecific)) + if (!m_threadSpecific || threadSpecificGet(m_threadSpecific)) return; - ThreadSpecificSet(m_threadSpecific, this); + threadSpecificSet(m_threadSpecific, this); Thread* thread = new Thread(getCurrentPlatformThread(), wtfThreadData().stack().origin()); MutexLocker lock(m_registeredThreadsMutex); diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.cpp b/Source/JavaScriptCore/heap/MarkedAllocator.cpp index 465e3a72a..20b556969 100644 --- a/Source/JavaScriptCore/heap/MarkedAllocator.cpp +++ b/Source/JavaScriptCore/heap/MarkedAllocator.cpp @@ -3,6 +3,7 @@ #include "GCActivityCallback.h" #include "Heap.h" +#include "IncrementalSweeper.h" #include "JSGlobalData.h" #include <wtf/CurrentTime.h> @@ -11,7 +12,7 @@ namespace JSC { bool MarkedAllocator::isPagedOut(double deadline) { unsigned itersSinceLastTimeCheck = 0; - HeapBlock* block = m_blockList.head(); + MarkedBlock* block = m_blockList.head(); while (block) { block = block->next(); ++itersSinceLastTimeCheck; @@ -29,7 +30,18 @@ bool MarkedAllocator::isPagedOut(double deadline) inline void* MarkedAllocator::tryAllocateHelper() { if (!m_freeList.head) { - for (MarkedBlock*& block = m_blocksToSweep; block; block = static_cast<MarkedBlock*>(block->next())) { + if (m_onlyContainsStructures && !m_heap->isSafeToSweepStructures()) { + if (m_currentBlock) { + m_currentBlock->didConsumeFreeList(); + m_currentBlock = 0; + } + // We sweep another random block here so that we can make progress + // toward being able to sweep Structures. + m_heap->sweeper()->sweepNextBlock(); + return 0; + } + + for (MarkedBlock*& block = m_blocksToSweep; block; block = block->next()) { m_freeList = block->sweep(MarkedBlock::SweepToFreeList); if (m_freeList.head) { m_currentBlock = block; @@ -104,7 +116,6 @@ MarkedBlock* MarkedAllocator::allocateBlock() void MarkedAllocator::addBlock(MarkedBlock* block) { ASSERT(!m_currentBlock); - ASSERT(!m_blocksToSweep); ASSERT(!m_freeList.head); m_blockList.append(block); @@ -115,11 +126,11 @@ void MarkedAllocator::addBlock(MarkedBlock* block) void MarkedAllocator::removeBlock(MarkedBlock* block) { if (m_currentBlock == block) { - m_currentBlock = static_cast<MarkedBlock*>(m_currentBlock->next()); + m_currentBlock = m_currentBlock->next(); m_freeList = MarkedBlock::FreeList(); } if (m_blocksToSweep == block) - m_blocksToSweep = static_cast<MarkedBlock*>(m_blocksToSweep->next()); + m_blocksToSweep = m_blocksToSweep->next(); m_blockList.remove(block); } diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.h b/Source/JavaScriptCore/heap/MarkedAllocator.h index 47bae9451..c1c431194 100644 --- a/Source/JavaScriptCore/heap/MarkedAllocator.h +++ b/Source/JavaScriptCore/heap/MarkedAllocator.h @@ -47,7 +47,7 @@ private: MarkedBlock::FreeList m_freeList; MarkedBlock* m_currentBlock; MarkedBlock* m_blocksToSweep; - DoublyLinkedList<HeapBlock> m_blockList; + DoublyLinkedList<MarkedBlock> m_blockList; size_t m_cellSize; bool m_cellsNeedDestruction; bool m_onlyContainsStructures; @@ -90,7 +90,7 @@ inline void MarkedAllocator::reset() { m_currentBlock = 0; m_freeList = MarkedBlock::FreeList(); - m_blocksToSweep = static_cast<MarkedBlock*>(m_blockList.head()); + m_blocksToSweep = m_blockList.head(); } inline void MarkedAllocator::zapFreeList() @@ -101,15 +101,16 @@ inline void MarkedAllocator::zapFreeList() } m_currentBlock->zapFreeList(m_freeList); + m_currentBlock = 0; m_freeList = MarkedBlock::FreeList(); } template <typename Functor> inline void MarkedAllocator::forEachBlock(Functor& functor) { - HeapBlock* next; - for (HeapBlock* block = m_blockList.head(); block; block = next) { + MarkedBlock* next; + for (MarkedBlock* block = m_blockList.head(); block; block = next) { next = block->next(); - functor(static_cast<MarkedBlock*>(block)); + functor(block); } } diff --git a/Source/JavaScriptCore/heap/MarkedBlock.cpp b/Source/JavaScriptCore/heap/MarkedBlock.cpp index 8ede87927..95ea2f414 100644 --- a/Source/JavaScriptCore/heap/MarkedBlock.cpp +++ b/Source/JavaScriptCore/heap/MarkedBlock.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "MarkedBlock.h" +#include "IncrementalSweeper.h" #include "JSCell.h" #include "JSObject.h" #include "ScopeChain.h" @@ -37,17 +38,8 @@ MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, Heap* return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize, cellsNeedDestruction, onlyContainsStructures); } -PageAllocationAligned MarkedBlock::destroy(MarkedBlock* block) -{ - PageAllocationAligned allocation; - swap(allocation, block->m_allocation); - - block->~MarkedBlock(); - return allocation; -} - MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures) - : HeapBlock(allocation) + : HeapBlock<MarkedBlock>(allocation) , m_atomsPerCell((cellSize + atomSize - 1) / atomSize) , m_endAtom(atomsPerBlock - m_atomsPerCell + 1) , m_cellsNeedDestruction(cellsNeedDestruction) @@ -69,10 +61,6 @@ inline void MarkedBlock::callDestructor(JSCell* cell) m_heap->m_destroyedTypeCounts.countVPtr(vptr); #endif -#if !ASSERT_DISABLED || ENABLE(GC_VALIDATION) - cell->clearStructure(); -#endif - cell->methodTable()->destroy(cell); cell->zap(); } @@ -140,10 +128,12 @@ MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode) ASSERT_NOT_REACHED(); return FreeList(); case Marked: + ASSERT(!m_onlyContainsStructures || heap()->isSafeToSweepStructures()); return sweepMode == SweepToFreeList ? specializedSweep<Marked, SweepToFreeList, destructorCallNeeded>() : specializedSweep<Marked, SweepOnly, destructorCallNeeded>(); case Zapped: + ASSERT(!m_onlyContainsStructures || heap()->isSafeToSweepStructures()); return sweepMode == SweepToFreeList ? specializedSweep<Zapped, SweepToFreeList, destructorCallNeeded>() : specializedSweep<Zapped, SweepOnly, destructorCallNeeded>(); diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h index ff7840632..ab2abd753 100644 --- a/Source/JavaScriptCore/heap/MarkedBlock.h +++ b/Source/JavaScriptCore/heap/MarkedBlock.h @@ -67,8 +67,7 @@ namespace JSC { // size is equal to the difference between the cell size and the object // size. - class MarkedBlock : public HeapBlock { - friend class WTF::DoublyLinkedListNode<MarkedBlock>; + class MarkedBlock : public HeapBlock<MarkedBlock> { public: // Ensure natural alignment for native types whilst recognizing that the smallest // object the heap will commonly allocate is four words. @@ -114,7 +113,6 @@ namespace JSC { }; static MarkedBlock* create(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures); - static PageAllocationAligned destroy(MarkedBlock*); static bool isAtomAligned(const void*); static MarkedBlock* blockFor(const void*); @@ -336,7 +334,7 @@ namespace JSC { inline size_t MarkedBlock::capacity() { - return m_allocation.size(); + return allocation().size(); } inline size_t MarkedBlock::atomNumber(const void* p) diff --git a/Source/JavaScriptCore/heap/MarkedSpace.cpp b/Source/JavaScriptCore/heap/MarkedSpace.cpp index a9e9ef64d..cd6be001c 100644 --- a/Source/JavaScriptCore/heap/MarkedSpace.cpp +++ b/Source/JavaScriptCore/heap/MarkedSpace.cpp @@ -21,6 +21,7 @@ #include "config.h" #include "MarkedSpace.h" +#include "IncrementalSweeper.h" #include "JSGlobalObject.h" #include "JSLock.h" #include "JSObject.h" @@ -108,6 +109,12 @@ void MarkedSpace::lastChanceToFinalize() forEachBlock<LastChanceToFinalize>(); } +void MarkedSpace::sweep() +{ + m_heap->sweeper()->willFinishSweeping(); + forEachBlock<Sweep>(); +} + void MarkedSpace::resetAllocators() { for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { diff --git a/Source/JavaScriptCore/heap/MarkedSpace.h b/Source/JavaScriptCore/heap/MarkedSpace.h index d2a0688f1..d5dae3584 100644 --- a/Source/JavaScriptCore/heap/MarkedSpace.h +++ b/Source/JavaScriptCore/heap/MarkedSpace.h @@ -235,11 +235,6 @@ inline void MarkedSpace::clearMarks() forEachBlock<ClearMarks>(); } -inline void MarkedSpace::sweep() -{ - forEachBlock<Sweep>(); -} - inline size_t MarkedSpace::objectCount() { return forEachBlock<MarkCount>(); diff --git a/Source/JavaScriptCore/heap/WeakSetInlines.h b/Source/JavaScriptCore/heap/WeakSetInlines.h index c1c87b380..76337fda7 100644 --- a/Source/JavaScriptCore/heap/WeakSetInlines.h +++ b/Source/JavaScriptCore/heap/WeakSetInlines.h @@ -49,9 +49,6 @@ inline void WeakBlock::finalize(WeakImpl* weakImpl) WeakHandleOwner* weakHandleOwner = weakImpl->weakHandleOwner(); if (!weakHandleOwner) return; -#if !ASSERT_DISABLED || ENABLE(GC_VALIDATION) - weakImpl->jsValue().asCell()->clearStructure(); -#endif weakHandleOwner->finalize(Handle<Unknown>::wrapSlot(&const_cast<JSValue&>(weakImpl->jsValue())), weakImpl->context()); } |