#pragma once
#include "FreeList.h"
#include "MarkedBlock.h"
#include <wtf/Noncopyable.h>
namespace JSC {
class BlockDirectory;
class GCDeferralContext;
class ThreadLocalCache;
class LocalAllocator : public BasicRawSentinelNode<LocalAllocator> {
WTF_MAKE_NONCOPYABLE(LocalAllocator);
public:
LocalAllocator(ThreadLocalCache*, BlockDirectory*);
LocalAllocator(LocalAllocator&&);
~LocalAllocator();
void* allocate(GCDeferralContext*, AllocationFailureMode);
void stopAllocating();
void prepareForAllocation();
void resumeAllocating();
void stopAllocatingForGood();
static ptrdiff_t offsetOfFreeList();
static ptrdiff_t offsetOfCellSize();
bool isFreeListedCell(const void*) const;
ThreadLocalCache* tlc() const { return m_tlc; }
private:
friend class BlockDirectory;
void reset();
JS_EXPORT_PRIVATE void* allocateSlowCase(GCDeferralContext*, AllocationFailureMode failureMode);
void didConsumeFreeList();
void* tryAllocateWithoutCollecting();
void* tryAllocateIn(MarkedBlock::Handle*);
void* allocateIn(MarkedBlock::Handle*);
ALWAYS_INLINE void doTestCollectionsIfNeeded(GCDeferralContext*);
ThreadLocalCache* m_tlc;
BlockDirectory* m_directory;
unsigned m_cellSize;
FreeList m_freeList;
MarkedBlock::Handle* m_currentBlock { nullptr };
MarkedBlock::Handle* m_lastActiveBlock { nullptr };
size_t m_allocationCursor { 0 }; };
inline ptrdiff_t LocalAllocator::offsetOfFreeList()
{
return OBJECT_OFFSETOF(LocalAllocator, m_freeList);
}
inline ptrdiff_t LocalAllocator::offsetOfCellSize()
{
return OBJECT_OFFSETOF(LocalAllocator, m_cellSize);
}
}