]>
Commit | Line | Data |
---|---|---|
6fe7ccc8 A |
1 | #ifndef MarkedAllocator_h |
2 | #define MarkedAllocator_h | |
3 | ||
4 | #include "MarkedBlock.h" | |
5 | #include <wtf/DoublyLinkedList.h> | |
6 | ||
7 | namespace JSC { | |
8 | ||
9 | class Heap; | |
10 | class MarkedSpace; | |
11 | class LLIntOffsetsExtractor; | |
12 | ||
13 | namespace DFG { | |
14 | class SpeculativeJIT; | |
15 | } | |
16 | ||
17 | class MarkedAllocator { | |
18 | friend class JIT; | |
19 | friend class DFG::SpeculativeJIT; | |
20 | ||
21 | public: | |
22 | MarkedAllocator(); | |
23 | void reset(); | |
24 | void zapFreeList(); | |
25 | size_t cellSize() { return m_cellSize; } | |
26 | bool cellsNeedDestruction() { return m_cellsNeedDestruction; } | |
27 | void* allocate(); | |
28 | Heap* heap() { return m_heap; } | |
29 | ||
30 | template<typename Functor> void forEachBlock(Functor&); | |
31 | ||
32 | void addBlock(MarkedBlock*); | |
33 | void removeBlock(MarkedBlock*); | |
34 | void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction); | |
35 | ||
36 | bool isPagedOut(double deadline); | |
37 | ||
38 | private: | |
39 | friend class LLIntOffsetsExtractor; | |
40 | ||
41 | JS_EXPORT_PRIVATE void* allocateSlowCase(); | |
42 | void* tryAllocate(); | |
43 | void* tryAllocateHelper(); | |
44 | MarkedBlock* allocateBlock(); | |
45 | ||
46 | MarkedBlock::FreeList m_freeList; | |
47 | MarkedBlock* m_currentBlock; | |
48 | DoublyLinkedList<HeapBlock> m_blockList; | |
49 | size_t m_cellSize; | |
50 | bool m_cellsNeedDestruction; | |
51 | Heap* m_heap; | |
52 | MarkedSpace* m_markedSpace; | |
53 | }; | |
54 | ||
55 | inline MarkedAllocator::MarkedAllocator() | |
56 | : m_currentBlock(0) | |
57 | , m_cellSize(0) | |
58 | , m_cellsNeedDestruction(true) | |
59 | , m_heap(0) | |
60 | , m_markedSpace(0) | |
61 | { | |
62 | } | |
63 | ||
64 | inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction) | |
65 | { | |
66 | m_heap = heap; | |
67 | m_markedSpace = markedSpace; | |
68 | m_cellSize = cellSize; | |
69 | m_cellsNeedDestruction = cellsNeedDestruction; | |
70 | } | |
71 | ||
72 | inline void* MarkedAllocator::allocate() | |
73 | { | |
74 | MarkedBlock::FreeCell* head = m_freeList.head; | |
75 | // This is a light-weight fast path to cover the most common case. | |
76 | if (UNLIKELY(!head)) | |
77 | return allocateSlowCase(); | |
78 | ||
79 | m_freeList.head = head->next; | |
80 | return head; | |
81 | } | |
82 | ||
83 | inline void MarkedAllocator::reset() | |
84 | { | |
85 | m_currentBlock = static_cast<MarkedBlock*>(m_blockList.head()); | |
86 | } | |
87 | ||
88 | inline void MarkedAllocator::zapFreeList() | |
89 | { | |
90 | if (!m_currentBlock) { | |
91 | ASSERT(!m_freeList.head); | |
92 | return; | |
93 | } | |
94 | ||
95 | m_currentBlock->zapFreeList(m_freeList); | |
96 | m_freeList = MarkedBlock::FreeList(); | |
97 | } | |
98 | ||
99 | template <typename Functor> inline void MarkedAllocator::forEachBlock(Functor& functor) | |
100 | { | |
101 | HeapBlock* next; | |
102 | for (HeapBlock* block = m_blockList.head(); block; block = next) { | |
103 | next = block->next(); | |
104 | functor(static_cast<MarkedBlock*>(block)); | |
105 | } | |
106 | } | |
107 | ||
108 | } // namespace JSC | |
109 | ||
110 | #endif |