summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/core/slang-memory-arena.cpp10
-rw-r--r--source/core/slang-memory-arena.h106
-rw-r--r--source/core/slang-string.h177
-rw-r--r--source/core/smart-pointer.h19
-rw-r--r--source/slang/emit.cpp16
-rw-r--r--source/slang/ir-insts.h47
-rw-r--r--source/slang/ir-legalize-types.cpp2
-rw-r--r--source/slang/ir.cpp23
-rw-r--r--source/slang/ir.h73
-rw-r--r--source/slang/lower-to-ir.cpp14
-rw-r--r--source/slang/memory_pool.cpp52
-rw-r--r--source/slang/memory_pool.h19
-rw-r--r--source/slang/slang.vcxproj2
-rw-r--r--source/slang/slang.vcxproj.filters8
14 files changed, 288 insertions, 280 deletions
diff --git a/source/core/slang-memory-arena.cpp b/source/core/slang-memory-arena.cpp
index 4d8b2ed2a..a0a89155c 100644
--- a/source/core/slang-memory-arena.cpp
+++ b/source/core/slang-memory-arena.cpp
@@ -222,6 +222,16 @@ MemoryArena::Block* MemoryArena::_newBlock(size_t allocSize, size_t alignment)
return block;
}
+void* MemoryArena::_allocateAlignedFromNewBlockAndZero(size_t sizeInBytes, size_t alignment)
+{
+ void* mem = _allocateAlignedFromNewBlock(sizeInBytes, alignment);
+ if (mem)
+ {
+ ::memset(mem, 0, sizeInBytes);
+ }
+ return mem;
+}
+
void* MemoryArena::_allocateAlignedFromNewBlock(size_t size, size_t alignment)
{
// Make sure init has been called (or has been set up in parameterized constructor)
diff --git a/source/core/slang-memory-arena.h b/source/core/slang-memory-arena.h
index 1c59ee7d7..54b380b32 100644
--- a/source/core/slang-memory-arena.h
+++ b/source/core/slang-memory-arena.h
@@ -46,7 +46,7 @@ public:
typedef MemoryArena ThisType;
/** The minimum alignment of the backing memory allocator.
- NOTE! That this should not be greater than the alignment of the underlying allocator.
+ NOTE! That this should not be greater than the alignment of the underlying allocator, and should never be less than sizeof(void*).
*/
static const size_t kMinAlignment = sizeof(void*);
/** Determines if an allocation is consistent with an allocation from this arena.
@@ -60,7 +60,7 @@ public:
/** Initialize the arena with specified block size and alignment
If the arena has been previously initialized will free and deallocate all memory */
- void init(size_t blockSize, size_t blockAlignment = kMinAlignment);
+ void init(size_t blockSizeInBytes, size_t blockAlignment = kMinAlignment);
/** Allocate some memory of at least size bytes without having any specific alignment.
@@ -72,6 +72,11 @@ public:
@return The allocation. Can be nullptr if backing allocator was not able to request required memory */
void* allocate(size_t sizeInBytes);
+ /** Same as allocate, but zeros memory before returning
+ @param size The size of the allocation requested (in bytes and must be > 0).
+ @return The allocation. Can be nullptr if backing allocator was not able to request required memory */
+ void* allocateAndZero(size_t sizeInBytes);
+
/** Allocate some aligned memory of at least size bytes
@param size Size of allocation wanted (must be > 0).
@param alignment Alignment of allocation - must be a power of 2.
@@ -100,15 +105,15 @@ public:
/// Allocate an array of a specified type. NOTE Constructor of T is NOT executed.
template <typename T>
- T* allocateArray(size_t size);
+ T* allocateArray(size_t numElems);
/// Allocate an array of a specified type, and copy array passed into it.
template <typename T>
- T* allocateAndCopyArray(const T* src, size_t size);
+ T* allocateAndCopyArray(const T* src, size_t numElems);
/// Allocate an array of a specified type, and zero it.
template <typename T>
- T* allocateAndZeroArray(size_t size);
+ T* allocateAndZeroArray(size_t numElems);
/** Deallocates all allocated memory. That backing memory will generally not be released so
subsequent allocation will be fast, and from the same memory. Note though that 'oversize' blocks
@@ -160,13 +165,14 @@ protected:
/// Create a new block with regular block alignment
Block* _newNormalBlock();
/// Allocates a new block with allocSize and alignment
- Block* _newBlock(size_t allocSize, size_t alignment);
+ Block* _newBlock(size_t allocSizeInBytes, size_t alignment);
- void* _allocateAlignedFromNewBlock(size_t size, size_t alignment);
+ void* _allocateAlignedFromNewBlock(size_t sizeInBytes, size_t alignment);
+ void* _allocateAlignedFromNewBlockAndZero(size_t sizeInBytes, size_t alignment);
/// Find block that contains data/size that is _NOT_ current (ie not first block in m_usedBlocks)
- const Block* _findNonCurrent(const void* data, size_t size) const;
- const Block* _findInBlocks(const Block* block, const void* data, size_t size) const;
+ const Block* _findNonCurrent(const void* data, size_t sizeInBytes) const;
+ const Block* _findInBlocks(const Block* block, const void* data, size_t sizeInBytes) const;
size_t _calcBlocksUsedMemory(const Block* block) const;
size_t _calcBlocksAllocatedMemory(const Block* block) const;
@@ -192,7 +198,7 @@ protected:
};
// --------------------------------------------------------------------------
-inline bool MemoryArena::isValid(const void* data, size_t size) const
+SLANG_FORCE_INLINE bool MemoryArena::isValid(const void* data, size_t size) const
{
assert(size);
uint8_t* ptr = (uint8_t*)data;
@@ -200,12 +206,12 @@ inline bool MemoryArena::isValid(const void* data, size_t size) const
}
// --------------------------------------------------------------------------
-SLANG_FORCE_INLINE void* MemoryArena::allocateUnaligned(size_t size)
+SLANG_FORCE_INLINE void* MemoryArena::allocateUnaligned(size_t sizeInBytes)
{
- assert(size > 0);
+ assert(sizeInBytes > 0);
// Align with the minimum alignment
uint8_t* mem = m_current;
- uint8_t* end = mem + size;
+ uint8_t* end = mem + sizeInBytes;
if (end <= m_end)
{
m_current = end;
@@ -213,33 +219,54 @@ SLANG_FORCE_INLINE void* MemoryArena::allocateUnaligned(size_t size)
}
else
{
- return _allocateAlignedFromNewBlock(size, kMinAlignment);
+ return _allocateAlignedFromNewBlock(sizeInBytes, kMinAlignment);
}
}
// --------------------------------------------------------------------------
-SLANG_FORCE_INLINE void* MemoryArena::allocate(size_t size)
+SLANG_FORCE_INLINE void* MemoryArena::allocate(size_t sizeInBytes)
{
- assert(size > 0);
+ assert(sizeInBytes > 0);
// Align with the minimum alignment
const size_t alignMask = kMinAlignment - 1;
uint8_t* mem = (uint8_t*)((size_t(m_current) + alignMask) & ~alignMask);
- if (mem + size <= m_end)
+ if (mem + sizeInBytes <= m_end)
{
- m_current = mem + size;
+ m_current = mem + sizeInBytes;
return mem;
}
else
{
- return _allocateAlignedFromNewBlock(size, kMinAlignment);
+ return _allocateAlignedFromNewBlock(sizeInBytes, kMinAlignment);
}
}
// --------------------------------------------------------------------------
-inline void* MemoryArena::allocateAligned(size_t size, size_t alignment)
+SLANG_FORCE_INLINE void* MemoryArena::allocateAndZero(size_t sizeInBytes)
{
- assert(size > 0);
+ // Implement without calling ::allocate, because in most common case we don't need to test for null.
+ assert(sizeInBytes > 0);
+ // Align with the minimum alignment
+ const size_t alignMask = kMinAlignment - 1;
+ uint8_t* mem = (uint8_t*)((size_t(m_current) + alignMask) & ~alignMask);
+ uint8_t* end = mem + sizeInBytes;
+ if ( end <= m_end)
+ {
+ ::memset(mem, 0, sizeInBytes);
+ m_current = end;
+ return mem;
+ }
+ else
+ {
+ return _allocateAlignedFromNewBlockAndZero(sizeInBytes, kMinAlignment);
+ }
+}
+
+// --------------------------------------------------------------------------
+SLANG_FORCE_INLINE void* MemoryArena::allocateAligned(size_t sizeInBytes, size_t alignment)
+{
+ assert(sizeInBytes > 0);
// Alignment must be a power of 2
assert(((alignment - 1) & alignment) == 0);
@@ -247,19 +274,19 @@ inline void* MemoryArena::allocateAligned(size_t size, size_t alignment)
const size_t alignMask = alignment - 1;
uint8_t* memory = (uint8_t*)((size_t(m_current) + alignMask) & ~alignMask);
- if (memory + size <= m_end)
+ if (memory + sizeInBytes <= m_end)
{
- m_current = memory + size;
+ m_current = memory + sizeInBytes;
return memory;
}
else
{
- return _allocateAlignedFromNewBlock(size, alignment);
+ return _allocateAlignedFromNewBlock(sizeInBytes, alignment);
}
}
// --------------------------------------------------------------------------
-inline const char* MemoryArena::allocateString(const char* str)
+SLANG_FORCE_INLINE const char* MemoryArena::allocateString(const char* str)
{
size_t size = ::strlen(str);
if (size == 0)
@@ -272,43 +299,42 @@ inline const char* MemoryArena::allocateString(const char* str)
}
// --------------------------------------------------------------------------
-inline const char* MemoryArena::allocateString(const char* chars, size_t charsCount)
+inline const char* MemoryArena::allocateString(const char* chars, size_t numChars)
{
- if (charsCount == 0)
+ if (numChars == 0)
{
return "";
}
- char* dst = (char*)allocateUnaligned(charsCount + 1);
- ::memcpy(dst, chars, charsCount);
+ char* dst = (char*)allocateUnaligned(numChars + 1);
+ ::memcpy(dst, chars, numChars);
// Add null-terminating zero
- dst[charsCount] = 0;
+ dst[numChars] = 0;
return dst;
}
// --------------------------------------------------------------------------
template <typename T>
-inline T* MemoryArena::allocate()
+SLANG_FORCE_INLINE T* MemoryArena::allocate()
{
return reinterpret_cast<T*>(allocateAligned(sizeof(T), SLANG_ALIGN_OF(T)));
}
// --------------------------------------------------------------------------
template <typename T>
-inline T* MemoryArena::allocateArray(size_t count)
+SLANG_FORCE_INLINE T* MemoryArena::allocateArray(size_t numElems)
{
- return (count > 0) ? reinterpret_cast<T*>(allocateAligned(sizeof(T) * count, SLANG_ALIGN_OF(T))) : nullptr;
+ return (numElems > 0) ? reinterpret_cast<T*>(allocateAligned(sizeof(T) * numElems, SLANG_ALIGN_OF(T))) : nullptr;
}
// --------------------------------------------------------------------------
template <typename T>
-inline T* MemoryArena::allocateAndCopyArray(const T* arr, size_t size)
+SLANG_FORCE_INLINE T* MemoryArena::allocateAndCopyArray(const T* arr, size_t numElems)
{
SLANG_COMPILE_TIME_ASSERT(std::is_pod<T>::value);
-
- if (size > 0)
+ if (numElems > 0)
{
- const size_t totalSize = sizeof(T) * size;
+ const size_t totalSize = sizeof(T) * numElems;
void* ptr = allocateAligned(totalSize, SLANG_ALIGN_OF(T));
::memcpy(ptr, arr, totalSize);
return reinterpret_cast<T*>(ptr);
@@ -318,11 +344,11 @@ inline T* MemoryArena::allocateAndCopyArray(const T* arr, size_t size)
// ---------------------------------------------------------------------------
template <typename T>
-inline T* MemoryArena::allocateAndZeroArray(size_t size)
+SLANG_FORCE_INLINE T* MemoryArena::allocateAndZeroArray(size_t numElems)
{
- if (size > 0)
+ if (numElems > 0)
{
- const size_t totalSize = sizeof(T) * size;
+ const size_t totalSize = sizeof(T) * numElems;
void* ptr = allocateAligned(totalSize, SLANG_ALIGN_OF(T));
::memset(ptr, 0, totalSize);
return reinterpret_cast<T*>(ptr);
diff --git a/source/core/slang-string.h b/source/core/slang-string.h
index a67597360..2609b37ab 100644
--- a/source/core/slang-string.h
+++ b/source/core/slang-string.h
@@ -62,84 +62,15 @@ namespace Slang
return (((unsigned char)ch) & 0xC0) == 0x80;
}
- // A `StringRepresentation` provides the backing storage for
- // all reference-counted string-related types.
- class StringRepresentation : public RefObject
- {
- public:
- UInt length;
- UInt capacity;
-
- UInt getLength()
- {
- return length;
- }
-
- char* getData()
- {
- return (char*) (this + 1);
- }
-
- static StringRepresentation* createWithCapacityAndLength(UInt capacity, UInt length)
- {
- SLANG_ASSERT(capacity >= length);
- void* allocation = operator new(sizeof(StringRepresentation) + capacity + 1);
- StringRepresentation* obj = new(allocation) StringRepresentation();
- obj->capacity = capacity;
- obj->length = length;
- obj->getData()[length] = 0;
- return obj;
- }
-
- static StringRepresentation* createWithCapacity(UInt capacity)
- {
- return createWithCapacityAndLength(capacity, 0);
- }
-
- static StringRepresentation* createWithLength(UInt length)
- {
- return createWithCapacityAndLength(length, length);
- }
-
- StringRepresentation* cloneWithCapacity(UInt newCapacity)
- {
- StringRepresentation* newObj = createWithCapacityAndLength(newCapacity, length);
- memcpy(getData(), newObj->getData(), length + 1);
- return newObj;
- }
-
- StringRepresentation* clone()
- {
- return cloneWithCapacity(length);
- }
-
- StringRepresentation* ensureCapacity(UInt required)
- {
- if (capacity >= required) return this;
-
- UInt newCapacity = capacity;
- if (!newCapacity) newCapacity = 16; // TODO: figure out good value for minimum capacity
-
- while (newCapacity < required)
- {
- newCapacity = 2 * newCapacity;
- }
-
- return cloneWithCapacity(newCapacity);
- }
- };
-
- class String;
-
struct UnownedStringSlice
{
public:
UnownedStringSlice()
: beginData(nullptr)
- , endData(0)
+ , endData(nullptr)
{}
- explicit UnownedStringSlice(char const* a):
+ explicit UnownedStringSlice(char const* a) :
beginData(a),
endData(a + strlen(a))
{}
@@ -147,6 +78,10 @@ namespace Slang
: beginData(b)
, endData(e)
{}
+ UnownedStringSlice(char const* b, size_t len)
+ : beginData(b)
+ , endData(b + len)
+ {}
char const* begin() const
{
@@ -202,11 +137,104 @@ namespace Slang
bool endsWith(UnownedStringSlice const& other) const;
bool endsWith(char const* str) const;
+ template <size_t SIZE>
+ SLANG_FORCE_INLINE static UnownedStringSlice fromLiteral(const char (&in)[SIZE]) { return UnownedStringSlice(in, SIZE - 1); }
+
private:
char const* beginData;
char const* endData;
};
+ // A `StringRepresentation` provides the backing storage for
+ // all reference-counted string-related types.
+ class StringRepresentation : public RefObject
+ {
+ public:
+ UInt length;
+ UInt capacity;
+
+ SLANG_FORCE_INLINE UInt getLength() const
+ {
+ return length;
+ }
+
+ SLANG_FORCE_INLINE char* getData()
+ {
+ return (char*) (this + 1);
+ }
+ SLANG_FORCE_INLINE const char* getData() const
+ {
+ return (const char*)(this + 1);
+ }
+
+ static const char* getData(const StringRepresentation* stringRep)
+ {
+ return stringRep ? stringRep->getData() : "";
+ }
+
+ static UnownedStringSlice asSlice(const StringRepresentation* rep)
+ {
+ return rep ? UnownedStringSlice(rep->getData(), rep->getLength()) : UnownedStringSlice();
+ }
+
+ static bool equal(const StringRepresentation* a, const StringRepresentation* b)
+ {
+ return (a == b) || asSlice(a) == asSlice(b);
+ }
+
+ static StringRepresentation* createWithCapacityAndLength(UInt capacity, UInt length)
+ {
+ SLANG_ASSERT(capacity >= length);
+ void* allocation = operator new(sizeof(StringRepresentation) + capacity + 1);
+ StringRepresentation* obj = new(allocation) StringRepresentation();
+ obj->capacity = capacity;
+ obj->length = length;
+ obj->getData()[length] = 0;
+ return obj;
+ }
+
+ static StringRepresentation* createWithCapacity(UInt capacity)
+ {
+ return createWithCapacityAndLength(capacity, 0);
+ }
+
+ static StringRepresentation* createWithLength(UInt length)
+ {
+ return createWithCapacityAndLength(length, length);
+ }
+
+ StringRepresentation* cloneWithCapacity(UInt newCapacity)
+ {
+ StringRepresentation* newObj = createWithCapacityAndLength(newCapacity, length);
+ memcpy(getData(), newObj->getData(), length + 1);
+ return newObj;
+ }
+
+ StringRepresentation* clone()
+ {
+ return cloneWithCapacity(length);
+ }
+
+ StringRepresentation* ensureCapacity(UInt required)
+ {
+ if (capacity >= required) return this;
+
+ UInt newCapacity = capacity;
+ if (!newCapacity) newCapacity = 16; // TODO: figure out good value for minimum capacity
+
+ while (newCapacity < required)
+ {
+ newCapacity = 2 * newCapacity;
+ }
+
+ return cloneWithCapacity(newCapacity);
+ }
+ };
+
+ class String;
+
+
+
struct UnownedTerminatedStringSlice : public UnownedStringSlice
{
public:
@@ -300,11 +328,12 @@ namespace Slang
RefPtr<StringRepresentation> buffer;
- String(StringRepresentation* buffer)
+ public:
+
+ explicit String(StringRepresentation* buffer)
: buffer(buffer)
{}
- public:
static String FromWString(const wchar_t * wstr);
static String FromWString(const wchar_t * wstr, const wchar_t * wend);
static String FromWChar(const wchar_t ch);
@@ -313,6 +342,8 @@ namespace Slang
{
}
+ SLANG_FORCE_INLINE StringRepresentation* getStringRepresentation() const { return buffer; }
+
const char * begin() const
{
return getData();
diff --git a/source/core/smart-pointer.h b/source/core/smart-pointer.h
index f45618050..abd7763ee 100644
--- a/source/core/smart-pointer.h
+++ b/source/core/smart-pointer.h
@@ -61,6 +61,18 @@ namespace Slang
{
return referenceCount;
}
+
+ // Use instead of dynamic_cast as it allows for replacement without using Rtti in the future
+ template<typename T>
+ SLANG_FORCE_INLINE const T* dynamicCast() const
+ {
+ return dynamic_cast<const T*>(this);
+ }
+ template<typename T>
+ SLANG_FORCE_INLINE T* dynamicCast()
+ {
+ return dynamic_cast<T*>(this);
+ }
};
inline void addReference(RefObject* obj)
@@ -78,7 +90,7 @@ namespace Slang
struct RefPtr
{
RefPtr()
- : pointer(0)
+ : pointer(nullptr)
{}
RefPtr(T* p)
@@ -96,7 +108,7 @@ namespace Slang
RefPtr(RefPtr<T>&& p)
: pointer(p.pointer)
{
- p.pointer = 0;
+ p.pointer = nullptr;
}
template <typename U>
@@ -170,8 +182,7 @@ namespace Slang
template<typename U>
RefPtr<U> As() const
{
- RefPtr<U> result(dynamic_cast<U*>(pointer));
- return result;
+ return RefPtr<U>(pointer->template dynamicCast<U>());
}
~RefPtr()
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 1d121d69b..2d774d8d8 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -1389,7 +1389,7 @@ struct EmitVisitor
bool isTargetIntrinsicModifierApplicable(
IRTargetIntrinsicDecoration* decoration)
{
- auto targetName = decoration->targetName;
+ auto targetName = String(decoration->targetName);
// If no target name was specified, then the modifier implicitly
// applies to all targets.
@@ -2133,7 +2133,7 @@ struct EmitVisitor
// then use that name instead.
if(auto intrinsicDecoration = findTargetIntrinsicDecoration(context, inst))
{
- return intrinsicDecoration->definition;
+ return String(intrinsicDecoration->definition);
}
// If we have a name hint on the instruction, then we will try to use that
@@ -2945,7 +2945,7 @@ struct EmitVisitor
args++;
argCount--;
- auto name = targetIntrinsic->definition;
+ auto name = String(targetIntrinsic->definition);
if(isOrdinaryName(name))
@@ -3845,11 +3845,11 @@ struct EmitVisitor
if(auto layoutDecoration = inst->findDecoration<IRLayoutDecoration>())
{
auto layout = layoutDecoration->layout;
- if(auto varLayout = layout.As<VarLayout>())
+ if(auto varLayout = layout->dynamicCast<VarLayout>())
{
emitIRSemantics(ctx, varLayout);
}
- else if (auto entryPointLayout = layout.As<EntryPointLayout>())
+ else if (auto entryPointLayout = layout->dynamicCast<EntryPointLayout>())
{
emitIRSemantics(ctx, entryPointLayout->resultLayout);
}
@@ -3864,7 +3864,7 @@ struct EmitVisitor
if (!decoration)
return nullptr;
- return (VarLayout*) decoration->layout.Ptr();
+ return (VarLayout*) decoration->layout;
}
void emitIRLayoutSemantics(
@@ -4757,7 +4757,7 @@ struct EmitVisitor
{
if( auto layoutDecoration = func->findDecoration<IRLayoutDecoration>() )
{
- return layoutDecoration->layout.As<EntryPointLayout>();
+ return layoutDecoration->layout->dynamicCast<EntryPointLayout>();
}
return nullptr;
}
@@ -4766,7 +4766,7 @@ struct EmitVisitor
{
if (auto layoutDecoration = func->findDecoration<IRLayoutDecoration>())
{
- if (auto entryPointLayout = layoutDecoration->layout.As<EntryPointLayout>())
+ if (auto entryPointLayout = layoutDecoration->layout->dynamicCast<EntryPointLayout>())
{
return entryPointLayout;
}
diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h
index e7ca08c6d..644036e89 100644
--- a/source/slang/ir-insts.h
+++ b/source/slang/ir-insts.h
@@ -32,12 +32,7 @@ struct IRLayoutDecoration : IRDecoration
{
enum { kDecorationOp = kIRDecorationOp_Layout };
- RefPtr<Layout> layout;
- virtual void dispose() override
- {
- IRDecoration::dispose();
- layout = nullptr;
- }
+ Layout* layout;
};
enum IRLoopControl
@@ -56,12 +51,7 @@ struct IRLoopControlDecoration : IRDecoration
struct IRTargetSpecificDecoration : IRDecoration
{
// TODO: have a more structured representation of target specifiers
- String targetName;
- virtual void dispose()override
- {
- IRDecoration::dispose();
- targetName = String();
- }
+ StringRepresentation* targetName;
};
struct IRTargetDecoration : IRTargetSpecificDecoration
@@ -73,12 +63,7 @@ struct IRTargetIntrinsicDecoration : IRTargetSpecificDecoration
{
enum { kDecorationOp = kIRDecorationOp_TargetIntrinsic };
- String definition;
- virtual void dispose()override
- {
- IRTargetSpecificDecoration::dispose();
- definition = String();
- }
+ StringRepresentation* definition;
};
struct IRGLSLOuterArrayDecoration : IRDecoration
@@ -138,12 +123,7 @@ struct IRNameHintDecoration : IRDecoration
// declaration.
struct IRDeclRef : IRInst
{
- DeclRef<Decl> declRef;
- virtual void dispose() override
- {
- IRInst::dispose();
- declRef = decltype(declRef)();
- }
+ Decl* declRef;
};
// An instruction that specializes another IR value
@@ -838,17 +818,32 @@ struct IRBuilder
{
SLANG_ASSERT(getModule());
auto decorationSize = sizeof(T);
- auto decoration = (T*)getModule()->memoryPool.allocZero(decorationSize);
+ auto decoration = (T*)getModule()->memoryArena.allocateAndZero(decorationSize);
+
+ // TODO: Do we need to run ctor after zeroing?
new(decoration)T();
decoration->op = op;
decoration->next = value->firstDecoration;
value->firstDecoration = decoration;
- getModule()->irObjectsToFree.Add(decoration);
return decoration;
}
+ template <typename T>
+ T* addRefObjectToFree(T* ptr)
+ {
+ getModule()->addRefObjectToFree(ptr);
+ return ptr;
+ }
+ StringRepresentation* addStringToFree(const String& string)
+ {
+ StringRepresentation* stringRep = string.getStringRepresentation();
+ getModule()->addRefObjectToFree(stringRep);
+ return stringRep;
+ }
+
+
template<typename T>
T* addDecoration(IRInst* value)
{
diff --git a/source/slang/ir-legalize-types.cpp b/source/slang/ir-legalize-types.cpp
index 9136ad671..931ceb85a 100644
--- a/source/slang/ir-legalize-types.cpp
+++ b/source/slang/ir-legalize-types.cpp
@@ -844,7 +844,7 @@ static LegalVal legalizeInst(
RefPtr<VarLayout> findVarLayout(IRInst* value)
{
if (auto layoutDecoration = value->findDecoration<IRLayoutDecoration>())
- return layoutDecoration->layout.As<VarLayout>();
+ return layoutDecoration->layout->dynamicCast<VarLayout>();
return nullptr;
}
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 83735d6df..6b2939987 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -763,7 +763,7 @@ namespace Slang
// Create an IR instruction/value and initialize it.
//
- // In this case `argCount` and `args` represnt the
+ // In this case `argCount` and `args` represent the
// arguments *after* the type (which is a mandatory
// argument for all instructions).
template<typename T>
@@ -791,9 +791,10 @@ namespace Slang
}
SLANG_ASSERT(module);
- T* inst = (T*)module->memoryPool.allocZero(size);
- new(inst)T();
+ T* inst = (T*)module->memoryArena.allocateAndZero(size);
+ // TODO: Do we need to run ctor after zeroing?
+ new(inst)T();
inst->operandCount = (uint32_t)(fixedArgCount + varArgCount);
@@ -833,7 +834,6 @@ namespace Slang
operand++;
}
}
- module->irObjectsToFree.Add(inst);
return inst;
}
@@ -2285,7 +2285,7 @@ namespace Slang
IRLayoutDecoration* IRBuilder::addLayoutDecoration(IRInst* inst, Layout* layout)
{
auto decoration = addDecoration<IRLayoutDecoration>(inst);
- decoration->layout = layout;
+ decoration->layout = addRefObjectToFree(layout);
return decoration;
}
@@ -2534,7 +2534,7 @@ namespace Slang
dump(context, "\n");
dumpIndent(context);
dump(context, "[target(");
- dump(context, decoration->targetName.Buffer());
+ dump(context, StringRepresentation::getData(decoration->targetName));
dump(context, ")]");
}
break;
@@ -2910,11 +2910,6 @@ namespace Slang
ff->debugValidate();
}
- void IRInst::dispose()
- {
- IRObject::dispose();
- }
-
// Insert this instruction into the same basic block
// as `other`, right before it.
void IRInst::insertBefore(IRInst* other)
@@ -4223,7 +4218,7 @@ namespace Slang
continue;
auto decoration = (IRTargetIntrinsicDecoration*) dd;
- if(decoration->targetName == targetName)
+ if(String(decoration->targetName) == targetName)
return decoration;
}
@@ -4469,7 +4464,7 @@ namespace Slang
if(!decoration)
continue;
- if(decoration->definition != "EmitVertex()")
+ if(StringRepresentation::asSlice(decoration->definition) != UnownedStringSlice::fromLiteral("EmitVertex()"))
{
continue;
}
@@ -5425,7 +5420,7 @@ namespace Slang
continue;
auto decoration = (IRTargetDecoration*) dd;
- if(decoration->targetName == targetName)
+ if(String(decoration->targetName) == targetName)
return TargetSpecializationLevel::specializedForTarget;
result = TargetSpecializationLevel::specializedForOtherTarget;
diff --git a/source/slang/ir.h b/source/slang/ir.h
index 4c601ce5d..a7f2cb4fb 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -10,7 +10,9 @@
#include "../core/basic.h"
#include "source-loc.h"
-#include "memory_pool.h"
+
+#include "../core/slang-memory-arena.h"
+
#include "type-system-shared.h"
namespace Slang {
@@ -128,18 +130,9 @@ enum IRDecorationOp : uint16_t
kIRDecorationOp_NameHint,
};
-// represents an object allocated in an IR memory pool
+// represents an object allocated in an IR memory arena
struct IRObject
{
- bool isDestroyed = false;
- virtual void dispose()
- {
- isDestroyed = true;
- }
- virtual ~IRObject()
- {
- isDestroyed = true;
- }
};
// A "decoration" that gets applied to an instruction.
@@ -247,9 +240,6 @@ struct IRInst : public IRObject
// that this value will now have no uses.
void replaceUsesWith(IRInst* other);
- // Clean up any non-pool resources used by this instruction
- virtual void dispose() override;
-
// Insert this instruction into the same basic block
// as `other`, right before/after it.
void insertBefore(IRInst* other);
@@ -332,8 +322,8 @@ struct IRInstListBase
- IRInst* first = 0;
- IRInst* last = 0;
+ IRInst* first = nullptr;
+ IRInst* last = nullptr;
IRInst* getFirst() { return first; }
IRInst* getLast() { return last; }
@@ -991,23 +981,50 @@ struct IRModuleInst : IRParentInst
struct IRModule : RefObject
{
- // The compilation session in use.
- Session* session;
- MemoryPool memoryPool;
- List<IRObject*> irObjectsToFree; // list of ir objects to run destructor upon destruction
+ enum
+ {
+ kMemoryArenaBlockSize = 16 * 1024, ///< Use 16k block size for memory arena
+ };
- IRModuleInst* moduleInst;
- IRModuleInst* getModuleInst() { return moduleInst; }
+ SLANG_FORCE_INLINE Session* getSession() const { return session; }
+ SLANG_FORCE_INLINE IRModuleInst* getModuleInst() const { return moduleInst; }
- IRInstListBase getGlobalInsts() { return getModuleInst()->getChildren(); }
+ IRInstListBase getGlobalInsts() const { return getModuleInst()->getChildren(); }
- ~IRModule()
+ void addRefObjectToFree(RefObject* obj)
+ {
+ if (obj)
+ {
+ obj->addReference();
+ m_refObjectsToFree.Add(obj);
+ }
+ }
+
+ /// Ctor
+ IRModule():
+ memoryArena(kMemoryArenaBlockSize)
{
- for (auto val : irObjectsToFree)
- if (!val->isDestroyed)
- val->dispose();
- irObjectsToFree = List<IRObject*>();
}
+
+ ~IRModule()
+ {
+ // Release all ref objects
+ for (RefObject* ptr: m_refObjectsToFree)
+ {
+ ptr->releaseReference();
+ }
+ // Clear any memory too
+ m_refObjectsToFree = List<RefObject*>();
+ }
+
+ MemoryArena memoryArena;
+
+ // The compilation session in use.
+ Session* session;
+ IRModuleInst* moduleInst;
+
+ protected:
+ List<RefObject*> m_refObjectsToFree;
};
void printSlangIRAssembly(StringBuilder& builder, IRModule* module);
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 280b89fb8..d57872fc9 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -4549,19 +4549,21 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
IRInst* irInst,
Decl* decl)
{
+ auto builder = getBuilder();
+
for (auto targetMod : decl->GetModifiersOfType<TargetIntrinsicModifier>())
{
- auto decoration = getBuilder()->addDecoration<IRTargetIntrinsicDecoration>(irInst);
- decoration->targetName = targetMod->targetToken.Content;
-
+ auto decoration = builder->addDecoration<IRTargetIntrinsicDecoration>(irInst);
+ decoration->targetName = builder->addStringToFree(targetMod->targetToken.Content);
+
auto definitionToken = targetMod->definitionToken;
if (definitionToken.type == TokenType::StringLiteral)
{
- decoration->definition = getStringLiteralTokenValue(definitionToken);
+ decoration->definition = builder->addStringToFree(getStringLiteralTokenValue(definitionToken));
}
else
{
- decoration->definition = definitionToken.Content;
+ decoration->definition = builder->addStringToFree(definitionToken.Content);
}
}
}
@@ -4900,7 +4902,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// target, and we need to reflect that at the IR level.
auto decoration = getBuilder()->addDecoration<IRTargetDecoration>(irFunc);
- decoration->targetName = targetMod->targetToken.Content;
+ decoration->targetName = getBuilder()->addStringToFree(targetMod->targetToken.Content);
}
// If this declaration was marked as having a target-specific lowering
diff --git a/source/slang/memory_pool.cpp b/source/slang/memory_pool.cpp
deleted file mode 100644
index 884c9cfe4..000000000
--- a/source/slang/memory_pool.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "memory_pool.h"
-
-namespace Slang
-{
- const size_t kPoolSegmentSize = 4 << 20; // use 4MB segments
-
- struct MemoryPoolSegment
- {
- unsigned char* data = nullptr;
- size_t allocPtr = 0;
- MemoryPoolSegment* nextSegment = nullptr;
- };
-
- MemoryPool::~MemoryPool()
- {
- while (curSegment)
- {
- auto nxtSegment = curSegment->nextSegment;
- free(curSegment->data);
- delete curSegment;
- curSegment = nxtSegment;
- }
- }
-
- void newSegment(MemoryPool* pool)
- {
- auto seg = new MemoryPoolSegment();
- seg->nextSegment = pool->curSegment;
- seg->data = (unsigned char*)malloc(kPoolSegmentSize);
- pool->curSegment = seg;
- }
-
- void * MemoryPool::alloc(size_t size)
- {
- assert(size < kPoolSegmentSize);
- // ensure there is a segment available
- if (!curSegment)
- newSegment(this);
- if (curSegment->allocPtr + size > kPoolSegmentSize)
- newSegment(this);
- // alloc memory from current segment
- void* rs = curSegment->data + curSegment->allocPtr;
- curSegment->allocPtr += size;
- return rs;
- }
- void * MemoryPool::allocZero(size_t size)
- {
- auto rs = alloc(size);
- memset(rs, 0, size);
- return rs;
- }
-}
diff --git a/source/slang/memory_pool.h b/source/slang/memory_pool.h
deleted file mode 100644
index ee3ee1aa3..000000000
--- a/source/slang/memory_pool.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef SLANG_MEMORY_POOL_H
-#define SLANG_MEMORY_POOL_H
-
-#include "../core/basic.h"
-
-namespace Slang
-{
- struct MemoryPoolSegment;
-
- struct MemoryPool : public RefObject
- {
- MemoryPoolSegment* curSegment = nullptr;
- ~MemoryPool();
- void* alloc(size_t size);
- void* allocZero(size_t size);
- };
-}
-
-#endif \ No newline at end of file
diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj
index 284907018..eeaf7410a 100644
--- a/source/slang/slang.vcxproj
+++ b/source/slang/slang.vcxproj
@@ -195,7 +195,6 @@
<ClInclude Include="lookup.h" />
<ClInclude Include="lower-to-ir.h" />
<ClInclude Include="mangle.h" />
- <ClInclude Include="memory_pool.h" />
<ClInclude Include="modifier-defs.h" />
<ClInclude Include="name.h" />
<ClInclude Include="object-meta-begin.h" />
@@ -241,7 +240,6 @@
<ClCompile Include="lookup.cpp" />
<ClCompile Include="lower-to-ir.cpp" />
<ClCompile Include="mangle.cpp" />
- <ClCompile Include="memory_pool.cpp" />
<ClCompile Include="name.cpp" />
<ClCompile Include="options.cpp" />
<ClCompile Include="parameter-binding.cpp" />
diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters
index f12163f27..e2b17530e 100644
--- a/source/slang/slang.vcxproj.filters
+++ b/source/slang/slang.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
@@ -84,9 +84,6 @@
<ClInclude Include="mangle.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="memory_pool.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="modifier-defs.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -218,9 +215,6 @@
<ClCompile Include="mangle.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="memory_pool.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="name.cpp">
<Filter>Source Files</Filter>
</ClCompile>