]> git.saurik.com Git - apple/javascriptcore.git/blob - heap/MarkedAllocator.cpp
JavaScriptCore-1097.13.tar.gz
[apple/javascriptcore.git] / heap / MarkedAllocator.cpp
1 #include "config.h"
2 #include "MarkedAllocator.h"
3
4 #include "GCActivityCallback.h"
5 #include "Heap.h"
6 #include "JSGlobalData.h"
7 #include <wtf/CurrentTime.h>
8
9 namespace JSC {
10
11 bool MarkedAllocator::isPagedOut(double deadline)
12 {
13 unsigned itersSinceLastTimeCheck = 0;
14 HeapBlock* block = m_blockList.head();
15 while (block) {
16 block = block->next();
17 ++itersSinceLastTimeCheck;
18 if (itersSinceLastTimeCheck >= Heap::s_timeCheckResolution) {
19 double currentTime = WTF::monotonicallyIncreasingTime();
20 if (currentTime > deadline)
21 return true;
22 itersSinceLastTimeCheck = 0;
23 }
24 }
25
26 return false;
27 }
28
29 inline void* MarkedAllocator::tryAllocateHelper()
30 {
31 if (!m_freeList.head) {
32 for (MarkedBlock*& block = m_currentBlock; block; block = static_cast<MarkedBlock*>(block->next())) {
33 m_freeList = block->sweep(MarkedBlock::SweepToFreeList);
34 if (m_freeList.head)
35 break;
36 block->didConsumeFreeList();
37 }
38
39 if (!m_freeList.head)
40 return 0;
41 }
42
43 MarkedBlock::FreeCell* head = m_freeList.head;
44 m_freeList.head = head->next;
45 ASSERT(head);
46 return head;
47 }
48
49 inline void* MarkedAllocator::tryAllocate()
50 {
51 ASSERT(!m_heap->isBusy());
52 m_heap->m_operationInProgress = Allocation;
53 void* result = tryAllocateHelper();
54 m_heap->m_operationInProgress = NoOperation;
55 return result;
56 }
57
58 void* MarkedAllocator::allocateSlowCase()
59 {
60 ASSERT(m_heap->globalData()->apiLock().currentThreadIsHoldingLock());
61 #if COLLECT_ON_EVERY_ALLOCATION
62 m_heap->collectAllGarbage();
63 ASSERT(m_heap->m_operationInProgress == NoOperation);
64 #endif
65
66 ASSERT(!m_freeList.head);
67 m_heap->didAllocate(m_freeList.bytes);
68
69 void* result = tryAllocate();
70
71 if (LIKELY(result != 0))
72 return result;
73
74 if (m_heap->shouldCollect()) {
75 m_heap->collect(Heap::DoNotSweep);
76
77 result = tryAllocate();
78 if (result)
79 return result;
80 }
81
82 ASSERT(!m_heap->shouldCollect());
83
84 MarkedBlock* block = allocateBlock();
85 ASSERT(block);
86 addBlock(block);
87
88 result = tryAllocate();
89 ASSERT(result);
90 return result;
91 }
92
93 MarkedBlock* MarkedAllocator::allocateBlock()
94 {
95 MarkedBlock* block = static_cast<MarkedBlock*>(m_heap->blockAllocator().allocate());
96 if (block)
97 block = MarkedBlock::recycle(block, m_heap, m_cellSize, m_cellsNeedDestruction);
98 else
99 block = MarkedBlock::create(m_heap, m_cellSize, m_cellsNeedDestruction);
100
101 m_markedSpace->didAddBlock(block);
102
103 return block;
104 }
105
106 void MarkedAllocator::addBlock(MarkedBlock* block)
107 {
108 ASSERT(!m_currentBlock);
109 ASSERT(!m_freeList.head);
110
111 m_blockList.append(block);
112 m_currentBlock = block;
113 m_freeList = block->sweep(MarkedBlock::SweepToFreeList);
114 }
115
116 void MarkedAllocator::removeBlock(MarkedBlock* block)
117 {
118 if (m_currentBlock == block)
119 m_currentBlock = 0;
120 m_blockList.remove(block);
121 }
122
123 } // namespace JSC