]>
git.saurik.com Git - apple/javascriptcore.git/blob - heap/MarkedAllocator.cpp
2 #include "MarkedAllocator.h"
4 #include "GCActivityCallback.h"
6 #include "IncrementalSweeper.h"
8 #include <wtf/CurrentTime.h>
12 bool MarkedAllocator::isPagedOut(double deadline
)
14 unsigned itersSinceLastTimeCheck
= 0;
15 MarkedBlock
* block
= m_blockList
.head();
17 block
= block
->next();
18 ++itersSinceLastTimeCheck
;
19 if (itersSinceLastTimeCheck
>= Heap::s_timeCheckResolution
) {
20 double currentTime
= WTF::monotonicallyIncreasingTime();
21 if (currentTime
> deadline
)
23 itersSinceLastTimeCheck
= 0;
30 inline void* MarkedAllocator::tryAllocateHelper(size_t bytes
)
32 if (!m_freeList
.head
) {
33 for (MarkedBlock
*& block
= m_blocksToSweep
; block
; block
= block
->next()) {
34 MarkedBlock::FreeList freeList
= block
->sweep(MarkedBlock::SweepToFreeList
);
36 block
->didConsumeFreeList();
40 if (bytes
> block
->cellSize()) {
41 block
->canonicalizeCellLivenessData(freeList
);
45 m_currentBlock
= block
;
46 m_freeList
= freeList
;
50 if (!m_freeList
.head
) {
56 MarkedBlock::FreeCell
* head
= m_freeList
.head
;
57 m_freeList
.head
= head
->next
;
62 inline void* MarkedAllocator::tryAllocate(size_t bytes
)
64 ASSERT(!m_heap
->isBusy());
65 m_heap
->m_operationInProgress
= Allocation
;
66 void* result
= tryAllocateHelper(bytes
);
67 m_heap
->m_operationInProgress
= NoOperation
;
71 void* MarkedAllocator::allocateSlowCase(size_t bytes
)
73 ASSERT(m_heap
->vm()->apiLock().currentThreadIsHoldingLock());
74 #if COLLECT_ON_EVERY_ALLOCATION
75 m_heap
->collectAllGarbage();
76 ASSERT(m_heap
->m_operationInProgress
== NoOperation
);
79 ASSERT(!m_freeList
.head
);
80 m_heap
->didAllocate(m_freeList
.bytes
);
82 void* result
= tryAllocate(bytes
);
84 if (LIKELY(result
!= 0))
87 if (m_heap
->shouldCollect()) {
88 m_heap
->collect(Heap::DoNotSweep
);
90 result
= tryAllocate(bytes
);
95 ASSERT(!m_heap
->shouldCollect());
97 MarkedBlock
* block
= allocateBlock(bytes
);
101 result
= tryAllocate(bytes
);
106 MarkedBlock
* MarkedAllocator::allocateBlock(size_t bytes
)
108 size_t minBlockSize
= MarkedBlock::blockSize
;
109 size_t minAllocationSize
= WTF::roundUpToMultipleOf(WTF::pageSize(), sizeof(MarkedBlock
) + bytes
);
110 size_t blockSize
= std::max(minBlockSize
, minAllocationSize
);
112 size_t cellSize
= m_cellSize
? m_cellSize
: WTF::roundUpToMultipleOf
<MarkedBlock::atomSize
>(bytes
);
114 if (blockSize
== MarkedBlock::blockSize
)
115 return MarkedBlock::create(m_heap
->blockAllocator().allocate
<MarkedBlock
>(), this, cellSize
, m_destructorType
);
116 return MarkedBlock::create(m_heap
->blockAllocator().allocateCustomSize(blockSize
, MarkedBlock::blockSize
), this, cellSize
, m_destructorType
);
119 void MarkedAllocator::addBlock(MarkedBlock
* block
)
121 ASSERT(!m_currentBlock
);
122 ASSERT(!m_freeList
.head
);
124 m_blockList
.append(block
);
125 m_blocksToSweep
= m_currentBlock
= block
;
126 m_freeList
= block
->sweep(MarkedBlock::SweepToFreeList
);
127 m_markedSpace
->didAddBlock(block
);
130 void MarkedAllocator::removeBlock(MarkedBlock
* block
)
132 if (m_currentBlock
== block
) {
133 m_currentBlock
= m_currentBlock
->next();
134 m_freeList
= MarkedBlock::FreeList();
136 if (m_blocksToSweep
== block
)
137 m_blocksToSweep
= m_blocksToSweep
->next();
138 m_blockList
.remove(block
);