summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/heap')
-rw-r--r--Source/JavaScriptCore/heap/BlockAllocator.cpp8
-rw-r--r--Source/JavaScriptCore/heap/BlockAllocator.h27
-rw-r--r--Source/JavaScriptCore/heap/CopiedBlock.h18
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpace.cpp30
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpace.h13
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h4
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp14
-rw-r--r--Source/JavaScriptCore/heap/Heap.h2
-rw-r--r--Source/JavaScriptCore/heap/HeapBlock.h34
-rw-r--r--Source/JavaScriptCore/heap/IncrementalSweeper.cpp58
-rw-r--r--Source/JavaScriptCore/heap/IncrementalSweeper.h19
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.cpp8
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.cpp21
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.h11
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.cpp18
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.h6
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.cpp7
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.h5
-rw-r--r--Source/JavaScriptCore/heap/WeakSetInlines.h3
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());
}