]> git.saurik.com Git - apple/javascriptcore.git/blame - heap/MarkedAllocator.cpp
JavaScriptCore-1218.tar.gz
[apple/javascriptcore.git] / heap / MarkedAllocator.cpp
CommitLineData
6fe7ccc8
A
1#include "config.h"
2#include "MarkedAllocator.h"
3
4#include "GCActivityCallback.h"
5#include "Heap.h"
93a37866
A
6#include "IncrementalSweeper.h"
7#include "VM.h"
6fe7ccc8
A
8#include <wtf/CurrentTime.h>
9
10namespace JSC {
11
12bool MarkedAllocator::isPagedOut(double deadline)
13{
14 unsigned itersSinceLastTimeCheck = 0;
93a37866 15 MarkedBlock* block = m_blockList.head();
6fe7ccc8
A
16 while (block) {
17 block = block->next();
18 ++itersSinceLastTimeCheck;
19 if (itersSinceLastTimeCheck >= Heap::s_timeCheckResolution) {
20 double currentTime = WTF::monotonicallyIncreasingTime();
21 if (currentTime > deadline)
22 return true;
23 itersSinceLastTimeCheck = 0;
24 }
25 }
26
27 return false;
28}
29
93a37866 30inline void* MarkedAllocator::tryAllocateHelper(size_t bytes)
6fe7ccc8
A
31{
32 if (!m_freeList.head) {
93a37866
A
33 for (MarkedBlock*& block = m_blocksToSweep; block; block = block->next()) {
34 MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList);
35 if (!freeList.head) {
36 block->didConsumeFreeList();
37 continue;
38 }
39
40 if (bytes > block->cellSize()) {
41 block->canonicalizeCellLivenessData(freeList);
42 continue;
43 }
44
45 m_currentBlock = block;
46 m_freeList = freeList;
47 break;
6fe7ccc8
A
48 }
49
93a37866
A
50 if (!m_freeList.head) {
51 m_currentBlock = 0;
6fe7ccc8 52 return 0;
93a37866 53 }
6fe7ccc8
A
54 }
55
56 MarkedBlock::FreeCell* head = m_freeList.head;
57 m_freeList.head = head->next;
58 ASSERT(head);
59 return head;
60}
61
93a37866 62inline void* MarkedAllocator::tryAllocate(size_t bytes)
6fe7ccc8
A
63{
64 ASSERT(!m_heap->isBusy());
65 m_heap->m_operationInProgress = Allocation;
93a37866 66 void* result = tryAllocateHelper(bytes);
6fe7ccc8
A
67 m_heap->m_operationInProgress = NoOperation;
68 return result;
69}
70
93a37866 71void* MarkedAllocator::allocateSlowCase(size_t bytes)
6fe7ccc8 72{
93a37866 73 ASSERT(m_heap->vm()->apiLock().currentThreadIsHoldingLock());
6fe7ccc8
A
74#if COLLECT_ON_EVERY_ALLOCATION
75 m_heap->collectAllGarbage();
76 ASSERT(m_heap->m_operationInProgress == NoOperation);
77#endif
78
79 ASSERT(!m_freeList.head);
80 m_heap->didAllocate(m_freeList.bytes);
81
93a37866 82 void* result = tryAllocate(bytes);
6fe7ccc8
A
83
84 if (LIKELY(result != 0))
85 return result;
86
87 if (m_heap->shouldCollect()) {
88 m_heap->collect(Heap::DoNotSweep);
89
93a37866 90 result = tryAllocate(bytes);
6fe7ccc8
A
91 if (result)
92 return result;
93 }
94
95 ASSERT(!m_heap->shouldCollect());
96
93a37866 97 MarkedBlock* block = allocateBlock(bytes);
6fe7ccc8
A
98 ASSERT(block);
99 addBlock(block);
100
93a37866 101 result = tryAllocate(bytes);
6fe7ccc8
A
102 ASSERT(result);
103 return result;
104}
93a37866
A
105
106MarkedBlock* MarkedAllocator::allocateBlock(size_t bytes)
6fe7ccc8 107{
93a37866
A
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);
111
112 size_t cellSize = m_cellSize ? m_cellSize : WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes);
113
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);
6fe7ccc8
A
117}
118
119void MarkedAllocator::addBlock(MarkedBlock* block)
120{
121 ASSERT(!m_currentBlock);
122 ASSERT(!m_freeList.head);
123
124 m_blockList.append(block);
93a37866 125 m_blocksToSweep = m_currentBlock = block;
6fe7ccc8 126 m_freeList = block->sweep(MarkedBlock::SweepToFreeList);
93a37866 127 m_markedSpace->didAddBlock(block);
6fe7ccc8
A
128}
129
130void MarkedAllocator::removeBlock(MarkedBlock* block)
131{
93a37866
A
132 if (m_currentBlock == block) {
133 m_currentBlock = m_currentBlock->next();
134 m_freeList = MarkedBlock::FreeList();
135 }
136 if (m_blocksToSweep == block)
137 m_blocksToSweep = m_blocksToSweep->next();
6fe7ccc8
A
138 m_blockList.remove(block);
139}
140
141} // namespace JSC