summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/compiler.h4
-rw-r--r--source/slang/emit.cpp3
-rw-r--r--source/slang/ir-insts.h20
-rw-r--r--source/slang/ir.cpp70
-rw-r--r--source/slang/ir.h26
-rw-r--r--source/slang/memory_pool.cpp52
-rw-r--r--source/slang/memory_pool.h19
-rw-r--r--source/slang/slang.cpp3
-rw-r--r--source/slang/slang.vcxproj2
-rw-r--r--source/slang/slang.vcxproj.filters2
10 files changed, 140 insertions, 61 deletions
diff --git a/source/slang/compiler.h b/source/slang/compiler.h
index fab1e19c8..7ead5d07e 100644
--- a/source/slang/compiler.h
+++ b/source/slang/compiler.h
@@ -179,7 +179,7 @@ namespace Slang
// This will only be valid/non-null after semantic
// checking and IR generation are complete, so it
// is not safe to use this field without testing for NULL.
- IRModule* irModule;
+ RefPtr<IRModule> irModule;
};
// A request to generate output in some target format
@@ -225,7 +225,7 @@ namespace Slang
RefPtr<ModuleDecl> moduleDecl;
// The IR for the module
- IRModule* irModule = nullptr;
+ RefPtr<IRModule> irModule = nullptr;
};
class Session;
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 672798359..b8fbc350e 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -8158,6 +8158,7 @@ String emitEntryPoint(
// TODO: do we want to emit directly from IR, or translate the
// IR back into AST for emission?
visitor.emitIRModule(&context, irModule);
+ destroyIRSpecializationState(irSpecializationState);
}
String code = sharedContext.sb.ProduceString();
@@ -8189,7 +8190,7 @@ String emitEntryPoint(
finalResultBuilder << code;
String finalResult = finalResultBuilder.ProduceString();
-
+
return finalResult;
}
diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h
index e2c1c2e03..1cfe83b97 100644
--- a/source/slang/ir-insts.h
+++ b/source/slang/ir-insts.h
@@ -610,22 +610,26 @@ struct IRBuilder
UInt caseArgCount,
IRValue* const* caseArgs);
-
- IRDecoration* addDecorationImpl(
- IRValue* value,
- UInt decorationSize,
- IRDecorationOp op);
-
template<typename T>
T* addDecoration(IRValue* value, IRDecorationOp op)
{
- return (T*) addDecorationImpl(value, sizeof(T), op);
+ assert(getModule());
+ auto decorationSize = sizeof(T);
+ auto decoration = (T*)getModule()->memoryPool.allocZero(decorationSize);
+ new(decoration)T();
+
+ decoration->op = op;
+
+ decoration->next = value->firstDecoration;
+ value->firstDecoration = decoration;
+ getModule()->irObjectsToFree.Add(decoration);
+ return decoration;
}
template<typename T>
T* addDecoration(IRValue* value)
{
- return (T*) addDecorationImpl(value, sizeof(T), IRDecorationOp(T::kDecorationOp));
+ return addDecoration<T>(value, IRDecorationOp(T::kDecorationOp));
}
IRHighLevelDeclDecoration* addHighLevelDeclDecoration(IRValue* value, Decl* decl);
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 441db09a6..8667a67bd 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -543,26 +543,19 @@ namespace Slang
value->sourceLoc = sourceLocInfo->sourceLoc;
}
- static IRValue* createValueImpl(
- IRBuilder* /*builder*/,
- UInt size,
- IROp op,
- IRType* type)
- {
- IRValue* value = (IRValue*) malloc(size);
- memset(value, 0, size);
- value->op = op;
- value->type = type;
- return value;
- }
-
template<typename T>
static T* createValue(
IRBuilder* builder,
IROp op,
IRType* type)
{
- return (T*) createValueImpl(builder, sizeof(T), op, type);
+ assert(builder->getModule());
+ T* value = (T*)builder->getModule()->memoryPool.allocZero(sizeof(T));
+ new(value)T();
+ value->op = op;
+ value->type = type;
+ builder->getModule()->irObjectsToFree.Add(value);
+ return value;
}
@@ -571,7 +564,8 @@ namespace Slang
// In this case `argCount` and `args` represnt the
// arguments *after* the type (which is a mandatory
// argument for all instructions).
- static IRInst* createInstImpl(
+ template<typename T>
+ static T* createInstImpl(
IRBuilder* builder,
UInt size,
IROp op,
@@ -581,8 +575,9 @@ namespace Slang
UInt varArgCount = 0,
IRValue* const* varArgs = nullptr)
{
- IRInst* inst = (IRInst*) malloc(size);
- memset(inst, 0, size);
+ assert(builder->getModule());
+ T* inst = (T*)builder->getModule()->memoryPool.allocZero(size);
+ new(inst)T();
inst->argCount = (uint32_t)(fixedArgCount + varArgCount);
@@ -611,7 +606,7 @@ namespace Slang
}
operand++;
}
-
+ builder->getModule()->irObjectsToFree.Add(inst);
return inst;
}
@@ -623,7 +618,7 @@ namespace Slang
UInt argCount,
IRValue* const* args)
{
- return (T*)createInstImpl(
+ return createInstImpl<T>(
builder,
sizeof(T),
op,
@@ -638,7 +633,7 @@ namespace Slang
IROp op,
IRType* type)
{
- return (T*)createInstImpl(
+ return createInstImpl<T>(
builder,
sizeof(T),
op,
@@ -654,7 +649,7 @@ namespace Slang
IRType* type,
IRValue* arg)
{
- return (T*)createInstImpl(
+ return createInstImpl<T>(
builder,
sizeof(T),
op,
@@ -672,7 +667,7 @@ namespace Slang
IRValue* arg2)
{
IRValue* args[] = { arg1, arg2 };
- return (T*)createInstImpl(
+ return createInstImpl<T>(
builder,
sizeof(T),
op,
@@ -689,7 +684,7 @@ namespace Slang
UInt argCount,
IRValue* const* args)
{
- return (T*)createInstImpl(
+ return createInstImpl<T>(
builder,
sizeof(T) + argCount * sizeof(IRUse),
op,
@@ -708,7 +703,7 @@ namespace Slang
UInt varArgCount,
IRValue* const* varArgs)
{
- return (T*)createInstImpl(
+ return createInstImpl<T>(
builder,
sizeof(T) + varArgCount * sizeof(IRUse),
op,
@@ -731,7 +726,7 @@ namespace Slang
IRValue* fixedArgs[] = { arg1 };
UInt fixedArgCount = sizeof(fixedArgs) / sizeof(fixedArgs[0]);
- return (T*)createInstImpl(
+ return createInstImpl<T>(
builder,
sizeof(T) + varArgCount * sizeof(IRUse),
op,
@@ -1705,22 +1700,6 @@ namespace Slang
return inst;
}
- IRDecoration* IRBuilder::addDecorationImpl(
- IRValue* inst,
- UInt decorationSize,
- IRDecorationOp op)
- {
- auto decoration = (IRDecoration*) malloc(decorationSize);
- memset(decoration, 0, decorationSize);
-
- decoration->op = op;
-
- decoration->next = inst->firstDecoration;
- inst->firstDecoration = decoration;
-
- return decoration;
- }
-
IRHighLevelDeclDecoration* IRBuilder::addHighLevelDeclDecoration(IRValue* inst, Decl* decl)
{
auto decoration = addDecoration<IRHighLevelDeclDecoration>(inst, kIRDecorationOp_HighLevelDecl);
@@ -2666,9 +2645,6 @@ namespace Slang
#else
// Run destructor to be sure...
this->~IRValue();
-
- // And then free the memory
- free((void*) this);
#endif
}
@@ -3729,7 +3705,7 @@ namespace Slang
CodeGenTarget target;
// The specialized module we are building
- IRModule* module;
+ RefPtr<IRModule> module;
// The original, unspecialized module we are copying
IRModule* originalModule;
@@ -5726,11 +5702,9 @@ namespace Slang
for (auto workItem : witnessTablesToSpecailize)
{
int diff = 0;
- specializeWitnessTable(context->shared, workItem.srcTable,
+ specializeWitnessTable(context->shared, workItem.srcTable,
workItem.specDeclRef.SubstituteImpl(SubstitutionSet(nullptr, nullptr, globalParamSubst), &diff), workItem.dstTable);
}
return globalParamSubst;
}
-
-
}
diff --git a/source/slang/ir.h b/source/slang/ir.h
index 0dc9daa9a..4cdd1f1de 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -10,6 +10,7 @@
#include "../core/basic.h"
#include "source-loc.h"
+#include "memory_pool.h"
namespace Slang {
@@ -114,15 +115,26 @@ enum IRDecorationOp : uint16_t
kIRDecorationOp_TargetIntrinsic,
};
+// represents an object allocated in an IR memory pool
+struct IRObject
+{
+ bool isDestroyed = false;
+ virtual ~IRObject()
+ {
+ isDestroyed = true;
+ }
+};
+
// A "decoration" that gets applied to an instruction.
// These usually don't affect semantics, but are useful
// for preserving high-level source information.
-struct IRDecoration
+struct IRDecoration : public IRObject
{
// Next decoration attached to the same instruction
IRDecoration* next;
IRDecorationOp op;
+ virtual ~IRDecoration() = default;
};
// Use AST-level types directly to represent the
@@ -132,7 +144,7 @@ typedef Type IRType;
struct IRBlock;
// Base class for values in the IR
-struct IRValue
+struct IRValue : public IRObject
{
// The operation that this value represents
IROp op;
@@ -536,6 +548,8 @@ struct IRModule : RefObject
{
// The compilation session in use.
Session* session;
+ MemoryPool memoryPool;
+ List<IRObject*> irObjectsToFree; // list of ir objects to run destructor upon destruction
// A list of all the functions and other
// global values declared in this module.
@@ -544,6 +558,14 @@ struct IRModule : RefObject
IRGlobalValue* getFirstGlobalValue() { return firstGlobalValue; }
IRGlobalValue* getlastGlobalValue() { return lastGlobalValue; }
+
+ ~IRModule()
+ {
+ for (auto val : irObjectsToFree)
+ if (!val->isDestroyed)
+ val->~IRObject();
+ irObjectsToFree = List<IRObject*>();
+ }
};
void printSlangIRAssembly(StringBuilder& builder, IRModule* module);
diff --git a/source/slang/memory_pool.cpp b/source/slang/memory_pool.cpp
new file mode 100644
index 000000000..884c9cfe4
--- /dev/null
+++ b/source/slang/memory_pool.cpp
@@ -0,0 +1,52 @@
+#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
new file mode 100644
index 000000000..ee3ee1aa3
--- /dev/null
+++ b/source/slang/memory_pool.h
@@ -0,0 +1,19 @@
+#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.cpp b/source/slang/slang.cpp
index 4238681f3..0f5d8e17a 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -751,6 +751,9 @@ SLANG_API void spDestroySession(
{
if(!session) return;
delete SESSION(session);
+#ifdef _MSC_VER
+ _CrtDumpMemoryLeaks();
+#endif
}
SLANG_API void spAddBuiltins(
diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj
index 1ff88020f..0154dd98f 100644
--- a/source/slang/slang.vcxproj
+++ b/source/slang/slang.vcxproj
@@ -186,6 +186,7 @@
<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" />
@@ -225,6 +226,7 @@
<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 e0bf59025..e64721f6d 100644
--- a/source/slang/slang.vcxproj.filters
+++ b/source/slang/slang.vcxproj.filters
@@ -45,6 +45,7 @@
<ClInclude Include="mangle.h" />
<ClInclude Include="legalize-types.h" />
<ClInclude Include="ir-ssa.h" />
+ <ClInclude Include="memory_pool.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="check.cpp" />
@@ -75,6 +76,7 @@
<ClCompile Include="ir-legalize-types.cpp" />
<ClCompile Include="legalize-types.cpp" />
<ClCompile Include="ir-ssa.cpp" />
+ <ClCompile Include="memory_pool.cpp" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="core.meta.slang" />