Roll out r108309, r108323, and r108326
[WebKit-https.git] / Source / JavaScriptCore / heap / MarkedAllocator.h
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
12 namespace DFG {
13 class SpeculativeJIT;
14 }
15
16 class MarkedAllocator {
17     friend class JIT;
18     friend class DFG::SpeculativeJIT;
19
20 public:
21     MarkedAllocator();
22     void reset();
23     void zapFreeList();
24     size_t cellSize() { return m_cellSize; }
25     bool cellsNeedDestruction() { return m_cellsNeedDestruction; }
26     void* allocate();
27     Heap* heap() { return m_heap; }
28     
29     template<typename Functor> void forEachBlock(Functor&);
30     
31     void addBlock(MarkedBlock*);
32     void removeBlock(MarkedBlock*);
33     void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction);
34     
35 private:
36     JS_EXPORT_PRIVATE void* allocateSlowCase();
37     void* tryAllocate();
38     void* tryAllocateHelper();
39     MarkedBlock* allocateBlock(AllocationEffort);
40     
41     MarkedBlock::FreeCell* m_firstFreeCell;
42     MarkedBlock* m_currentBlock;
43     DoublyLinkedList<HeapBlock> m_blockList;
44     size_t m_cellSize;
45     bool m_cellsNeedDestruction;
46     Heap* m_heap;
47     MarkedSpace* m_markedSpace;
48 };
49
50 inline MarkedAllocator::MarkedAllocator()
51     : m_firstFreeCell(0)
52     , m_currentBlock(0)
53     , m_cellSize(0)
54     , m_cellsNeedDestruction(true)
55     , m_heap(0)
56     , m_markedSpace(0)
57 {
58 }
59
60 inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction)
61 {
62     m_heap = heap;
63     m_markedSpace = markedSpace;
64     m_cellSize = cellSize;
65     m_cellsNeedDestruction = cellsNeedDestruction;
66 }
67
68 inline void* MarkedAllocator::allocate()
69 {
70     MarkedBlock::FreeCell* firstFreeCell = m_firstFreeCell;
71     // This is a light-weight fast path to cover the most common case.
72     if (UNLIKELY(!firstFreeCell))
73         return allocateSlowCase();
74     
75     m_firstFreeCell = firstFreeCell->next;
76     return firstFreeCell;
77 }
78
79 inline void MarkedAllocator::reset()
80 {
81     m_currentBlock = static_cast<MarkedBlock*>(m_blockList.head());
82 }
83
84 inline void MarkedAllocator::zapFreeList()
85 {
86     if (!m_currentBlock) {
87         ASSERT(!m_firstFreeCell);
88         return;
89     }
90     
91     m_currentBlock->zapFreeList(m_firstFreeCell);
92     m_firstFreeCell = 0;
93 }
94
95 template <typename Functor> inline void MarkedAllocator::forEachBlock(Functor& functor)
96 {
97     HeapBlock* next;
98     for (HeapBlock* block = m_blockList.head(); block; block = next) {
99         next = block->next();
100         functor(static_cast<MarkedBlock*>(block));
101     }
102 }
103     
104 } // namespace JSC
105
106 #endif