1 #ifndef MarkedAllocator_h
2 #define MarkedAllocator_h
4 #include "MarkedBlock.h"
5 #include <wtf/DoublyLinkedList.h>
11 class LLIntOffsetsExtractor
;
17 class MarkedAllocator
{
18 friend class LLIntOffsetsExtractor
;
21 static ptrdiff_t offsetOfFreeListHead();
24 void lastChanceToFinalize();
26 void stopAllocating();
27 void resumeAllocating();
28 size_t cellSize() { return m_cellSize
; }
29 MarkedBlock::DestructorType
destructorType() { return m_destructorType
; }
30 void* allocate(size_t);
31 Heap
* heap() { return m_heap
; }
32 MarkedBlock
* takeLastActiveBlock()
34 MarkedBlock
* block
= m_lastActiveBlock
;
35 m_lastActiveBlock
= 0;
39 template<typename Functor
> void forEachBlock(Functor
&);
41 void addBlock(MarkedBlock
*);
42 void removeBlock(MarkedBlock
*);
43 void init(Heap
*, MarkedSpace
*, size_t cellSize
, MarkedBlock::DestructorType
);
45 bool isPagedOut(double deadline
);
48 JS_EXPORT_PRIVATE
void* allocateSlowCase(size_t);
49 void* tryAllocate(size_t);
50 void* tryAllocateHelper(size_t);
51 void* tryPopFreeList(size_t);
52 MarkedBlock
* allocateBlock(size_t);
53 ALWAYS_INLINE
void doTestCollectionsIfNeeded();
55 MarkedBlock::FreeList m_freeList
;
56 MarkedBlock
* m_currentBlock
;
57 MarkedBlock
* m_lastActiveBlock
;
58 MarkedBlock
* m_nextBlockToSweep
;
59 DoublyLinkedList
<MarkedBlock
> m_blockList
;
60 DoublyLinkedList
<MarkedBlock
> m_retiredBlocks
;
62 MarkedBlock::DestructorType m_destructorType
;
64 MarkedSpace
* m_markedSpace
;
67 inline ptrdiff_t MarkedAllocator::offsetOfFreeListHead()
69 return OBJECT_OFFSETOF(MarkedAllocator
, m_freeList
) + OBJECT_OFFSETOF(MarkedBlock::FreeList
, head
);
72 inline MarkedAllocator::MarkedAllocator()
74 , m_lastActiveBlock(0)
75 , m_nextBlockToSweep(0)
77 , m_destructorType(MarkedBlock::None
)
83 inline void MarkedAllocator::init(Heap
* heap
, MarkedSpace
* markedSpace
, size_t cellSize
, MarkedBlock::DestructorType destructorType
)
86 m_markedSpace
= markedSpace
;
87 m_cellSize
= cellSize
;
88 m_destructorType
= destructorType
;
91 inline void* MarkedAllocator::allocate(size_t bytes
)
93 MarkedBlock::FreeCell
* head
= m_freeList
.head
;
94 if (UNLIKELY(!head
)) {
95 void* result
= allocateSlowCase(bytes
);
97 memset(result
, 0xCD, bytes
);
102 m_freeList
.head
= head
->next
;
104 memset(head
, 0xCD, bytes
);
109 inline void MarkedAllocator::stopAllocating()
111 ASSERT(!m_lastActiveBlock
);
112 if (!m_currentBlock
) {
113 ASSERT(!m_freeList
.head
);
117 m_currentBlock
->stopAllocating(m_freeList
);
118 m_lastActiveBlock
= m_currentBlock
;
120 m_freeList
= MarkedBlock::FreeList();
123 inline void MarkedAllocator::resumeAllocating()
125 if (!m_lastActiveBlock
)
128 m_freeList
= m_lastActiveBlock
->resumeAllocating();
129 m_currentBlock
= m_lastActiveBlock
;
130 m_lastActiveBlock
= 0;
133 template <typename Functor
> inline void MarkedAllocator::forEachBlock(Functor
& functor
)
136 for (MarkedBlock
* block
= m_blockList
.head(); block
; block
= next
) {
137 next
= block
->next();
141 for (MarkedBlock
* block
= m_retiredBlocks
.head(); block
; block
= next
) {
142 next
= block
->next();