MarkedAllocator.h 2.21 KB
Newer Older
mhahnenberg@apple.com's avatar
mhahnenberg@apple.com committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
#ifndef MarkedAllocator_h
#define MarkedAllocator_h

#include "MarkedBlock.h"
#include <wtf/DoublyLinkedList.h>

namespace JSC {

class Heap;
class MarkedSpace;

namespace DFG {
class SpeculativeJIT;
}

class MarkedAllocator {
    friend class JIT;
    friend class DFG::SpeculativeJIT;

public:
    MarkedAllocator();
    void reset();
    void zapFreeList();
    size_t cellSize() { return m_cellSize; }
    void* allocate();
    Heap* heap() { return m_heap; }
    
    template<typename Functor> void forEachBlock(Functor&);
    
    void addBlock(MarkedBlock*);
    void removeBlock(MarkedBlock*);
    void setHeap(Heap* heap) { m_heap = heap; }
    void setCellSize(size_t cellSize) { m_cellSize = cellSize; }
    void setMarkedSpace(MarkedSpace* space) { m_markedSpace = space; }
    
private:
    JS_EXPORT_PRIVATE void* allocateSlowCase();
    void* tryAllocate();
    void* tryAllocateHelper();
    MarkedBlock* allocateBlock(AllocationEffort);
    
    MarkedBlock::FreeCell* m_firstFreeCell;
    MarkedBlock* m_currentBlock;
    DoublyLinkedList<HeapBlock> m_blockList;
    size_t m_cellSize;
    Heap* m_heap;
    MarkedSpace* m_markedSpace;
};

inline MarkedAllocator::MarkedAllocator()
    : m_firstFreeCell(0)
    , m_currentBlock(0)
    , m_cellSize(0)
    , m_heap(0)
    , m_markedSpace(0)
{
}
    
inline void* MarkedAllocator::allocate()
{
    MarkedBlock::FreeCell* firstFreeCell = m_firstFreeCell;
    // This is a light-weight fast path to cover the most common case.
    if (UNLIKELY(!firstFreeCell))
        return allocateSlowCase();
    
    m_firstFreeCell = firstFreeCell->next;
    return firstFreeCell;
}

inline void MarkedAllocator::reset()
{
    m_currentBlock = static_cast<MarkedBlock*>(m_blockList.head());
}

inline void MarkedAllocator::zapFreeList()
{
    if (!m_currentBlock) {
        ASSERT(!m_firstFreeCell);
        return;
    }
    
    m_currentBlock->zapFreeList(m_firstFreeCell);
    m_firstFreeCell = 0;
}

template <typename Functor> inline void MarkedAllocator::forEachBlock(Functor& functor)
{
    HeapBlock* next;
    for (HeapBlock* block = m_blockList.head(); block; block = next) {
        next = block->next();
        functor(static_cast<MarkedBlock*>(block));
    }
}
    
} // namespace JSC

#endif