#pragma once
#include "BMalloced.h"
#include "IsoDirectoryPage.h"
#include "IsoTLSAllocatorEntry.h"
#include "PhysicalPageMap.h"
namespace bmalloc {
class AllIsoHeaps;
class BEXPORT IsoHeapImplBase {
MAKE_BMALLOCED;
public:
virtual ~IsoHeapImplBase();
virtual void scavenge(Vector<DeferredDecommit>&) = 0;
virtual void scavengeToHighWatermark(Vector<DeferredDecommit>&) = 0;
virtual size_t freeableMemory() = 0;
virtual size_t footprint() = 0;
void scavengeNow();
static void finishScavenging(Vector<DeferredDecommit>&);
protected:
IsoHeapImplBase();
void addToAllIsoHeaps();
private:
friend class AllIsoHeaps;
IsoHeapImplBase* m_next { nullptr };
};
template<typename Config>
class IsoHeapImpl final : public IsoHeapImplBase {
static constexpr unsigned numPagesInInlineDirectory = 32;
public:
IsoHeapImpl();
EligibilityResult<Config> takeFirstEligible();
void didBecomeEligible(IsoDirectory<Config, numPagesInInlineDirectory>*);
void didBecomeEligible(IsoDirectory<Config, IsoDirectoryPage<Config>::numPages>*);
void scavenge(Vector<DeferredDecommit>&) override;
void scavengeToHighWatermark(Vector<DeferredDecommit>&) override;
size_t freeableMemory() override;
size_t footprint() override;
unsigned allocatorOffset();
unsigned deallocatorOffset();
unsigned numLiveObjects();
unsigned numCommittedPages();
template<typename Func>
void forEachDirectory(const Func&);
template<typename Func>
void forEachCommittedPage(const Func&);
template<typename Func>
void forEachLiveObject(const Func&);
void didCommit(void* ptr, size_t bytes);
void didDecommit(void* ptr, size_t bytes);
void isNowFreeable(void* ptr, size_t bytes);
void isNoLongerFreeable(void* ptr, size_t bytes);
Mutex& lock;
private:
IsoDirectory<Config, numPagesInInlineDirectory> m_inlineDirectory;
IsoDirectoryPage<Config>* m_headDirectory { nullptr };
IsoDirectoryPage<Config>* m_tailDirectory { nullptr };
size_t m_footprint { 0 };
size_t m_freeableMemory { 0 };
#if ENABLE_PHYSICAL_PAGE_MAP
PhysicalPageMap m_physicalPageMap;
#endif
unsigned m_nextDirectoryPageIndex { 1 }; unsigned m_directoryHighWatermark { 0 };
bool m_isInlineDirectoryEligible { true };
IsoDirectoryPage<Config>* m_firstEligibleDirectory { nullptr };
IsoTLSAllocatorEntry<Config> m_allocator;
};
}