This includes transferring AllowZeroAllocator from iallocator.h to jit.h (as CompIAllocator)
unsigned prologSize,
unsigned epilogSize DEBUGARG(void* codePtr))
{
- IAllocator* allowZeroAlloc = new (compiler, CMK_GC) AllowZeroAllocator(compiler->getAllocatorGC());
+ IAllocator* allowZeroAlloc = new (compiler, CMK_GC) CompIAllocator(compiler->getAllocatorGC());
GcInfoEncoder* gcInfoEncoder = new (compiler, CMK_GC)
GcInfoEncoder(compiler->info.compCompHnd, compiler->info.compMethodInfo, allowZeroAlloc, NOMEM);
assert(gcInfoEncoder != nullptr);
void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize DEBUGARG(void* codePtr))
{
- IAllocator* allowZeroAlloc = new (compiler, CMK_GC) AllowZeroAllocator(compiler->getAllocatorGC());
+ IAllocator* allowZeroAlloc = new (compiler, CMK_GC) CompIAllocator(compiler->getAllocatorGC());
GcInfoEncoder* gcInfoEncoder = new (compiler, CMK_GC)
GcInfoEncoder(compiler->info.compCompHnd, compiler->info.compMethodInfo, allowZeroAlloc, NOMEM);
assert(gcInfoEncoder);
#else // !JIT32_GCENCODER
void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize DEBUGARG(void* codePtr))
{
- IAllocator* allowZeroAlloc = new (compiler, CMK_GC) AllowZeroAllocator(compiler->getAllocatorGC());
+ IAllocator* allowZeroAlloc = new (compiler, CMK_GC) CompIAllocator(compiler->getAllocatorGC());
GcInfoEncoder* gcInfoEncoder = new (compiler, CMK_GC)
GcInfoEncoder(compiler->info.compCompHnd, compiler->info.compMethodInfo, allowZeroAlloc, NOMEM);
assert(gcInfoEncoder);
{
m_inlineStrategy = nullptr;
compInlineResult = inlineInfo->inlineResult;
- compAsIAllocator = nullptr; // We shouldn't be using the compAsIAllocator for other than the root compiler.
+
+ // We shouldn't be using the compAllocatorGeneric for other than the root compiler.
+ compAllocatorGeneric = nullptr;
#if MEASURE_MEM_ALLOC
- compAsIAllocatorBitset = nullptr;
- compAsIAllocatorGC = nullptr;
- compAsIAllocatorLoopHoist = nullptr;
+ compAllocatorBitset = nullptr;
+ compAllocatorGC = nullptr;
+ compAllocatorLoopHoist = nullptr;
#ifdef DEBUG
- compAsIAllocatorDebugOnly = nullptr;
+ compAllocatorDebugOnly = nullptr;
#endif // DEBUG
#endif // MEASURE_MEM_ALLOC
{
m_inlineStrategy = new (this, CMK_Inlining) InlineStrategy(this);
compInlineResult = nullptr;
- compAsIAllocator = new (this, CMK_Unknown) CompAllocator(this, CMK_AsIAllocator);
+
+ compAllocatorGeneric = new (this, CMK_Unknown) CompAllocator(this, CMK_Generic);
#if MEASURE_MEM_ALLOC
- compAsIAllocatorBitset = new (this, CMK_Unknown) CompAllocator(this, CMK_bitset);
- compAsIAllocatorGC = new (this, CMK_Unknown) CompAllocator(this, CMK_GC);
- compAsIAllocatorLoopHoist = new (this, CMK_Unknown) CompAllocator(this, CMK_LoopHoist);
+ compAllocatorBitset = new (this, CMK_Unknown) CompAllocator(this, CMK_bitset);
+ compAllocatorGC = new (this, CMK_Unknown) CompAllocator(this, CMK_GC);
+ compAllocatorLoopHoist = new (this, CMK_Unknown) CompAllocator(this, CMK_LoopHoist);
#ifdef DEBUG
- compAsIAllocatorDebugOnly = new (this, CMK_Unknown) CompAllocator(this, CMK_DebugOnly);
+ compAllocatorDebugOnly = new (this, CMK_Unknown) CompAllocator(this, CMK_DebugOnly);
#endif // DEBUG
#endif // MEASURE_MEM_ALLOC
ArenaAllocator* compAllocator;
public:
- // This one presents an implementation of the "IAllocator" abstract class that uses "compAllocator",
- // suitable for use by utilcode collection types.
- CompAllocator* compAsIAllocator;
-
+ CompAllocator* compAllocatorGeneric; // An allocator that uses the CMK_Generic tracker.
#if MEASURE_MEM_ALLOC
- CompAllocator* compAsIAllocatorBitset; // An allocator that uses the CMK_bitset tracker.
- CompAllocator* compAsIAllocatorGC; // An allocator that uses the CMK_GC tracker.
- CompAllocator* compAsIAllocatorLoopHoist; // An allocator that uses the CMK_LoopHoist tracker.
+ CompAllocator* compAllocatorBitset; // An allocator that uses the CMK_bitset tracker.
+ CompAllocator* compAllocatorGC; // An allocator that uses the CMK_GC tracker.
+ CompAllocator* compAllocatorLoopHoist; // An allocator that uses the CMK_LoopHoist tracker.
#ifdef DEBUG
- CompAllocator* compAsIAllocatorDebugOnly; // An allocator that uses the CMK_DebugOnly tracker.
-#endif // DEBUG
-#endif // MEASURE_MEM_ALLOC
+ CompAllocator* compAllocatorDebugOnly; // An allocator that uses the CMK_DebugOnly tracker.
+#endif // DEBUG
+#endif // MEASURE_MEM_ALLOC
void compFunctionTraceStart();
void compFunctionTraceEnd(void* methodCodePtr, ULONG methodCodeSize, bool isNYI);
CompAllocator* getAllocator()
{
- return compAsIAllocator;
+ return compAllocatorGeneric;
}
#if MEASURE_MEM_ALLOC
CompAllocator* getAllocatorBitset()
{
- return compAsIAllocatorBitset;
+ return compAllocatorBitset;
}
CompAllocator* getAllocatorGC()
{
- return compAsIAllocatorGC;
+ return compAllocatorGC;
}
CompAllocator* getAllocatorLoopHoist()
{
- return compAsIAllocatorLoopHoist;
+ return compAllocatorLoopHoist;
}
#else // !MEASURE_MEM_ALLOC
CompAllocator* getAllocatorBitset()
{
- return compAsIAllocator;
+ return compAllocatorGeneric;
}
CompAllocator* getAllocatorGC()
{
- return compAsIAllocator;
+ return compAllocatorGeneric;
}
CompAllocator* getAllocatorLoopHoist()
{
- return compAsIAllocator;
+ return compAllocatorGeneric;
}
#endif // !MEASURE_MEM_ALLOC
CompAllocator* getAllocatorDebugOnly()
{
#if MEASURE_MEM_ALLOC
- return compAsIAllocatorDebugOnly;
+ return compAllocatorDebugOnly;
#else // !MEASURE_MEM_ALLOC
- return compAsIAllocator;
+ return compAllocatorGeneric;
#endif // !MEASURE_MEM_ALLOC
}
#endif // DEBUG
#include "bitset.h"
#include "compiler.h"
-#include "iallocator.h"
#include "bitsetasshortlong.h"
///////////////////////////////////////////////////////////////////////////////
CompMemKindMacro(hashBv)
CompMemKindMacro(bitset)
CompMemKindMacro(FixedBitVect)
-CompMemKindMacro(AsIAllocator)
+CompMemKindMacro(Generic)
CompMemKindMacro(IndirAssignMap)
CompMemKindMacro(FieldSeqStore)
CompMemKindMacro(ZeroOffsetFieldMap)
#pragma once
-class HostAllocator final : public IAllocator
+class HostAllocator final
{
private:
static HostAllocator s_hostAllocator;
}
public:
- void* Alloc(size_t size) override;
+ void* Alloc(size_t size);
- void* ArrayAlloc(size_t elemSize, size_t numElems) override;
+ void* ArrayAlloc(size_t elemSize, size_t numElems);
- void Free(void* p) override;
+ void Free(void* p);
static HostAllocator* getHostAllocator();
};
/*****************************************************************************/
+// CompMemKind values are used to tag memory allocations performed via
+// the compiler's allocator so that the memory usage of various compiler
+// components can be tracked separately (when MEASURE_MEM_ALLOC is defined).
+
enum CompMemKind
{
#define CompMemKindMacro(kind) CMK_##kind,
class Compiler;
-// This class implements the "IAllocator" interface, so that we can use
-// utilcode collection classes in the JIT, and have them use the JIT's allocator.
+// Allows general purpose code (e.g. collection classes) to allocate memory
+// of a pre-determined kind via the compiler's allocator.
-class CompAllocator final : public IAllocator
+class CompAllocator
{
Compiler* const m_comp;
#if MEASURE_MEM_ALLOC
{
}
- inline void* Alloc(size_t sz) override;
+ // Allocates a block of memory at least `sz` in size.
+ // Zero-length allocation are not allowed.
+ inline void* Alloc(size_t sz);
- inline void* ArrayAlloc(size_t elems, size_t elemSize) override;
+ // Allocates a block of memory at least `elems * elemSize` in size.
+ // Zero-length allocation are not allowed.
+ inline void* ArrayAlloc(size_t elems, size_t elemSize);
- // For the compiler's no-release allocator, free operations are no-ops.
- void Free(void* p) override
+ // For the compiler's ArenaAllocator, free operations are no-ops.
+ void Free(void* p)
{
}
};
return mem;
}
+// A CompAllocator wrapper that implements IAllocator and allows zero-length
+// memory allocations (the compiler's ArenAllocator does not support zero-length
+// allocation).
+
+class CompIAllocator : public IAllocator
+{
+ CompAllocator* const m_alloc;
+ char m_zeroLenAllocTarg;
+
+public:
+ CompIAllocator(CompAllocator* alloc) : m_alloc(alloc)
+ {
+ }
+
+ // Allocates a block of memory at least `sz` in size.
+ virtual void* Alloc(size_t sz) override
+ {
+ if (sz == 0)
+ {
+ return &m_zeroLenAllocTarg;
+ }
+ else
+ {
+ return m_alloc->Alloc(sz);
+ }
+ }
+
+ // Allocates a block of memory at least `elems * elemSize` in size.
+ virtual void* ArrayAlloc(size_t elemSize, size_t numElems) override
+ {
+ if ((elemSize == 0) || (numElems == 0))
+ {
+ return &m_zeroLenAllocTarg;
+ }
+ else
+ {
+ return m_alloc->ArrayAlloc(elemSize, numElems);
+ }
+ }
+
+ // Frees the block of memory pointed to by p.
+ virtual void Free(void* p) override
+ {
+ m_alloc->Free(p);
+ }
+};
+
class JitTls
{
#ifdef DEBUG
LinearScan::LinearScan(Compiler* theCompiler)
: compiler(theCompiler)
#if MEASURE_MEM_ALLOC
- , lsraIAllocator(nullptr)
+ , lsraAllocator(nullptr)
#endif // MEASURE_MEM_ALLOC
, intervals(LinearScanMemoryAllocatorInterval(theCompiler))
, refPositions(LinearScanMemoryAllocatorRefPosition(theCompiler))
private:
#if MEASURE_MEM_ALLOC
- CompAllocator* lsraIAllocator;
+ CompAllocator* lsraAllocator;
#endif
CompAllocator* getAllocator(Compiler* comp)
{
#if MEASURE_MEM_ALLOC
- if (lsraIAllocator == nullptr)
+ if (lsraAllocator == nullptr)
{
- lsraIAllocator = new (comp, CMK_LSRA) CompAllocator(comp, CMK_LSRA);
+ lsraAllocator = new (comp, CMK_LSRA) CompAllocator(comp, CMK_LSRA);
}
- return lsraIAllocator;
+ return lsraAllocator;
#else
return comp->getAllocator();
#endif
void Compiler::fgSsaBuild()
{
- CompAllocator* pIAllocator = new (this, CMK_SSA) CompAllocator(this, CMK_SSA);
-
// If this is not the first invocation, reset data structures for SSA.
if (fgSsaPassesCompleted > 0)
{
fgResetForSsa();
}
- SsaBuilder builder(this, pIAllocator);
+ SsaBuilder builder(this, new (this, CMK_SSA) CompAllocator(this, CMK_SSA));
builder.Build();
fgSsaPassesCompleted++;
#ifdef DEBUG
*
* @remarks Initializes the class and member pointers/objects that use constructors.
*/
-SsaBuilder::SsaBuilder(Compiler* pCompiler, CompAllocator* pIAllocator)
+SsaBuilder::SsaBuilder(Compiler* pCompiler, CompAllocator* pAllocator)
: m_pCompiler(pCompiler)
- , m_allocator(pIAllocator)
+ , m_allocator(pAllocator)
#ifdef SSA_FEATURE_DOMARR
, m_pDomPreOrder(NULL)
, m_pDomPostOrder(NULL)
#endif
#ifdef SSA_FEATURE_USEDEF
- , m_uses(jitstd::allocator<void>(pIAllocator))
- , m_defs(jitstd::allocator<void>(pIAllocator))
+ , m_uses(jitstd::allocator<void>(pAllocator))
+ , m_defs(jitstd::allocator<void>(pAllocator))
#endif
{
}
public:
// Constructor
- SsaBuilder(Compiler* pCompiler, CompAllocator* pIAllocator);
+ SsaBuilder(Compiler* pCompiler, CompAllocator* pAllocator);
// Requires stmt nodes to be already sequenced in evaluation order. Analyzes the graph
// for introduction of phi-nodes as GT_PHI tree nodes at the beginning of each block.