1#ifndef MarkedAllocator_h 2#define MarkedAllocator_h 3 4#include "MarkedBlock.h" 5#include <wtf/DoublyLinkedList.h> 6 7namespace JSC { 8 9class Heap; 10class MarkedSpace; 11class LLIntOffsetsExtractor; 12 13namespace DFG { 14class SpeculativeJIT; 15} 16 17class MarkedAllocator { 18 friend class LLIntOffsetsExtractor; 19 20public: 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 39private: 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 55inline ptrdiff_t MarkedAllocator::offsetOfFreeListHead() 56{ 57 return OBJECT_OFFSETOF(MarkedAllocator, m_freeList) + OBJECT_OFFSETOF(MarkedBlock::FreeList, head); 58} 59 60inline 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 70inline 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 78inline 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 96inline void MarkedAllocator::reset() 97{ 98 m_currentBlock = 0; 99 m_freeList = MarkedBlock::FreeList(); 100 m_blocksToSweep = m_blockList.head(); 101} 102 103inline 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 115template <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 127