Ensure the shared symbol table levels are read-only to make multi-threading safe. Also removed inadvertent extra copies of the symbol table shared across all stages.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22939 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-09-06 19:52:57 +00:00
parent 69f4b517c2
commit 38f3b890de
14 changed files with 230 additions and 125 deletions

View file

@ -80,7 +80,7 @@ class TAnonMember;
class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
explicit TSymbol(const TString *n) : name(n) { }
explicit TSymbol(const TString *n) : name(n), writable(true) { }
virtual TSymbol* clone(TStructureMap& remapper) = 0;
virtual ~TSymbol() { }
@ -88,18 +88,28 @@ public:
void changeName(const char* buf) { name = new TString(buf); }
virtual const TString& getMangledName() const { return getName(); }
virtual TFunction* getAsFunction() { return 0; }
virtual const TFunction* getAsFunction() const { return 0; }
virtual TVariable* getAsVariable() { return 0; }
virtual TAnonMember* getAsAnonMember() { return 0; }
virtual const TVariable* getAsVariable() const { return 0; }
virtual const TAnonMember* getAsAnonMember() const { return 0; }
void setUniqueId(int id) { uniqueId = id; }
int getUniqueId() const { return uniqueId; }
virtual void dump(TInfoSink &infoSink) const = 0;
void readOnly() { writable = false; }
protected:
explicit TSymbol(const TSymbol&);
TSymbol& operator=(const TSymbol&);
const TString *name;
unsigned int uniqueId; // For cross-scope comparing during code generation
//
// N.B.: Non-const functions that will be generally used should assert an this,
// to avoid overwriting shared symbol-table information.
//
bool writable;
};
//
@ -119,12 +129,12 @@ public:
virtual ~TVariable() { }
virtual TVariable* getAsVariable() { return this; }
TType& getType() { return type; }
virtual const TVariable* getAsVariable() const { return this; }
TType& getWritableType() { assert(writable); return type; }
const TType& getType() const { return type; }
bool isUserType() const { return userType; }
void setStorageQualifier(TStorageQualifier qualifier) { type.getQualifier().storage = qualifier; }
void updateArrayInformationType(TType *t) { arrayInformationType = t; }
TType* getArrayInformationType() { return arrayInformationType; }
void updateArrayInformationType(TType *t) { assert(writable); arrayInformationType = t; }
TType* getArrayInformationType() { assert(writable); return arrayInformationType; }
virtual void dump(TInfoSink &infoSink) const;
@ -193,22 +203,24 @@ public:
virtual ~TFunction();
virtual TFunction* getAsFunction() { return this; }
virtual const TFunction* getAsFunction() const { return this; }
void addParameter(TParameter& p)
{
assert(writable);
parameters.push_back(p);
p.type->appendMangledName(mangledName);
}
const TString& getMangledName() const { return mangledName; }
const TType& getReturnType() const { return returnType; }
void relateToOperator(TOperator o) { op = o; }
void relateToOperator(TOperator o) { assert(writable); op = o; }
TOperator getBuiltInOp() const { return op; }
void setDefined() { defined = true; }
bool isDefined() { return defined; }
void setDefined() { assert(writable); defined = true; }
bool isDefined() const { return defined; }
int getParamCount() const { return static_cast<int>(parameters.size()); }
TParameter& operator [](int i) { return parameters[i]; }
TParameter& operator [](int i) { assert(writable); return parameters[i]; }
const TParameter& operator [](int i) const { return parameters[i]; }
virtual void dump(TInfoSink &infoSink) const;
@ -232,7 +244,7 @@ public:
virtual TAnonMember* clone(TStructureMap& remapper);
virtual ~TAnonMember() { }
TAnonMember* getAsAnonMember() { return this; }
const TAnonMember* getAsAnonMember() const { return this; }
TSymbol& getAnonContainer() const { return anonContainer; }
unsigned int getMemberNumber() const { return memberNumber; }
virtual void dump(TInfoSink &infoSink) const;
@ -266,7 +278,7 @@ public:
symbol.changeName(buf);
bool isOkay = true;
TTypeList& types = *symbol.getAsVariable()->getType().getStruct();
const TTypeList& types = *symbol.getAsVariable()->getType().getStruct();
for (unsigned int m = 0; m < types.size(); ++m) {
TAnonMember* member = new TAnonMember(&types[m].type->getFieldName(), m, symbol);
result = level.insert(tLevelPair(member->getMangledName(), member));
@ -351,6 +363,7 @@ public:
void relateToOperator(const char* name, TOperator op);
void dump(TInfoSink &infoSink) const;
TSymbolTableLevel* clone(TStructureMap& remapper);
void readOnly();
protected:
explicit TSymbolTableLevel(TSymbolTableLevel&);
@ -397,15 +410,17 @@ public:
// 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
// 2: built-ins specific to a compile, like resources that are context-dependent, or redeclared built-ins
// 3: user-shader globals
//
protected:
static const int globalLevel = 3;
bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
bool isGlobalLevel(int level) { return level <= 3; } // include user globals
public:
bool isEmpty() { return table.size() == 0; }
bool atBuiltInLevel() { return table.size() <= globalLevel; } // exclude user globals
bool atGlobalLevel() { return table.size() <= globalLevel + 1; } // include user globals
bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
bool atGlobalLevel() { return isGlobalLevel(currentLevel()); }
void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
@ -440,7 +455,7 @@ public:
return table[currentLevel()]->insert(symbol);
}
TSymbol* find(const TString& name, bool* builtIn = 0, bool *sameScope = 0)
TSymbol* find(const TString& name, bool* builtIn = 0, bool *currentScope = 0, bool *sharedLevel = 0)
{
int level = currentLevel();
TSymbol* symbol;
@ -450,9 +465,11 @@ public:
} while (symbol == 0 && level >= 0);
level++;
if (builtIn)
*builtIn = level < 2;
if (sameScope)
*sameScope = level == currentLevel();
*builtIn = isBuiltInLevel(level);
if (currentScope)
*currentScope = level == currentLevel();
if (sharedLevel)
*sharedLevel = isSharedLevel(level);
return symbol;
}
@ -469,6 +486,12 @@ public:
void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }
void readOnly()
{
for (unsigned int level = 0; level < table.size(); ++level)
table[level]->readOnly();
}
protected:
TSymbolTable(TSymbolTable&);
TSymbolTable& operator=(TSymbolTableLevel&);