]> git.saurik.com Git - apple/javascriptcore.git/blob - heap/MarkedAllocator.h
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / 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 class LLIntOffsetsExtractor;
12
13 namespace DFG {
14 class SpeculativeJIT;
15 }
16
17 class MarkedAllocator {
18 friend class LLIntOffsetsExtractor;
19
20 public:
21 static ptrdiff_t offsetOfFreeListHead();
22
23 MarkedAllocator();
24 void reset();
25 void canonicalizeCellLivenessData();
26 size_t cellSize() { return m_cellSize; }
27 MarkedBlock::DestructorType destructorType() { return m_destructorType; }
28 void* allocate(size_t);
29 Heap* heap() { return m_heap; }
30
31 template<typename Functor> void forEachBlock(Functor&);
32
33 void addBlock(MarkedBlock*);
34 void removeBlock(MarkedBlock*);
35 void init(Heap*, MarkedSpace*, size_t cellSize, MarkedBlock::DestructorType);
36
37 bool isPagedOut(double deadline);
38
39 private:
40 JS_EXPORT_PRIVATE void* allocateSlowCase(size_t);
41 void* tryAllocate(size_t);
42 void* tryAllocateHelper(size_t);
43 MarkedBlock* allocateBlock(size_t);
44
45 MarkedBlock::FreeList m_freeList;
46 MarkedBlock* m_currentBlock;
47 MarkedBlock* m_blocksToSweep;
48 DoublyLinkedList<MarkedBlock> m_blockList;
49 size_t m_cellSize;
50 MarkedBlock::DestructorType m_destructorType;
51 Heap* m_heap;
52 MarkedSpace* m_markedSpace;
53 };
54
55 inline ptrdiff_t MarkedAllocator::offsetOfFreeListHead()
56 {
57 return OBJECT_OFFSETOF(MarkedAllocator, m_freeList) + OBJECT_OFFSETOF(MarkedBlock::FreeList, head);
58 }
59
60 inline MarkedAllocator::MarkedAllocator()
61 : m_currentBlock(0)
62 , m_blocksToSweep(0)
63 , m_cellSize(0)
64 , m_destructorType(MarkedBlock::None)
65 , m_heap(0)
66 , m_markedSpace(0)
67 {
68 }
69
70 inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, MarkedBlock::DestructorType destructorType)
71 {
72 m_heap = heap;
73 m_markedSpace = markedSpace;
74 m_cellSize = cellSize;
75 m_destructorType = destructorType;
76 }
77
78 inline void* MarkedAllocator::allocate(size_t bytes)
79 {
80 MarkedBlock::FreeCell* head = m_freeList.head;
81 if (UNLIKELY(!head)) {
82 void* result = allocateSlowCase(bytes);
83 #ifndef NDEBUG
84 memset(result, 0xCD, bytes);
85 #endif
86 return result;
87 }
88
89 m_freeList.head = head->next;
90 #ifndef NDEBUG
91 memset(head, 0xCD, bytes);
92 #endif
93 return head;
94 }
95
96 inline void MarkedAllocator::reset()
97 {
98 m_currentBlock = 0;
99 m_freeList = MarkedBlock::FreeList();
100 m_blocksToSweep = m_blockList.head();
101 }
102
103 inline void MarkedAllocator::canonicalizeCellLivenessData()
104 {
105 if (!m_currentBlock) {
106 ASSERT(!m_freeList.head);
107 return;
108 }
109
110 m_currentBlock->canonicalizeCellLivenessData(m_freeList);
111 m_currentBlock = 0;
112 m_freeList = MarkedBlock::FreeList();
113 }
114
115 template <typename Functor> inline void MarkedAllocator::forEachBlock(Functor& functor)
116 {
117 MarkedBlock* next;
118 for (MarkedBlock* block = m_blockList.head(); block; block = next) {
119 next = block->next();
120 functor(block);
121 }
122 }
123
124 } // namespace JSC
125
126 #endif