summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2018-02-20 23:55:51 -0500
committerGitHub <noreply@github.com>2018-02-20 23:55:51 -0500
commit01c4134d33cea3a4f98fad9248584278fd4bc452 (patch)
tree8ca6b0f7e844fbf56cb1991284aff3ebbcc8aa89
parent51cdcad24b5271ac8c0f816174c6a760e264ed9e (diff)
parent4cf46e5c8b2af8a4ea4db15cd402aae4145a614c (diff)
Merge pull request #417 from csyonghe/leakfix
Fix IR memory leaks.
-rw-r--r--slang.h1
-rw-r--r--source/core/smart-pointer.h14
-rw-r--r--source/slang/compiler.h8
-rw-r--r--source/slang/emit.cpp23
-rw-r--r--source/slang/ir-insts.h47
-rw-r--r--source/slang/ir.cpp85
-rw-r--r--source/slang/ir.h42
-rw-r--r--source/slang/lower-to-ir.cpp1
-rw-r--r--source/slang/memory_pool.cpp52
-rw-r--r--source/slang/memory_pool.h19
-rw-r--r--source/slang/slang.cpp24
-rw-r--r--source/slang/slang.vcxproj2
-rw-r--r--source/slang/slang.vcxproj.filters2
-rw-r--r--source/slang/syntax-base-defs.h4
-rw-r--r--source/slang/syntax.cpp42
-rw-r--r--source/slang/type-defs.h24
-rw-r--r--tools/render-test/slang-support.cpp3
17 files changed, 282 insertions, 111 deletions
diff --git a/slang.h b/slang.h
index 422de04cc..724e49d13 100644
--- a/slang.h
+++ b/slang.h
@@ -1237,6 +1237,7 @@ namespace slang
#include "source/slang/dxc-support.cpp"
#include "source/slang/emit.cpp"
#include "source/slang/ir.cpp"
+#include "source/slang/memory_pool.cpp"
#include "source/slang/ir-legalize-types.cpp"
#include "source/slang/ir-ssa.cpp"
#include "source/slang/legalize-types.cpp"
diff --git a/source/core/smart-pointer.h b/source/core/smart-pointer.h
index 17d6caaa4..bc1683a5b 100644
--- a/source/core/smart-pointer.h
+++ b/source/core/smart-pointer.h
@@ -35,6 +35,11 @@ namespace Slang
referenceCount++;
}
+ void decreaseReference()
+ {
+ --referenceCount;
+ }
+
void releaseReference()
{
SLANG_ASSERT(referenceCount != 0);
@@ -192,6 +197,15 @@ namespace Slang
return pointer;
}
+ T* detach()
+ {
+ if (pointer)
+ dynamic_cast<RefObject*>(pointer)->decreaseReference();
+ auto rs = pointer;
+ pointer = nullptr;
+ return rs;
+ }
+
private:
T* pointer;
diff --git a/source/slang/compiler.h b/source/slang/compiler.h
index fab1e19c8..845de5c81 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;
@@ -313,6 +313,8 @@ namespace Slang
// Map from the logical name of a module to its definition
Dictionary<Name*, RefPtr<LoadedModule>> mapNameToLoadedModules;
+ // The resulting specialized IR module for each entry point request
+ List<RefPtr<IRModule>> compiledModules;
CompileRequest(Session* session);
@@ -450,7 +452,6 @@ namespace Slang
Dictionary<int, RefPtr<Type>> builtinTypes;
Dictionary<String, Decl*> magicDecls;
- List<RefPtr<Type>> canonicalTypes;
void initializeTypes();
@@ -505,6 +506,7 @@ namespace Slang
RefPtr<Scope> const& scope,
String const& path,
String const& source);
+ ~Session();
};
}
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 672798359..d2ed1c7c3 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -8084,17 +8084,17 @@ String emitEntryPoint(
EmitVisitor visitor(&context);
+ // We are going to create a fresh IR module that we will use to
+ // clone any code needed by the user's entry point.
+ IRSpecializationState* irSpecializationState = createIRSpecializationState(
+ entryPoint,
+ programLayout,
+ target,
+ targetRequest);
{
TypeLegalizationContext typeLegalizationContext;
typeLegalizationContext.session = entryPoint->compileRequest->mSession;
- // We are going to create a fresh IR module that we will use to
- // clone any code needed by the user's entry point.
- IRSpecializationState* irSpecializationState = createIRSpecializationState(
- entryPoint,
- programLayout,
- target,
- targetRequest);
IRModule* irModule = getIRModule(irSpecializationState);
typeLegalizationContext.irModule = irModule;
@@ -8158,7 +8158,12 @@ String emitEntryPoint(
// TODO: do we want to emit directly from IR, or translate the
// IR back into AST for emission?
visitor.emitIRModule(&context, irModule);
+
+ // retain the specialized ir module, because the current
+ // GlobalGenericParamSubstitution implementation may reference ir objects
+ targetRequest->compileRequest->compiledModules.Add(irModule);
}
+ destroyIRSpecializationState(irSpecializationState);
String code = sharedContext.sb.ProduceString();
sharedContext.sb.Clear();
@@ -8166,8 +8171,6 @@ String emitEntryPoint(
// Now that we've emitted the code for all the declaratiosn in the file,
// it is time to stich together the final output.
-
-
// There may be global-scope modifiers that we should emit now
visitor.emitGLSLPreprocessorDirectives(translationUnitSyntax);
String prefix = sharedContext.sb.ProduceString();
@@ -8189,7 +8192,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..aaebb9973 100644
--- a/source/slang/ir-insts.h
+++ b/source/slang/ir-insts.h
@@ -33,6 +33,11 @@ struct IRLayoutDecoration : IRDecoration
enum { kDecorationOp = kIRDecorationOp_Layout };
RefPtr<Layout> layout;
+ virtual void dispose() override
+ {
+ IRDecoration::dispose();
+ layout = nullptr;
+ }
};
enum IRLoopControl
@@ -52,6 +57,11 @@ struct IRTargetSpecificDecoration : IRDecoration
{
// TODO: have a more structured representation of target specifiers
String targetName;
+ virtual void dispose()override
+ {
+ IRDecoration::dispose();
+ targetName = String();
+ }
};
struct IRTargetDecoration : IRTargetSpecificDecoration
@@ -64,6 +74,11 @@ struct IRTargetIntrinsicDecoration : IRTargetSpecificDecoration
enum { kDecorationOp = kIRDecorationOp_TargetIntrinsic };
String definition;
+ virtual void dispose()override
+ {
+ IRTargetSpecificDecoration::dispose();
+ definition = String();
+ }
};
//
@@ -73,6 +88,11 @@ struct IRTargetIntrinsicDecoration : IRTargetSpecificDecoration
struct IRDeclRef : IRValue
{
DeclRef<Decl> declRef;
+ virtual void dispose() override
+ {
+ IRValue::dispose();
+ declRef = decltype(declRef)();
+ }
};
// An instruction that specializes another IR value
@@ -333,6 +353,13 @@ struct IRWitnessTable : IRGlobalValue
RefPtr<GenericDecl> genericDecl;
DeclRef<Decl> subTypeDeclRef, supTypeDeclRef;
IRValueList<IRWitnessTableEntry> entries;
+ virtual void dispose() override
+ {
+ IRGlobalValue::dispose();
+ genericDecl = decltype(genericDecl)();
+ subTypeDeclRef = decltype(subTypeDeclRef)();
+ supTypeDeclRef = decltype(supTypeDeclRef)();
+ }
};
// An instruction that yields an undefined value.
@@ -610,22 +637,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..65f792577 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,12 +2645,15 @@ namespace Slang
#else
// Run destructor to be sure...
this->~IRValue();
-
- // And then free the memory
- free((void*) this);
#endif
}
+ void IRValue::dispose()
+ {
+ IRObject::dispose();
+ type = decltype(type)();
+ }
+
// Insert this instruction into the same basic block
// as `other`, right before it.
void IRInst::insertBefore(IRInst* other)
@@ -3729,7 +3711,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;
@@ -4763,9 +4745,9 @@ namespace Slang
if( !module )
{
module = builder->createModule();
- sharedBuilder->module = module;
}
+ sharedBuilder->module = module;
sharedContext->module = module;
sharedContext->originalModule = originalModule;
sharedContext->target = target;
@@ -4801,6 +4783,12 @@ namespace Slang
IRSharedSpecContext* getSharedContext() { return &sharedContextStorage; }
IRSpecContext* getContext() { return &contextStorage; }
+ ~IRSpecializationState()
+ {
+ newProgramLayout = nullptr;
+ contextStorage = IRSpecContext();
+ sharedContextStorage = IRSharedSpecContext();
+ }
};
IRSpecializationState* createIRSpecializationState(
@@ -4840,7 +4828,6 @@ namespace Slang
auto context = state->getContext();
context->shared = sharedContext;
context->builder = &sharedContext->builderStorage;
-
// Create the GlobalGenericParamSubstitution for substituting global generic types
// into user-provided type arguments
auto globalParamSubst = createGlobalGenericParamSubstitution(entryPointRequest, programLayout, context, originalIRModule);
@@ -5726,11 +5713,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..fdca73a83 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,10 +115,24 @@ enum IRDecorationOp : uint16_t
kIRDecorationOp_TargetIntrinsic,
};
+// represents an object allocated in an IR memory pool
+struct IRObject
+{
+ bool isDestroyed = false;
+ virtual void dispose()
+ {
+ isDestroyed = true;
+ }
+ 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;
@@ -132,7 +147,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;
@@ -169,6 +184,8 @@ struct IRValue
// Free a value (which needs to have been removed
// from its parent, had its uses eliminated, etc.)
void deallocate();
+
+ virtual void dispose() override;
};
// Values that are contained in a doubly-linked
@@ -480,6 +497,11 @@ struct IRGlobalValue : IRValue
void removeFromParent();
void moveToEnd();
+ virtual void dispose() override
+ {
+ IRValue::dispose();
+ mangledName = String();
+ }
};
/// @brief A global value that potentially holds executable code.
@@ -529,6 +551,12 @@ struct IRFunc : IRGlobalValueWithCode
// which are actually the parameters of the first
// block.
IRParam* getFirstParam();
+
+ virtual void dispose() override
+ {
+ IRGlobalValueWithCode::dispose();
+ genericDecls = decltype(genericDecls)();
+ }
};
// A module is a parent to functions, global variables, types, etc.
@@ -536,6 +564,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 +574,14 @@ struct IRModule : RefObject
IRGlobalValue* getFirstGlobalValue() { return firstGlobalValue; }
IRGlobalValue* getlastGlobalValue() { return lastGlobalValue; }
+
+ ~IRModule()
+ {
+ for (auto val : irObjectsToFree)
+ if (!val->isDestroyed)
+ val->dispose();
+ irObjectsToFree = List<IRObject*>();
+ }
};
void printSlangIRAssembly(StringBuilder& builder, IRModule* module);
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 53cb2e772..b99e2713f 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -2870,6 +2870,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
if (parentDecl->ParentDecl)
witnessTable->genericDecl = dynamic_cast<GenericDecl*>(parentDecl->ParentDecl);
witnessTable->subTypeDeclRef = makeDeclRef(parentDecl);
+ witnessTable->subTypeDeclRef.substitutions = createDefaultSubstitutions(context->getSession(), parentDecl);
witnessTable->supTypeDeclRef = inheritanceDecl->base.type->AsDeclRefType()->declRef;
// Register the value now, rather than later, to avoid
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..42e412438 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -123,7 +123,13 @@ CompileRequest::CompileRequest(Session* session)
}
CompileRequest::~CompileRequest()
-{}
+{
+ // delete things that may reference IR objects first
+ targets = decltype(targets)();
+ translationUnits = decltype(translationUnits)();
+ entryPoints = decltype(entryPoints)();
+ types = decltype(types)();
+}
RefPtr<Expr> CompileRequest::parseTypeString(TranslationUnitRequest * translationUnit, String typeStr, RefPtr<Scope> scope)
@@ -734,6 +740,19 @@ void Session::addBuiltinSource(
loadedModuleCode.Add(syntax);
}
+Session::~Session()
+{
+ // free all built-in types first
+ errorType = nullptr;
+ initializerListType = nullptr;
+ overloadedType = nullptr;
+ irBasicBlockType = nullptr;
+
+ builtinTypes = decltype(builtinTypes)();
+ // destroy modules next
+ loadedModuleCode = decltype(loadedModuleCode)();
+}
+
}
// implementation of C interface
@@ -751,6 +770,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" />
diff --git a/source/slang/syntax-base-defs.h b/source/slang/syntax-base-defs.h
index 2eb130863..2c15f7215 100644
--- a/source/slang/syntax-base-defs.h
+++ b/source/slang/syntax-base-defs.h
@@ -119,7 +119,7 @@ public:
protected:
virtual bool EqualsImpl(Type * type) = 0;
- virtual Type* CreateCanonicalType() = 0;
+ virtual RefPtr<Type> CreateCanonicalType() = 0;
Type* canonicalType = nullptr;
RefPtr<Type> canonicalTypeRefPtr;
@@ -227,7 +227,7 @@ RAW(
return rs;
}
typedef List<KeyValuePair<RefPtr<Type>, RefPtr<Val>>> WitnessTableLookupTable;
-)
+ )
// The witness tables for each interface this actual type implements
SYNTAX_FIELD(WitnessTableLookupTable, witnessTables)
END_SYNTAX_CLASS()
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp
index e050fc977..62e467a44 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -18,7 +18,7 @@ namespace Slang
return basicType->baseType == this->baseType;
}
- Type* BasicExpressionType::CreateCanonicalType()
+ RefPtr<Type> BasicExpressionType::CreateCanonicalType()
{
// A basic type is already canonical, in our setup
return this;
@@ -194,9 +194,12 @@ void Type::accept(IValVisitor* visitor, void* extra)
if (!et->canonicalType)
{
// TODO(tfoley): worry about thread safety here?
- et->canonicalType = et->CreateCanonicalType();
+ auto canType = et->CreateCanonicalType();
+ et->canonicalType = canType;
if (dynamic_cast<Type*>(et->canonicalType) != this)
- et->canonicalTypeRefPtr = et->canonicalType;
+ et->canonicalTypeRefPtr = canType;
+ else
+ canType.detach();
SLANG_ASSERT(et->canonicalType);
}
return et->canonicalType;
@@ -318,10 +321,10 @@ void Type::accept(IValVisitor* visitor, void* extra)
substitutions->args.Add(valueType);
auto declRef = DeclRef<Decl>(typeDecl.Ptr(), substitutions);
-
- return DeclRefType::Create(
+ auto rsType = DeclRefType::Create(
this,
- declRef)->As<PtrTypeBase>();
+ declRef);
+ return rsType->As<PtrTypeBase>();
}
RefPtr<ArrayExpressionType> Session::getArrayType(
@@ -381,13 +384,12 @@ void Type::accept(IValVisitor* visitor, void* extra)
return this;
}
- Type* ArrayExpressionType::CreateCanonicalType()
+ RefPtr<Type> ArrayExpressionType::CreateCanonicalType()
{
auto canonicalElementType = baseType->GetCanonicalType();
auto canonicalArrayType = getArrayType(
canonicalElementType,
ArrayLength);
- session->canonicalTypes.Add(canonicalArrayType);
return canonicalArrayType;
}
int ArrayExpressionType::GetHashCode()
@@ -420,11 +422,10 @@ void Type::accept(IValVisitor* visitor, void* extra)
return valueType->Equals(t->valueType);
}
- Type* GroupSharedType::CreateCanonicalType()
+ RefPtr<Type> GroupSharedType::CreateCanonicalType()
{
auto canonicalValueType = valueType->GetCanonicalType();
auto canonicalGroupSharedType = getSession()->getGroupSharedType(canonicalValueType);
- session->canonicalTypes.Add(canonicalGroupSharedType);
return canonicalGroupSharedType;
}
@@ -456,7 +457,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
return false;
}
- Type* DeclRefType::CreateCanonicalType()
+ RefPtr<Type> DeclRefType::CreateCanonicalType()
{
// A declaration reference is already canonical
return this;
@@ -792,7 +793,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
return false;
}
- Type* OverloadGroupType::CreateCanonicalType()
+ RefPtr<Type> OverloadGroupType::CreateCanonicalType()
{
return this;
}
@@ -814,7 +815,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
return false;
}
- Type* IRBasicBlockType::CreateCanonicalType()
+ RefPtr<Type> IRBasicBlockType::CreateCanonicalType()
{
return this;
}
@@ -836,7 +837,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
return false;
}
- Type* InitializerListType::CreateCanonicalType()
+ RefPtr<Type> InitializerListType::CreateCanonicalType()
{
return this;
}
@@ -860,7 +861,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
return false;
}
- Type* ErrorType::CreateCanonicalType()
+ RefPtr<Type> ErrorType::CreateCanonicalType()
{
return this;
}
@@ -889,7 +890,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
UNREACHABLE_RETURN(false);
}
- Type* NamedExpressionType::CreateCanonicalType()
+ RefPtr<Type> NamedExpressionType::CreateCanonicalType()
{
if (!innerType)
innerType = GetType(declRef);
@@ -981,7 +982,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
return substType;
}
- Type* FuncType::CreateCanonicalType()
+ RefPtr<Type> FuncType::CreateCanonicalType()
{
// result type
RefPtr<Type> canResultType = resultType->GetCanonicalType();
@@ -998,8 +999,6 @@ void Type::accept(IValVisitor* visitor, void* extra)
canType->resultType = resultType;
canType->paramTypes = canParamTypes;
- session->canonicalTypes.Add(canType);
-
return canType;
}
@@ -1035,10 +1034,9 @@ void Type::accept(IValVisitor* visitor, void* extra)
return false;
}
- Type* TypeType::CreateCanonicalType()
+ RefPtr<Type> TypeType::CreateCanonicalType()
{
auto canType = getTypeType(type->GetCanonicalType());
- session->canonicalTypes.Add(canType);
return canType;
}
@@ -1070,7 +1068,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
return declRef.GetHashCode();
}
- Type* GenericDeclRefType::CreateCanonicalType()
+ RefPtr<Type> GenericDeclRefType::CreateCanonicalType()
{
return this;
}
diff --git a/source/slang/type-defs.h b/source/slang/type-defs.h
index a5b9cd659..14e99caf9 100644
--- a/source/slang/type-defs.h
+++ b/source/slang/type-defs.h
@@ -10,7 +10,7 @@ public:
protected:
virtual bool EqualsImpl(Type * type) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
virtual int GetHashCode() override;
)
END_SYNTAX_CLASS()
@@ -23,7 +23,7 @@ RAW(
protected:
virtual bool EqualsImpl(Type * type) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
virtual int GetHashCode() override;
)
END_SYNTAX_CLASS()
@@ -37,7 +37,7 @@ public:
protected:
virtual bool EqualsImpl(Type * type) override;
virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
virtual int GetHashCode() override;
)
END_SYNTAX_CLASS()
@@ -51,7 +51,7 @@ public:
protected:
virtual bool EqualsImpl(Type * type) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
virtual int GetHashCode() override;
)
END_SYNTAX_CLASS()
@@ -77,7 +77,7 @@ RAW(
protected:
virtual int GetHashCode() override;
virtual bool EqualsImpl(Type * type) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
)
END_SYNTAX_CLASS()
@@ -103,7 +103,7 @@ RAW(
protected:
virtual BasicExpressionType* GetScalarType() override;
virtual bool EqualsImpl(Type * type) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
)
END_SYNTAX_CLASS()
@@ -312,7 +312,7 @@ RAW(
protected:
virtual bool EqualsImpl(Type * type) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override;
virtual int GetHashCode() override;
)
@@ -331,7 +331,7 @@ RAW(
protected:
virtual bool EqualsImpl(Type * type) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
virtual int GetHashCode() override;
)
@@ -356,7 +356,7 @@ public:
protected:
virtual bool EqualsImpl(Type * type) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
virtual int GetHashCode() override;
)
END_SYNTAX_CLASS()
@@ -440,7 +440,7 @@ RAW(
protected:
virtual bool EqualsImpl(Type * type) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
virtual int GetHashCode() override;
)
END_SYNTAX_CLASS()
@@ -469,7 +469,7 @@ RAW(
protected:
virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int* ioDiff) override;
virtual bool EqualsImpl(Type * type) override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
virtual int GetHashCode() override;
)
END_SYNTAX_CLASS()
@@ -495,6 +495,6 @@ SYNTAX_CLASS(GenericDeclRefType, Type)
protected:
virtual bool EqualsImpl(Type * type) override;
virtual int GetHashCode() override;
- virtual Type* CreateCanonicalType() override;
+ virtual RefPtr<Type> CreateCanonicalType() override;
)
END_SYNTAX_CLASS()
diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp
index 2a6401d5b..5599a3396 100644
--- a/tools/render-test/slang-support.cpp
+++ b/tools/render-test/slang-support.cpp
@@ -99,8 +99,9 @@ struct SlangShaderCompilerWrapper : public ShaderCompiler
spFindProfile(slangSession, request.computeShader.profile),
(int)rawTypeNames.Count(),
rawTypeNames.Buffer());
- int compileErr = spCompile(slangRequest);
+
spSetLineDirectiveMode(slangRequest, SLANG_LINE_DIRECTIVE_MODE_NONE);
+ int compileErr = spCompile(slangRequest);
if (auto diagnostics = spGetDiagnosticOutput(slangRequest))
{
fprintf(stderr, "%s", diagnostics);