Commit 978ddc59 by Nicolas Capens Committed by Nicolas Capens

Fixed memory leak associated with TLS.

We used to allocate thread-local memory on each compile. If the compile did not happen on the same thread as ShInitialize, we leaked the thread-local memory. It turns out that there is no need to allocate any thread-local memory. This patch cleans up all the unnecessary junk around TLS. BUG=chromium:181691 Change-Id: I4b67ab23dc856d93424ae51ebf8aaf8966b732e4 Reviewed-on: https://swiftshader-review.googlesource.com/1361Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent ff7f1003
......@@ -36,14 +36,14 @@ inline void DecodeSourceLoc(TSourceLoc loc, int* string, int* line) {
//
// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
//
#define POOL_ALLOCATOR_NEW_DELETE(A) \
void* operator new(size_t s) { return (A).allocate(s); } \
void* operator new(size_t, void *_Where) { return (_Where); } \
void operator delete(void*) { } \
void operator delete(void *, void *) { } \
void* operator new[](size_t s) { return (A).allocate(s); } \
void* operator new[](size_t, void *_Where) { return (_Where); } \
void operator delete[](void*) { } \
#define POOL_ALLOCATOR_NEW_DELETE() \
void* operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
void* operator new(size_t, void *_Where) { return (_Where); } \
void operator delete(void*) { } \
void operator delete(void *, void *) { } \
void* operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
void* operator new[](size_t, void *_Where) { return (_Where); } \
void operator delete[](void*) { } \
void operator delete[](void *, void *) { }
//
......@@ -54,7 +54,7 @@ typedef std::basic_string <char, std::char_traits<char>, TStringAllocator> TStri
typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
inline TString* NewPoolTString(const char* s)
{
void* memory = GlobalPoolAllocator.allocate(sizeof(TString));
void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TString));
return new(memory) TString(s);
}
......
......@@ -92,7 +92,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
shaderType, shaderSpec, compileOptions, true,
sourcePath, infoSink);
GlobalParseContext = &parseContext;
SetGlobalParseContext(&parseContext);
// We preserve symbols at the built-in level from compile-to-compile.
// Start pushing the user-defined symbols at global level.
......
......@@ -11,6 +11,7 @@
class ConstantUnion {
public:
POOL_ALLOCATOR_NEW_DELETE();
ConstantUnion()
{
iConst = 0;
......
......@@ -10,25 +10,8 @@
#include "compiler/InitializeParseContext.h"
#include "compiler/osinclude.h"
OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
bool InitProcess()
{
if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
//
// Function is re-entrant.
//
return true;
}
ThreadInitializeIndex = OS_AllocTLSIndex();
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
return false;
}
if (!InitializePoolIndex()) {
assert(0 && "InitProcess(): Failed to initalize global pool");
return false;
......@@ -39,77 +22,11 @@ bool InitProcess()
return false;
}
return InitThread();
}
bool DetachProcess()
{
bool success = true;
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
return true;
success = DetachThread();
if (!FreeParseContextIndex())
success = false;
FreePoolIndex();
OS_FreeTLSIndex(ThreadInitializeIndex);
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
return success;
}
bool InitThread()
{
//
// This function is re-entrant
//
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitThread(): Process hasn't been initalised.");
return false;
}
if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
return true;
InitializeGlobalPools();
if (!InitializeGlobalParseContext())
return false;
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
assert(0 && "InitThread(): Unable to set init flag.");
return false;
}
return true;
}
bool DetachThread()
void DetachProcess()
{
bool success = true;
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
return true;
//
// Function is re-entrant and this thread may not have been initalised.
//
if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
assert(0 && "DetachThread(): Unable to clear init flag.");
success = false;
}
if (!FreeParseContext())
success = false;
FreeGlobalPools();
}
return success;
FreeParseContextIndex();
FreePoolIndex();
}
......@@ -7,10 +7,7 @@
#define __INITIALIZEDLL_H
bool InitProcess();
bool DetachProcess();
bool InitThread();
bool DetachThread();
void DetachProcess();
#endif // __INITIALIZEDLL_H
......@@ -7,8 +7,6 @@
#ifndef __INITIALIZE_GLOBALS_INCLUDED_
#define __INITIALIZE_GLOBALS_INCLUDED_
void InitializeGlobalPools();
void FreeGlobalPools();
bool InitializePoolIndex();
void FreePoolIndex();
......
......@@ -12,85 +12,29 @@ OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
bool InitializeParseContextIndex()
{
if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
return false;
}
assert(GlobalParseContextIndex == OS_INVALID_TLS_INDEX);
//
// Allocate a TLS index.
//
GlobalParseContextIndex = OS_AllocTLSIndex();
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
return false;
}
return true;
return GlobalParseContextIndex != OS_INVALID_TLS_INDEX;
}
bool FreeParseContextIndex()
void FreeParseContextIndex()
{
OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "FreeParseContextIndex(): Parse Context index not initalized");
return false;
}
assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
OS_FreeTLSIndex(GlobalParseContextIndex);
GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
return OS_FreeTLSIndex(tlsiIndex);
}
bool InitializeGlobalParseContext()
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalized");
return false;
}
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
if (lpParseContext != 0) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
return false;
}
TThreadParseContext *lpThreadData = new TThreadParseContext();
if (lpThreadData == 0) {
assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
return false;
}
lpThreadData->lpGlobalParseContext = 0;
OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
return true;
}
bool FreeParseContext()
void SetGlobalParseContext(TParseContext* context)
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "FreeParseContext(): Parse Context index not initalized");
return false;
}
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
if (lpParseContext)
delete lpParseContext;
return true;
assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
OS_SetTLSValue(GlobalParseContextIndex, context);
}
TParseContextPointer& GetGlobalParseContext()
TParseContext* GetGlobalParseContext()
{
//
// Minimal error checking for speed
//
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
return lpParseContext->lpGlobalParseContext;
assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
return static_cast<TParseContext*>(OS_GetTLSValue(GlobalParseContextIndex));
}
......@@ -8,19 +8,10 @@
#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
bool InitializeParseContextIndex();
bool FreeParseContextIndex();
bool InitializeGlobalParseContext();
bool FreeParseContext();
void FreeParseContextIndex();
struct TParseContext;
typedef TParseContext* TParseContextPointer;
extern TParseContextPointer& GetGlobalParseContext();
#define GlobalParseContext GetGlobalParseContext()
typedef struct TThreadParseContextRec
{
TParseContext *lpGlobalParseContext;
} TThreadParseContext;
extern void SetGlobalParseContext(TParseContext* context);
extern TParseContext* GetGlobalParseContext();
#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
......@@ -16,55 +16,32 @@
OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX;
void InitializeGlobalPools()
{
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
if (globalPools)
return;
TThreadGlobalPools* threadData = new TThreadGlobalPools();
threadData->globalPoolAllocator = 0;
OS_SetTLSValue(PoolIndex, threadData);
}
void FreeGlobalPools()
{
// Release the allocated memory for this thread.
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
if (!globalPools)
return;
delete globalPools;
}
bool InitializePoolIndex()
{
// Allocate a TLS index.
if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX)
return false;
assert(PoolIndex == OS_INVALID_TLS_INDEX);
return true;
PoolIndex = OS_AllocTLSIndex();
return PoolIndex != OS_INVALID_TLS_INDEX;
}
void FreePoolIndex()
{
// Release the TLS index.
assert(PoolIndex != OS_INVALID_TLS_INDEX);
OS_FreeTLSIndex(PoolIndex);
PoolIndex = OS_INVALID_TLS_INDEX;
}
TPoolAllocator& GetGlobalPoolAllocator()
TPoolAllocator* GetGlobalPoolAllocator()
{
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
return *threadData->globalPoolAllocator;
assert(PoolIndex != OS_INVALID_TLS_INDEX);
return static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
}
void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
{
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
threadData->globalPoolAllocator = poolAllocator;
assert(PoolIndex != OS_INVALID_TLS_INDEX);
OS_SetTLSValue(PoolIndex, poolAllocator);
}
//
......
......@@ -219,14 +219,8 @@ private:
// different times. But a simple use is to have a global pop
// with everyone using the same global allocator.
//
extern TPoolAllocator& GetGlobalPoolAllocator();
extern TPoolAllocator* GetGlobalPoolAllocator();
extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
#define GlobalPoolAllocator GetGlobalPoolAllocator()
struct TThreadGlobalPools
{
TPoolAllocator* globalPoolAllocator;
};
//
// This STL compatible allocator is intended to be used as the allocator
......@@ -253,7 +247,7 @@ public:
pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const { return &x; }
pool_allocator() : allocator(&GlobalPoolAllocator) { }
pool_allocator() : allocator(GetGlobalPoolAllocator()) { }
pool_allocator(TPoolAllocator& a) : allocator(&a) { }
pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
......
......@@ -23,10 +23,7 @@
//
int ShInitialize()
{
if (!InitProcess())
return 0;
return 1;
return InitProcess() ? 1 : 0;
}
//
......@@ -34,9 +31,7 @@ int ShInitialize()
//
int ShFinalize()
{
if (!DetachProcess())
return 0;
DetachProcess();
return 1;
}
......@@ -69,9 +64,6 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
const ShBuiltInResources* resources)
{
if (!InitThread())
return 0;
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
TCompiler* compiler = base->getAsCompiler();
if (compiler == 0)
......@@ -110,9 +102,6 @@ int ShCompile(
const int numStrings,
int compileOptions)
{
if (!InitThread())
return 0;
if (handle == 0)
return 0;
......
......@@ -40,9 +40,10 @@
//
class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
POOL_ALLOCATOR_NEW_DELETE();
TSymbol(const TString *n) : name(n) { }
virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
const TString& getName() const { return *name; }
virtual const TString& getMangledName() const { return getName(); }
virtual bool isFunction() const { return false; }
......@@ -179,7 +180,7 @@ public:
typedef const tLevel::value_type tLevelPair;
typedef std::pair<tLevel::iterator, bool> tInsertResult;
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
POOL_ALLOCATOR_NEW_DELETE();
TSymbolTableLevel() { }
~TSymbolTableLevel();
......
......@@ -435,7 +435,7 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node)
return true;
bool valid = true;
TSymbolTable& symbolTable = GlobalParseContext->symbolTable;
TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable;
TSymbol* symbol = symbolTable.find(node->getName());
ASSERT(symbol && symbol->isFunction());
TFunction* function = static_cast<TFunction*>(symbol);
......
......@@ -196,7 +196,7 @@ class TInfoSink;
//
class TIntermNode {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
POOL_ALLOCATOR_NEW_DELETE();
TIntermNode() : line(0) {}
......@@ -510,8 +510,7 @@ enum Visit
class TIntermTraverser
{
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
POOL_ALLOCATOR_NEW_DELETE();
TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
preVisit(preVisit),
inVisit(inVisit),
......
......@@ -21,7 +21,7 @@ struct TVectorFields {
class TInfoSink;
class TIntermediate {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
POOL_ALLOCATOR_NEW_DELETE();
TIntermediate(TInfoSink& i) : infoSink(i) { }
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
......
......@@ -24,6 +24,8 @@
namespace es2
{
bool Shader::compilerInitialized = false;
Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
{
mSource = NULL;
......@@ -154,7 +156,11 @@ void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
TranslatorASM *Shader::createCompiler(ShShaderType type)
{
ShInitialize();
if(!compilerInitialized)
{
ShInitialize();
compilerInitialized = true;
}
TranslatorASM *assembler = new TranslatorASM(this, type, SH_GLES2_SPEC);
......@@ -233,6 +239,7 @@ void Shader::flagForDeletion()
void Shader::releaseCompiler()
{
ShFinalize();
compilerInitialized = false;
}
GLenum Shader::parseType(const std::string &type)
......
......@@ -97,6 +97,7 @@ public:
static void releaseCompiler();
protected:
static bool compilerInitialized;
TranslatorASM *createCompiler(ShShaderType type);
void clear();
......
......@@ -36,14 +36,14 @@ inline void DecodeSourceLoc(TSourceLoc loc, int* string, int* line) {
//
// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
//
#define POOL_ALLOCATOR_NEW_DELETE(A) \
void* operator new(size_t s) { return (A).allocate(s); } \
void* operator new(size_t, void *_Where) { return (_Where); } \
void operator delete(void*) { } \
void operator delete(void *, void *) { } \
void* operator new[](size_t s) { return (A).allocate(s); } \
void* operator new[](size_t, void *_Where) { return (_Where); } \
void operator delete[](void*) { } \
#define POOL_ALLOCATOR_NEW_DELETE() \
void* operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
void* operator new(size_t, void *_Where) { return (_Where); } \
void operator delete(void*) { } \
void operator delete(void *, void *) { } \
void* operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
void* operator new[](size_t, void *_Where) { return (_Where); } \
void operator delete[](void*) { } \
void operator delete[](void *, void *) { }
//
......@@ -54,7 +54,7 @@ typedef std::basic_string <char, std::char_traits<char>, TStringAllocator> TStri
typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
inline TString* NewPoolTString(const char* s)
{
void* memory = GlobalPoolAllocator.allocate(sizeof(TString));
void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TString));
return new(memory) TString(s);
}
......
......@@ -92,7 +92,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
shaderType, shaderSpec, compileOptions, true,
sourcePath, infoSink);
GlobalParseContext = &parseContext;
SetGlobalParseContext(&parseContext);
// We preserve symbols at the built-in level from compile-to-compile.
// Start pushing the user-defined symbols at global level.
......
......@@ -11,6 +11,7 @@
class ConstantUnion {
public:
POOL_ALLOCATOR_NEW_DELETE();
ConstantUnion()
{
iConst = 0;
......
......@@ -10,25 +10,8 @@
#include "compiler/InitializeParseContext.h"
#include "compiler/osinclude.h"
OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
bool InitProcess()
{
if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
//
// Function is re-entrant.
//
return true;
}
ThreadInitializeIndex = OS_AllocTLSIndex();
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
return false;
}
if (!InitializePoolIndex()) {
assert(0 && "InitProcess(): Failed to initalize global pool");
return false;
......@@ -39,77 +22,11 @@ bool InitProcess()
return false;
}
return InitThread();
}
bool DetachProcess()
{
bool success = true;
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
return true;
success = DetachThread();
if (!FreeParseContextIndex())
success = false;
FreePoolIndex();
OS_FreeTLSIndex(ThreadInitializeIndex);
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
return success;
}
bool InitThread()
{
//
// This function is re-entrant
//
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitThread(): Process hasn't been initalised.");
return false;
}
if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
return true;
InitializeGlobalPools();
if (!InitializeGlobalParseContext())
return false;
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
assert(0 && "InitThread(): Unable to set init flag.");
return false;
}
return true;
}
bool DetachThread()
void DetachProcess()
{
bool success = true;
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
return true;
//
// Function is re-entrant and this thread may not have been initalised.
//
if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
assert(0 && "DetachThread(): Unable to clear init flag.");
success = false;
}
if (!FreeParseContext())
success = false;
FreeGlobalPools();
}
return success;
FreeParseContextIndex();
FreePoolIndex();
}
......@@ -7,10 +7,7 @@
#define __INITIALIZEDLL_H
bool InitProcess();
bool DetachProcess();
bool InitThread();
bool DetachThread();
void DetachProcess();
#endif // __INITIALIZEDLL_H
......@@ -7,8 +7,6 @@
#ifndef __INITIALIZE_GLOBALS_INCLUDED_
#define __INITIALIZE_GLOBALS_INCLUDED_
void InitializeGlobalPools();
void FreeGlobalPools();
bool InitializePoolIndex();
void FreePoolIndex();
......
......@@ -12,85 +12,29 @@ OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
bool InitializeParseContextIndex()
{
if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
return false;
}
assert(GlobalParseContextIndex == OS_INVALID_TLS_INDEX);
//
// Allocate a TLS index.
//
GlobalParseContextIndex = OS_AllocTLSIndex();
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
return false;
}
return true;
return GlobalParseContextIndex != OS_INVALID_TLS_INDEX;
}
bool FreeParseContextIndex()
void FreeParseContextIndex()
{
OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "FreeParseContextIndex(): Parse Context index not initalized");
return false;
}
assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
OS_FreeTLSIndex(GlobalParseContextIndex);
GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
return OS_FreeTLSIndex(tlsiIndex);
}
bool InitializeGlobalParseContext()
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalized");
return false;
}
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
if (lpParseContext != 0) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalized");
return false;
}
TThreadParseContext *lpThreadData = new TThreadParseContext();
if (lpThreadData == 0) {
assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
return false;
}
lpThreadData->lpGlobalParseContext = 0;
OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
return true;
}
bool FreeParseContext()
void SetGlobalParseContext(TParseContext* context)
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "FreeParseContext(): Parse Context index not initalized");
return false;
}
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
if (lpParseContext)
delete lpParseContext;
return true;
assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
OS_SetTLSValue(GlobalParseContextIndex, context);
}
TParseContextPointer& GetGlobalParseContext()
TParseContext* GetGlobalParseContext()
{
//
// Minimal error checking for speed
//
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
return lpParseContext->lpGlobalParseContext;
assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
return static_cast<TParseContext*>(OS_GetTLSValue(GlobalParseContextIndex));
}
......@@ -8,19 +8,10 @@
#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
bool InitializeParseContextIndex();
bool FreeParseContextIndex();
bool InitializeGlobalParseContext();
bool FreeParseContext();
void FreeParseContextIndex();
struct TParseContext;
typedef TParseContext* TParseContextPointer;
extern TParseContextPointer& GetGlobalParseContext();
#define GlobalParseContext GetGlobalParseContext()
typedef struct TThreadParseContextRec
{
TParseContext *lpGlobalParseContext;
} TThreadParseContext;
extern void SetGlobalParseContext(TParseContext* context);
extern TParseContext* GetGlobalParseContext();
#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
......@@ -16,55 +16,32 @@
OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX;
void InitializeGlobalPools()
{
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
if (globalPools)
return;
TThreadGlobalPools* threadData = new TThreadGlobalPools();
threadData->globalPoolAllocator = 0;
OS_SetTLSValue(PoolIndex, threadData);
}
void FreeGlobalPools()
{
// Release the allocated memory for this thread.
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
if (!globalPools)
return;
delete globalPools;
}
bool InitializePoolIndex()
{
// Allocate a TLS index.
if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX)
return false;
assert(PoolIndex == OS_INVALID_TLS_INDEX);
return true;
PoolIndex = OS_AllocTLSIndex();
return PoolIndex != OS_INVALID_TLS_INDEX;
}
void FreePoolIndex()
{
// Release the TLS index.
assert(PoolIndex != OS_INVALID_TLS_INDEX);
OS_FreeTLSIndex(PoolIndex);
PoolIndex = OS_INVALID_TLS_INDEX;
}
TPoolAllocator& GetGlobalPoolAllocator()
TPoolAllocator* GetGlobalPoolAllocator()
{
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
return *threadData->globalPoolAllocator;
assert(PoolIndex != OS_INVALID_TLS_INDEX);
return static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
}
void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
{
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
threadData->globalPoolAllocator = poolAllocator;
assert(PoolIndex != OS_INVALID_TLS_INDEX);
OS_SetTLSValue(PoolIndex, poolAllocator);
}
//
......
......@@ -219,14 +219,8 @@ private:
// different times. But a simple use is to have a global pop
// with everyone using the same global allocator.
//
extern TPoolAllocator& GetGlobalPoolAllocator();
extern TPoolAllocator* GetGlobalPoolAllocator();
extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
#define GlobalPoolAllocator GetGlobalPoolAllocator()
struct TThreadGlobalPools
{
TPoolAllocator* globalPoolAllocator;
};
//
// This STL compatible allocator is intended to be used as the allocator
......@@ -253,7 +247,7 @@ public:
pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const { return &x; }
pool_allocator() : allocator(&GlobalPoolAllocator) { }
pool_allocator() : allocator(GetGlobalPoolAllocator()) { }
pool_allocator(TPoolAllocator& a) : allocator(&a) { }
pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
......
......@@ -23,10 +23,7 @@
//
int ShInitialize()
{
if (!InitProcess())
return 0;
return 1;
return InitProcess() ? 1 : 0;
}
//
......@@ -34,9 +31,7 @@ int ShInitialize()
//
int ShFinalize()
{
if (!DetachProcess())
return 0;
DetachProcess();
return 1;
}
......@@ -69,9 +64,6 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
const ShBuiltInResources* resources)
{
if (!InitThread())
return 0;
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
TCompiler* compiler = base->getAsCompiler();
if (compiler == 0)
......@@ -110,9 +102,6 @@ int ShCompile(
const int numStrings,
int compileOptions)
{
if (!InitThread())
return 0;
if (handle == 0)
return 0;
......
......@@ -40,9 +40,10 @@
//
class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
POOL_ALLOCATOR_NEW_DELETE();
TSymbol(const TString *n) : name(n) { }
virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
const TString& getName() const { return *name; }
virtual const TString& getMangledName() const { return getName(); }
virtual bool isFunction() const { return false; }
......@@ -179,7 +180,7 @@ public:
typedef const tLevel::value_type tLevelPair;
typedef std::pair<tLevel::iterator, bool> tInsertResult;
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
POOL_ALLOCATOR_NEW_DELETE();
TSymbolTableLevel() { }
~TSymbolTableLevel();
......
......@@ -435,7 +435,7 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node)
return true;
bool valid = true;
TSymbolTable& symbolTable = GlobalParseContext->symbolTable;
TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable;
TSymbol* symbol = symbolTable.find(node->getName());
ASSERT(symbol && symbol->isFunction());
TFunction* function = static_cast<TFunction*>(symbol);
......
......@@ -196,7 +196,7 @@ class TInfoSink;
//
class TIntermNode {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
POOL_ALLOCATOR_NEW_DELETE();
TIntermNode() : line(0) {}
......@@ -510,8 +510,7 @@ enum Visit
class TIntermTraverser
{
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
POOL_ALLOCATOR_NEW_DELETE();
TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
preVisit(preVisit),
inVisit(inVisit),
......
......@@ -21,7 +21,7 @@ struct TVectorFields {
class TInfoSink;
class TIntermediate {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
POOL_ALLOCATOR_NEW_DELETE();
TIntermediate(TInfoSink& i) : infoSink(i) { }
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
......
......@@ -24,6 +24,8 @@
namespace rad
{
bool Shader::compilerInitialized = false;
Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
{
mSource = NULL;
......@@ -154,7 +156,11 @@ void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
TranslatorASM *Shader::createCompiler(ShShaderType type)
{
ShInitialize();
if(!compilerInitialized)
{
ShInitialize();
compilerInitialized = true;
}
TranslatorASM *assembler = new TranslatorASM(this, type, SH_GLES2_SPEC);
......@@ -233,6 +239,7 @@ void Shader::flagForDeletion()
void Shader::releaseCompiler()
{
ShFinalize();
compilerInitialized = false;
}
GLenum Shader::parseType(const std::string &type)
......
......@@ -97,6 +97,7 @@ public:
static void releaseCompiler();
protected:
static bool compilerInitialized;
TranslatorASM *createCompiler(ShShaderType type);
void clear();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment