Skip to content
Snippets Groups Projects
Commit a5ea9c63 authored by John Kessenich's avatar John Kessenich
Browse files

Dynamically allocate symbol table containers, so timing of clean up can be...

Dynamically allocate symbol table containers, so timing of clean up can be more easily controlled WRT memory pool cleanup.


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22681 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent 99a05762
No related branches found
No related tags found
No related merge requests found
#! /bin/bash
rm -f StandAlone/StandAlone
rm -f StandAlone/glsangValidator
rm -f glslang/MachineIndependent/lib/libglslang.so
# build the StandAlone app and all it's dependencies
make -C StandAlone
# so we can find the shared library
LD_LIBRARY_PATH=`pwd`/glslang/MachineIndependent/lib:${LD_LIBRARY_PATH}
LD_LIBRARY_PATH=`pwd`/glslang/MachineIndependent/lib
export LD_LIBRARY_PATH
# run using test data
......
......@@ -109,8 +109,6 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil
parseContext.scanContext = &scanContext;
parseContext.ppContext = &ppContext;
assert(symbolTable.isEmpty() || symbolTable.atSharedBuiltInLevel());
//
// Parse the built-ins. This should only happen once per
// language symbol table when no 'resources' are passed in.
......@@ -140,29 +138,29 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil
//
// To call for per-stage initialization, with the common table already complete.
//
void InitializeSymbolTable(TBuiltIns& builtIns, int version, EProfile profile, EShLanguage language, TInfoSink& infoSink, TSymbolTable* commonTable, TSymbolTable* symbolTables)
void InitializeSymbolTable(TBuiltIns& builtIns, int version, EProfile profile, EShLanguage language, TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables)
{
int commonIndex = EPcGeneral;
if (profile == EEsProfile && language == EShLangFragment)
commonIndex = EPcFragment;
symbolTables[language].adoptLevels(commonTable[commonIndex]);
InitializeSymbolTable(builtIns.getStageString(language), version, profile, language, infoSink, symbolTables[language]);
IdentifyBuiltIns(version, profile, language, symbolTables[language]);
(*symbolTables[language]).adoptLevels(*commonTable[commonIndex]);
InitializeSymbolTable(builtIns.getStageString(language), version, profile, language, infoSink, *symbolTables[language]);
IdentifyBuiltIns(version, profile, language, *symbolTables[language]);
if (profile == EEsProfile)
symbolTables[language].setNoBuiltInRedeclarations();
(*symbolTables[language]).setNoBuiltInRedeclarations();
}
bool GenerateBuiltInSymbolTable(TInfoSink& infoSink, TSymbolTable* commonTable, TSymbolTable* symbolTables, int version, EProfile profile)
bool GenerateBuiltInSymbolTable(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile)
{
TBuiltIns builtIns;
builtIns.initialize(version, profile);
// do the common table
InitializeSymbolTable(builtIns.getCommonString(), version, profile, EShLangVertex, infoSink, commonTable[EPcGeneral]);
InitializeSymbolTable(builtIns.getCommonString(), version, profile, EShLangVertex, infoSink, *commonTable[EPcGeneral]);
if (profile == EEsProfile)
InitializeSymbolTable(builtIns.getCommonString(), version, profile, EShLangFragment, infoSink, commonTable[EPcFragment]);
InitializeSymbolTable(builtIns.getCommonString(), version, profile, EShLangFragment, infoSink, *commonTable[EPcFragment]);
// do the per-stage tables
InitializeSymbolTable(builtIns, version, profile, EShLangVertex, infoSink, commonTable, symbolTables);
......@@ -222,9 +220,15 @@ void SetupBuiltinSymbolTable(int version, EProfile profile)
TPoolAllocator* builtInPoolAllocator = new TPoolAllocator();
SetThreadPoolAllocator(*builtInPoolAllocator);
// Dynamically allocate the symbol tables so we can control when they are deallocated WRT the pool.
TSymbolTable* commonTable[EPcCount];
TSymbolTable* stageTables[EShLangCount];
for (int precClass = 0; precClass < EPcCount; ++precClass)
commonTable[precClass] = new TSymbolTable;
for (int stage = 0; stage < EShLangCount; ++stage)
stageTables[stage] = new TSymbolTable;
// Generate the local symbol tables using the new pool
TSymbolTable commonTable[2];
TSymbolTable stageTables[EShLangCount];
GenerateBuiltInSymbolTable(infoSink, commonTable, stageTables, version, profile);
// Switch to the process-global pool
......@@ -232,23 +236,23 @@ void SetupBuiltinSymbolTable(int version, EProfile profile)
// Copy the local symbol tables from the new pool to the global tables using the process-global pool
for (int precClass = 0; precClass < EPcCount; ++precClass) {
if (! commonTable[precClass].isEmpty()) {
if (! commonTable[precClass]->isEmpty()) {
CommonSymbolTable[versionIndex][profile][precClass] = new TSymbolTable;
CommonSymbolTable[versionIndex][profile][precClass]->copyTable(commonTable[precClass]);
CommonSymbolTable[versionIndex][profile][precClass]->copyTable(*commonTable[precClass]);
}
}
for (int stage = 0; stage < EShLangCount; ++stage) {
if (! stageTables[stage].isEmpty()) {
if (! stageTables[stage]->isEmpty()) {
SharedSymbolTables[versionIndex][profile][stage] = new TSymbolTable;
SharedSymbolTables[versionIndex][profile][stage]->copyTable(stageTables[stage]);
SharedSymbolTables[versionIndex][profile][stage]->copyTable(*stageTables[stage]);
}
}
// Explicitly clean up the local tables before deleting the pool they used and before releasing the lock.
// Clean up the local tables before deleting the pool they used.
for (int precClass = 0; precClass < EPcCount; ++precClass)
commonTable[precClass].~TSymbolTable();
delete commonTable[precClass];
for (int stage = 0; stage < EShLangCount; ++stage)
stageTables[stage].~TSymbolTable();
delete stageTables[stage];
delete builtInPoolAllocator;
SetThreadPoolAllocator(savedGPA);
......@@ -458,7 +462,10 @@ int ShCompile(
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
[profile]
[compiler->getLanguage()];
TSymbolTable symbolTable;
// Dynamically allocate the symbol table so we can control when it is deallocated WRT the pool.
TSymbolTable* symbolTableMemory = new TSymbolTable;
TSymbolTable& symbolTable = *symbolTableMemory;
if (cachedTable)
symbolTable.adoptLevels(*cachedTable);
......@@ -531,12 +538,8 @@ int ShCompile(
intermediate.remove(parseContext.treeRoot);
//
// Ensure symbol table is returned to the built-in level,
// throwing away all but the built-ins.
//
while (! symbolTable.atSharedBuiltInLevel())
symbolTable.pop(0);
// Clean up the symbol table before deallocating the pool memory it used.
delete symbolTableMemory;
//
// Throw away all the temporary memory used by the compilation process.
......
......@@ -373,19 +373,13 @@ public:
}
~TSymbolTable()
{
// this can be called explicitly; safest to code it so it can be called multiple times
// don't deallocate levels passed in from elsewhere
while (table.size() > adoptedLevels)
pop(0);
}
//
// While level adopting is generic, the methods below enact a the following
// convention for levels:
// 0: common built-ins shared across all stages, all compiles, only one copy for all symbol tables
// 1: per-stage built-ins, shared across all compiles, but a different copy per stage
// 2: built-ins specific to a compile, like resources that are context-dependent
// 3: user-shader globals
//
void adoptLevels(TSymbolTable& symTable)
{
for (unsigned int level = 0; level < symTable.table.size(); ++level) {
......@@ -395,11 +389,21 @@ public:
uniqueId = symTable.uniqueId;
noBuiltInRedeclarations = symTable.noBuiltInRedeclarations;
}
//
// While level adopting is generic, the methods below enact a the following
// convention for levels:
// 0: common built-ins shared across all stages, all compiles, only one copy for all symbol tables
// 1: per-stage built-ins, shared across all compiles, but a different copy per stage
// 2: built-ins specific to a compile, like resources that are context-dependent
// 3: user-shader globals
//
protected:
static const int globalLevel = 3;
public:
bool isEmpty() { return table.size() == 0; }
bool atBuiltInLevel() { return atSharedBuiltInLevel() || atDynamicBuiltInLevel(); }
bool atSharedBuiltInLevel() { return table.size() <= 2; }
bool atDynamicBuiltInLevel() { return table.size() == 3; }
bool atGlobalLevel() { return table.size() <= 4; }
bool atBuiltInLevel() { return table.size() <= globalLevel; } // exclude user globals
bool atGlobalLevel() { return table.size() <= globalLevel + 1; } // include user globals
void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
......@@ -411,7 +415,7 @@ public:
void pop(TPrecisionQualifier *p)
{
table[currentLevel()]->getPreviousDefaultPrecisions(p);
delete table[currentLevel()];
delete table.back();
table.pop_back();
}
......@@ -453,12 +457,8 @@ public:
void relateToOperator(const char* name, TOperator op)
{
for (unsigned int level = 0; level < table.size(); ++level) {
if (atSharedBuiltInLevel())
table[level]->relateToOperator(name, op);
else
break;
}
for (unsigned int level = 0; level < table.size(); ++level)
table[level]->relateToOperator(name, op);
}
int getMaxSymbolId() { return uniqueId; }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment